k8s04 - 什么是NodeIP、PodIP、ClusterIP、NodePort、Port、TargetPort、HostPort

1、IP 类型

Kubernetes 集群里有三种IP地址,分别如下:

名称 说明
NodeIP Worker 节点的IP地址,即物理网卡的 IP 地址。
PodIP Pod 的 IP 地址,即 Containerd 容器的IP 地址,此为虚拟 IP 地址。
ClusterIP Service 的 IP 地址,此为虚拟 IP 地址。

1.1、NodeIP

  • 可以是物理机的 IP(也可能是虚拟机 IP)。

    • 每个Service都会在Node节点上开通一个端口,外部可以通过 nodeIP:nodePort 即可访问nServicen里的nPod,和我们访问服务器部署的项目一样,IP:端口/项目名
  • 在 K8S 中查询 NodeIP

kubectl get nodes -o wide

显示出来的InternalIP就是NodeIP

1.2、Pod IP

  • Pod IP 是每个 Pod 的 IP 地址,他是 ContainerdEngine 根据网桥的IP地址段进行分配的,通常是一个虚拟的二层网络

    • 同 Service 下的 Pod 可以直接根据 PodIP 相互通信
    • 不同 Service下的pod在集群间pod通信要借助于 ClusterIP
    • Pod 和集群外通信,要借助于 NodeIP
  • 在 kubernetes 查询 Pod IP
    kubectl get pods -n kubernetes-dashboard -o wide

1.3、ClusterIP

  • 即 Service 的 IP 地址,是虚拟 IP 地址。在集群外部无法 Ping 通,只能在集群内部使用。

  • ClusterIP是一个虚拟的 IP,但更像是一个伪造的 IP 网络,原因有以下几点:

    • ClusterIP 仅仅作用于 Service 对象,并由 Kubernetes 管理和分配地址
    • ClusterIP 无法被 Ping,他没有一个“实体网络对象”来响应
    • ClusterIP 只能结合 ServicePort 组成一个具体的通信端口,单独的 ClusterIP 不具备通信的基础,并且他们属于 Kubernetes 集群这样一个封闭的空间。
  • 在不同 Service 下的 Pod 节点在集群间可以通过 ClusterIP 相互访问

  • 在kubernetes查询Cluster IP

kubectl get svc -n kubernetes-dashboard

2、Port类型

2.1、nodePort

  • 外部流量访问 K8S 集群中 Service 入口的一种方式(另一种方式是LoadBalancer),即 nodeIP:nodePort 是提供给外部流量访问 K8S 集群中 Service 的入口。比如外部用户要访问集群中的一个 Web 应用,那么我们可以配置对应 Service 的type=NodePort,nodePort=30001。其他用户就可以通过浏览器 http://NodeIP:30001 访问到该 Web 服务。对于无需被外部访问的服务,如数据库等,我们就不必设置 Service的 NodePort。

  • nodePort 方式会自动在集群所有的 Worker 节点监听这个端口,客户端可以访问任何一个 Worker 的这个端口都能访问到服务

2.2、port

  • K8S 集群内部服务之间访问 Service 的入口。即 ClusterIP:Port 是 Service 暴露在 ClusterIP 上的端口。以一个 MySQL 服务为例,容器暴露了 13306 端口,集群内其他容器通过 13306 端口访问 MySQL 服务,但是外部流量不能访问 MySQL 服务,因为 MySQL 服务没有配置 NodePort。

对应的 service.yaml如下:

apiVersion: v1
kind: Service
metadata:
 name: mysql-service
spec:
 ports:
 - port: 13306
   targetPort: 3306
 selector:
  name: mysql-pod

2.3、targetPort

  • 容器的端口(最终的流量端口)。targetPort 是 pod 上的端口,从 port 和 nodePort 上来的流量,经过 kube-proxy 流入到后端 pod 的 targetPort上,最后进入容器。

注意在打包镜像时程序暴露的端口,保持一致方便管理,以下是官方的 Nginx(参考DockerFile)暴露 80 端口,service.yaml 如下:

apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 type: NodePort         // 有配置NodePort,外部流量可访问 K8S 中的服务
 ports:
 - port: 30080          // 服务访问端口
   targetPort: 80       // 容器端口
   nodePort: 30001      // NodePort
 selector:
  name: nginx-pod

2.4、hostPort

  • 这是一种直接定义 Pod 网络的方式。hostPort 是直接将容器的端口与所调度的 Worker 节点上的端口路由,这样用户就可以通过 Worker 主机的 IP 加上端口来访问 Pod 了,如:
apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  containers:
    - name: influxdb
      image: influxdb
      ports:
        - containerPort: 8086
          hostPort: 8086

hostPort 只会在 Pod 当前运行的 Worker 节点上监听端口。这样做就会有个缺点,因为 Pod 重新调度的时候该 Pod 被调度到的宿主机可能会变动,这样提供给外部请求的 IP 就变化了,用户必须自己维护一个 Pod 与所在宿主机的对应关系。

使用了 hostPort 的容器只能调度到端口不冲突的 Worker 节点上,除非有必要(比如运行一些系统级的 Daemon 服务),不建议使用端口映射功能。如果需要对外暴露服务,建议使用 NodePort。

  • hostPort 只在 Pod 当前运行的 Worker 节点上暴露端口,只是一个简单的映射关系,如果 Pod 重启被调度到其他 Worker 节点上,那么外部服务的访问就失效了;这一点与 nodePort 有明显区别

  • port 和 nodePort 都是 Service 的端口,前者暴露给 K8S 集群内部服务访问,后者暴露给 K8S 集群外部访问。从上两个端口过来的数据都需要经过反向代理 kube-proxy,流入后端 Pod 的 targetPort 上,最后到达 Pod 内的容器。

posted @ 2023-02-02 20:37  unchch  阅读(3263)  评论(0编辑  收藏  举报