Вопрос или проблема
Я создал многомастеровый встроенный кластер K3s таким образом:
имя хоста: k3s01
curl -sfL https://get.k3s.io | K3S_TOKEN=xxx INSTALL_K3S_EXEC="server --disable servicelb --disable traefik --bind-address=10.0.0.4 --tls-san 10.0.0.4 --node-external-ip=168.119.x.x --node-ip=10.0.0.4 --flannel-iface=enp7s0 --advertise-address=PUBIP-OF-LB --cluster-init" sh -
имя хоста: k8s02
curl -sfL https://get.k3s.io | K3S_TOKEN=xxx INSTALL_K3S_EXEC="server --disable servicelb --disable traefik --bind-address=10.0.0.2 --tls-san 10.0.0.2 --node-ip 10.0.0.2 --node-external-ip=168.119.x.x --flannel-iface=enp7s0 --server=https://10.0.0.4:6443" sh -
имя хоста: k8s03
curl -sfL https://get.k3s.io | K3S_TOKEN=xxx INSTALL_K3S_EXEC="server --disable servicelb --disable traefik --bind-address=10.0.0.3 --tls-san 10.0.0.3 --node-ip 10.0.0.3 --node-external-ip=168.119.x.x --flannel-iface=enp7s0 --server=https://10.0.0.4:6443" sh -
Я могу подключаться с моего локального компьютера с помощью kubectl через LB-IP!
LB: tcp 6443 -> 6443
Я также могу использовать kubectl из любого из вышеперечисленных узлов.
Я развернул CSI для Hetzner, который тоже работает нормально. Испытано с их тестовым развертыванием!
Тем не менее, после всего этого (пока все работает хорошо) я попытался установить ingress-nginx.
Развертывание началось без каких-либо проблем.
Но я обнаружил, что существует проблема с коммуникацией с apiserver изнутри кластера, как показывает следующий лог контроллера ingress-nginx:
E1204 11:42:25.216392 8 leaderelection.go:321] ошибка при получении блокировки ресурса ingress-nginx/ingress-controller-leader-nginx: Получить "https://10.43.0.1:443/api/v1/namespaces/ingress-nginx/configmaps/ingress-controller-leader-nginx": dial tcp 10.43.0.1:443: подключение: соединение отказано
Хм, странно! Хорошо, давайте проверим:
kubectl get svc kubernetes -o yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2020-12-04T11:22:25Z"
labels:
component: apiserver
provider: kubernetes
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
.: {}
f:component: {}
f:provider: {}
f:spec:
f:clusterIP: {}
f:ports:
.: {}
k:{"port":443,"protocol":"TCP"}:
.: {}
f:name: {}
f:port: {}
f:protocol: {}
f:targetPort: {}
f:sessionAffinity: {}
f:type: {}
manager: k3s
operation: Update
time: "2020-12-04T11:22:25Z"
name: kubernetes
namespace: default
resourceVersion: "10434"
selfLink: /api/v1/namespaces/default/services/kubernetes
uid: f0993556-3b7f-40aa-a293-45170cb03002
spec:
clusterIP: 10.43.0.1
ports:
- name: https
port: 443
protocol: TCP
targetPort: 6443
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
Выглядит хорошо.
kubectl get endpoints -o yaml
apiVersion: v1
items:
- apiVersion: v1
kind: Endpoints
metadata:
creationTimestamp: "2020-12-04T11:22:25Z"
labels:
endpointslice.kubernetes.io/skip-mirror: "true"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:labels:
.: {}
f:endpointslice.kubernetes.io/skip-mirror: {}
f:subsets: {}
manager: k3s
operation: Update
time: "2020-12-04T11:23:39Z"
name: kubernetes
namespace: default
resourceVersion: "808"
selfLink: /api/v1/namespaces/default/endpoints/kubernetes
uid: cb450392-b4c9-4c2f-bfde-1a3b20ac4b5d
subsets:
- addresses:
- ip: 167.233.x.x
- ip: 168.119.x.x
- ip: 168.119.x.x
ports:
- name: https
port: 6443
protocol: TCP
kind: List
metadata:
resourceVersion: ""
selfLink: ""
Хорошо, почему здесь публичные IP-адреса?
Давайте проверим из одного пода, чтобы напрямую вызвать один из IP:
kubectl exec -it ingress-controler-pod-xxxx -- bash
bash-5.0$ curl https://167.233.x.x:6443 --insecure
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}bash-5.0$ curl https://10.43.0.1:443
curl: (7) Не удалось подключиться к 10.43.0.1 порт 443: Соединение отказано
Хорошо… это странно!
Также иногда возникают ошибки, такие как:
Ошибка от сервера: ошибка при подключении к бэкенду: dial tcp: поиск k8s02: Попробуйте еще раз
появляются, когда я пытаюсь войти в под или отобразить логи.
Это происходит только тогда, когда я пытаюсь сделать это к целевому поду, работающему на другом хосте.
Есть ли что-то неправильное с DNS?
cat /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
Я не могу разрешить мои хосты по их имени. Однако я указал IP-адреса только в настройках K3s.
Должен ли я иметь работающий DNS между моими хостами?
Есть ли что-то неправильное с параметрами установки K3s?
У меня была похожая проблема, вызванная неправильно настроенным разрешением DNS, проверьте, можете ли вы разрешить имена узлов друг для друга.
Ответ или решение
Проблема, с которой вы столкнулись, связана с ошибкой подключения к API серверу Kubernetes из подов вашего ingress-nginx контроллера. Ошибка dial tcp 10.43.0.1:443: connect: connection refused
указывает на то, что под не может подключиться к IP-адресу, который должен указывать на API сервер Kubernetes.
Возможные причины проблемы
-
Несоответствие конфигурации: Ваша настройка K3s с параметрами, которые вы указали, может быть причиной возникновения проблемы. Вы использовали публичные IP-адреса в конфигурации, что может приводить к ошибкам при попытке подключения изнутри кластера. K3s создает сервис
kubernetes
сClusterIP
10.43.0.1, и он должен направлять запросы к API серверу наlocalhost:6443
. -
DNS и разрешение имен: Похоже, что у вас могут быть проблемы с DNS. Убедитесь, что все узлы могут разрешать друг друга по именам. Это критично для корректного взаимодействия между компонентами Kubernetes.
-
Ошибка эндпоинтов: В выводе
kubectl get endpoints
видно, что эндпоинты указывают на публичные IP-адреса. Эндпоинты для сервиса Kubernetes должны указывать на IP-адреса узлов, где запущены API серверы. Это указывает на возможную неправильную конфигурацию сети или на запуск API сервера на неправильных IP.
Решение проблемы
-
Проверка доступа к API серверу:
Внутри вашего контроллера ingress-nginx выполните команду:kubectl exec -it <имя-пода-ingress-nginx> -- curl -k https://10.43.0.1:443
Это должно вернуть ответ от API сервера. Если вы все еще получаете ошибку подключения, это может указывать на то, что сервис
kubernetes
неправильно настроен или что API сервер не слушает на ожидаемых портах. -
Проверка конфигурации узлов:
Убедитесь, что каждый узел может связываться с другими узлами по их внутренним IP-адресам. Попробуйте выполнить следующие команды с каждого узла:ping <IP-адрес-другого-узла>
-
Проверка конфигурации DNS:
Проверьте, что все узлы могут разрешать внутренние сервисные имена Kubernetes. Убедитесь, что файл/etc/resolv.conf
настроен корректно. Вы можете попробовать использовать DNS-сервис, предоставляемый K3s:- Убедитесь, что на каждом узле установлен правильный Kubernetes DNS, например CoreDNS.
- Если он не установлен, вы можете установить его с использованием Helm или Manifests.
-
Перепроверка параметров установки K3s:
Возможно, при установке K3s были указаны неверные параметры. Вы можете попробовать пересоздать кластер с более простыми параметрами или использовать автоматические параметры конфигурации K3s. Проверьте документацию K3s на наличие актуальной информации о параметрах установки. -
Просмотр логов и диагностика:
Проверьте логи для сервиса K3s и компонентов, чтобы определить, есть ли специфические ошибки или предупреждения, которые могут помочь в диагностике проблемы:journalctl -u k3s
Также стоит проверить логи ingress-nginx контроллера:
kubectl logs <имя-пода-ingress-nginx>
Заключение
Данная проблема может требовать устранения неполадок в нескольких областях: конфликтующие конфигурации, проблемы с DNS или проблемы с сетью между узлами. Важно провести комплексную проверку всех перечисленных аспектов для успешного решения проблемы. Если ни одно из предложенных решений не сработает, возможен вариант с переустановкой K3s кластера с минимально необходимыми параметрами.