Я пытаюсь настроить кластер HA Kubernetes в облаке Hetzner, следуя это гид. Я создал 6 серверов, 3 хоста уровня управления и 3 рабочих. При попытке использовать kubeadm для присоединения второго сервера к кластеру я получаю следующие ошибки:
На k8s-сервере-1:
06 июля 14:09:01 k8s-server-1 kubelet[8059]: E0706 14:09:01.430599 8059 controller.go:187] не удалось обновить аренду, ошибка: ошибка rpc: код = неизвестное описание = крайний срок контекста превышен
06 июля 14:08:54 k8s-server-1 kubelet[8059]: E0706 14:08:54.370142 8059 controller.go:187] не удалось обновить аренду, ошибка: ошибка rpc: код = неизвестное описание = крайний срок контекста превышен
06 июля 14:08:51 k8s-server-1 kubelet[8059]: E0706 14:08:51.762075 8059 kubelet_node_status.go:470] «Ошибка обновления состояния узла, повторная попытка» err = «ошибка при получении узла «k8s-server» -1\": получите "https://my.kubernetes.test:6443/api/v1/nodes/k8s-server-1?resourceVersion=0&timeout=10s\": срок действия контекста превышен"
06 июля 14:08:47 k8s-server-1 kubelet[8059]: E0706 14:08:47.325309 8059 event.go:273] Невозможно записать событие: '&v1.Event{TypeMeta:v1.TypeMeta{Вид:"" , APIVersion:""}, ObjectMeta:v1.ObjectMeta{Name:"kube-apiserver-k8s-server-1.168f32516b37209a", GenerateName:"", Namespace:"kube-system", SelfLink:"", UID:"" , ResourceVersion:"", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1. Time)(nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers :[]string(nil), ClusterName:"", ManagedFields:[]v1.ManagedFieldsEntry(nil)}, InvolvedObject:v1.ObjectReference{Kind:"Pod", Namespace:"kube-system", Name:"kube- apiserver-k8s-server-1", UID: "10b8928a4f8e5e0b449a40ab35a3efdc", APIVersion: "v1", ResourceVersion: "", FieldPath: "spec.containers{kube-apiserver}"}, Reason: "Неработоспособен", Сообщение: "Готовность ошибка зонда: сбой зонда HTTP светодиод с кодом состояния: 500", Источник: v1.EventSource {Компонент: "kubelet", Host: "k8s-server-1"}, FirstTimestamp: v1.Time {Time: time.Time {wall: 0xc0312fd0ee49429a, ext: 115787424848, loc:(*time.Location)(0x74c3600)}}, LastTimestamp:v1.Time{Time:time.Time{wall:0xc0312fd16f1a0a1d, ext:117801107410, loc:(*time.Location)(0x74c3600)}}, Count: 2, тип: "Предупреждение", EventTime:v1.MicroTime{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, Series:(*v1.EventSeries) (ноль), Действие:"", Связано:(*v1.ObjectReference)(ноль), ReportingController:"", ReportingInstance:""}': 'Patch "https://my.kubernetes.test:6443/api/ v1/namespaces/kube-system/events/kube-apiserver-k8s-server-1.168f32516b37209a": чтение tcp 192.168.178.2:60934->192.168.178.8:6443: использование закрытого сетевого подключения (можно повторить попытку после сна)
06 июля 14:08:47 k8s-server-1 kubelet[8059]: E0706 14:08:47.324053 8059 controller.go:187] не удалось обновить аренду, ошибка: ошибка rpc: код = неизвестное описание = крайний срок контекста превышен
06 июля 14:08:46 k8s-server-1 kubelet[8059]: I0706 14:08:46.986663 8059 status_manager.go:566] «Не удалось получить статус для модуля» podUID=10b8928a4f8e5e0b449a40ab35a3efdc pod="kube-system/kube- apiserver-k8s-server-1" error="etcdserver: время ожидания запроса истекло"
На k8s-сервере-2:
06 июля 14:09:04 k8s-server-2 kubelet[6685]: E0706 14:09:04.072247 6685 event.go:264] Сервер отклонил событие '&v1.Event{TypeMeta:v1.TypeMeta{Вид: "", APIVersion :""}, ObjectMeta:v1.ObjectMeta{Name:"weave-net-9fldg.168f3252093de42e", GenerateName:"", пространство имен:"kube-system", SelfLink:"", UID:"", ResourceVersion:"" , Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)(nil) , DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string( nil), ClusterName: "", ManagedFields: [] v1.ManagedFieldsEntry (nil)}, InvolvedObject: v1.ObjectReference {Kind: "Pod", Namespace: "kube-system", Name: "weave-net-9fldg", UID: "88743b7a-aa81-4948-be9b-78c4bbf436fe", APIVersion: "v1", ResourceVersion: "714", FieldPath: "spec.initContainers{weave-init}"}, Причина: "Вытащил", Сообщение: "Успешно вытащил изображение \"docker.io/weaveworks/weave-kube :2.8.1\" в 6.525660057s", Источник:v1.EventSource{Компонент:"kubelet", Хост:"k8s-server-2"}, FirstTimestamp:v1.Time{Time:time.Time{wall:0xc0312fd1997fa82e, ext:11173601176, loc:(*time.Location)(0x74c3600)}}, LastTimestamp:v1.Time{Time:time.Time{wall:0xc0312fd1997fa82e, ext:11173601176, loc:(*time.Location)(0x74c3600)} }, Счетчик: 1, Тип: «Обычный», EventTime: v1.MicroTime {Время: время. Время {стена: 0x0, доб: 0, loc: (* время. Местоположение) (ноль)}}, Серия: (* v1.EventSeries)(nil), Действие:"", Связано:(*v1.ObjectReference)(nil), ReportingController:"", ReportingInstance:""}': 'ошибка rpc: код = Неизвестное описание = крайний срок контекста превышен' (не будет повторной попытки!)
06 июля 14:08:57 k8s-server-2 kubelet[6685]: E0706 14:08:57.993540 6685 controller.go:144] не удалось убедиться, что аренда существует, повторная попытка через 400 мс, ошибка: Get "https://my .kubernetes.test:6443/apis/coordinate.k8s.io/v1/namespaces/kube-node-lease/leases/k8s-server-2?timeout=10s": срок действия контекста превышен
06 июля 14:08:57 k8s-server-2 kubelet[6685]: I0706 14:08:57.352989 6685 scope.go:111] «Удалить контейнер» containerID = «9e05ad27088c41bdd02bd0d32a16706fc6eab6e458031f0714c182554c182554c186554c186554
06 июля 14:08:56 k8s-server-2 kubelet[6685]: E0706 14:08:56.992481 6685 event.go:273] Невозможно записать событие: '&v1.Event{TypeMeta:v1.TypeMeta{Вид:"" , APIVersion:""}, ObjectMeta:v1.ObjectMeta{Name:"weave-net-9fldg.168f3252093de42e", GenerateName:"", пространство имен:"kube-system", SelfLink:"", UID:"", ResourceVersion: "", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)( nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[] строка (ноль), ClusterName: "", ManagedFields: [] v1.ManagedFieldsEntry (nil)}, InvolvedObject: v1.ObjectReference {Вид: "Pod", пространство имен: "kube-system", имя: "weave-net-9fldg ", UID:"88743b7a-aa81-4948-be9b-78c4bbf436fe", APIVersion:"v1", ResourceVersion:"714", FieldPath:"spec.initContainers{weave-init}"}, Reason:"Pulled", Сообщение: "Образ успешно извлечен \"docker.io/weaveworks/weave-kub e:2.8.1\" в 6.525660057s", Источник: v1.EventSource{Компонент:"kubelet", Хост:"k8s-server-2"}, FirstTimestamp:v1.Time{Time:time.Time{wall:0xc0312fd1997fa82e , ext:11173601176, loc:(*time.Location)(0x74c3600)}}, LastTimestamp:v1.Time{Time:time.Time{wall:0xc0312fd1997fa82e, ext:11173601176, loc:(*time.Location)(0x74c3600) }}, Счетчик: 1, Тип: "Обычный", EventTime: v1.MicroTime {Время: время. Время {стена: 0x0, доб: 0, loc: (* время. Местоположение) (ноль)}}, Серии: ( *v1.EventSeries)(nil), Action:"", Related:(*v1.ObjectReference)(nil), ReportingController:"", ReportingInstance:""}': 'Post "https://my.kubernetes.test :6443/api/v1/namespaces/kube-system/events": чтение tcp 192.168.178.3:47722->192.168.178.8:6443: использование закрытого сетевого подключения (можно повторить попытку после сна)
06 июля 14:08:56 k8s-server-2 kubelet[6685]: E0706 14:08:56.990109 6685 kubelet_node_status.go:470] «Ошибка обновления состояния узла, повторная попытка» err = «ошибка при получении узла «k8s-server» -2\": Получите \"https://my.kubernetes.test:6443/api/v1/nodes/k8s-server-2?timeout=10s\": net/http: запрос отменен (клиент.Время ожидания превышено во время жду заголовки)"
06 июля 14:08:56 k8s-server-2 kubelet[6685]: I0706 14:08:56.989160 6685 scope.go:111] «Удалить контейнер» containerID = «9e05ad27088c41bdd02bd0d32a16706fc6eab6e458031f0714c182552»
06 июля 14:08:56 k8s-server-2 kubelet[6685]: E0706 14:08:56.988865 6685 kubelet.go:1683] «Не удалось создать модуль зеркала для» err="Post\"https://my. kubernetes.test:6443/api/v1/namespaces/kube-system/pods\": чтение tcp 192.168.178.3:47722->192.168.178.8:6443: использование закрытого сетевого подключения" pod="kube-system/etcd- k8s-сервер-2"
06 июля 14:08:54 k8s-server-2 kubelet[6685]: E0706 14:08:54.210098 6685 pod_workers.go:190] «Ошибка синхронизации модуля, пропуск» err = «не удалось \"StartContainer\" для \" etcd\" с CrashLoopBackOff: \"отсрочка 10-секундного перезапуска не удалась container=etcd pod=etcd-k8s-server-2_kube-system(22b3a914daf1bef98cb01ddd7868523d)\"" pod="kube-system/etcd-k8s-server-2" podUID =22b3a914daf1bef98cb01ddd7868523d
06 июля 14:08:54 k8s-server-2 kubelet[6685]: I0706 14:08:54.208472 6685 scope.go:111] «Удалить контейнер» containerID = «9e05ad27088c41bdd02bd0d32a16706fc6eab6e458031f0714c182554c182554c186554c186554c186554
06 июля, 14:08:54 k8s-server-2 kubelet[6685]: E0706 14:08:54.208199 6685 kubelet.go:1683] «Не удалось создать зеркальный модуль для» err = «ошибка rpc: code = Unknown desc = context крайний срок превышен" pod="kube-system/etcd-k8s-server-2"
06 июля 14:08:53 k8s-server-2 kubelet[6685]: E0706 14:08:53.347043 6685 event.go:264] Сервер отклонил событие '& v1.Event {TypeMeta: v1.TypeMeta {Вид: "", APIVersion :""}, ObjectMeta:v1.ObjectMeta{Name:"kube-proxy-2z5js.168f3250c7fc2120", GenerateName:"", пространство имен:"kube-system", SelfLink:"", UID:"", ResourceVersion:"" , Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)(nil) , DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Finalizers:[]string( nil), ClusterName: "", ManagedFields: [] v1.ManagedFieldsEntry (nil)}, InvolvedObject: v1.ObjectReference {Вид: "Pod", Пространство имен: "kube-system", Имя: "kube-proxy-2z5js", UID: «0ac8fe5d-7332-4a4d-abee-48c6d4dee38f», APIVersion: «v1», ResourceVersion: «711», FieldPath: «spec.containers {kube-proxy}»}, Reason: «Started», Message: «Started контейнер kube-proxy", Источник: v1.EventSource{Compone nt:"kubelet", Host:"k8s-server-2"}, FirstTimestamp:v1.Time{Time:time.Time{wall:0xc0312fd04243d720, ext:5783805064, loc:(*time.Location)(0x74c3600)}} , LastTimestamp:v1.Time{Time:time.Time{wall:0xc0312fd04243d720, ext:5783805064, loc:(*time.Location)(0x74c3600)}}, Count:1, Type:"Normal", EventTime:v1.MicroTime {Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, Series:(*v1.EventSeries)(nil), Action:"", Related:(* v1.ObjectReference)(nil), ReportingController:"", ReportingInstance:""}': 'ошибка rpc: code = Unknown desc = превышен срок контекста' (не будет повторяться!)
06 июля 14:08:53 k8s-server-2 kubelet[6685]: I0706 14:08:53.269542 6685 scope.go:111] "RemoveContainer" containerID="e2664d16d53ff5ae6de27fe52e84651791bca1ca70a6987c9a4e3e7418ea"
6 июля 14:08:47 k8s-server-2 kubelet[6685]: I0706 14:08:47.194425 6685 scope.go:111] «Удалить контейнер» containerID = «7aaa63419740b5e30cc76770abc92dfbabe1f48d4d812b4abc891465f73»
06 июля 14:08:46 k8s-server-2 kubelet[6685]: I0706 14:08:46.987598 6685 status_manager.go:566] «Не удалось получить статус модуля» podUID=778e041efc75c1983cbb59f2b3d46d09 pod="kube-system/kube- controller-manager-k8s-server-2" error="etcdserver: время ожидания запроса истекло"
06 июля 14:08:46 k8s-server-2 kubelet[6685]: E0706 14:08:46.986807 6685 controller.go:144] не удалось убедиться, что аренда существует, повторная попытка через 200 мс, ошибка: etcdserver: время ожидания запроса истекло
06 июля 14:08:46 k8s-server-2 kubelet[6685]: E0706 14:08:46.986800 6685 kubelet_node_status.go:470] «Ошибка обновления состояния узла, повторная попытка» err = «ошибка при получении узла «k8s-server» -2\": etcdserver: время запроса истекло"
Список серверов:
| Имя | Публичный IP-адрес | Частный IP |
| --- | --- | --- |
| k8s-сервер-1 | 192.168.178.2 | 10.23.1.2 |
| k8s-сервер-2 | 192.168.178.3 | 10.23.1.3 |
| k8s-сервер-3 | 192.168.178.4 | 10.23.1.4 |
| k8s-воркер-1 | 192.168.178.5 | 10.23.1.5 |
| k8s-воркер-2 | 192.168.178.6 | 10.23.1.6 |
| k8s-воркер-3 | 192.168.178.7 | 10.23.1.7 |
Кроме того, к k8s-server-* применяются следующие правила брандмауэра (применяется только к трафику, маршрутизируемому через общедоступный IP-адрес, а не внутри частной сети):
| Направление | Порт | Источник/Назначение |
| --- | --- | --- |
| Вход | 80 | любой |
| Вход | 443 | любой |
| Вход | 22 | статическая компания IP |
| Вход | 6443 | статическая компания IP |
| Выход | любой | любой |
Внутри той же сети есть балансировщик нагрузки, который направляет трафик на k8s-server-1. Публичный IP-адрес — 192.168.178.8, а частный — 10.23.1.8.
Что я запускал на обоих узлах:
apt-получить обновление
apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) стабильный" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-получить обновление
apt-get установить docker-ce docker-ce-cli containerd.io
systemctl включить docker.service
systemctl включить containerd.service
кошка <<ЕОФ | судо тройник /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"журнал-драйвер": "json-файл",
"журнал-опций": {
"максимальный размер": "100 м"
},
"драйвер хранилища": "overlay2"
}
EOF
systemctl включить докер
systemctl демон-перезагрузка
systemctl перезапустить докер
кошка <<ЕОФ | sudo тройник /etc/modules-load.d/k8s.conf
br_netfilter
EOF
кошка <<ЕОФ | тройник судо /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --система
apt-получить обновление
apt-get install -y apt-transport-https ca-сертификаты curl
curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo тройник /etc/apt/sources.list.d/kubernetes.list
apt-получить обновление
apt-get install -y kubelet kubeadm kubectl
apt-mark удерживать kubelet kubeadm kubectl
... на сервере 1:
вытягивание образов конфигурации kubeadm
kubeadm init --apiserver-advertise-address=10.23.1.2 --control-plane-endpoint "my.kubernetes.test:6443" --upload-certs
мкдир ~/.кубе
cp /etc/kubernetes/admin.conf ~/.kube/config
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(версия kubectl | base64 | tr -d '\n')"
посмотреть, как kubectl получает pod -n kube-system
смотреть, как kubectl получает узлы
... на сервере 2:
вытягивание образов конфигурации kubeadm
kubeadm join my.kubernetes.test:6443 --token XXXXX.XXXXX --discovery-token-ca-cert-hash sha256:XXXXXXXXXX --control-plane --certificate-key XXXXXXXXXX