W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
對(duì)于這里的許多步驟,你可能希望知道運(yùn)行在集群中的 Pod 看起來是什么樣的。 最簡單的方法是運(yùn)行一個(gè)交互式的 busybox Pod:
kubectl run -it --rm --restart=Never busybox --image=gcr.io/google-containers/busybox sh
Note: 如果沒有看到命令提示符,請按回車。
如果你已經(jīng)有了你想使用的正在運(yùn)行的 Pod,則可以運(yùn)行以下命令去進(jìn)入:
kubectl exec <POD-NAME> -c <CONTAINER-NAME> -- <COMMAND>
為了完成本次實(shí)踐的任務(wù),我們先運(yùn)行幾個(gè) Pod。 由于你可能正在調(diào)試自己的 Service,所以,你可以使用自己的信息進(jìn)行替換, 或者你也可以跟著教程并開始下面的步驟來獲得第二個(gè)數(shù)據(jù)點(diǎn)。
kubectl create deployment hostnames --image=k8s.gcr.io/serve_hostname
deployment.apps/hostnames created
?kubectl
?命令將打印創(chuàng)建或變更的資源的類型和名稱,它們可以在后續(xù)命令中使用。 讓我們將這個(gè) deployment 的副本數(shù)擴(kuò)至 3。
kubectl scale deployment hostnames --replicas=3
deployment.apps/hostnames scaled
請注意這與你使用以下 YAML 方式啟動(dòng) Deployment 類似:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: hostnames
name: hostnames
spec:
selector:
matchLabels:
app: hostnames
replicas: 3
template:
metadata:
labels:
app: hostnames
spec:
containers:
- name: hostnames
image: k8s.gcr.io/serve_hostname
"app" 標(biāo)簽是 ?kubectl create deployment
? 根據(jù) Deployment 名稱自動(dòng)設(shè)置的。
確認(rèn)你的 Pods 是運(yùn)行狀態(tài):
kubectl get pods -l app=hostnames
NAME READY STATUS RESTARTS AGE
hostnames-632524106-bbpiw 1/1 Running 0 2m
hostnames-632524106-ly40y 1/1 Running 0 2m
hostnames-632524106-tlaok 1/1 Running 0 2m
你還可以確認(rèn)你的 Pod 是否正在提供服務(wù)。你可以獲取 Pod IP 地址列表并直接對(duì)其進(jìn)行測試。
kubectl get pods -l app=hostnames \
-o go-template='{{range .items}}{{.status.podIP}}{{"\n"}}{{end}}'
10.244.0.5
10.244.0.6
10.244.0.7
用于本教程的示例容器通過 HTTP 在端口 9376 上提供其自己的主機(jī)名, 但是如果要調(diào)試自己的應(yīng)用程序,則需要使用你的 Pod 正在偵聽的端口號(hào)。
在 Pod 內(nèi)運(yùn)行:
for ep in 10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376; do
wget -qO- $ep
done
輸出類似這樣:
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
如果此時(shí)你沒有收到期望的響應(yīng),則你的 Pod 狀態(tài)可能不健康,或者可能沒有在你認(rèn)為正確的端口上進(jìn)行監(jiān)聽。 你可能會(huì)發(fā)現(xiàn) ?kubectl logs
? 命令對(duì)于查看正在發(fā)生的事情很有用, 或者你可能需要通過?kubectl exec
? 直接進(jìn)入 Pod 中并從那里進(jìn)行調(diào)試。
假設(shè)到目前為止一切都已按計(jì)劃進(jìn)行,那么你可以開始調(diào)查為何你的 Service 無法正常工作。
細(xì)心的讀者會(huì)注意到我們實(shí)際上尚未創(chuàng)建 Service -這是有意而為之。 這一步有時(shí)會(huì)被遺忘,這是首先要檢查的步驟。
那么,如果我嘗試訪問不存在的 Service 會(huì)怎樣? 假設(shè)你有另一個(gè) Pod 通過名稱匹配到 Service ,你將得到類似結(jié)果:
wget -O- hostnames
Resolving hostnames (hostnames)... failed: Name or service not known.
wget: unable to resolve host address 'hostnames'
首先要檢查的是該 Service 是否真實(shí)存在:
kubectl get svc hostnames
No resources found.
Error from server (NotFound): services "hostnames" not found
讓我們創(chuàng)建 Service。 和以前一樣,在這次實(shí)踐中 - 你可以在此處使用自己的 Service 的內(nèi)容。
kubectl expose deployment hostnames --port=80 --target-port=9376
service/hostnames exposed
重新運(yùn)行查詢命令:
kubectl get svc hostnames
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hostnames ClusterIP 10.0.1.175 <none> 80/TCP 5s
現(xiàn)在你知道了 Service 確實(shí)存在。
同前,此步驟效果與通過 YAML 方式啟動(dòng) 'Service' 一樣:
apiVersion: v1
kind: Service
metadata:
name: hostnames
spec:
selector:
app: hostnames
ports:
- name: default
protocol: TCP
port: 80
targetPort: 9376
為了突出配置范圍的完整性,你在此處創(chuàng)建的 Service 使用的端口號(hào)與 Pods 不同。 對(duì)于許多真實(shí)的 Service,這些值可以是相同的。
如果你部署了任何可能影響到 ?hostnames-*
? Pod 的傳入流量的網(wǎng)絡(luò)策略入站規(guī)則, 則需要對(duì)其進(jìn)行檢查。
通??蛻舳送ㄟ^ DNS 名稱來匹配到 Service。
從相同命名空間下的 Pod 中運(yùn)行以下命令:
nslookup hostnames
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
如果失敗,那么你的 Pod 和 Service 可能位于不同的命名空間中, 請嘗試使用限定命名空間的名稱(同樣在 Pod 內(nèi)運(yùn)行):
nslookup hostnames.default
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames.default
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
如果成功,那么需要調(diào)整你的應(yīng)用,使用跨命名空間的名稱去訪問它, 或者在相同的命名空間中運(yùn)行應(yīng)用和 Service。如果仍然失敗,請嘗試一個(gè)完全限定的名稱:
nslookup hostnames.default.svc.cluster.local
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: hostnames.default.svc.cluster.local
Address 1: 10.0.1.175 hostnames.default.svc.cluster.local
注意這里的后綴:"default.svc.cluster.local"。"default" 是我們正在操作的命名空間。 "svc" 表示這是一個(gè) Service。"cluster.local" 是你的集群域,在你自己的集群中可能會(huì)有所不同。
你也可以在集群中的節(jié)點(diǎn)上嘗試此操作:
Note: 10.0.0.10 是集群的 DNS 服務(wù) IP,你的可能有所不同。
nslookup hostnames.default.svc.cluster.local 10.0.0.10
Server: 10.0.0.10
Address: 10.0.0.10#53
Name: hostnames.default.svc.cluster.local
Address: 10.0.1.175
如果你能夠使用完全限定的名稱查找,但不能使用相對(duì)名稱,則需要檢查你 Pod 中的 ?/etc/resolv.conf
? 文件是否正確。在 Pod 中運(yùn)行以下命令:
cat /etc/resolv.conf
你應(yīng)該可以看到類似這樣的輸出:
nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local example.com
options ndots:5
?nameserver
?行必須指示你的集群的 DNS Service, 它是通過 ?--cluster-dns
? 標(biāo)志傳遞到 kubelet 的。
?search
?行必須包含一個(gè)適當(dāng)?shù)暮缶Y,以便查找 Service 名稱。 在本例中,它查找本地命名空間(?default.svc.cluster.local
?)中的服務(wù)和 所有命名空間(?svc.cluster.local
?)中的服務(wù),最后在集群(?cluster.local
?)中查找 服務(wù)的名稱。根據(jù)你自己的安裝情況,可能會(huì)有額外的記錄(最多 6 條)。 集群后綴是通過 ?--cluster-domain
? 標(biāo)志傳遞給 ?kubelet
?的。 本文中,我們假定后綴是 “cluster.local”。 你的集群配置可能不同,這種情況下,你應(yīng)該在上面的所有命令中更改它。
?options
?行必須設(shè)置足夠高的 ?ndots
?,以便 DNS 客戶端庫考慮搜索路徑。 在默認(rèn)情況下,Kubernetes 將這個(gè)值設(shè)置為 5,這個(gè)值足夠高,足以覆蓋它生成的所有 DNS 名稱。
如果上面的方式仍然失敗,DNS 查找不到你需要的 Service ,你可以后退一步, 看看還有什么其它東西沒有正常工作。 Kubernetes 主 Service 應(yīng)該一直是工作的。在 Pod 中運(yùn)行如下命令:
nslookup kubernetes.default
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
如果失敗,你可能需要轉(zhuǎn)到本文的 kube-proxy 節(jié), 或者甚至回到文檔的頂部重新開始,但不是調(diào)試你自己的 Service ,而是調(diào)試 DNS Service。
假設(shè)你已經(jīng)確認(rèn) DNS 工作正常,那么接下來要測試的是你的 Service 能否通過它的 IP 正常訪問。 從集群中的一個(gè) Pod,嘗試訪問 Service 的 IP(從上面的 ?kubectl get
? 命令獲取)。
for i in $(seq 1 3); do
wget -qO- 10.0.1.175:80
done
輸出應(yīng)該類似這樣:
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
如果 Service 狀態(tài)是正常的,你應(yīng)該得到正確的響應(yīng)。如果沒有,有很多可能出錯(cuò)的地方,請繼續(xù)閱讀。
這聽起來可能很愚蠢,但你應(yīng)該兩次甚至三次檢查你的 Service 配置是否正確,并且與你的 Pod 匹配。 查看你的 Service 配置并驗(yàn)證它:
kubectl get service hostnames -o json
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "hostnames",
"namespace": "default",
"uid": "428c8b6c-24bc-11e5-936d-42010af0a9bc",
"resourceVersion": "347189",
"creationTimestamp": "2015-07-07T15:24:29Z",
"labels": {
"app": "hostnames"
}
},
"spec": {
"ports": [
{
"name": "default",
"protocol": "TCP",
"port": 80,
"targetPort": 9376,
"nodePort": 0
}
],
"selector": {
"app": "hostnames"
},
"clusterIP": "10.0.1.175",
"type": "ClusterIP",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {}
}
}
spec.ports[]
? 中列出?targetPort
?對(duì)你的 Pod 來說正確嗎(許多 Pod 使用與 Service 不同的端口)?protocol
?和 Pod 的是否對(duì)應(yīng)?如果你已經(jīng)走到了這一步,你已經(jīng)確認(rèn)你的 Service 被正確定義,并能通過 DNS 解析。 現(xiàn)在,讓我們檢查一下,你運(yùn)行的 Pod 確實(shí)是被 Service 選中的。
早些時(shí)候,我們已經(jīng)看到 Pod 是運(yùn)行狀態(tài)。我們可以再檢查一下:
kubectl get pods -l app=hostnames
NAME READY STATUS RESTARTS AGE
hostnames-632524106-bbpiw 1/1 Running 0 1h
hostnames-632524106-ly40y 1/1 Running 0 1h
hostnames-632524106-tlaok 1/1 Running 0 1h
?-l app=hostnames
? 參數(shù)是在 Service 上配置的標(biāo)簽選擇器。
"AGE" 列表明這些 Pod 已經(jīng)啟動(dòng)一個(gè)小時(shí)了,這意味著它們運(yùn)行良好,而未崩潰。
"RESTARTS" 列表明 Pod 沒有經(jīng)常崩潰或重啟。經(jīng)常性崩潰可能導(dǎo)致間歇性連接問題。 如果重啟次數(shù)過大,通過調(diào)試 Pod 了解相關(guān)技術(shù)。
在 Kubernetes 系統(tǒng)中有一個(gè)控制回路,它評(píng)估每個(gè) Service 的選擇算符,并將結(jié)果保存到 Endpoints 對(duì)象中。
kubectl get endpoints hostnames
NAME ENDPOINTS
hostnames 10.244.0.5:9376,10.244.0.6:9376,10.244.0.7:9376
這證實(shí) Endpoints 控制器已經(jīng)為你的 Service 找到了正確的 Pods。 如果 ?ENDPOINTS
?列的值為 ?<none>
?,則應(yīng)檢查 Service 的 ?spec.selector
? 字段, 以及你實(shí)際想選擇的 Pod 的 ?metadata.labels
? 的值。 常見的錯(cuò)誤是輸入錯(cuò)誤或其他錯(cuò)誤,例如 Service 想選擇 ?app=hostnames
?,但是 Deployment 指定的是 ?run=hostnames
?。在 1.18之前的版本中 ?kubectl run
? 也可以被用來創(chuàng)建 Deployment。
至此,你知道你的 Service 已存在,并且已匹配到你的Pod。在本實(shí)驗(yàn)的開始,你已經(jīng)檢查了 Pod 本身。 讓我們再次檢查 Pod 是否確實(shí)在工作 - 你可以繞過 Service 機(jī)制并直接轉(zhuǎn)到 Pod,如上面的 Endpoint 所示。
Note: 這些命令使用的是 Pod 端口(9376),而不是 Service 端口(80)。
在 Pod 中運(yùn)行:
for ep in 10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376; do
wget -qO- $ep
done
輸出應(yīng)該類似這樣:
hostnames-632524106-bbpiw
hostnames-632524106-ly40y
hostnames-632524106-tlaok
你希望 Endpoint 列表中的每個(gè) Pod 都返回自己的主機(jī)名。 如果情況并非如此(或你自己的 Pod 的正確行為是什么),你應(yīng)調(diào)查發(fā)生了什么事情。
如果你到達(dá)這里,則說明你的 Service 正在運(yùn)行,擁有 Endpoints,Pod 真正在提供服務(wù)。 此時(shí),整個(gè) Service 代理機(jī)制是可疑的。讓我們一步一步地確認(rèn)它沒問題。
Service 的默認(rèn)實(shí)現(xiàn)(在大多數(shù)集群上應(yīng)用的)是 kube-proxy。 這是一個(gè)在每個(gè)節(jié)點(diǎn)上運(yùn)行的程序,負(fù)責(zé)配置用于提供 Service 抽象的機(jī)制之一。 如果你的集群不使用 kube-proxy,則以下各節(jié)將不適用,你將必須檢查你正在使用的 Service 的實(shí)現(xiàn)方式。
確認(rèn) ?kube-proxy
? 正在節(jié)點(diǎn)上運(yùn)行。 在節(jié)點(diǎn)上直接運(yùn)行,你將會(huì)得到類似以下的輸出:
ps auxw | grep kube-proxy
root 4194 0.4 0.1 101864 17696 ? Sl Jul04 25:43 /usr/local/bin/kube-proxy --master=https://kubernetes-master --kubeconfig=/var/lib/kube-proxy/kubeconfig --v=2
下一步,確認(rèn)它并沒有出現(xiàn)明顯的失敗,比如連接主節(jié)點(diǎn)失敗。要做到這一點(diǎn),你必須查看日志。 訪問日志的方式取決于你節(jié)點(diǎn)的操作系統(tǒng)。 在某些操作系統(tǒng)上日志是一個(gè)文件,如 /var/log/messages kube-proxy.log, 而其他操作系統(tǒng)使用 ?journalctl
?訪問日志。你應(yīng)該看到輸出類似于:
I1027 22:14:53.995134 5063 server.go:200] Running in resource-only container "/kube-proxy"
I1027 22:14:53.998163 5063 server.go:247] Using iptables Proxier.
I1027 22:14:53.999055 5063 server.go:255] Tearing down userspace rules. Errors here are acceptable.
I1027 22:14:54.038140 5063 proxier.go:352] Setting endpoints for "kube-system/kube-dns:dns-tcp" to [10.244.1.3:53]
I1027 22:14:54.038164 5063 proxier.go:352] Setting endpoints for "kube-system/kube-dns:dns" to [10.244.1.3:53]
I1027 22:14:54.038209 5063 proxier.go:352] Setting endpoints for "default/kubernetes:https" to [10.240.0.2:443]
I1027 22:14:54.038238 5063 proxier.go:429] Not syncing iptables until Services and Endpoints have been received from master
I1027 22:14:54.040048 5063 proxier.go:294] Adding new service "default/kubernetes:https" at 10.0.0.1:443/TCP
I1027 22:14:54.040154 5063 proxier.go:294] Adding new service "kube-system/kube-dns:dns" at 10.0.0.10:53/UDP
I1027 22:14:54.040223 5063 proxier.go:294] Adding new service "kube-system/kube-dns:dns-tcp" at 10.0.0.10:53/TCP
如果你看到有關(guān)無法連接主節(jié)點(diǎn)的錯(cuò)誤消息,則應(yīng)再次檢查節(jié)點(diǎn)配置和安裝步驟。
?kube-proxy
? 無法正確運(yùn)行的可能原因之一是找不到所需的 ?conntrack
?二進(jìn)制文件。 在一些 Linux 系統(tǒng)上,這也是可能發(fā)生的,這取決于你如何安裝集群, 例如,你是手動(dòng)開始一步步安裝 Kubernetes。如果是這樣的話,你需要手動(dòng)安裝 ?conntrack
?包(例如,在 Ubuntu 上使用 ?sudo apt install conntrack
?),然后重試。
Kube-proxy 可以以若干模式之一運(yùn)行。在上述日志中,?Using iptables Proxier
? 行表示 kube-proxy 在 "iptables" 模式下運(yùn)行。 最常見的另一種模式是 "ipvs"。先前的 "userspace" 模式已經(jīng)被這些所代替。
在 "iptables" 模式中, 你應(yīng)該可以在節(jié)點(diǎn)上看到如下輸出:
iptables-save | grep hostnames
-A KUBE-SEP-57KPRZ3JQVENLNBR -s 10.244.3.6/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-57KPRZ3JQVENLNBR -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.3.6:9376
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -s 10.244.1.7/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-WNBA2IHDGP2BOBGZ -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.1.7:9376
-A KUBE-SEP-X3P2623AGDH6CDF3 -s 10.244.2.3/32 -m comment --comment "default/hostnames:" -j MARK --set-xmark 0x00004000/0x00004000
-A KUBE-SEP-X3P2623AGDH6CDF3 -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.2.3:9376
-A KUBE-SERVICES -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames: cluster IP" -m tcp --dport 80 -j KUBE-SVC-NWV5X2332I4OT4T3
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-WNBA2IHDGP2BOBGZ
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-X3P2623AGDH6CDF3
-A KUBE-SVC-NWV5X2332I4OT4T3 -m comment --comment "default/hostnames:" -j KUBE-SEP-57KPRZ3JQVENLNBR
對(duì)于每個(gè) Service 的每個(gè)端口,應(yīng)有 1 條 ?KUBE-SERVICES
? 規(guī)則、一個(gè) ?KUBE-SVC-<hash>
? 鏈。 對(duì)于每個(gè) Pod 末端,在那個(gè) ?KUBE-SVC-<hash>
? 鏈中應(yīng)該有一些規(guī)則與之對(duì)應(yīng),還應(yīng)該 有一個(gè) ?KUBE-SEP-<hash>
? 鏈與之對(duì)應(yīng),其中包含為數(shù)不多的幾條規(guī)則。 實(shí)際的規(guī)則數(shù)量可能會(huì)根據(jù)你實(shí)際的配置(包括 NodePort 和 LoadBalancer 服務(wù))有所不同。
在 "ipvs" 模式中, 你應(yīng)該在節(jié)點(diǎn)下看到如下輸出:
ipvsadm -ln
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
...
TCP 10.0.1.175:80 rr
-> 10.244.0.5:9376 Masq 1 0 0
-> 10.244.0.6:9376 Masq 1 0 0
-> 10.244.0.7:9376 Masq 1 0 0
...
對(duì)于每個(gè) Service 的每個(gè)端口,還有 NodePort,External IP 和 LoadBalancer 類型服務(wù) 的 IP,kube-proxy 將創(chuàng)建一個(gè)虛擬服務(wù)器。 對(duì)于每個(gè) Pod 末端,它將創(chuàng)建相應(yīng)的真實(shí)服務(wù)器。 在此示例中,服務(wù)主機(jī)名(?10.0.1.175:80
?)擁有 3 個(gè)末端(?10.244.0.5:9376
?、 ?10.244.0.6:9376
? 和 ?10.244.0.7:9376
?)。
在極少數(shù)情況下,你可能會(huì)用到 "userspace" 模式。在你的節(jié)點(diǎn)上運(yùn)行:
iptables-save | grep hostnames
-A KUBE-PORTALS-CONTAINER -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j REDIRECT --to-ports 48577
-A KUBE-PORTALS-HOST -d 10.0.1.175/32 -p tcp -m comment --comment "default/hostnames:default" -m tcp --dport 80 -j DNAT --to-destination 10.240.115.247:48577
對(duì)于 Service (本例中只有一個(gè))的每個(gè)端口,應(yīng)當(dāng)有 2 條規(guī)則: 一條 "KUBE-PORTALS-CONTAINER" 和一條 "KUBE-PORTALS-HOST" 規(guī)則。
幾乎沒有人應(yīng)該再使用 "userspace" 模式,因此你在這里不會(huì)花更多的時(shí)間。
假設(shè)你確實(shí)遇到上述情況之一,請重試從節(jié)點(diǎn)上通過 IP 訪問你的 Service :
curl 10.0.1.175:80
hostnames-632524106-bbpiw
如果失敗,并且你正在使用用戶空間代理,則可以嘗試直接訪問代理。 如果你使用的是 iptables 代理,請?zhí)^本節(jié)。
回顧上面的 ?iptables-save
? 輸出,并提取 ?kube-proxy
? 為你的 Service 所使用的端口號(hào)。 在上面的例子中,端口號(hào)是 “48577”?,F(xiàn)在試著連接它:
curl localhost:48577
hostnames-632524106-tlaok
如果這步操作仍然失敗,請查看 ?kube-proxy
? 日志中的特定行,如:
Setting endpoints for default/hostnames:default to [10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376]
如果你沒有看到這些,請嘗試將 ?-V
? 標(biāo)志設(shè)置為 4 并重新啟動(dòng) ?kube-proxy
?,然后再查看日志。
這聽起來似乎不太可能,但是確實(shí)可能發(fā)生,并且應(yīng)該可行。
如果網(wǎng)絡(luò)沒有為“發(fā)夾模式(Hairpin)”流量生成正確配置, 通常當(dāng) ?kube-proxy
? 以 ?iptables
?模式運(yùn)行,并且 Pod 與橋接網(wǎng)絡(luò)連接時(shí),就會(huì)發(fā)生這種情況。 ?kubelet
?提供了 ?hairpin-mode
? 標(biāo)志。 如果 Service 的末端嘗試訪問自己的 Service VIP,則該端點(diǎn)可以把流量負(fù)載均衡回來到它們自身。 ?hairpin-mode
? 標(biāo)志必須被設(shè)置為 ?hairpin-veth
? 或者 ?promiscuous-bridge
?。
診斷此類問題的常見步驟如下:
hairpin-mode
? 被設(shè)置為 ?hairpin-veth
? 或 ?promiscuous-bridge
?。 你應(yīng)該可以看到下面這樣。本例中 ?hairpin-mode
? 被設(shè)置為 ?promiscuous-bridge
?。ps auxw | grep kubelet
root 3392 1.1 0.8 186804 65208 ? Sl 00:51 11:11 /usr/local/bin/kubelet --enable-debugging-handlers=true --config=/etc/kubernetes/manifests --allow-privileged=True --v=4 --cluster-dns=10.0.0.10 --cluster-domain=cluster.local --configure-cbr0=true --cgroup-root=/ --system-cgroups=/system --hairpin-mode=promiscuous-bridge --runtime-cgroups=/docker-daemon --kubelet-cgroups=/kubelet --babysit-daemons=true --max-pods=110 --serialize-image-pulls=false --outofdisk-transition-frequency=0
hairpin-mode
?。要做到這一點(diǎn),你必須查看 kubelet 日志。 訪問日志取決于節(jié)點(diǎn)的操作系統(tǒng)。在一些操作系統(tǒng)上,它是一個(gè)文件,如 /var/log/kubelet.log, 而其他操作系統(tǒng)則使用 ?journalctl
?訪問日志。請注意,由于兼容性, 有效的 ?hairpin-mode
? 可能不匹配 ?--hairpin-mode
? 標(biāo)志。在 kubelet.log 中檢查是否有帶有關(guān)鍵字 ?hairpin
?的日志行。應(yīng)該有日志行指示有效的 ?hairpin-mode
?,就像下面這樣。I0629 00:51:43.648698 3252 kubelet.go:380] Hairpin mode set to "promiscuous-bridge"
hairpin-veth
?, 要保證 ?Kubelet
?有操作節(jié)點(diǎn)上 ?/sys
? 的權(quán)限。 如果一切正常,你將會(huì)看到如下輸出:for intf in /sys/devices/virtual/net/cbr0/brif/*; do cat $intf/hairpin_mode; done
1
1
1
1
promiscuous-bridge
?, 要保證 ?Kubelet
?有操作節(jié)點(diǎn)上 Linux 網(wǎng)橋的權(quán)限。如果 ?cbr0
?橋正在被使用且被正確設(shè)置,你將會(huì)看到如下輸出:ifconfig cbr0 |grep PROMISC
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1460 Metric:1
如果你走到這一步,那么就真的是奇怪的事情發(fā)生了。你的 Service 正在運(yùn)行,有 Endpoints 存在, 你的 Pods 也確實(shí)在提供服務(wù)。你的 DNS 正常,?iptables
?規(guī)則已經(jīng)安裝,?kube-proxy
? 看起來也正常。 然而 Service 還是沒有正常工作。這種情況下,請告訴我們,以便我們可以幫助調(diào)查!
通過 Forum 或者 GitHub 聯(lián)系我們。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: