集群問題
系統
Error: unknown flag: --etcd-quorum-read
刪除service 里面的相應字段
start request repeated too quickly for kube-apiserver.service
查看是不是有之前的進程占用,然后將service 字段摳出來手動啟動查看可否成功,也可顯示錯誤
health check for peer acd2ba924953b1ec could not connect: dial tcp 192.168.81.60:2380: getsockopt: connection refused
分析是因為etcd1的配置文件/etc/etcd/etcd.conf中的ETCD_INITIAL_CLUSTER_STATE是new,而在配置中ETCD_INITIAL_CLUSTER寫入了etcd2/3的IP:PORT,這時etcd1嘗試去連接etcd2、etcd3,但是etcd2、3的etcd服務此時還未啟動,因此需要先啟動etcd2和3的etcd服務,再去啟動etcd1。
dial tcp 127.0.0.1:2379: getsockopt: connection refused
etcd.conf ETCD_LISTEN_CLIENT_URLS 選項中加入 https://127.0.0.1:2379`
Unable to connect to the server: x509: certificate is valid for etcd1, etcd2, node1, node2, kube.NETes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster, kubernetes.default.svc.cluster.local, not k8s1
修改/root/cfssl/kubernetes/kubernetes-server-csr.json 加入錯誤中的k8s
FAIled at step CHDIR spawning /usr/local/bin/kubelet: No such file or directory
mkdir /var/lib/kubelet (具體看service 里面WorkingDirectory)
failed to run Kubelet: misconfiguration: kubelet cgroup driver: "systemd" is different from Docker cgroup driver: "cgroupfs"
vim /usr/lib/systemd/system/docker.service ExecStart=/usr/local/bin/dockerd --exec-opt native.cgroupdriver=systemd 具體按照報錯修改
etcd cluster is unavailable or misconfigured; error #0: dial tcp 127.0.0.1:4
vim /etcd/etcd/etcd.conf ETCD_LISTEN_CLIENT_URLS=https://192.168.50.12:2379,https://127.0.0.1:2379;
master 狀態 flanned 正常 pod 內部通訊 互相ping 通node 狀態 宿主機 能ping 通百度容器 能ping 宿主機svc
現象
容器 不能ping 百度
kubectl run -it --rm DNS-test --image=busybox:1.28.4 sh 測試dns
Error registering network: failed to acquire lease: node "k8s-node2" pod cid
kubectl patch node k8s-master -p '{"spec":{"podCIDR":"10.244.0.0/12"}}'
kubectl patch node k8s-node1 -p '{"spec":{"podCIDR":"10.244.0.0/12"}}'
Unable to connect to the server: x509: certificate signed by unknown authori
原因:重新初始化環境沒有清理干凈
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]:
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
error: no configuration has been provided, try setting KUBERNETES_MASTER environment variable
在/etc/profile末尾增加export KUBECONFIG=/etc/kubernetes/admin.conf添加完后執行source /etc/profile
svc不能被解析的原因
現象
pod 能ping 外網 但是不能解析百度 能ping114 不能ping svc 地址
解決
對應的node上面沒有開啟轉發(具體問題可以先查看node上面的kube-proxy logs 因為svc 是通過 kube-proxy分發出去的)echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
Error registering network: failed to acquire lease: node "master2" pod cidr not assigned
設置 pod ip 的網段 ,網段之所以是 10.244.0.0/16,是因為后面安裝 flannel 網絡插件時,yaml 文件里面的 ip 段也是這個,兩個保持一致,不然可能會使得 Node 間 Cluster IP 不通。這個參數必須得指定,如果這里不設置的話后面安裝 flannel 網絡插件時會報這個錯誤
Applying cgroup … caused: mkdir …no space left on device或者在describe pod的時候出現cannot allocate memory
解決方法
當大量pod 出現evictive情況
說明節點資源不夠,清理空間
ingress 獲取源地址ip為127.0.0.1 問題
https://Github.com/kubernetes/ingress-Nginx/issues/8052#issuecomment-1003699587
如果ingress-nginx啟用了enable-ssl-passthrough,就需要添加enable-real-ip: true
forwarded-for-header: proxy_protocol到configmap里面就可以了
etcd 節點異?;謴?openshift)
master 節點故障,docker ps -a |grep etcd |grep -v POD 發現etcd 異常退出
查看日志
docker logs -f etcd...
···
etcdserer : open wal error: wal : file not found
恢復步驟
將故障節點剝離集群,恢復后添加
etcdctl2 cluster-health
獲取問題節點的member id
etcdclt2 member remove $memberid
將問題節點移除
----
停止問題節點上的etcd 服務
mkdir -pv /etc/orgin/node/pods-stopped
mv /etc/origin/node/pods/* /etc/orgin/node/pods-stopped
rm -rf /var/lib/etcd/*
----
更新ansible中的inventory host 內容,設置new etcd 配置
[osev3:clildren]
masters
etcd
nodes
new_etcd
----
從集群中釋放問題節點
----
更新etcd 擴容腳本
ansible-playbook playbooks/openshift-master/openshift_node_groups.yaml
----
驗證
etcdctl clister-health
節點not ready
rpc error: code = ResourceExhausted desc = grpc: trying to send message larger than max (xxxxxxx vs. 8388608)
描述
集群有個master節點NotReady。kubelet報錯 “Warning ContainerGCFailed ... ”
Warning ContainerGCFailed ...
rpc error: code = ResourceExhausted desc = grpc: trying to send message larger
than max (xxxxxxx vs. 8388608)
這個錯和下面是一個問題。
rpc error: code = ResourceExhausted desc = grpc: received message larger
than max (xxxxx vs. 4194304)
原因
-
kubelet與cri-o通信,cri-o返回信息大小超過grpc的限制
-
kubelet無法與cri-o通信,導致內部大量錯誤出現
超過的根源在于容器數量過多,grpc返回信息過大,從而你超過了限制,無法正確返回。
解決方法
查看GRPC Buff塊大小,擴大至8MB。擴大方法參考
https://github.com/cri-o/cri-o/pull/2027github.com/cri-o/cri-o/pull/2027
假如已經是8MB,仍然報錯,則可能是鏡像等docker資源需要清理??梢詧绦?/p>
docker system prune
為了根除此類錯誤,可以在節點上設置完善的Garbage Collection機制。參考
Garbage Collectiondocs.openshift.com/container-platform/3.11/admin_guide/garbage_collection.html
node 拉取鏡像速度很快,但是起pod 鏡像很慢
Pods get stuck in ContainerCreating state when pulling image takes long
https://github.com/kubernetes/kubernetes/issues/83471
apiserver 前面使用的是 f5的負載均 策略有問題,導致請求全部打在了master1上、
應用故障
不同ns之前的pod怎么訪問
創建一個networkpolicy 的 Ingress
apiVersion: extension/v1beta1
Kind: NetworkPolicy
metadata:
generation:
name: allow-from-{ns1}-namespace
namespace: {ns2}
spec:
ingress:
- from:
- namespaceSelector:
matchLabels:
name: {ns1}
podSelector: {}
policyType:
- Ingress
pod內出現no space left on device
說明持久化存儲資源不足
pod處于running 域名訪問404
檢查route ingress 是否為正常狀態 本地配置host是否解析正常
network plugin cni failed to set up pod
關鍵詞: cni networkplugin
報錯: networkPlugin cni filed to send cni request: post http://xxx/dial .var/run/openshift/cni-server.sock: connet: connetc refuse
解決
找到調度的節點,重啟sdn
kubectl get openshift-sdn delete po --grace-period=0 --force sdn-xxx
不通pod 通過service hostname 訪問不通
經過排查為 networkplicy 缺少
https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
pod 不斷被重建
因為ns開啟可vpa導致
admission是會去手動改request值 updater組件會發現request大于推薦去驅逐 然后admission掛了 改不了request pod一起來 updater發現它大于推薦request 就會驅逐 然后一直循環在驅逐
然后pod會提示找不到cm
應用做更新,所有的yaml都在一個文件里面,可能是cm更新的慢了,然后pod會提示找不到cm,pod重啟還是會找不到cm
timeout expired waiting for volumes to attach or mount for pod
eureka的問題:pod不存在了,容器存在,up中有ip,可以調度
pod狀態terminating,強制刪除了,但是容器沒有刪除導致的
pod自動重啟,pod名字不變,ip 和創建時間變化
VPA目前驅逐pod后 pod名字不會變 但是ip和創建時間會變,VPA關閉后無此現象
壓力測試 短連接 pod 負載不均衡
會話保持必須關閉
a應用配置ssl 之后跳轉到了其他的地址
a 應用使用了b 應用的證書
pod 存活幾秒鐘重啟
vpa-admin-controller 異常pod
FAQ
service 選擇不通的depoy 的pod
service 通過label 選擇pod, 可以在A,B 的deploy 分別添加一個相同的標簽,svc 中的selector 使用這個相同的標簽,這樣就可以選擇A 和 B 的deploy創建的pod
通過router4層可以下載,通過7層下載502 gataway
檢查haproxy的問題,開啟haproxy的日志
ip地址沖突排查
表現為ping 不通,telnet 失敗
arping -I ens33 10.0.13.3
如果存在多個mac 地址,則表明地址沖突
如何刪除terminating 的ns
現象
kubectl get ns
demo terminating 50d
查看編排內容
kubectl get ns demo -o json
"spec": {
"finalizers": [
"kubernetes"
]
},
刪除上面這段 然后導入到新的jjson 文件里面
curl -k -H "Content-Type: application/json" -X PUT --data-binary @1.sjon http://127.0.0.1:8001/api/v1/namespaces/demo/finalize
configmap 中的entrypoint.sh 無執行權限
在configmap下面增加熟悉mode:493(十進制,八進制就是755)
configmap:
name: xxx
items:
- key: entrypoinyt.sh
path: entrypoiny.sh
mode: 493
build image no space left on device
怎么修改
修改docker 啟動參數
vim /etc/systemd/system/multi-user.target.wants/docker.service
在 exec 參數后面加上 --graph=/xx/xxx/xx
systemctl daemon-reload
systemctl restart docker
修改daemon.jsono
{
"data-root": "/xxx/xxx"
}
the server doesn’t have a resource type ‘xxx’
~/.kube 客戶端認證文件失效或者損壞,從其他節點的root用戶拷一份過來即可
tcp router 不通,無法通過tcp連接到服務
登陸到router 部署的節點
netstat -tnlp 查看端口是否正常監聽
kubectl -n default routerxxx rsh
grep -i "xxxx" -r ./
查看tcp-router是否有明顯錯誤日志
kubectl -n defaut logs -f routerxxx --tail=10
查看端口范圍
iptables -nL INPUT
怎么指定用戶id啟動應用runasuser
創建sa
kubectl create sa -n xxx xxx
添加sa到對應的scc
kubectl adm policy add-scc-to-user anyuid -n xx -z xxx
修改部署文件
serviceAccount: xxx
serviceAccountName: xxx
spec.template.spec.container[]
securityContext:
runAsuser: xxx
node可以解析,pod不能解析
解決 Kubernetes 中 Pod 無法正常域名解析問題分析與 IPVS parseIP Error 問題
系統環境:
CoreDNS 版本:1.6.7
Docker 版本:19.03.8
Kubernetes 版本:1.18.1
操作系統版本:centos 7.8
CentOS 內核版本:3.10.0-1062
參考地址:
Kubernetes Github
CentOS 升級內核版本
Kubernetes 官方文檔 - Services
Kubernetes 官方文檔 - 調試DNS服務
Kubernetes 官方文檔 - 自定義DNS服務
Issues "ipvs do not sync endpoint error: parseIP Error"
問題分析比較長,分析的懷疑人生...
一、問題描述
最近將 Kubernetes 升級到 1.18.1 版本,不過升級完后,查看工作節點的部分 Pod 無法啟動,查看消息全是
connetion timeout
的問題,一看連接超時的地址大部分是以域名方式連接集群內部地址(ClusterIP),少部分是以域名方式連接集群外部地址,通過 IP 進行遠程連接的應用倒是沒有問題(例如,應用通過 IP 連接 MySQL),由此判斷,初步懷疑很可能是 DNS 出現了問題,后來慢慢發現 kube-proxy 中的錯誤,再定位到 IPVS parseIP Error 錯誤,再到解決問題。下面是分析及姐問題的過程。
二、部署 DNS 調試工具
為了探針是否為 DNS 問題,這里需要提前部署用于測試 DNS 問題的 dnsutils 鏡像,該鏡像中包含了用于測試 DNS 問題的工具包,非常利于我們分析與發現問題。接下來,我們將在 Kubernetes 中部署這個工具鏡像。
1、創建 DNS 工具 Pod 部署文件
創建用于部署的 Deployment 資源文件 ndsutils.yaml:
ndsutils.yaml
apiVersion: v1
kind: Pod
metadata:
name: dnsutils
spec:
containers:
- name: dnsutils
image: mydlqclub/dnsutils:1.3
imagePullPolicy: IfNotPresent
command: ["sleep","3600"]
2、通過 Kubectl 工具部署 NDS 工具鏡像
通過 Kubectl 工具,將對上面 DNS 工具鏡像部署到 Kubernetes 中:
-n:指定應用部署的 Namespace 空間。
$ kubectl create -f ndsutils.yaml -n kube-system
三、問題分析
1、進入 DNS 工具 Pod 的命令行
上面 DNS 工具已經部署完成,我們可也通過 Kubectl 工具進入 Pod 命令行,然后,使用里面的一些工具進行問題分析,命令如下:
exec:讓指定 Pod 容器執行某些命令。
-i:將控制臺內容傳入到容器。
-t:進入容器的 tty 使用 bash 命令行。
-n:指定上面部署 DNS Pod 所在的 Namespace。
$ kubectl exec -it dnsutils /bin/sh -n kube-system
2、通過 Ping 和 Nsloopup 命令測試
進入容器 sh 命令行界面后,先使用 ping 命令來分別探測觀察是否能夠 ping 通集群內部和集群外部的地址,觀察到的信息如下:
## Ping 集群外部,例如這里 ping 一下百度
$ ping www.baidu.com
ping: bad address 'www.baidu.com'
## Ping 集群內部 kube-apiserver 的 Service 地址
$ ping kubernetes.default
ping: bad address 'kubernetes.default'
## 使用 nslookup 命令查詢域名信息
$ nslookup kubernetes.default
;; connection timed out; no servers could be reached
## 直接 Ping 集群內部 kube-apiserver 的 IP 地址
$ ping 10.96.0.1
PING 10.96.0.1 (10.96.0.1): 56 data bytes
64 bytes from 10.96.0.1: seq=0 ttl=64 time=0.096 ms
64 bytes from 10.96.0.1: seq=1 ttl=64 time=0.050 ms
64 bytes from 10.96.0.1: seq=2 ttl=64 time=0.068 ms
## 退出 dnsutils Pod 命令行
$ exit
可以觀察到兩次 ping 域名都不能 ping 通,且使用 nsloopup 分析域名信息時超時。然而,使用 ping kube-apiserver 的 IP 地址 "10.96.0.1" 則可以正常通信,所以,排除網絡插件(flannel、calico 等)的問題。初步判斷,很可能是 CoreDNS 組件的錯誤引起的某些問題,所以接下來我們測試 CoreDNS 是否正常。
3、檢測 CoreDNS 應用是否正常運行
首先,檢查 CoreDNS Pod 是否正在運行,如果 READY 為 0,則顯示 CoreDNS 組件有問題:
-l:指定根據 label 標簽進行查找,篩選有該 label 的 Pod。
-n:指定 CoreDNS 組件部署的 Namespace。
$ kubectl get pods -l k8s-app=kube-dns -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-669f77d7cc-8pkpw 1/1 Running 2 6h5m
coredns-669f77d7cc-jk9wk 1/1 Running 2 6h5m
可也看到 CoreDNS 兩個 Pod 均正常啟動,所以再查看兩個 Pod 中的日志信息,看看有無錯誤日志:
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name);
do kubectl logs --namespace=kube-system $p; done
.:53
[INFO] plugin/reload: Running configuration MD5 = 4e235fcc3696966e76816bcd9034ebc7
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
.:53
[INFO] plugin/reload: Running configuration MD5 = 4e235fcc3696966e76816bcd9034ebc7
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
通過上面信息可以觀察到,日志中信息也是正常啟動沒有問題。再接下來,查看下 CoreDNS 的入口 Service "kube-dns" 是否存在:
kube-dns 的 IP 為 10.96.0.10,集群內的 Pod 都是通過該 IP 與 DNS 組件進行交互,查詢 DNS 信息。
$ kubectl get service -n kube-system | grep kube-dns
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP
上面顯示 Service "kube-dns" 也存在,但是 Service 是通過 endpoints 和 Pod 進行綁定的,所以看看這個 CoreDNS 的 endpoints 是否存在,及信息是否正確:
$ kubectl get endpoints kube-dns -n kube-system
NAME ENDPOINTS
kube-dns 10.244.0.21:53,d10.244.2.82:53,10.244.0.21:9153
可以看到 endpoints 配置也是正常的,正確的與兩個 CporeDNS Pod 進行了關聯。
經過上面一系列檢測 CoreDNS 組件確實是正常運行。接下來,觀察 CoreDNS 域名解析日志,進而確定 Pod 中的域名解析請求是否能夠正常進入 CoreDNS。
4、觀察 CoreDNS 域名解析日志信息
使用
kubectl edit
命令來修改存儲于 Kubernetes
ConfigMap
中的
CoreDNS
配置參數信息,添加
log
參數,讓 CoreDNS 日志中顯示域名解析信息:
CoreDNS 配置參數說明:
errors: 輸出錯誤信息到控制臺。
health:CoreDNS 進行監控檢測,檢測地址為 http://localhost:8080/health 如果狀態為不健康則讓 Pod 進行重啟。
ready: 全部插件已經加載完成時,將通過 endpoints 在 8081 端口返回 HTTP 狀態 200。
kubernetes:CoreDNS 將根據 Kubernetes 服務和 pod 的 IP 回復 DNS 查詢。
prometheus:是否開啟 CoreDNS Metrics 信息接口,如果配置則開啟,接口地址為 http://localhost:9153/metrics
forward:任何不在Kubernetes 集群內的域名查詢將被轉發到預定義的解析器 (/etc/resolv.conf)。
cache:啟用緩存,30 秒 TTL。
loop:檢測簡單的轉發循環,如果找到循環則停止 CoreDNS 進程。
reload:監聽 CoreDNS 配置,如果配置發生變化則重新加載配置。
loadbalance:DNS 負載均衡器,默認 round_robin。
## 編輯 coredns 配置
$ kubectl edit configmap coredns -n kube-system
apiVersion: v1
data:
Corefile: |
.:53 {
log #添加log
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
保存更改后 CoreDNS 會自動重新加載配置信息,不過可能需要等上一兩分鐘才能將這些更改傳播到 CoreDNS Pod。等一段時間后,再次查看 CoreDNS 日志:
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name);
do kubectl logs --namespace=kube-system $p; done
.:53
[INFO] plugin/reload: Running configuration MD5 = 6434d0912b39645ed0707a3569fd69dc
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[INFO] Reloading
[INFO] plugin/health: Going into lameduck mode for 5s
[INFO] 127.0.0.1:47278 - 55171 "HINFO IN 4940754309314083739.5160468069505858354. udp 57 false 512" NXDOMAIN qr,rd,ra 57 0.040844011s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
.:53
[INFO] plugin/reload: Running configuration MD5 = 6434d0912b39645ed0707a3569fd69dc
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[INFO] Reloading
[INFO] plugin/health: Going into lameduck mode for 5s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
[INFO] 127.0.0.1:32896 - 49064 "HINFO IN 1027842207973621585.7098421666386159336. udp 57 false 512" NXDOMAIN qr,rd,ra 57 0.044098742s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
可以看到 CoreDNS 已經重新加載了配置,我們再次進入 dnsuitls Pod 中執行 ping 命令:
## 進入 DNSutils Pod 命令行
$ kubectl exec -it dnsutils /bin/sh -n kube-system
## 執行 ping 命令
$ ping www.baidu.com
## 退出 dnsutils Pod 命令行
$ exit
然后,再次查看 CoreDNS 的日志信息:
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name);
do kubectl logs --namespace=kube-system $p; done
.:53
[INFO] plugin/reload: Running configuration MD5 = 6434d0912b39645ed0707a3569fd69dc
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[INFO] Reloading
[INFO] plugin/health: Going into lameduck mode for 5s
[INFO] 127.0.0.1:47278 - 55171 "HINFO IN 4940754309314083739.5160468069505858354. udp 57 false 512" NXDOMAIN qr,rd,ra 57 0.040844011s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
.:53
[INFO] plugin/reload: Running configuration MD5 = 6434d0912b39645ed0707a3569fd69dc
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[INFO] Reloading
[INFO] plugin/health: Going into lameduck mode for 5s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
[INFO] 127.0.0.1:32896 - 49064 "HINFO IN 1027842207973621585.7098421666386159336. udp 57 false 512" NXDOMAIN qr,rd,ra 57 0.044098742s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
發現和之前沒有執行 ping 命令時候一樣,沒有 DNS 域名解析的日志信息,說明 Pod 執行域名解析時,請求并沒有進入 CoreDNS 中。接下來在查看 Pod 中 DNS 配置信息,進而分析問題。
5、查看 Pod 中的 DNS 配置信息
一般 Pod 中的
DNS
策略默認為
ClusterFirst
,該參數起到的作用是,優先從
Kubernetes DNS
插件地址讀取
DNS
配置。所以,我們正常創建的 Pod 中,DNS 配置 DNS 服務器地址應該指定為 Kubernetes 集群的 DNS 插件 Service 提供的虛擬 IP 地址。
注:其中 DNS 策略(dnsPolicy)支持四種類型:
Default: 從 DNS 所在節點繼承 DNS 配置,即該 Pod 的 DNS 配置與宿主機完全一致。
ClusterFirst:預先從 Kubenetes 的 DNS 插件中進行 DNS 解析,如果解析不成功,才會使用宿主機的 DNS 進行解析。
ClusterFirstWithHostNet:Pod 是用 HOST 模式啟動的(hostnetwork),用 HOST 模式表示 Pod 中的所有容器,都使用宿主機的 /etc/resolv.conf 配置進行 DNS 解析,但如果使用了 HOST 模式,還繼續使用 Kubernetes 的 DNS 服務,那就將 dnsPolicy 設置為 ClusterFirstWithHostNet。
None:完全忽略 kubernetes 系統提供的 DNS,以 Pod Spec 中 dnsConfig 配置為主。
為了再分析原因,我們接著進入 dnsutils Pod 中,查看 Pod 中 DNS 配置文件
/etc/resolv.conf
配置參數是否正確:
resolv.conf 配置參數說明:
search: 指明域名查詢順序。
nameserver: 指定 DNS 服務器的 IP 地址,可以配置多個 nameserver。
## 進入 dnsutils Pod 內部 sh 命令行
$ kubectl exec -it dnsutils /bin/sh -n kube-system
## 查看 resolv.conf 配置文件
$ cat /etc/resolv.conf
nameserver 10.96.0.10
search kube-system.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
## 退出 DNSutils Pod 命令行
$ exit
可以看到 Pod 內部的 resolv.conf 內容,其中 nameserver 指定 DNS 解析服務器 IP 為 "10.96.0.10" ,這個 IP 地址正是本人 Kubernetes 集群 CoreDNS 的 Service "kube-dns" 的 cluterIP,說明當 Pod 內部進行域名解析時,確實是將查詢請求發送到 Service "kube-dns" 提供的虛擬 IP 進行域名解析。
那么,既然 Pod 中 DNS 配置文件沒問題,且 CoreDNS 也沒問題,會不會是 Pod 本身域名解析不正常呢?或者 Service "kube-dns" 是否能夠正常轉發域名解析請求到 CoreDNS Pod 中?
當然,猜想是沒有用的,進行一下測試來觀察問題到底出在哪里。
6、進行觀察來定位問題所在
上面懷疑是 Pod 本身解析域名有問題,不能正常解析域名?;蛘?Pod 沒問題,但是請求域名解析時將請求發送到 Service "kube-dns" 后不能正常轉發請求到 CoreDNS Pod。 為了驗證這兩點,我們可以修改 Pod 中的 /etc/resolv.conf 配置來進行測試驗證。
修改
resolv.conf
中
DNS
解析請求地址為
阿里云 DNS
服務器地址,然后執行
ping
命令驗證是否為
Pod
解析域名是否有問題:
## 進入 dnsutils Pod 內部 sh 命令行
$ kubectl exec -it dnsutils /bin/sh -n kube-system
## 編輯 /etc/resolv.conf 文件,修改 nameserver 參數為阿里云提供的 DNS 服務器地址
$ vi /etc/resolv.conf
nameserver 223.5.5.5
#nameserver 10.96.0.10
search kube-system.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
## 修改完后再進行 ping 命令測試,看看是否能夠解析 www.mydlq.club 網址
$ ping www.mydlq.club
PING www.mydlq.club (140.143.8.181) 56(84) bytes of data.
64 bytes from 140.143.8.181 (140.143.8.181): icmp_seq=1 ttl=128 time=9.70 ms
64 bytes from 140.143.8.181 (140.143.8.181): icmp_seq=2 ttl=128 time=9.21 ms
## 退出 DNSutils Pod 命令行
$ exit
上面可也觀察到 Pod 中更換 DNS 服務器地址后,域名解析正常,說明 Pod 本身域名解析是沒有問題的。
接下來再修改
resolv.conf
中
DNS
解析請求地址為
CoreDNS Pod
的
IP
地址,這樣讓
Pod
直接連接
CoreDNS Pod
的
IP
,而不通過
Service
進行轉發,再進行
ping
命令測試,進而判斷
Service
kube-dns
是否能夠正常轉發請求到
CoreDNS Pod
的問題:
## 查看 CoreDNS Pod 的 IP 地址
$ kubectl get pods -n kube-system -o wide | grep coredns
coredns-669f77d7cc-rss5f 1/1 Running 0 10.244.2.155 k8s-node-2-13
coredns-669f77d7cc-rt8l6 1/1 Running 0 10.244.1.163 k8s-node-2-12
## 進入 dnsutils Pod 內部 sh 命令行
$ kubectl exec -it dnsutils /bin/sh -n kube-system
## 編輯 /etc/resolv.conf 文件,修改 nameserver 參數為阿里云提供的 DNS 服務器地址
$ vi /etc/resolv.conf
nameserver 10.244.2.155
nameserver 10.244.1.163
#nameserver 10.96.0.10
search kube-system.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
## 修改完后再進行 ping 命令測試,看看是否能夠解析 www.mydlq.club 網址
$ ping www.mydlq.club
PING www.baidu.com (39.156.66.18): 56 data bytes
64 bytes from 39.156.66.18: seq=0 ttl=127 time=6.054 ms
64 bytes from 39.156.66.18: seq=1 ttl=127 time=4.678 ms
## 退出 DNSutils Pod 命令行
$ exit
## 觀察 CoreDNS 日志信息,查看有無域名解析相關日志
$ for p in $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name);
do kubectl logs --namespace=kube-system $p; done
.:53
[INFO] plugin/reload: Running configuration MD5 = 6434d0912b39645ed0707a3569fd69dc
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[INFO] Reloading
[INFO] plugin/health: Going into lameduck mode for 5s
[INFO] 127.0.0.1:47278 - 55171 "HINFO IN 4940754309314083739.5160468069505858354. udp 57 false 512" NXDOMAIN qr,rd,ra 57 0.040844011s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
[INFO] 10.244.1.162:40261 - 21083 "AAAA IN www.mydlq.club.kube-system.svc.cluster.local. udp 62 false 512" NXDOMAIN qr,aa,rd 155 0.000398875s
[INFO] 10.244.1.162:40261 - 20812 "A IN www.mydlq.club.kube-system.svc.cluster.local. udp 62 false 512" NXDOMAIN qr,aa,rd 155 0.000505793s
[INFO] 10.244.1.162:55066 - 53460 "AAAA IN www.mydlq.club.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000215384s
[INFO] 10.244.1.162:55066 - 53239 "A IN www.mydlq.club.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000267642s
.:53
[INFO] plugin/reload: Running configuration MD5 = 6434d0912b39645ed0707a3569fd69dc
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[INFO] Reloading
[INFO] plugin/health: Going into lameduck mode for 5s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
[INFO] 127.0.0.1:32896 - 49064 "HINFO IN 1027842207973621585.7098421666386159336. udp 57 false 512" NXDOMAIN qr,rd,ra 57 0.044098742s
[INFO] plugin/reload: Running configuration MD5 = a4809ab99f6713c362194263016e6fac
[INFO] Reloading complete
[INFO] 10.244.1.162:40261 - 21083 "AAAA IN www.mydlq.club.kube-system.svc.cluster.local. udp 62 false 512" NXDOMAIN qr,aa,rd 155 0.000217299s
[INFO] 10.244.1.162:40261 - 20812 "A IN www.mydlq.club.kube-system.svc.cluster.local. udp 62 false 512" NXDOMAIN qr,aa,rd 155 0.000264552s
[INFO] 10.244.1.162:55066 - 53460 "AAAA IN www.mydlq.club.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000144795s
[INFO] 10.244.1.162:55066 - 53239 "A IN www.mydlq.club.svc.cluster.local. udp 50 false 512" NXDOMAIN qr,aa,rd 143 0.000221163s
經過上面兩個測試,已經可以得知,如果
Pod DNS
配置中直接修改
DNS
服務器地址為
CoreDNS Pod
的
IP
地址,
DNS
解析確實沒有問題,能夠正常解析。不過,正常的情況下 Pod 中 DNS 配置的服務器地址一般是 CoreDNS 的 Service 地址,不直接綁定 Pod IP(因為 Pod 每次重啟 IP 都會發生變化)。 所以問題找到了,正是在 Pod 向 CoreDNS 的 Service "kube-dns" 進行域名解析請求轉發時,出現了問題,一般
Service
的問題都跟
Kube-proxy
組件有關,接下來觀察該組件是否存在問題。
7、分析 Kube-Proxy 是否存在問題
觀察 Kube-proxy 的日志,查看是否存在問題:
## 查看 kube-proxy Pod 列表
$ kubectl get pods -n kube-system | grep kube-proxy
kube-proxy-6kdj2 1/1 Running 3 9h
kube-proxy-lw2q6 1/1 Running 3 9h
kube-proxy-mftlt 1/1 Running 3 9h
## 選擇一個 kube-proxy Pod,查看最后 5 條日志內容
$ kubectl logs kube-proxy-6kdj2 --tail=5 -n kube-system
E0326 15:20:23.159364 1 proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[10 96 0 10 0 0 0 0 0 0 0 0 0 0 0 0]
E0326 15:20:23.159388 1 proxier.go:1192] Failed to sync endpoint for service: 10.8.0.10:53/UPD, err: parseIP Error ip=[10 96 0 16 0 0 0 0 0 0 0 0 0 0 0 0]
E0326 15:20:23.159479 1 proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[10 96 0 10 0 0 0 0 0 0 0 0 0 0 0 0]
E0326 15:20:23.159501 1 proxier.go:1192] Failed to sync endpoint for service: 10.8.0.10:53/TCP, err: parseIP Error ip=[10 96 0 16 0 0 0 0 0 0 0 0 0 0 0 0]
E0326 15:20:23.159595 1 proxier.go:1950] Failed to list IPVS destinations, error: parseIP Error ip=[10 96 0 10 0 0 0 0 0 0 0 0 0 0 0 0]
通過 kube-proxy Pod 的日志可以看到,里面有很多 Error 級別的日志信息,根據關鍵字
IPVS
、
parseIP Error
可知,可能是由于 IPVS 模塊對 IP 進行格式化導致出現問題。
因為這個問題是升級到 kubernetes 1.18 版本才出現的,所以去 Kubernetes Github 查看相關 issues,發現有人在升級 Kubernetes 版本到 1.18 后,也遇見了相同的問題,經過 issue 中 Kubernetes 維護人員討論,分析出原因可能為新版 Kubernetes 使用的 IPVS 模塊是比較新的,需要系統內核版本支持,本人使用的是 CentOS 系統,內核版本為 3.10,里面的 IPVS 模塊比較老舊,缺少新版 Kubernetes IPVS 所需的依賴。
根據該 issue 討論結果,解決該問題的辦法是,更新內核為新的版本。
注:該 issues 地址為 https://github.com/kubernetes/kubernetes/issues/89520
四、解決問題
1、升級系統內核版本
升級 Kubernetes 集群各個節點的 CentOS 系統內核版本:
## 載入公鑰
$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
## 安裝 ELRepo 最新版本
$ yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
## 列出可以使用的 kernel 包版本
$ yum list available --disablerepo=* --enablerepo=elrepo-kernel
## 安裝指定的 kernel 版本:
$ yum install -y kernel-lt-4.4.218-1.el7.elrepo --enablerepo=elrepo-kernel
## 查看系統可用內核
$ cat /boot/grub2/grub.cfg | grep menuentry
menuentry 'CentOS Linux (3.10.0-1062.el7.x86_64) 7 (Core)' --class centos (略)
menuentry 'CentOS Linux (4.4.218-1.el7.elrepo.x86_64) 7 (Core)' --class centos ...(略)
## 設置開機從新內核啟動
$ grub2-set-default "CentOS Linux (4.4.218-1.el7.elrepo.x86_64) 7 (Core)"
## 查看內核啟動項
$ grub2-editenv list
saved_entry=CentOS Linux (4.4.218-1.el7.elrepo.x86_64) 7 (Core)
重啟系統使內核生效:
$ reboot
啟動完成查看內核版本是否更新:
$ uname -r
4.4.218-1.el7.elrepo.x86_64
2、測試 Pod 中 DNS 是否能夠正常解析
進入 Pod 內部使用 ping 命令測試 DNS 是否能正常解析:
## 進入 dnsutils Pod 內部 sh 命令行
$ kubectl exec -it dnsutils /bin/sh -n kube-system
## Ping 集群外部,例如這里 ping 一下百度
$ ping www.baidu.com
64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=1 ttl=127 time=7.20 ms
64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=2 ttl=127 time=6.60 ms
64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=3 ttl=127 time=6.38 ms
## Ping 集群內部 kube-api 的 Service 地址
$ ping kubernetes.default
64 bytes from kubernetes.default.svc.cluster.local (10.96.0.1): icmp_seq=1 ttl=64 time=0.051 ms
64 bytes from kubernetes.default.svc.cluster.local (10.96.0.1): icmp_seq=2 ttl=64 time=0.051 ms
64 bytes from kubernetes.default.svc.cluster.local (10.96.0.1): icmp_seq=3 ttl=64 time=0.064 ms
可以看到 Pod 中的域名解析已經恢復正常。
pod ping 不通node
環境說明
pod ---> router--->svc---redis pod
namesapce 1 的pod 訪問不了router 訪問拒絕
原因: apiserver 重啟導致sdn重啟,防火墻策略沒有生效,重啟防火墻后解決






