Ubuntu16.04をUbuntu18.04にアップグレードしたらその上で動いていたcorednsが動かなくなった。その時のワークアラウンドのメモ。
アップグレード後のPodの状態
下記の通り、coredns がRestartし始める。
$ kubectl get pod -A -l k8s-app=kube-dns
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-66bff467f8-26zvc 0/1 CrashLoopBackOff 8 7m17s
kube-system coredns-66bff467f8-jn99c 0/1 CrashLoopBackOff 6 7m17s
ログを見てみるとDNSのルックアップがループしている的なコメントが。
$ kubectl -n kube-system logs -f coredns-66bff467f8-jn99c
.:53
[INFO] plugin/reload: Running configuration MD5 = 4e235fcc3696966e76816bcd9034ebc7
CoreDNS-1.6.7
linux/amd64, go1.13.6, da7f65b
[FATAL] plugin/loop: Loop (127.0.0.1:35197 -> :53) detected for zone ".", see https://coredns.io/plugins/loop#troubleshooting. Query: "HINFO 7248960742876715166.6460750388055986840."
実際の設定ファイルを確認すると
$ kubectl -n kube-system get configmap coredns -o jsonpath={.data.Corefile}
.:53 {
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
}
/etc/resolv.conf
を参照して転送していることがわかる。kubeletがcorednsコンテナを立てるときに、host側の/etc/resolv.conf
をコピーしているので、ノードの/etc/resolv.conf
を確認するとsystemd-resolved
を使い始めたことにより、転送が自身に向いていることがわかる。ホスト側であれば、systemd-resolvedが別のDNSに転送するのだが、CoreDNSではループしてしまうことが問題。
$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
# 127.0.0.53 is the systemd-resolved stub resolver.
# run "systemd-resolve --status" to see details about the actual nameservers.
nameserver 127.0.0.53
search corp.local
ワークアラウンド
これらを回避するためにノードの/var/lib/kubelet/config.yaml
にresolvConf: "/run/systemd/resolve/resolv.conf"
を下記のように追加する。
$ sudo cat /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
clusterDNS:
- 10.96.0.10
clusterDomain: cluster.local
cpuManagerReconcilePeriod: 0s
evictionPressureTransitionPeriod: 0s
fileCheckFrequency: 0s
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 0s
imageMinimumGCAge: 0s
kind: KubeletConfiguration
nodeStatusReportFrequency: 0s
nodeStatusUpdateFrequency: 0s
rotateCertificates: true
runtimeRequestTimeout: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s
resolvConf: "/run/systemd/resolve/resolv.conf"
その後、kubeletを再起動して、corednsを再スケジューリングすると問題が治る。
$ sudo systemctl restart kubelet
$ kubectl -n kube-system delete pod -l k8s-app=kube-dns
$ kubectl -n kube-system get pod -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-66bff467f8-4rxwp 1/1 Running 0 23s
coredns-66bff467f8-gbhwd 1/1 Running 0 23s