濟(jì)南旅游網(wǎng)站建設(shè)現(xiàn)狀sem和seo哪個(gè)工作好
開(kāi)篇
- 《K3s 系列文章》
- 《Rancher 系列文章》
問(wèn)題概述
20220606 5G IoT 網(wǎng)關(guān)設(shè)備同時(shí)安裝 K3S Server, 但是 POD 卻無(wú)法訪(fǎng)問(wèn)互聯(lián)網(wǎng)地址,查看 CoreDNS 日志提示如下:
...
[ERROR] plugin/errors: 2 update.traefik.io. A: read udp 10.42.0.3:38545->8.8.8.8:53: i/o timeout
[ERROR] plugin/errors: 2 update.traefik.io. AAAA: read udp 10.42.0.3:38990->8.8.8.8:53: i/o timeout
...
即 DNS 查詢(xún) forward 到了 8.8.8.8 這個(gè) DNS 服務(wù)器,并且查詢(xún)超時(shí)。
從而導(dǎo)致需要聯(lián)網(wǎng)啟動(dòng)的 POD 無(wú)法正常啟動(dòng),頻繁 CrashLoopBackoff, 如下圖:
但是通過(guò) Node 直接訪(fǎng)問(wèn),卻是可以正常訪(fǎng)問(wèn)的,如下圖:
環(huán)境信息
- 硬件:5G IoT 網(wǎng)關(guān)
- 網(wǎng)絡(luò):
- 互聯(lián)網(wǎng)訪(fǎng)問(wèn):5G 網(wǎng)卡:就是一個(gè) usb 網(wǎng)卡,需要通過(guò)撥號(hào)程序啟動(dòng),程序會(huì)調(diào)用系統(tǒng)的 dhcp/dnsmasq/resolvconf 等
- 內(nèi)網(wǎng)訪(fǎng)問(wèn):wlan 網(wǎng)卡
- 軟件:K3S Server v1.21.7+k3s1, dnsmasq 等
分析
網(wǎng)絡(luò)詳細(xì)配置信息
一步一步檢查分析:
- 看
/etc/resolv.conf
, 發(fā)現(xiàn)配置是 127.0.0.1 - netstat 查看 本地 53 端口確實(shí)在運(yùn)行
- 這種情況一般都是本地啟動(dòng)了 DNS 服務(wù)器或 緩存,查看 dnsmasq 進(jìn)程是否存在,確實(shí)存在
- dnsmasq 用的 resolv.conf 配置是
/run/dnsmasq/resolv.conf
$ cat /etc/resolv.conf
# Generated by resolvconf
nameserver 127.0.0.1$ netstat -anpl|grep 53
(Not all processes could be identified, non-owned process infowill not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN -
tcp6 0 0 :::53 :::* LISTEN -
udp 0 0 0.0.0.0:53 0.0.0.0:* -
udp6 0 0 :::53 :::* -$ ps -ef|grep dnsmasq
dnsmasq 912 1 0 6 月 06 ? 00:00:00 /usr/sbin/dnsmasq -x /run/dnsmasq/dnsmasq.pid -u dnsmasq -r /run/dnsmasq/resolv.conf -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service --trust-anchor=...$ systemctl status dnsmasq.service
● dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS serverLoaded: loaded (/lib/systemd/system/dnsmasq.service; enabled; vendor preset: enabled)Active: active (running) since Mon 2022-06-06 17:21:31 CST; 16h agoMain PID: 912 (dnsmasq)Tasks: 1 (limit: 4242)Memory: 1.1MCGroup: /system.slice/dnsmasq.service└─912 /usr/sbin/dnsmasq -x /run/dnsmasq/dnsmasq.pid -u dnsmasq -r /run/dnsmasq/resolv.conf -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service --trust-anchor=...6 月 06 17:21:31 orangebox-7eb3 dnsmasq[912]: started, version 2.80 cachesize 150
6 月 06 17:21:31 orangebox-7eb3 dnsmasq[912]: compile time options: IPv6 GNU-getopt DBus i18n IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset auth DNSSEC loop-detect inotify dumpfile
6 月 06 17:21:31 orangebox-7eb3 dnsmasq-dhcp[912]: DHCP, IP range 192.168.51.100 -- 192.168.51.200, lease time 3d
6 月 06 17:21:31 orangebox-7eb3 dnsmasq[912]: read /etc/hosts - 8 addresses
6 月 06 17:21:31 orangebox-7eb3 dnsmasq[912]: no servers found in /run/dnsmasq/resolv.conf, will retry
6 月 06 17:21:31 orangebox-7eb3 dnsmasq[928]: Too few arguments.
6 月 06 17:21:31 orangebox-7eb3 systemd[1]: Started dnsmasq - A lightweight DHCP and caching DNS server.
6 月 06 17:22:18 orangebox-7eb3 dnsmasq[912]: reading /run/dnsmasq/resolv.conf
6 月 06 17:22:18 orangebox-7eb3 dnsmasq[912]: using nameserver 222.66.251.8#53
6 月 06 17:22:18 orangebox-7eb3 dnsmasq[912]: using nameserver 116.236.159.8#53$ cat /run/dnsmasq/resolv.conf
# Generated by resolvconf
nameserver 222.66.251.8
nameserver 116.236.159.8
CoreDNS 分析
這里很奇怪,就是沒(méi)發(fā)現(xiàn)哪兒有配置 DNS 8.8.8.8, 但是日志中卻顯示指向了這個(gè) DNS:
[ERROR] plugin/errors: 2 update.traefik.io. A: read udp 10.42.0.3:38545->8.8.8.8:53: i/o timeout
[ERROR] plugin/errors: 2 update.traefik.io. AAAA: read udp 10.42.0.3:38990->8.8.8.8:53: i/o timeout
先查看一下 CoreDNS 的配置:(K3S 的 CoreDNS 是通過(guò) manifests 啟動(dòng)的,位于:/var/lib/rancher/k3s/server/manifests/coredns.yaml
下)
apiVersion: v1
kind: ConfigMap
metadata:name: corednsnamespace: kube-system
data:Corefile: |.:53 {errorshealthreadykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpa}hosts /etc/coredns/NodeHosts {ttl 60reload 15sfallthrough}prometheus :9153forward . /etc/resolv.confcache 30loopreloadloadbalance}
這里主要有 2 個(gè)配置需要關(guān)注:
forward . /etc/resolv.conf
loop
CoreDNS 問(wèn)題常用分析流程
檢查 DNS Pod 是否正常運(yùn)行 - 結(jié)果:是的;
# kubectl -n kube-system get pods -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-7448499f4d-pbxk6 1/1 Running 1 15h
檢查 DNS 服務(wù)是否存在正確的 cluster-ip - 結(jié)果:是的:
# kubectl -n kube-system get svc -l k8s-app=kube-dns
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.43.0.10 <none> 53/UDP,53/TCP,9153/TCP 15h
檢查是否能解析域名: 先是內(nèi)部域名 - 結(jié)果:無(wú)法解析:
$ kubectl run -it --rm --restart=Never busybox --image=busybox -- nslookup kubernetes.default
Server: 10.43.0.10
Address: 10.43.0.10:53;; connection timed out; no servers could be reached
再試外部域名 - 結(jié)果:無(wú)法解析:
$ kubectl run -it --rm --restart=Never busybox --image=busybox -- nslookup www.baidu.com
Server: 10.43.0.10
Address: 10.43.0.10:53;; connection timed out; no servers could be reached
檢查 resolv.conf 中的 nameserver 配置 - 結(jié)果:確實(shí)是 8.8.8.8
$ kubectl run -i --restart=Never --rm test-${RANDOM} --image=ubuntu --overrides='{"kind":"Pod", "apiVersion":"v1", "spec": {"dnsPolicy":"Default"}}' -- sh -c 'cat /etc/resolv.conf'
nameserver 8.8.8.8
pod "test-7517" deleted
綜上: 應(yīng)該是 POD 內(nèi)的 /etc/resolv.conf
被配置為 nameserver 8.8.8.8
導(dǎo)致了此次問(wèn)題。 但是整個(gè) Node OS 級(jí)別并沒(méi)有配置 nameserver 8.8.8.8
, 所以懷疑是:Kubernetes、Kubelet、CoreDNS 或 CRI 層面有這樣的機(jī)制:在 DNS 配置異常時(shí),自動(dòng)配置其為 nameserver 8.8.8.8
。
那么,要解決問(wèn)題,還是要找到 DNS 配置異常。
容器網(wǎng)絡(luò) DNS 服務(wù)
我這里暫時(shí)沒(méi)有查到 Kubernetes、Kubelet、CoreDNS 或 CRI 的相關(guān) DNS 的具體證據(jù),K3S 的 CRI 是 containerd,但是我在 Docker 的官方文檔 看到了這樣的描述:
📚? Reference: If the container cannot reach any of the IP addresses you specify, Google’s public DNS server 8.8.8.8 is added, so that your container can resolve internet domains. 如果容器無(wú)法到達(dá)您指定的任何 (DNS) IP 地址,則添加谷歌的公共 DNS 服務(wù)器 8.8.8.8,以便您的容器可以解析 internet 域。
這里猜測(cè) Kubernetes、Kubelet、CoreDNS 或 CRI 可能也有類(lèi)似的機(jī)制。
從這里分析可以知道,根因還是 DNS 配置問(wèn)題,CoreDNS 配置是默認(rèn)的,那么最大的可能就是 /etc/resolv.conf
配置為 nameserver 127.0.0.1
導(dǎo)致的此次問(wèn)題。
根因分析
根因: /etc/resolv.conf
配置為 nameserver 127.0.0.1
導(dǎo)致的此次問(wèn)題。
CoreDNS 的官方文檔明確說(shuō)明了這種情況:
📚? Reference:
loop | CoreDNS Docs 當(dāng) CoreDNS 日志包含消息
Loop ... detected ...
時(shí),這意味著檢測(cè)插件loop
在其中一個(gè)上游 DNS 服務(wù)器中檢測(cè)到無(wú)限轉(zhuǎn)發(fā)循環(huán)。這是一個(gè)致命錯(cuò)誤,因?yàn)槭褂脽o(wú)限循環(huán)進(jìn)行操作將消耗內(nèi)存和 CPU,直到主機(jī)最終內(nèi)存不足死亡。 轉(zhuǎn)發(fā)環(huán)路通常由以下原因引起: 最常見(jiàn)的是,CoreDNS 直接轉(zhuǎn)發(fā)請(qǐng)求給自己。例如,通過(guò)127.0.0.1
、::1
或127.0.0.53
等環(huán)回地址 要解決此問(wèn)題,請(qǐng)查看 Corefile 中檢測(cè)到循環(huán)的區(qū)域的任何轉(zhuǎn)發(fā)。確保他們沒(méi)有轉(zhuǎn)發(fā)到一個(gè)本地地址或到另一個(gè) DNS 服務(wù)器,這是轉(zhuǎn)發(fā)請(qǐng)求回 CoreDNS。如果 forward 正在使用一個(gè)文件(例如/etc/resolv.conf),請(qǐng)確保該文件不包含本地地址。
這里可以看到,我們的 CoreDNS 配置包含:forward . /etc/resolv.conf
, 且 Node 上的 /etc/resolv.conf
為nameserver 127.0.0.1
. 和上面提到的無(wú)限轉(zhuǎn)發(fā)循環(huán) 的 致命錯(cuò)誤 匹配。
轉(zhuǎn)發(fā)環(huán)路通常由以下原因引起:
最常見(jiàn)的是,CoreDNS 將請(qǐng)求直接轉(zhuǎn)發(fā)到自身。例如,通過(guò)環(huán)回地址,例如 ,或 127.0.0.1::1127.0.0.53
解決辦法
📚? Reference:
loop | CoreDNS Docs 官方提供了 3 種解決辦法:
- kubelet 添加
--resolv-conf
直接指向"真正"的resolv.conf
, 一般是:/run/systemd/resolve/resolv.conf
- 禁用 Node 上的本地 DNS 緩存
- quick dirty 辦法:修改 Corefile, 把
forward . /etc/resolv.conf
替換為forward . 8.8.8.8
等可以訪(fǎng)問(wèn)的 DNS 地址
針對(duì)上面的辦法,我們逐一分析下:
- ?? 可行:kubelet 添加
--resolv-conf
直接指向"真正"的resolv.conf
: 如上文所述,我們的"真正"的resolv.conf
為:/run/dnsmasq/resolv.conf
- ? 不可行:禁用 Node 上的本地 DNS 緩存,因?yàn)檫@是基于 5G IoT 網(wǎng)關(guān)的特殊情況,5G 網(wǎng)關(guān)程序機(jī)制就是如此,要用到 dnsmasq
- ? 不可行:dirty 的辦法,并且 5G 網(wǎng)關(guān)獲取到的 DNS 是不固定,隨時(shí)變化的,所以我們也無(wú)法指定
forward . <固定的 DNS 地址>
綜上,解決辦法如下: 在 K3S service 中添加如下字段:--resolv-conf /run/dnsmasq/resolv.conf
添加后如下:
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
After=network-online.target[Install]
WantedBy=multi-user.target[Service]
Type=notify
EnvironmentFile=/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s server --flannel-iface wlan0 --write-kubeconfig-mode "644" --disable-cloud-controller --resolv-conf /run/dnsmasq/resolv.conf
然后執(zhí)行如下命令 reload 和 重啟:
systemctl daemon-reload
systemctl stop k3s.service
k3s-killall.sh
systemctl start k3s.service
即可恢復(fù)正常。
如果需要在安裝時(shí)解決,解決辦法如下:
- 使用 k3s-ansible 腳本,group_vars 額外再添加如下
--resolv-conf
參數(shù):extra_server_args: '--resolv-conf /run/dnsmasq/resolv.conf'
- 使用 k3s 官方腳本:參考 K3s Server 配置參考 | Rancher 文檔, 添加參數(shù):
--resolv-conf /run/dnsmasq/resolv.conf
或使用環(huán)境變量:K3S_RESOLV_CONF=/run/dnsmasq/resolv.conf
🎉🎉🎉
📚?參考文檔
- DNS | Rancher 文檔
- loop | CoreDNS Docs
- K3s Server 配置參考 | Rancher 文檔
- Container networking | Docker Documentation
三人行, 必有我?guī)? 知識(shí)共享, 天下為公. 本文由東風(fēng)微鳴技術(shù)博客 EWhisper.cn 編寫(xiě).