Contents
はじめに
AWS上に作ったkubernetes環境ですが、いつもはEC2インスタンスを止めて余計な料金が発生しないようにしてました。使いたいときだけEC2起動させればkubernetesが使える環境にしていたのです。
ただいつの頃からかEC2インスタンスを起動しても↓のようになってしまいkubernetesの環境が復旧しませんでしたorz
ubuntu@master1:~$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-5fb6b5764b-smxcb 0/1 Running 3 4d16h kube-system calico-node-q2qg5 1/1 Running 3 4d16h kube-system calico-node-qwkgt 1/1 Running 3 4d16h kube-system calico-node-td2tv 1/1 Running 3 4d16h kube-system coredns-7945fb857d-m55kd 0/1 Completed 0 4d16h kube-system coredns-7945fb857d-xl2xm 0/1 Completed 0 4d16h kube-system kube-apiserver-master1 1/1 Running 3 4d16h kube-system kube-controller-manager-master1 1/1 Running 3 4d16h kube-system kube-proxy-qwp2h 1/1 Running 3 4d16h kube-system kube-proxy-r889s 1/1 Running 3 4d16h kube-system kube-proxy-zbbd4 1/1 Running 3 4d16h kube-system kube-scheduler-master1 1/1 Running 3 4d16h ubuntu@master1:~$ kubectl get node NAME STATUS ROLES AGE VERSION master1 Ready master 4d16h v1.15.1 worker1 Ready worker 4d17h v1.15.1 worker2 Ready worker 4d17h v1.15.1 ubuntu@master1:~$
そもそもkubernetesをhardwayで作らない限り遭遇しない事象だとは思いますが一応の原因と事象の解消が出来たので書き残しておきます。
知識ないのにhardwayなんかに手を出すからこうなるorz
ちなみにkubernetesのversionは1.15.1で確認してます。
事象発生時のlog
事象発生時に取得したものです↓
ubuntu@master1:~$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-5fb6b5764b-smxcb 0/1 Running 3 4d17h kube-system calico-node-q2qg5 1/1 Running 3 4d17h kube-system calico-node-qwkgt 1/1 Running 3 4d17h kube-system calico-node-td2tv 1/1 Running 3 4d17h kube-system coredns-7945fb857d-m55kd 0/1 Completed 0 4d17h kube-system coredns-7945fb857d-xl2xm 0/1 Completed 0 4d17h kube-system kube-apiserver-master1 1/1 Running 3 4d17h kube-system kube-controller-manager-master1 1/1 Running 3 4d17h kube-system kube-proxy-qwp2h 1/1 Running 3 4d17h kube-system kube-proxy-r889s 1/1 Running 3 4d17h kube-system kube-proxy-zbbd4 1/1 Running 3 4d17h kube-system kube-scheduler-master1 1/1 Running 3 4d17h ubuntu@master1:~$ ubuntu@master1:~$ ubuntu@master1:~$ ubuntu@master1:~$ kubectl get node NAME STATUS ROLES AGE VERSION master1 Ready master 4d17h v1.15.1 worker1 Ready worker 4d17h v1.15.1 worker2 Ready worker 4d17h v1.15.1 ubuntu@master1:~$ ubuntu@master1:~$ ubuntu@master1:~$ ubuntu@master1:~$ kubectl get service --all-namespaces NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.32.0.1 <none> 443/TCP 4d18h kube-system kube-dns ClusterIP 10.32.0.10 <none> 53/UDP,53/TCP 4d17h ubuntu@master1:~$ ubuntu@master1:~$ ubuntu@master1:~$ ubuntu@master1:~$ kubectl get endpoints --all-namespaces NAMESPACE NAME ENDPOINTS AGE default kubernetes 10.63.0.11:6443 4d18h kube-system kube-controller-manager <none> 4d18h kube-system kube-dns <none> 4d17h kube-system kube-scheduler <none> 4d18h ubuntu@master1:~$
corednsのCompletedはcalico-kube-contorollersのReadiness Probeが失敗しているのが原因だと思ったので一旦保留。
kubectl logs -n kube-system calico-kube-controllers-5fb6b5764b-smxcbの抜粋
ubuntu@master1:~$ kubectl logs -n kube-system calico-kube-controllers-5fb6b5764b-smxcb E0807 01:55:55.830808 1 reflector.go:205] github.com/projectcalico/kube-controllers/pkg/controllers/namespace/namespace_controller.go:159: Failed to list *v1.Namespace: Get https://10.32.0.1:443/api/v1/namespaces?limit=500&resourceVersion=0: dial tcp 10.32.0.1:443: i/o timeout E0807 01:55:56.785157 1 reflector.go:205] github.com/projectcalico/kube-controllers/pkg/controllers/pod/pod_controller.go:206: Failed to list *v1.Pod: Get https://10.32.0.1:443/api/v1/pods?limit=500&resourceVersion=0: dial tcp 10.32.0.1:443: i/o timeout E0807 01:55:56.967279 1 reflector.go:205] github.com/projectcalico/kube-controllers/pkg/controllers/networkpolicy/policy_controller.go:147: Failed to list *v1.NetworkPolicy: Get https://10.32.0.1:443/apis/networking.k8s.io/v1/networkpolicies?limit=500&resourceVersion=0: dial tcp 10.32.0.1:443: i/o timeout E0807 01:55:57.700603 1 reflector.go:205] github.com/projectcalico/kube-controllers/pkg/controllers/node/node_controller.go:136: Failed to list *v1.Node: Get https://10.32.0.1:443/api/v1/nodes?limit=500&resourceVersion=0: dial tcp 10.32.0.1:443: i/o timeout E0807 01:55:58.383990 1 reflector.go:205] github.com/projectcalico/kube-controllers/pkg/controllers/serviceaccount/serviceaaccount_controller.go:153: Failed to list *v1.ServiceAccount: Get https://10.32.0.1:443/api/v1/serviceaccounts?limit=500&resourceVersion=0: dial tcp 10.32.0.1:443: i/o timeout
dial tcp 10.32.0.1:443: i/o timeoutってkube-apiserverと通信できていない?
kubectl get events –sort-by=.metadata.creationTimestamp –all-namespaces | grep calico-kube-controllersの抜粋
ubuntu@master1:~$ kubectl get events --sort-by=.metadata.creationTimestamp --all-namespaces | grep calico-kube-controllers kube-system 40m Normal Started pod/calico-kube-controllers-5fb6b5764b-smxcb Started container calico-kube-controllers kube-system 40m Normal Created pod/calico-kube-controllers-5fb6b5764b-smxcb Created container calico-kube-controllers kube-system 16s Warning Unhealthy pod/calico-kube-controllers-5fb6b5764b-smxcb Readiness probe failed: Error reaching apiserver: taking a long time to check apiserver kube-system 20m Warning Unhealthy pod/calico-kube-controllers-5fb6b5764b-smxcb Readiness probe failed: Error reaching apiserver: <nil> with http status code: 0
Readiness probe failed: Error reaching apiserver: taking a long time to check apiserverってことはapiserverとの通信に時間が掛かりすぎててReadiness probeが失敗しているらしい。ぐぬぬ。
どうもkube-proxyが怪しい
色々手探りで調べてみるとkube-proxyをDaemonSetにした辺りから挙動がおかしくなっているようでした。実際kube-proxyをDaemonSetからsystemdに戻すと事象が解決します。
これやってからダメになったのかorz
そこでkube-proxyがDaemonSetなときとsystemdでの違いを探してみました。
色々調べて引っかかったのはnetstat -anpでの接続情報。成功時と失敗時でそれぞれ取得してみました。
kube-proxyがsystemdの場合(成功)
ubuntu@master1:~$ sudo netstat -anp | grep kube-proxy Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 16840/kube-proxy tcp 0 0 10.63.0.11:38520 10.63.0.11:6443 ESTABLISHED 16840/kube-proxy tcp6 0 0 :::10256 :::* LISTEN 16840/kube-proxy ubuntu@master1:~$
※見やすいようにタグだけ追加
10.63.0.11:6443でESTABLISHEDしてるのがわかります。
kube-proxyがdaemonsetの場合(失敗)
ubuntu@master1:~$ sudo netstat -anp | grep kube-proxy Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 3155/kube-proxy tcp 0 1 10.63.0.11:58066 10.32.0.1:443 SYN_SENT 3155/kube-proxy tcp 0 1 10.63.0.11:58064 10.32.0.1:443 SYN_SENT 3155/kube-proxy tcp6 0 0 :::10256 :::* LISTEN 3155/kube-proxy ubuntu@master1:~$
※見やすいようにタグだけ追加
Foreign Addressが10.32.0.1:443になっていてSYN_SENTの状態。
Foreign Addressが違う・・・
おそらくcalico-kube-controllersからmasterにいるkube-apiserverへの通信がうまくいっていない。原因はkube-proxyだろうと思う。
kube-proxyのmanifestを修正する
色々ググった結果、KUBERNETES_SERVICE_HOSTとKUBERNETES_SERVICE_PORTを設定することで対処できるんじゃないかと祈りながら設定。
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: labels: k8s-app: kube-proxy addonmanager.kubernetes.io/mode: Reconcile name: kube-proxy namespace: kube-system spec: selector: matchLabels: k8s-app: kube-proxy updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 template: metadata: labels: k8s-app: kube-proxy annotations: scheduler.alpha.kubernetes.io/critical-pod: '' spec: priorityClassName: system-node-critical hostNetwork: true nodeSelector: beta.kubernetes.io/os: linux tolerations: - operator: "Exists" effect: "NoExecute" - operator: "Exists" effect: "NoSchedule" containers: - name: kube-proxy image: gcr.io/google_containers/kube-proxy-amd64:v1.15.1 command: - /bin/sh - -c - kube-proxy - --config=/var/lib/kube-proxy/kube-proxy-config.yaml env: - name: KUBERNETES_SERVICE_HOST value: "10.63.0.11" - name: KUBERNETES_SERVICE_PORT value: "6443" securityContext: privileged: true volumeMounts: - mountPath: /var/lib/kube-proxy name: kube-proxy readOnly: true volumes: - hostPath: path: /var/lib/kube-proxy name: kube-proxy serviceAccountName: kube-proxy --- apiVersion: v1 kind: ServiceAccount metadata: name: kube-proxy namespace: kube-system labels: addonmanager.kubernetes.io/mode: Reconcile --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: system:kube-proxy labels: addonmanager.kubernetes.io/mode: Reconcile subjects: - kind: ServiceAccount name: kube-proxy namespace: kube-system roleRef: kind: ClusterRole name: system:node-proxier apiGroup: rbac.authorization.k8s.io
古いの消してからこれをkubectl apply -f すると
ubuntu@master1:~/hardway/kube-proxy$ sudo netstat -anp | grep kube-proxy Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 2693/kube-proxy tcp 0 0 10.63.0.11:48442 10.63.0.11:6443 ESTABLISHED 2693/kube-proxy tcp6 0 0 :::10256 :::* LISTEN 2693/kube-proxy
Foreign Addressが10.63.0.11:6443でESTABLISHEDになってます。
calico-kube-controllersのpodを確認すると
ubuntu@master1:~/hardway/kube-proxy$ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-5fb6b5764b-smxcb 1/1 Running 4 4d18h kube-system calico-node-q2qg5 1/1 Running 4 4d18h kube-system calico-node-qwkgt 1/1 Running 4 4d18h kube-system calico-node-td2tv 1/1 Running 4 4d18h kube-system coredns-7945fb857d-b6b8v 1/1 Running 1 47m kube-system coredns-7945fb857d-ckrft 1/1 Running 1 47m kube-system kube-apiserver-master1 1/1 Running 4 4d18h kube-system kube-controller-manager-master1 1/1 Running 4 4d18h kube-system kube-proxy-k2f74 1/1 Running 1 33m kube-system kube-proxy-w87zg 1/1 Running 1 33m kube-system kube-proxy-x9mxn 1/1 Running 1 33m kube-system kube-scheduler-master1 1/1 Running 4 4d18h ubuntu@master1:~/hardway/kube-proxy$ ubuntu@master1:~/hardway/kube-proxy$ kubectl get pod --all-namespaces -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kube-system calico-kube-controllers-5fb6b5764b-smxcb 1/1 Running 4 4d18h 10.63.0.101 worker1 <none> <none> kube-system calico-node-q2qg5 1/1 Running 4 4d18h 10.63.0.11 master1 <none> <none> kube-system calico-node-qwkgt 1/1 Running 4 4d18h 10.63.0.102 worker2 <none> <none> kube-system calico-node-td2tv 1/1 Running 4 4d18h 10.63.0.101 worker1 <none> <none> kube-system coredns-7945fb857d-b6b8v 1/1 Running 1 53m 10.200.235.133 worker1 <none> <none> kube-system coredns-7945fb857d-ckrft 1/1 Running 1 53m 10.200.189.71 worker2 <none> <none> kube-system kube-apiserver-master1 1/1 Running 4 4d18h 10.63.0.11 master1 <none> <none> kube-system kube-controller-manager-master1 1/1 Running 4 4d18h 10.63.0.11 master1 <none> <none> kube-system kube-proxy-k2f74 1/1 Running 1 39m 10.63.0.101 worker1 <none> <none> kube-system kube-proxy-w87zg 1/1 Running 1 39m 10.63.0.11 master1 <none> <none> kube-system kube-proxy-x9mxn 1/1 Running 1 39m 10.63.0.102 worker2 <none> <none> kube-system kube-scheduler-master1 1/1 Running 4 4d18h 10.63.0.11 master1 <none> <none> ubuntu@master1:~/hardway/kube-proxy$
ということで各nodeを再起動してもkubernetesは復旧するようになりました。
原因がわからない
kube-proxyがsystemdのとき、envにKUBERNETES_SERVICE_HOSTもKUBERNETES_SERVICE_PORTも設定してないんですよね・・・。setにもない。
ちなみにkube-proxyに先ほどのenv設定あるなしは当然差分が出てくれる。
・manifestにenv設定なし
ubuntu@master1:~/hardway/kube-proxy$ kubectl get pod --all-namespaces -o wide | grep kube-proxy kube-system kube-proxy-6rbp7 1/1 Running 0 39s 10.63.0.101 worker1 <none> <none> kube-system kube-proxy-8dtf8 1/1 Running 0 39s 10.63.0.11 master1 <none> <none> kube-system kube-proxy-wgfx6 1/1 Running 0 39s 10.63.0.102 worker2 <none> <none> ubuntu@master1:~/hardway/kube-proxy$ kubectl exec -n kube-system kube-proxy-8dtf8 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=master1 KUBE_DNS_PORT_53_UDP_PORT=53 KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT_443_TCP=tcp://10.32.0.1:443 KUBE_DNS_PORT=udp://10.32.0.10:53 KUBE_DNS_PORT_53_UDP_ADDR=10.32.0.10 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_ADDR=10.32.0.1 KUBE_DNS_SERVICE_PORT=53 KUBE_DNS_SERVICE_PORT_DNS=53 KUBE_DNS_PORT_53_TCP=tcp://10.32.0.10:53 KUBE_DNS_PORT_53_TCP_PORT=53 KUBERNETES_PORT=tcp://10.32.0.1:443 KUBE_DNS_SERVICE_HOST=10.32.0.10 KUBE_DNS_SERVICE_PORT_DNS_TCP=53 KUBE_DNS_PORT_53_UDP=udp://10.32.0.10:53 KUBE_DNS_PORT_53_UDP_PROTO=udp KUBE_DNS_PORT_53_TCP_PROTO=tcp KUBE_DNS_PORT_53_TCP_ADDR=10.32.0.10 KUBERNETES_SERVICE_HOST=10.32.0.1 HOME=/root ubuntu@master1:~/hardway/kube-proxy$
・manifestにenv設定あり
ubuntu@master1:~/hardway/kube-proxy$ kubectl get pod --all-namespaces -o wide | grep kube-proxy kube-system kube-proxy-k2f74 1/1 Running 1 43m 10.63.0.101 worker1 <none> <none> kube-system kube-proxy-w87zg 1/1 Running 1 43m 10.63.0.11 master1 <none> <none> kube-system kube-proxy-x9mxn 1/1 Running 1 43m 10.63.0.102 worker2 <none> <none> ubuntu@master1:~/hardway/kube-proxy$ kubectl exec -n kube-system kube-proxy-w87zg env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=master1 KUBERNETES_SERVICE_HOST=10.63.0.11 KUBERNETES_SERVICE_PORT=6443 KUBE_DNS_SERVICE_PORT_DNS=53 KUBE_DNS_SERVICE_PORT_DNS_TCP=53 KUBE_DNS_PORT=udp://10.32.0.10:53 KUBE_DNS_PORT_53_UDP=udp://10.32.0.10:53 KUBE_DNS_PORT_53_TCP_PROTO=tcp KUBE_DNS_PORT_53_TCP_PORT=53 KUBE_DNS_SERVICE_PORT=53 KUBERNETES_PORT_443_TCP=tcp://10.32.0.1:443 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT=tcp://10.32.0.1:443 KUBERNETES_PORT_443_TCP_ADDR=10.32.0.1 KUBE_DNS_PORT_53_UDP_PORT=53 KUBE_DNS_PORT_53_UDP_PROTO=udp KUBE_DNS_PORT_53_TCP_ADDR=10.32.0.10 KUBERNETES_PORT_443_TCP_PROTO=tcp KUBERNETES_PORT_443_TCP_PORT=443 KUBE_DNS_SERVICE_HOST=10.32.0.10 KUBE_DNS_PORT_53_TCP=tcp://10.32.0.10:53 KUBE_DNS_PORT_53_UDP_ADDR=10.32.0.10 HOME=/root ubuntu@master1:~/hardway/kube-proxy$
参考サイト
KUBERNETES_SERVICE_HOSTの存在を知ったサイト
KUBERNETES_SERVICE_HOSTだけでは動かずKUBERNETES_SERVICE_PORTの存在を知ったサイト
最後に
色々試して解決!!(謎は残ったけどorz)
ちなみにcalico-kube-controllersをmaster1のnodeに作成されるようにしてもダメでした。master1にあるcalico-kube-controllersからならmaster1にあるkube-apiserverに通信できるかなーと思ったけどkube-proxyがダメだと無理なんですね。kube-proxyの大切さを痛感しました。iptables全然わからないのがつらい。