背景
對于port 可能有以下大概三種需求
- 同一個pod 里不同container 可以訪問
- 在一個cluster 里, 不同pod 里可以訪問
- 暴露到集群外面躯保。即 可以在集群外通過ip 端口訪問
先來了解下 k8s cluster networking
k8s cluster networking
每個pod 都有自己的 IP 地址 泣矛。這意味著你不需要 處理容器port 對 主機(jī) port 的映射窖维。pods 就像VM 或者 物理機(jī)哪樣
k8s 的IP 地址 存在于 pod scope - 在一個Pod 的 容器們 共享 networknamespaces, 包括IP 地址曙寡。這意味著在一個pod 里的容器們 能夠通過localhost
訪問彼此的 端口讼溺。這也意味著 在一個pod 里的容器們需要協(xié)調(diào) 端口的使用。這就叫做 "IP-per-pod" model
來看一個例子
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
selector:
matchLabels:
run: my-nginx
replicas: 2
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 80
將上面代碼保存為nginx.yaml
kubectl apply -f nginx.yaml
# 查看pod
kubectl get pods -l run=my-nginx -o wide
# 查看pod ip
kubectl get pods -l run=my-nginx -o yaml | grep podIP
你可以ssh 連接到集群里的任意一個node 并curl IPs叼耙。 Note: 這個容器沒有用node 的80 端口腕窥。也沒有用NAT 規(guī)則到這個pod 上。這意味著可以在同一個node 上使用相同的 containerPort 并且在 你的集群里用ip 從node或者其他 pod 上去訪問 它們筛婉。類似 Docker, ports 仍然可以被 published 到 host node 的接口上油昂。但在這個網(wǎng)絡(luò)模型下這個需求大大減少了。
Service
為什么需要 service ?
我們可以直接與pod 交流倾贰。但是當(dāng) 一個node die 的時候會發(fā)生什么呢冕碟?
pod 也會die, 然后Deployment 會創(chuàng)建新的pods(IP不同)。這是 Service 要解決的問題匆浙。
來看一個service yaml
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 80
selector:
run: my-nginx
kubectl get svc my-nginx
? k8s_demo kubectl get svc my-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.68.82.69 <none> 8080/TCP 26s
你可以從集群里的任意node 上 curl nginx Service on <CLUSTER-IP>:<PORT>安寺。 Note: service IP 是完全虛擬的。
訪問 Service
兩種方式
- 環(huán)境變量
- DNS
環(huán)境變量
kubectl exec my-nginx-3800858182-jr4a2 -- printenv | grep SERVICE
這事你并沒有發(fā)現(xiàn) my-nginx servervice.因為 pods 先啟動的首尼。還帶來的一個缺點是 2個pods 都在一個機(jī)器上挑庶,當(dāng)機(jī)器掛掉, service 也會掛掉软能。我們先殺死兩個pod 然后 等待deployment 重新創(chuàng)建迎捺。會正確調(diào)度并且?guī)в姓_的環(huán)境變量。
DNS
k8s 提供了DNS 集群附加服務(wù)會自動授予其他services dns name查排。你可以檢查它是不是在你的集群運行.
你可以在一個pod里 curl <service-name>:<port> 來訪問service
kubectl get services kube-dns --namespace=kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.68.0.2 <none> 53/UDP,53/TCP,9153/TCP 338d
expose internet
使用Nodeport 或者loadbalance
其他
當(dāng)刪除一個service, 再apply, cluster IP 也會變化
下面這張圖 是說明了 deployment 的port 參數(shù)凳枝。這表示這個參數(shù)是不必要的,即使沒有也會暴露出來