k8s 端口映射

0 参考

https://www.jianshu.com/p/8275f2031c83

1 梳理

  1. nodePort
    外部流量访问 k8s 集群中的 service 有两种方式,分别是 负载均衡(LoadBalancer)和 nodeIP:nodePort。比如外部用户要访问k8s集群中的一个Web应用,那么我们可以配置对应service的type=NodePort,nodePort=30001。其他用户就可以通过浏览器http://node:30001访问到该web服务。而数据库等服务可能不需要被外界访问,只需被内部服务访问即可,那么我们就不必设置service的NodePort。
  2. port
    k8s集群内部服务之间访问service的入口。即clusterIP:port是service暴露在clusterIP上的端口。mysql容器暴露了3306端口,集群内其他容器通过33306端口访问mysql服务,但是外部流量不能访问mysql服务,因为mysql服务没有配置NodePort。对应的service.yaml如下:
apiVersion: v1
kind: Service
metadata:
 name: mysql-service
spec:
 ports:
 - port: 33306 # 集群内其他服务访问的端口,即暴露出去的端口
   targetPort: 3306 # 服务本身的端口,即 docker export 出来的端口
 selector:
  name: mysql-pod
  1. targetPort
    容器的端口(最终的流量端口)。targetPort是pod上的端口,从port和nodePort上来的流量,经过kube-proxy流入到后端pod的targetPort上,最后进入容器。
    制作容器时暴露的端口一致(使用DockerFile中的EXPOSE),例如官方的nginx(参考DockerFile)暴露80端口。 对应的service.yaml如下
apiVersion: v1
kind: Service
metadata:
 name: nginx-service
spec:
 type: NodePort         // 有配置NodePort,外部流量可访问k8s中的服务
 ports:
 - port: 30080          // 集群内部服务间访问该服务的端口
   targetPort: 80       // 容器暴露出去的端口,docker 中暴露的端口
   nodePort: 30001      // 外部访问的端口
 selector:
  name: nginx-pod
  1. hostPort
    这是一种直接定义Pod网络的方式。hostPort是直接将容器的端口与所调度的节点上的端口路由,这样用户就可以通过宿主机的IP加上来访问Pod了,如:
apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  containers:
    - name: influxdb
      image: influxdb
      ports:
        - containerPort: 8086
          hostPort: 8086

这样做有个缺点,因为Pod重新调度的时候该Pod被调度到的宿主机可能会变动,这样就变化了,用户必须自己维护一个Pod与所在宿主机的对应关系。
使用了 hostPort 的容器只能调度到端口不冲突的 Node 上,除非有必要(比如运行一些系统级的 daemon 服务),不建议使用端口映射功能。如果需要对外暴露服务,建议使用 NodePort Service。

2 总结

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

posted @ 2022-08-31 12:06  MeiyangLi  阅读(2025)  评论(0编辑  收藏  举报