Files
K3S/docs/troubleshooting.md
2026-04-27 08:40:08 +03:00

13 KiB
Raw Permalink Blame History

Решение проблем

Таблица проблем

Проблема Причина Решение
Permission denied (publickey) Ключ не скопирован ssh-copy-id user@server
Vault decryption failed Неверный пароль vault Проверь VAULT_PASSWORD в .env
kube-vip VIP не пингуется Неверный интерфейс Проверь kube_vip_interface — должен совпадать с ip a на master01
RPi K3S не стартует Не включены cgroups `ssh pi@rpi "cat /proc/cgroups
PVC в Pending NFS не монтируется kubectl get events -A — проверь монтирование NFS на нодах
ingress EXTERNAL-IP <pending> kube-vip не работает `kubectl -n kube-system get pods
etcd нет кворума Нода упала Нужно минимум 2 из 3 нод. kubectl get nodes
worker01/rpi01 не присоединились master01 не готов Убедись что master01 полностью стартовал. serial: 1 гарантирует порядок
Kiali: "Could not get token" Нет Secret kubectl -n istio-system get secret kiali-admin-token
Grafana PVC Pending NFS StorageClass не default kubectl get scnfs-master01 должен быть (default)
Molecule: image pull failed Нет интернета docker pull geerlingguy/docker-ubuntu2204-ansible:latest вручную
Molecule: idempotency failed Таск не идемпотентен Добавь changed_when: false
ansible-lint ошибки Синтаксис make molecule-lint и исправь файлы
etcd restore: снимок не найден Неверный путь make etcd-list-snapshots — снимок должен быть на первом мастере
add-node: нода не присоединяется kube-vip не работает `kubectl -n kube-system get pods
remove-node: drain завис PodDisruptionBudget kubectl get pdb -A — проверь PDB
cert-manager: сертификат Pending Нет публичного домена При letsencrypt нужен публичный домен + ingress-nginx
Harbor: registry push fails Неверный externalURL harbor_ingress_host должен совпадать с реальным hostname
Jenkins: агент не стартует RBAC kubectl get events -n jenkins — проверь ServiceAccount
Vault: sealed после рестарта Нет auto-unseal Настрой vault_auto_unseal_type или используй k8s unsealer
NetBird: клиент не подключается DNS не настроен Настрой A-записи для Management, Signal, Coturn LB IPs
MinIO: distributed не поднимается Мало нод Distributed требует минимум 4 реплики/ноды
Nextcloud: redirect loop HTTP→HTTPS конфликт Добавь TRUSTED_PROXIES в конфиг Nextcloud
yandex-dns-controller: 401 Unauthorized Неверный токен Проверь yandex_dns.token в vault.yml; токен получается на oauth.yandex.ru
yandex-dns-controller: запись не создаётся managed: false Убедись что managed: true в ConfigMap
yandex-dns-controller: старая запись не удалена Нет в state Запись была создана вручную, не контроллером — удали вручную если нужно
ingress-add-domains: 404 Ingress не найден в namespace сервиса kubectl get ingress -A -l app.kubernetes.io/instance=ingress-add-domains
ingress-add-domains: 503 Сервис/порт неверный kubectl -n <namespace> get svc <name> — проверь имя и порт
ingress-proxypass: 502 Bad Gateway Кластер не достигает внешний IP curl -v http://<external-ip>:<port> с ноды кластера; проверь файрвол на внешнем хосте
ingress-proxypass: 503 Endpoints пустой kubectl -n ingress-proxypass get endpoints — должны быть адреса
ingress-proxypass: 404 Имя хоста не совпадает kubectl -n ingress-proxypass describe ingress <name> — хост должен совпасть точно
splitgw: трафик не перехватывается TPROXY mark не применён iptables -t mangle -L SPLITGW -v -n — должны быть правила; journalctl -u splitgw-rules -f
splitgw: sing-box не стартует Ошибка конфига journalctl -u singbox -f; sing-box check --config /etc/sing-box/config.json
splitgw: YouTube всё равно без VPN DNS утечка DNS-запросы должны идти через TPROXY; nslookup youtube.com 8.8.8.8 с устройства
hysteria2-server: порт закрыт Файрвол VPS ufw allow 443/udp или firewall-cmd --add-port=443/udp --permanent
hysteria2-server: клиент не подключается Самоподписанный сертификат Добавь insecure=1 в URL или установи tls_mode: acme
mediaserver: Prowlarr не видит индексеры Hysteria2 sidecar упал kubectl -n mediaserver logs <prowlarr-pod> -c hysteria2

Подробный вывод

ANSIBLE_VERBOSITY=2 make install                # основной вывод
ANSIBLE_VERBOSITY=4 make install                # максимальный вывод
ANSIBLE_VERBOSITY=2 ANSIBLE_TAGS=k3s make install  # подробно для k3s

Диагностика нод

make shell   # открыть bash в ansible-контейнере

# Внутри контейнера:
ansible all -m ping
ansible all -m shell -a "systemctl status k3s"
ansible k3s_master -m shell -a "k3s kubectl get nodes"
ansible k3s_master -m shell -a "journalctl -u k3s -n 50 --no-pager"

Диагностика кластера

export KUBECONFIG=$(pwd)/kubeconfig

# Общий статус
kubectl get nodes -o wide
kubectl get pods -A | grep -v Running
kubectl get events -A --sort-by='.lastTimestamp' | tail -30

# Ресурсы
kubectl top nodes
kubectl top pods -A --sort-by=cpu

# Конкретный под
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --tail=100 -f
kubectl logs <pod> -n <namespace> --previous   # логи предыдущего контейнера

# PVC проблемы
kubectl describe pvc <pvc> -n <namespace>
kubectl get pv

# Ingress проблемы
kubectl describe ingress <name> -n <namespace>
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller -f

Проверка etcd

kubectl -n kube-system exec -it \
  $(kubectl -n kube-system get pods -l component=etcd -o name | head -1) \
  -- etcdctl --endpoints=https://127.0.0.1:2379 \
     --cacert=/var/lib/kubernetes/k3s/server/tls/etcd/server-ca.crt \
     --cert=/var/lib/kubernetes/k3s/server/tls/etcd/server-client.crt \
     --key=/var/lib/kubernetes/k3s/server/tls/etcd/server-client.key \
     member list

Диагностика NFS

# На NFS сервере:
make shell
ansible nfs_server -m shell -a "exportfs -v"
ansible nfs_server -m shell -a "showmount -e localhost"

# На нодах кластера:
ansible k3s_cluster -m shell -a "mount | grep nfs"
ansible k3s_cluster -m shell -a "showmount -e 192.168.1.10"

Диагностика kube-vip

# Статус подов
kubectl -n kube-system get pods -l app.kubernetes.io/name=kube-vip

# Логи
kubectl -n kube-system logs -l app.kubernetes.io/name=kube-vip

# Проверить VIP
ping 192.168.1.100   # kube_vip_address
curl -k https://192.168.1.100:6443/healthz

Диагностика cert-manager

kubectl get certificate -A
kubectl get certificaterequest -A
kubectl get challenges -A
kubectl describe certificate <name> -n <namespace>
kubectl logs -n cert-manager deployment/cert-manager -f

Диагностика ingress-add-domains

# Все созданные Ingresses
kubectl get ingress -A -l app.kubernetes.io/instance=ingress-add-domains

# Детали конкретного Ingress
kubectl describe ingress <name> -n <namespace>

# Проверить что сервис существует
kubectl -n <namespace> get svc <service-name>

# Логи nginx-контроллера
kubectl -n ingress-nginx logs -l app.kubernetes.io/name=ingress-nginx --tail=50

Диагностика ingress-proxypass

# Ресурсы namespace
kubectl -n ingress-proxypass get all,ingress,endpoints

# Проверить Endpoints заполнены (Addresses не должен быть <none>)
kubectl -n ingress-proxypass describe endpoints <name>

# Тест изнутри кластера
kubectl run curl --rm -it --image=curlimages/curl -- \
  curl -v http://<service>.ingress-proxypass.svc.cluster.local:<port>

# Проверить что nginx подхватил правила
kubectl -n ingress-nginx logs -l app.kubernetes.io/name=ingress-nginx --tail=50

Диагностика splitgw

# Статус сервисов на хосте gateway
systemctl status singbox splitgw-rules
journalctl -u singbox -f
journalctl -u splitgw-rules -f

# Проверить TPROXY-правила iptables
iptables -t mangle -L SPLITGW -v -n
iptables -t mangle -L PREROUTING -v -n

# Проверить sing-box конфиг
sing-box check --config /etc/sing-box/config.json

# Диагностика DNS (с устройства-источника)
nslookup youtube.com
nslookup vk.com

Диагностика hysteria2-server

# Статус на VPS
systemctl status hysteria2
journalctl -u hysteria2 -f

# Проверить порт открыт (UDP)
ss -ulnp | grep 443
# С клиентской машины:
nc -u <vps-ip> 443

# Тест подключения
curl -v --proxy hysteria2://pass@<vps-ip>:443?insecure=1 https://example.com

Типичные Molecule ошибки

Ошибка Решение
Unable to pull image docker pull geerlingguy/docker-ubuntu2204-ansible:latest
FAILED: assert ... is defined Добавь переменную в converge.yml секцию vars:
Idempotency: CHANGED Добавь changed_when: false к таску
yamllint: wrong indentation Исправь отступы, запусти make molecule-lint
ansible-lint: no-changed-when Добавь changed_when: <условие>
sysctl: Operation not permitted Добавь privileged: true в molecule.yml

Детальная отладка Molecule (addons и cluster)

1) Сначала локализуй место падения

make molecule-addon-all

molecule-addon-all падает на первом сломанном аддоне.
После этого запускай конкретный сценарий:

make molecule-addon-<addon-name>

2) Запуск с продолжением после ошибок

Полезно для обзора нескольких проблем за один прогон:

make -k molecule-addon-all

-k (keep going) позволит пройти дальше даже после падения отдельных аддонов.

3) Типовые причины падений verify

  • Bool как строка

    • Симптом: assert v.flag == true падает, но в сообщении видно True.
    • Безопасный паттерн:
      • (v.flag | string | lower) == 'true'
  • Multi-document YAML

    • Симптом: from_yaml не может распарсить файл, где несколько ---.
    • Используй:
      • from_yaml_all | list
  • Файлы /tmp и delegate_to

    • Симптом: no such file or directory в helm lint/template.
    • Причина: файл рендерится на target-host, а читается на localhost.
    • Решение: рендерить/копировать и читать в одном контексте (чаще всего delegate_to: localhost, run_once: true).
  • Undefined variables в шаблонах

    • Симптом: AnsibleUndefinedVariable.
    • Решение: добавить недостающие vars в molecule/default/converge.yml (даже если они есть в role defaults).

4) Проверка cluster-сценария (3 master + 2 worker)

make molecule-cluster

Если видишь warning:

'molecule/default/molecule.yml' glob failed

и при этом команда заканчивается ✓ cluster topology: OK, это служебный warning shared-state Molecule, не функциональная ошибка сценария.