Сторінки

субота, 28 вересня 2019 р.

Розгортання Kubernetes кластера на VirtualBox


Ціль статті написати інструкцію по розгортанню  локального тринодового Kubernetes кластера з використанням 3х віртуальних машин на базі VirtualBox. В якості операційної системи кластера вибір впав на Ubuntu Server 18.04 LTS. 

Kubernetes (K8S) - це система управління кластерними контейнерами, яка реалізує функції автоматичного розгортання, автоматичного розширення та обслуговування застосунками у контейнерах.
Існує два типи нод K8S: нода управління (master) та робоча нода (slave). Нода управління в основному відповідає за управління кластером K8S, обмін інформацією та планування завдань між нодами кластера, управління життєвим циклом контейнерів, Под (Pod), просторами імен (NameSpaces), PV тощо. Робочі ноди в основному забезпечують обчислювальні ресурси для контейнерів і под. Поди та контейнери працюють на робочих нодах. Робочі ноди спілкуються з нодами управління за допомогою служб kubelet для управління життєвим циклом контейнерів та спілкування з іншими нодами кластеру. Більше деталей про Kubernetes можна знайти в різних джерелах.

Налаштування віртуальної машини

Для початку необхідно створити та налаштувати одну віртуальну машину для master ноди з мінімальними характеристиками 2 CPUs та 2GB RAM (в джерелах знайдена інформація, що для master ноди важливо мати мінімально 2 CPUs). Далі клонуємо її замість того, щоб виконувати одні й ті ж налаштування для інших двох віртуальних машин.
  • Виділим 3 GB RAM пам’яті і 15 GB дискового простору.
  • Викачаєм ISO образ Ubuntu Server 18.04 LTS https://ubuntu.com/download/server.
  • Налаштуємо мережеві параметри віртуальної машини.
Створимо два мережевих адаптера.
Для першого адаптера задамо NAT для виходу віртуальної машини в інтернет.
Другий адаптер буде налаштований як host-only network для взаємодії віртуальних машин між собою та хостом. Також необхідно встановити Promiscuous mode to Allow All.




Після налаштування віртуальної машини можемо її запустити та встановити на неї Ubuntu Server. При встановленні необхідно відключити DHCP всередині налаштувань інтерфейсу enp0s8 ( для нашого host-only адаптера), а також встановити статичну IPv4 адресу, наприклад 192.168.56.120.



Також корисно встановити SSH сервер для доступу до віртуальної машини з хост-системи, використовуючи Putty або через термінал, наприклад

Це усуває недолік неможливості скопіювати та вставити дані з хост-системи без додаткових дій, що можуть бути непростими без GUI.

Якщо потрібно змонтувати VBoxGuestAdditionsISO, то за посиланням можете це зробити. https://wiki.merionet.ru/servernye-resheniya/11/samoe-interesnoe-pro-guest-additions-v-virtualbox/


Тепер зробимо ще кілька речей та встановимо потрібні програми.

Ми збираємось запускати багато команд, тому нам потрібні права root
sudo su

1. Встановимо Host Name master
hostnamectl set-hostname master

2. Відредагуємо файл /etc/hosts, додавши до нього доменні імена
cat <<EOF >>/etc/hosts
192.168.56.120 master
192.168.56.121 slave1
192.168.56.122 slave2
EOF

3. Якщо потрібно змінити IP, можемо відредагувати файл /etc/netplan/50-cloud-init.yaml
nano /etc/netplan/50-cloud-init.yaml

На деяких системах встановити/змінити IP-адресу host-only адаптера можна у файлі /etc/network/interfaces:

# Host-only network
auto enp0s8
iface enp0s8 inet static
address 192.168.56.120
netmask 255.255.255.0
network 192.168.56.0
broadcast 192.168.56.255

Ім'я вашого інтерфейсу може бути іншим, тому перевірте його через ip addr або ifconfig -a, щоб побачити назву вашого інтерфейсу. У моєму випадку enp0s8 - це мій host-only network, а enp0s3 - мій звичайний адаптер, який може бачити мережу моєї хост-машини та налаштований для DHCP.

4. Потрібно вимкнути swap розділ (вимога k8s). Можемо використовувати swapoff, але також потрібно відредагувати файл /etc/fstab, щоб видалити або закоментувати будь-які записи swap. Цього вимагає kubeadm під час "pre-flight checks".
swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab
або використайте редактор
 nano /etc/fstab

Превірити
cat /proc/swaps

5. Відключіть firewall
systemctl disable ufw && systemctl stop ufw

6. Виключити підтримку SELinux
setenforce 0
sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

7. Прочитати стан IP forwarding:
sysctl net.ipv4.ip_forward

Включити IP forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward

8. Налаштуйте параметри ядра для передачі мостового трафіку IPv4 до ланцюжка iptables. Це потрібно для Flannel (він весь трафік IPv4 пропускає через ланцюг iptables)

cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl --system

9. Встановимо наступні додатки HTTPS support, Curl
apt-get update
apt-get install -y apt-transport-https ca-certificates curl software-properties-common

10. Інсталюємо Docker:
apt-get install -y docker.io
systemctl enable docker && systemctl start docker
docker version

11. Завантажити ключ для Kubernetes repo і додати його до свого менеджера ключів:
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

12. Додати kubernetes repo до системи
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF

13. Встановити і запустити kubeadm, kubelet та kubectl:
apt-get update
apt-get install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet

Перевірити версію:
kubeadm version

14. Kubernetes і Docker повинні мати однакову cgroup, і це може бути або cgroupfs, або systemd. Рекомендується встановити systemd. https://kubernetes.io/docs/setup/production-environment/container-runtimes/#cgroup-drivers
При цьому коли використовується Docker, kubeadm автоматично визначає cgroup для kubelet і встановлює її в файл /var/lib/kubelet/kubeadm-flags.env протягом runtime. https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#configure-cgroup-driver-used-by-kubelet-on-control-plane-node

Щоб перевірити docker групу
docker info | grep -i cgroup

Для оновлення до systemd виконайте наступне
cat << EOF> /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver = systemd"]
}
EOF

Перезавантажте Docker і Kubernetes
systemctl daemon-reload
systemctl restart kubelet
systemctl restart docker

або просто перезавантажте віртуальну машину.

Клонування мастера

Саме час для клонування нашої машини.
Переконайтесь, що при клонуванні була згенерована нова mac-адреса та переконайтеся, що віртуальні машини мають різні mac-адреси.





Створіть linked clone машини




Після завершення завантажте машини та змініть наступні речі:
  • Встановіть IP-адресу 192.168.56.121 (або 122 для slave2) для host only network. 
nano /etc/netplan/50-cloud-init.yaml
  • Встановіть ім'я хоста slave1 або slave2.
hostnamectl set-hostname slave1

Перезавантажте та перевірте чи пінгуються slave машини.
Отже, все необхідне зроблено для розгортання кластеру k8s.

 

Розгортання Кластеру 


Тепер нам потрібно переконатися, що hostname відповідає нашому IP для host only network. Виконайте
hostname -i
і воно повинно повернути IP-адресу машини. Якщо це не так, просто спробуйте перезапустити VM або перевірити конфігурацію мережі /etc/hosts .

Kubernetes використовує мережевий драйвер для встановлення мережевого протоколу між нодами, подами та контейнерами. Є кілька різних мережевих драйверів, всі вони описані в документації. https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network

Використаємо Flannel. Він підтримує різні cpus: amd64, arm, 32-бітні процесори та інші. Підмережа IP-адреси становить 10.244.0.0, що дозволяє уникнути конфліктів з маршрутизаторами, які використовують 192.168.0.0 або 172.20.0.0.

Проініціалізуємо Kubernetes кластер на master.
kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.56.120

--apiserver-advertise-address - визначає, на якій IP-адресі Kubernetes має свій API сервер.
--pod-network-cidr - необхідний для драйвера Flannel та вказує адресний простір для контейнерів.

P.S. IP машини 192.168.56.120 доступно для хоста та інших машин. Якщо використовувати bridge network adapter, а не окремі адаптери Nat та host-only network, може виникнути проблема. Кожен раз, коли буде відбуватися завантаження машини, вона матиме інший IP, який би не працював для Kubernetes. Ноди почнуть шукати початкову IP-адресу та не знайдуть її.

Перш ніж додати в кластер slave ноди, нам потрібно зробити kubeadm роботу від звичайного користувача. Таким чином, виходимо з-під root та виконуємо команди, які прописані після ініціалізації Kubernetes кластеру

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Оскільки ми зконфігурували два мережевих адаптери enp0s3 та enp0s8, Flannel може використати enp0s3, а нам потрібно enp0s8. Для цього перед встановленням мережевого драйвера Flannel потрібно в кофігурації явно задати інтерфейс enp0s8.

Редагуємо файл kube-flannel.yml, додавши рядок - --iface=enp0s8
sudo nano kube-flannel.yml


containers:
  - name: kube-flannel
    image: quay.io/coreos/flannel:v0.10.0-amd64
    command:
    - /opt/bin/flanneld
    args:
    - --ip-masq
    - --kube-subnet-mgr
    - --iface=enp0s8


Встановлюємо драйвер
kubectl apply -f kube-flannel.yml

Перевіримо, що вибраний правильний інтерфейс, переглянувши логи kube-flanne-ds
kubectl logs kube-flannel-ds-amd64-j25ht -n kube-system 




Перевіримо статус под кластера
kubectl get pods --all-namespaces



Можемо переглянути журнал Kublet
sudo journalctl -u kubelet | less

Перегляд статусу нод
kubectl get nodes -o wide

NAME STATUS ROLES AGE VERSION
master Ready master 24m v1.16.0

Можна налаштувати master ноду так, щоб вона була доступна для планування робочих навантажень.
kubectl taint nodes --all node-role.kubernetes.io/master-

Тепер додамо в кластер slave ноди.

Скопіюємо команду
kubeadm join $IP --token $TOKEN --discovery-token-ca-cert-hash $DISCOVERY_TOKEN  
з результату команди kubeadm init та виконаємо на кожній ноді.
$IP - ip головної ноди, $TOKEN - маркер, згенерований kubeadm init, він дійсний лише протягом 24 годин, оскільки він використовується лише для автентифікації нод, а майстер $DISCOVERY_TOKEN - хеш сертифіката маркера.

Якщо ви забудете скопіювати команду приєднання з результатів init, ви можете відновити маркер або прочитати існуючий з конфігурації.

kubeadm token list
kubeadm token create --print-join-command

Перевіримо ще раз статус


Також корисно створити просту поду та перевірити чи нема проблем з DNS https://kubernetes.io/docs/tasks/administer-cluster/dns-debugging-resolution/

kubectl apply -f https://k8s.io/examples/admin/dns/busybox.yaml

kubectl get pods busybox

NAME      READY     STATUS    RESTARTS   AGE
busybox   1/1       Running   0          <some-time>

Після запуску поди можете виконати nslookup.
kubectl exec -ti busybox -- nslookup kubernetes.default

І якщо ви бачите наступне, то DNS працює правильно.

 

Problems

Проблеми, з якими зіштовхнувся з Kubernetes version: v1.16.0
Траплялося так, що coredns зависав в статусі Pending.

NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-78fcdf6894-kgg8d 0/1 Pending 0 2h
kube-system coredns-78fcdf6894-vl9jf 0/1 Pending 0 2h

Рішення, яке домомагало, це додати пропущену версію CNI в kube-flannel-cfg. Для редагування ConfigMap flannel виконайте наступну команду

KUBE_EDITOR="nano" kubectl edit cm -n kube-system kube-flannel-cfg

та додайте рядок "cniVersion": "0.2.0"

   apiVersion: v1
   data:
     cni-conf.json: |
       {
         "name": "cbr0",
        "cniVersion": "0.2.0",
        "plugins": [

Перезавантажте ноду.
Ручне редагування конфіг файлу /etc/cni/net.d/10-flannel.conflist
та виконання systemctl restart kubelet також допомагає, але налаштування будуть скинуті після перезавантаження ноди.

Посилання

Немає коментарів:

Дописати коментар