K8s nodePort、port、targetPort、hostPort

1. nodePort

外部流量訪問k8s集羣中service入口的一種方式(另一種方式是LoadBalancer),即nodeIP:nodePort是提供給外部流量訪問k8s集羣中service的入口。比如外部用戶要訪問k8s集羣中的一個Web應用,那麼我們可以配置對應service的type=NodePort,nodePort=30001。其他用戶就可以通過瀏覽器http://node:30001訪問到該web服務。而數據庫等服務可能不需要被外界訪問,只需被內部服務訪問即可,那麼我們就不必設置service的NodePort。

[zhangweijian@master k8s]$ kubectl describe svc nginx-service-nodeport  -n testzhang
Name:                     nginx-service-nodeport
Namespace:                testzhang
Labels:                   <none>
Annotations:              <none>
Selector:                 name=nginx
Type:                     NodePort
IP:                       10.1.194.115
Port:                     <unset>  8000/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31143/TCP
Endpoints:                10.244.1.174:80,10.244.2.88:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

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
 selector:
  name: mysql-pod

3.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       // 容器端口
   nodePort: 30001      // NodePort   如果不給值, docker會隨機給默認值
 selector:
  name: nginx-pod

4.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。

5. 總結

總的來說,port和nodePort都是service的端口,前者暴露給k8s集羣內部服務訪問,後者暴露給k8s集羣外部流量訪問。從上兩個端口過來的數據都需要經過反向代理kube-proxy,流入後端pod的targetPort上,最後到達pod內的容器。

參考:
https://blog.csdn.net/yjk13703623757/article/details/79819415

https://jimmysong.io/posts/accessing-kubernetes-pods-from-outside-of-the-cluster/

https://feisky.gitbooks.io/kubernetes/practice/portmap.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章