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¶
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:
и для цепочки 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
Настройка 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
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):
Установка 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.*
Удалить кластер¶
$ 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
Links:¶
- https://kubernetes.io/docs/tutorials/stateless-application/guestbook/