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