Я повторил вашу проблему и написал для вас пошаговый процесс отладки, чтобы вы могли понять, о чем я думал.
Я создал кластер из двух узлов (мастер + рабочий) с помощью kubeadm и сделал снимок. Затем я удалил все узлы и воссоздал их из снимков.
После воссоздания главного узла из снимка я начал видеть ту же ошибку, которую вы видите:
@kmaster ~]$ kubectl get po -v=10
I0217 11:04:38.397823 3372 loader.go:375] Config loaded from file: /home/user/.kube/config
I0217 11:04:38.398909 3372 round_trippers.go:423] curl -k -v -XGET -H "Accept: application/json, */*" -H "User-Agent: kubectl/v1.17.3 (linux/amd64) kubernetes/06ad960" 'https://10.156.0.20:6443/api?timeout=32s'
^C
Соединение зависло, поэтому я прервал его (Ctrl + c). Сначала я заметил, что IP-адрес того места, где подключался kubectl, отличался от IP-адреса узла, поэтому я изменил файл .kube/config
, предоставив правильный IP-адрес.
После этого вот что показал запущенный kubectl:
$ kubectl get po -v=10
I0217 11:26:57.020744 15929 loader.go:375] Config loaded from file: /home/user/.kube/config
...
I0217 11:26:57.025155 15929 helpers.go:221] Connection error: Get https://10.156.0.23:6443/api?timeout=32s: dial tcp 10.156.0.23:6443: connect: connection refused
F0217 11:26:57.025201 15929 helpers.go:114] The connection to the server 10.156.0.23:6443 was refused - did you specify the right host or port?
Как вы видите, соединение с apiserver было отклонено, поэтому я проверил, работает ли apiserver:
$ sudo docker ps -a | grep apiserver
5e957ff48d11 90d27391b780 "kube-apiserver --ad…" 24 seconds ago Exited (2) 3 seconds ago k8s_kube-apiserver_kube-apiserver-kmaster_kube-system_997514ff25ec38012de6a5be7c43b0ae_14
d78e179f1565 k8s.gcr.io/pause:3.1 "/pause" 26 minutes ago Up 26 minutes k8s_POD_kube-apiserver-kmaster_kube-system_997514ff25ec38012de6a5be7c43b0ae_1
api-сервер по какой-то причине завершает работу. Я проверил его журналы (я только включаю соответствующие журналы для удобства чтения):
$ sudo docker logs 5e957ff48d11
...
W0217 11:30:46.710541 1 clientconn.go:1120] grpc: addrConn.createTransport failed to connect to {https://127.0.0.1:2379 0 <nil>}. Err :connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:2379: connect: connection refused". Reconnecting...
panic: context deadline exceeded
Обратите внимание, что apiserver пытался подключиться к etcd (уведомление порт: 2379), и получение соединения отклонено. Моим первым предположением было то, что etcd не работал, поэтому я проверил контейнер etcd:
$ sudo docker ps -a | grep etcd
4a249cb0743b 303ce5db0e90 "etcd --advertise-cl…" 2 minutes ago Exited (1) 2 minutes ago k8s_etcd_etcd-kmaster_kube-system_9018aafee02ebb028a7befd10063ec1e_19
b89b7e7227de k8s.gcr.io/pause:3.1 "/pause" 30 minutes ago Up 30 minutes k8s_POD_etcd-kmaster_kube-system_9018aafee02ebb028a7befd10063ec1e_1
Я был прав: Выход (1) 2 минуты go. Я проверил его журналы:
$ sudo docker logs 4a249cb0743b
...
2020-02-17 11:34:31.493215 C | etcdmain: listen tcp 10.156.0.20:2380: bind: cannot assign requested address
etcd пытался связать со старым IP-адресом.
Я изменил /etc/kubernetes/manifests/etcd.yaml
и изменил старый IP-адрес на новый IP везде в файле.
Быстрый sudo docker ps | grep etcd
показал, что работает. Через некоторое время также начал работать apierver.
Затем я попытался запустить kubectl:
$ kubectl get po
Unable to connect to the server: x509: certificate is valid for 10.96.0.1, 10.156.0.20, not 10.156.0.23
Неверный сертификат apiserver. Сертификат SSL был сгенерирован для старого IP, так что это означало бы, что мне нужно создать новый сертификат с новым IP.
$ sudo kubeadm init phase certs apiserver
...
[certs] Using existing apiserver certificate and key on disk
Это не то, что я ожидал. Я хотел создать новые сертификаты, а не использовать старые.
Я удалил старые сертификаты:
$ sudo rm /etc/kubernetes/pki/apiserver.crt \
/etc/kubernetes/pki/apiserver.key
И попытался сгенерировать сертификаты еще раз:
$ sudo kubeadm init phase certs apiserver
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kmaster kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.156.0.23]
Выглядит хорошо. Теперь давайте попробуем использовать kubectl:
$ kubectl get no
NAME STATUS ROLES AGE VERSION
instance-21 Ready master 102m v1.17.3
instance-22 Ready <none> 95m v1.17.3
Как вы видите, теперь он работает.