Skip to content

K8s wg


tags: - Kubernetes - Wireguard


# Кластер на wireguard Создадим мульти-нодовый кластер Kubernetes (k8s), в котором: - Узлы этого кластера могут располагаться по всему миру, у разных поставщиков услуг, и могут быть как защищены сетями NAT, так и иметь прямой доступ к интернету. - Единственный UDP-порт, который будет доступен извне, будет использоваться для подключения к виртуальной частной сети (VPN), и, при необходимости, можно добавить дополнительные порты, такие как NodePort. - Только узлы в той же VPN могут присоединиться к кластеру, и только устройства в этой же VPN могут получить доступ к API Kubernetes и использовать инструмент командной строки

Как развернуть wireguard используя ansible смотрим тут

Кластер будем устанавливать в ручном режиме для лучшего понимания процесса ansible role

Выполняем на master и worker нодах

Disable dns-search tech0.ru

ошибка проявляется на подах с alpine /etc/network/interfaces.d/50-cloud-init удалить везде в интерфейсах dns-search ....

  • не должно быть днс на 127.0.0.53 типо systemd-resolved внутри подов /etc/resolv.conf search gitlab.svc.cluster.local svc.cluster.local cluster.local далее в этой строке тут ничего не должно быть nameserver 10.96.0.10 options ndots:5

если потребуется можно в настройках coredns добавить log чтобы видеть все dns запросы

Disable the local DNS cache on host nodes

иначе coredns будет (релодиться и крашится)[https://github.com/coredns/coredns/blob/master/plugin/loop/README.md#troubleshooting-loops-in-kubernetes-clusters]

Disable Swap

sudo swapoff -a

Hosts

sudo vi /etc/hosts

#Add the following list in the end of line
10.0.1.1 ztv-master01
10.0.1.101 ztv-worker01
10.0.1.102 ztv-worker02

Подготовительные действия

$ sudo tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

$ sudo modprobe overlay
$ sudo modprobe br_netfilter
$ lsmod | egrep "br_netfilter|overlay"

$ sudo tee /etc/sysctl.d/kubernetes.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

$ sudo sysctl --system

Iptables

Нужно проверить, что есть правило для цепочки INPUT, иначе coredns поды не будут READY:

iptables -I INPUT -s 10.6.0.0/24 -d 10.6.0.0/24 -j ACCEPT
и для цепочки FORWARD не должно быть запрещающих правил, которые бы блокировали, вот эти правила:
-A FLANNEL-FWD -s 10.244.0.0/16 -m comment --comment "flanneld forward" -j ACCEPT
-A FLANNEL-FWD -d 10.244.0.0/16 -m comment --comment "flanneld forward" -j ACCEPT

Kubelet

С установленным wireguard получится так, что интерфейсов будет больше чем 1 и если не назначить kubelet конкретный IP нашего wg0, то он назначит INTERNAL_IP для ноды тот, который назначил VPS: wg0

su -
echo "KUBELET_EXTRA_ARGS=--node-ip=$(ip addr show wg0 | grep -oP '(?<=inet\s)\d+\.\d+\.\d+\.\d+')" > /etc/default/kubelet
or добавь подстроку '--node-ip=10.192.1.1' в конец строки чтобы получилось "ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --node-ip=10.192.1.1"

systemctl daemon-reload
systemctl restart kubelet.service

Настройка containerd использовать systemd как cgroup driver:

$ sudo apt update && sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates containerd.io

$ containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1

$ sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml

$ sudo systemctl restart containerd && sudo systemctl enable containerd

Основные пакеты для k8s

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/cgoogle.gpg

$ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"

$ sudo apt update &&  sudo apt install kubelet kubeadm kubectl -y && sudo apt-mark hold kubelet kubeadm kubectl

$ kubectl version

Запускаем только на master node

Инициализация кластера

$ sudo kubeadm init \
    --apiserver-advertise-address=EXTERNAL_IP_ADDRESS \
    --pod-network-cidr=10.244.0.0/16  \
    --control-plane-endpoint=ztv-master01 \
    --cluster-name=k8s \
    --node-name "ztv-master01"

--control-plance-endpoint указываем на внутренный ip адрес или внетреннее имя для loadbalancer(если кто хочет может выставлять наружу через внешние)
--apiserver-advertise-address если не установить то если есть 2 и > интерфесов на данном control plane, то будет назначен адрес интерфейса данного master и выбран из сети имеющей маршрут по умолчанию, что не всегда удобно , особенно если мы не хотим чтобы etcd на внешнем интерфейсе был, поэтому ставим конкретный Внутренний ip адрес мастера данного
--apiserver-cert-extra-sans - нужно указать ip адреса или имена на которые будут доп сертификаты, чтобы можно было подключаться например через loadbalancer

$ mkdir -p $HOME/.kube && sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config &&  sudo chown $(id -u):$(id -g) $HOME/.kube/config
Если нужно чтобы мастер нода использовалась и как worker нода, то нужно снять taint
$ kubectl taint node ztv-master01 node-role.kubernetes.io/control-plane:NoSchedule-
Для включения kubernetes complete в bash:
echo 'source <(kubectl completion bash)' >>~/.bashrc
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -o default -F __start_kubectl k' >>~/.bashrc
complete -F _complete_alias k

На worker нодах выполняем

После инициализации кластера внизу будет запись по присоединению worker ноды к кластеру - выполняем or kubeadm token create --print-join-command

sudo kubeadm join ......

На master ноде

Проверьте, что после join INTERNAL-IP на нодах - это ip адреса wg0 интерфейсов(должна сработать запись, добавленная в файл /etc/default/kubelet):

$ kubectl -n kube-system get nodes -o wide

Установка CNI

До установки CNI Узлы находятся статусе “NotReady”. Flanneld по умолчанию пытается привязаться к интерфейсу, который не относится к VPN. И это не то, что нам нужно. Я хочу, чтобы вся коммуникация между узлами происходила через VPN. Без локальных IP-адресов, без общедоступных IP-адресов - только через VPN. Поэтому настраиваем сетевые интерфейсы, к которым Flannel должен быть привязан.

$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

insert in containers:args:
    - --iface=wg0

$ kubectl apply -f kube-flannel.yml            после обновления CNI обязательно удалить все поды kube-proxy

или устанавливаем calico потому что flannel имеет проблемы например из подов с alpine не работает dns
curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/calico.yaml
если не работает смотрим --pod-network-cidr сеть которую указали использовать для подов при инициализации кластера и изменяем в манифесте CALICO_IPV4POOL_CIDR
а также нужно чтобы через wireguard было взаимодествие: https://docs.tigera.io/calico/latest/networking/ipam/ip-autodetection
kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD=interface=wg0.*
Если нужно установить label на worker ноды
$ kubectl label node <WORKER_NODE_NAME>  node-role.kubernetes.io/worker=worker

Удалить кластер

$ kubectl delete deployment kube-dns --namespace=kube-system
$ kubectl delete deployment kubernetes-dashboard --namespace=kube-system
$ kubectl delete -f kube-flannel.yml
$ kubectl drain your-kub-host --delete-local-data --force --ignore-daemonsets
$ sudo kubeadm reset; sudo rm -rf /etc/kubernetes/; sudo rm -rf /etc/cni/net.d/; sudo rm -rf /var/lib/kubelet; sudo rm -rf /opt/cni/; sudo rm -rf $HOME/.kube/
$ sudo apt purge kubectl kubelet kubeadm kubernetes-cni -y

Тестирование кластера

Test Deployment

$ kubectl create deployment nginx-app --image=nginx --replicas 2
$ kubectl expose deployment nginx-app --name=nginx-web-svc --type NodePort --port 80 --target-port 80
$ kubectl describe svc nginx-web-svc
nginx-web-svc       NodePort    10.100.242.254   <none>        80:31116/TCP     5d22h
$ iptables -A INPUT -p tcp --dport 31116 -j ACCEPT

curl -LI <IP>:31116

$ kubectl scale deployment nginx-app --replicas=5

$ kubectl exec -it nginx-app- -c nginx -- sh
$ kubectl exec -it nginx-app-5777b5f95-82424 -- bash

Test Pod without Deployment

kubectl run -it --rm test-nginx-svc --image=nginx  -- bash
kubectl exec -it test-nginx-svc -c test-nginx-svc -- bash
  • https://kubernetes.io/docs/tutorials/stateless-application/guestbook/