Kubernetes 的網(wǎng)絡(luò)模型
通過(guò)前面教程的學(xué)習(xí),我們已經(jīng)可以將容器化的應(yīng)用程序在 Kubernetes 中運(yùn)行起來(lái),并且發(fā)布到 Kubernetes 內(nèi)/外的網(wǎng)絡(luò)上。
通常,Docker 使用一種 host-private
的聯(lián)網(wǎng)方式,在此情況下,只有兩個(gè)容器都在同一個(gè)節(jié)點(diǎn)(主機(jī))上時(shí),一個(gè)容器才可以通過(guò)網(wǎng)絡(luò)連接另一個(gè)容器。為了使 Docker 容器可以跨節(jié)點(diǎn)通信,必須在宿主節(jié)點(diǎn)(主機(jī))的 IP 地址上分配端口,并將該端口接收到的網(wǎng)絡(luò)請(qǐng)求轉(zhuǎn)發(fā)(或代理)到容器中。這意味著,用戶必須非常小心地為容器分配宿主節(jié)點(diǎn)(主機(jī))的端口號(hào),或者端口號(hào)可以自動(dòng)分配。
在一個(gè)集群中,多個(gè)開(kāi)發(fā)者之間協(xié)調(diào)分配端口號(hào)是非常困難的。Kubernetes 認(rèn)為集群中的兩個(gè) Pod 應(yīng)該能夠互相通信,無(wú)論他們各自在哪個(gè)節(jié)點(diǎn)上。每一個(gè) Pod 都被分配自己的 “cluster-private-IP”,因此,您無(wú)需在 Pod 間建立連接,或者將容器的端口映射到宿主機(jī)的端口。因此:
- Pod 中的任意容器可以使用 localhost 直連同 Pod 中另一個(gè)容器的端口
- 集群中的任意 Pod 可以使用另一的 Pod 的 cluster-private-IP 直連對(duì)方的端口,(無(wú)需 NAT 映射)
在集群中部署nginx
創(chuàng)建文件 run-my-nginx.yaml
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
- 部署 Pod
kubectl apply -f ./run-my-nginx.yaml
- 檢查運(yùn)行情況:
kubectl get pods -l run=my-nginx -o wide
輸出結(jié)果:
NAME READY STATUS RESTARTS AGE IP NODE
my-nginx-3800858182-jr4a2 1/1 Running 0 13s 10.244.3.4 kubernetes-minion-905m
my-nginx-3800858182-kna2y 1/1 Running 0 13s 10.244.2.5 kubernetes-minion-ljyd
- 執(zhí)行命令
kubectl get pods -l run=my-nginx -o yaml | grep podIP
, 檢查 Pod 的 IP 地址,輸出結(jié)果如下:
cni.projectcalico.org/podIP: 10.244.84.185/32
cni.projectcalico.org/podIPs: 10.244.84.185/32
podIP: 10.244.84.185
podIPs:
cni.projectcalico.org/podIP: 10.244.14.61/32
cni.projectcalico.org/podIPs: 10.244.14.61/32
podIP: 10.244.14.61
podIPs:
在集群中的任意節(jié)點(diǎn)上,您可以執(zhí)行curl 10.244.84.185或
curl 10.244.14.61 獲得 nginx 的響應(yīng)。
- 容器并沒(méi)有使用節(jié)點(diǎn)上的 80 端口
- 沒(méi)有使用 NAT 規(guī)則對(duì)容器端口進(jìn)行映射
這意味著,您可以
- 在同一節(jié)點(diǎn)上使用 80 端口運(yùn)行多個(gè) nginx Pod
- 在集群的任意節(jié)點(diǎn)/Pod 上使用 nginx Pod 的 clusterIP 訪問(wèn) nginx 的 80 端口
同 Docker 一樣,Kubernets 中,仍然可以將 Pod 的端口映射到宿主節(jié)點(diǎn)的網(wǎng)絡(luò)地址上(使用 nodePort),但是使用 Kubernetes 的網(wǎng)絡(luò)模型時(shí),這類需求已經(jīng)大大減少了。
創(chuàng)建 Service
上面的步驟中,我們已經(jīng)創(chuàng)建了 nginx Pod,運(yùn)行在集群的 IP 地址空間。您可以直接通過(guò) Pod 的地址訪問(wèn)其端口,但是如果某一個(gè) Pod 終止了該怎么辦?Pod 因?yàn)楣收匣蚱渌蚪K止后,Deployment Controller 將創(chuàng)建一個(gè)新的 Pod 以替代該 Pod,但是 IP 地址將發(fā)生變化。Kubernetes Service 解決了這樣的問(wèn)題。
Kubernetes Service:
- 定義了集群中一組 Pod 的邏輯集合,該集合中的 Pod 提供了相同的功能
- 被創(chuàng)建后,獲得一個(gè)唯一的 IP 地址(ClusterIP)。直到該 Service 被刪除,此地址不會(huì)發(fā)生改變
- Pod 可以直接連接 Service IP 地址上的端口,且發(fā)送到該 IP 地址的網(wǎng)絡(luò)請(qǐng)求被自動(dòng)負(fù)載均衡分發(fā)到 Service 所選取的 Pod 集合中
執(zhí)行命令 kubectl expose deployment/my-nginx
可以為上面的兩個(gè) nginx Pod 創(chuàng)建 Service,輸出結(jié)果如下所示:
service/my-nginx exposed
該命令等價(jià)于 kubectl apply -f nginx-svc.yaml
,其中 nginx-svc.yaml 文件的內(nèi)容如下所示:
apiVersion: v1
kind: Service
metadata:
name: my-nginx
labels:
run: my-nginx
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
run: my-nginx
該 yaml 文件將創(chuàng)建一個(gè) Service:
- 該 Service 通過(guò) label selector 選取包含
run: my-nginx
標(biāo)簽的 Pod 作為后端 Pod - 該 Service 暴露一個(gè)端口 80(
spec.ports[*].port
) - 該 Service 將 80 端口上接收到的網(wǎng)絡(luò)請(qǐng)求轉(zhuǎn)發(fā)到后端 Pod 的 80 (
spec.ports[*].targetPort
)端口上,支持負(fù)載均衡
執(zhí)行命令 kubectl get svc my-nginx
,輸出結(jié)果如下
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx ClusterIP 10.100.223.157 <none> 80/TCP 75s
Service 的后端 Pod 實(shí)際上通過(guò) Endpoints
來(lái)暴露。Kubernetes 會(huì)持續(xù)檢查 Service 的 label selector spec.selector
,并將符合條件的 Pod 更新到與 Service 同名(my-nginx)的 Endpoints 對(duì)象。如果 Pod 終止了,該 Pod 將被自動(dòng)從 Endpoints 中移除,新建的 Pod 將自動(dòng)被添加到該 Endpoint。
執(zhí)行命令 kubectl describe svc my-nginx
,輸出結(jié)果如下,請(qǐng)注意 Endpoints 中的 IP 地址與上面獲得的 Pod 地址相同:
Name: my-nginx
Namespace: default
Labels: <none>
Annotations: <none>
Selector: run=my-nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.100.223.157
IPs: 10.100.223.157
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.14.61:80,10.244.84.185:80
Session Affinity: None
Events: <none>
執(zhí)行命令 kubectl get ep my-nginx
,輸出結(jié)果
NAME ENDPOINTS AGE
my-nginx 10.244.14.61:80,10.244.84.185:80 8m37s
此時(shí),您可以在集群的任意節(jié)點(diǎn)上執(zhí)行curl 10.100.223.157:80
,通過(guò) Service 的 ClusterIP:Port 訪問(wèn) nginx。
訪問(wèn) Service
Kubernetes 支持兩種方式發(fā)現(xiàn)服務(wù):
- 環(huán)境變量
- DNS 參考
環(huán)境變量
針對(duì)每一個(gè)有效的 Service,kubelet 在創(chuàng)建 Pod 時(shí),向 Pod 添加一組環(huán)境變量。這種做法引發(fā)了一個(gè) Pod 和 Service 的順序問(wèn)題。例如,
- 執(zhí)行命令
kubectl exec my-nginx-df7bbf6f5-87hqg -- printenv | grep SERVICE
(您的 Pod 名字可能不一樣),輸出結(jié)果如下
KUARD_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443
KUARD_SERVICE_HOST=10.110.143.73
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT=443
DNS
Kubernetes 提供了一個(gè) DNS cluster addon,可自動(dòng)為 Service 分配 DNS name。
查看該 addon 在您的集群上是否可用
kubectl get services kube-dns --namespace=kube-system
輸出結(jié)果:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-608098.html
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 140d
可以從集群中任何 Pod 中按 Service 的名稱訪問(wèn)該 Service。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-608098.html
- 執(zhí)行命令
kubectl run curl --image=radial/busyboxplus:curl -i --tty
獲得 busyboxplus 容器的命令行終端,該命令輸出結(jié)果
If you don't see a command prompt, try pressing enter.
[ root@curl:/ ]$
- 然后,單擊回車鍵,并執(zhí)行命令
nslookup my-nginx
,輸出結(jié)果如下所示:
[ root@curl:/ ]$ nslookup my-nginx
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: my-nginx
Address 1: 10.100.223.157 my-nginx.default.svc.cluster.local
- 執(zhí)行命令
curl my-nginx:80
,可獲得 Nginx 的響應(yīng)。
[ root@curl:/ ]$ curl my-nginx:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a >nginx.org</a>.<br/>
Commercial support is available at
<a >nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 執(zhí)行命令
exit
可推出該容器的命令行 - 執(zhí)行命令
kubectl delete deployment curl
可刪除剛才創(chuàng)建的curl
測(cè)試容器
到了這里,關(guān)于k8s服務(wù)發(fā)現(xiàn)之第五彈--使用 Service 連接到應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!