Kubernetes - це скоріше фреймворк для побудови кластеру, тому способів його розгортання є дуже багато, хоч вони і різні за актуальністю. Останнім часом з'явилось багато managed-рішень від cloud-платформ і менших хостерів на зразок DigitalOcean чи Scaleway. Установка ж на bare-metal інсталяції часто буває складнішою, адже потрібно наперед продумати деякі додаткові аспекти.
Раніше я вже описував створення кластеру Kubernetes за допомогою Kubespray і, виходячи із комітів до його репозиторію, він і досі лишається актуальним. Але цього разу я хочу приділити час іншому проекту по розгортанню K8s - k0s.
k0s - опенсорс проект, головним розробником якого є компанія Mirantis. Код проекту написаний на мові Go і для опису кластеру k0s використовує YAML конфігураційний файл. Має наступні ключові особливості:
- різні методи інсталяцій: single-node, multi-node (в тому числі HA майстрів), airgap (установка в середовище із обмеженим інтернет доступом) та Docker (щось на зразок kind)
- уміє керувати повним життєвим циклом кластеру за допомогою k0sctl: оновлення, бекап чи відновлення
- у якості CNI із коробки підтримує Kube-Router (за замовчуванням) та Calico. Інші екстеншени також підтримуються, але це вже ручна робота, яка надалі ймовірно дасть про себе знати
- CRI лише containerd. Історія із custom варіантами аналогічна custom CNI
- OpenEBS представлений у якості CSI (Container Storage Interface)
- інші, менш помітні особливості: скромніші системні вимоги, ванільний K8s тощо
На відміну від KubeSpray знання Ansible не потрібні, хоч налаштування, як не дивно, також відбуваються по ssh. Цього разу будемо будувати Kubernetes кластер високої доступності, тобто із 3-ма майстрами, а надалі додамо ще один воркер. Три майстри необхідні для того, щоб запобігти Split-brain процесу, точніше ця вимога необхідна лише для бази etcd, котра працює на майстрах.
1. BASIC K0S USAGE. KUBERNETES CONTROL PLANE HA CLUSTER
Cтворимо 4 віртуалки під будь-якою Linux ОС із ядром версії 3.10 або новішим:
192.168.1.11 k8s-m1
192.168.1.12 k8s-m2
192.168.1.13 k8s-m3
192.168.1.21 k8s-s1
Я користуюсь останнім LTS-релізом Ubuntu. Копіюємо ключ на кожну віртуалку для безпарольного доступу. Він має бути попередньо згенерований:
$ ssh-copy-id -i id_rsa.pub ubuntu@192.168.1.11
Видаляємо вміст /etc/machine-id на кожному вузлі, якщо він був створений із загального образу віртуальної машини:
$ :> /etc/machine-id
Після чого перевантажуємо всі майбутні вузли. Створимо конфігураційний файл, котрий буде потрібний для створення k8s-кластеру:
$ k0sctl init --controller-count 3 ubuntu@192.168.1.11 ubuntu@192.168.1.12 ubuntu@192.168.1.13 ubuntu@192.168.1.21 > k0sctl.yaml
Де control plane буде складатись із 3-x машин, а воркера лише із одного.
Вимкнемо телеметрію:
$ export DISABLE_TELEMETRY=true
Запустимо власне створення:
$ k0sctl apply --config k0sctl.yaml
...
k0sctl v0.15.0 Copyright 2022, k0sctl authors.
By continuing to use k0sctl you agree to these terms:
https://k0sproject.io/licenses/eula
INFO ==> Running phase: Connect to hosts
INFO [ssh] 192.168.1.21:22: connected
INFO [ssh] 192.168.1.11:22: connected
INFO [ssh] 192.168.1.13:22: connected
INFO [ssh] 192.168.1.12:22: connected
INFO ==> Running phase: Detect host operating systems
INFO [ssh] 192.168.1.21:22: is running Ubuntu 22.04.2 LTS
INFO [ssh] 192.168.1.11:22: is running Ubuntu 22.04.2 LTS
INFO [ssh] 192.168.1.12:22: is running Ubuntu 22.04.2 LTS
INFO [ssh] 192.168.1.13:22: is running Ubuntu 22.04.2 LTS
INFO ==> Running phase: Acquire exclusive host lock
INFO ==> Running phase: Prepare hosts
INFO ==> Running phase: Gather host facts
INFO [ssh] 192.168.1.11:22: using k8s-m1 as hostname
INFO [ssh] 192.168.1.21:22: using k8s-s1 as hostname
INFO [ssh] 192.168.1.13:22: using k8s-m3 as hostname
INFO [ssh] 192.168.1.12:22: using k8s-m2 as hostname
INFO [ssh] 192.168.1.11:22: discovered enp0s3 as private interface
INFO [ssh] 192.168.1.21:22: discovered enp0s3 as private interface
INFO [ssh] 192.168.1.13:22: discovered enp0s3 as private interface
INFO [ssh] 192.168.1.12:22: discovered enp0s3 as private interface
INFO ==> Running phase: Validate hosts
INFO ==> Running phase: Gather k0s facts
INFO ==> Running phase: Validate facts
INFO ==> Running phase: Download k0s on hosts
INFO [ssh] 192.168.1.11:22: downloading k0s v1.27.1+k0s.0
INFO [ssh] 192.168.1.13:22: downloading k0s v1.27.1+k0s.0
INFO [ssh] 192.168.1.12:22: downloading k0s v1.27.1+k0s.0
INFO [ssh] 192.168.1.21:22: downloading k0s v1.27.1+k0s.0
INFO ==> Running phase: Configure k0s
WARN [ssh] 192.168.1.11:22: generating default configuration
INFO [ssh] 192.168.1.12:22: validating configuration
INFO [ssh] 192.168.1.13:22: validating configuration
INFO [ssh] 192.168.1.11:22: validating configuration
INFO [ssh] 192.168.1.12:22: configuration was changed
INFO [ssh] 192.168.1.11:22: configuration was changed
INFO [ssh] 192.168.1.13:22: configuration was changed
INFO ==> Running phase: Initialize the k0s cluster
INFO [ssh] 192.168.1.11:22: installing k0s controller
INFO [ssh] 192.168.1.11:22: waiting for the k0s service to start
INFO [ssh] 192.168.1.11:22: waiting for kubernetes api to respond
INFO ==> Running phase: Install controllers
INFO [ssh] 192.168.1.11:22: generating token
INFO [ssh] 192.168.1.12:22: writing join token
INFO [ssh] 192.168.1.12:22: installing k0s controller
INFO [ssh] 192.168.1.12:22: starting service
INFO [ssh] 192.168.1.12:22: waiting for the k0s service to start
INFO [ssh] 192.168.1.12:22: waiting for kubernetes api to respond
INFO [ssh] 192.168.1.11:22: generating token
INFO [ssh] 192.168.1.13:22: writing join token
INFO [ssh] 192.168.1.13:22: installing k0s controller
INFO [ssh] 192.168.1.13:22: starting service
INFO [ssh] 192.168.1.13:22: waiting for the k0s service to start
INFO [ssh] 192.168.1.13:22: waiting for kubernetes api to respond
INFO ==> Running phase: Install workers
INFO [ssh] 192.168.1.21:22: validating api connection to https://192.168.1.11:6443
INFO [ssh] 192.168.1.11:22: generating token
INFO [ssh] 192.168.1.21:22: writing join token
INFO [ssh] 192.168.1.21:22: installing k0s worker
INFO [ssh] 192.168.1.21:22: starting service
INFO [ssh] 192.168.1.21:22: waiting for node to become ready
INFO ==> Running phase: Release exclusive host lock
INFO ==> Running phase: Disconnect from hosts
INFO ==> Finished in 2m23s
INFO k0s cluster version 1.27.1+k0s.0 is now installed
INFO Tip: To access the cluster you can now fetch the admin kubeconfig using:
INFO k0sctl kubeconfig
Створимо локальний конфіг kubeconfig:
$ k0sctl kubeconfig --config k0sctl.yaml > k0s.config
У останніх версіях k8s control plane вузли не відображаються, адже на них не запущено kubelet:
$ kubectl get nodes --kubeconfig k0s.config
NAME STATUS ROLES AGE VERSION
k8s-s1 Ready <none> 43m v1.27.1+k0s
$ kubectl get cs -o wide --kubeconfig k0s.config
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME STATUS MESSAGE ERROR
etcd-0 Healthy {"health":"true","reason":""}
controller-manager Healthy ok
scheduler Healthy ok
Або ж можна експортувати змінну KUBECONFIG і надалі не писати --kubeconfig ключа:
$ export KUBECONFIG=/path/to/k0s.config
$ kubectl cluster-info
Kubernetes control plane is running at https://192.168.1.11:6443
CoreDNS is running at https://192.168.1.11:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Для того, щоб control plane вузли працювали в режимі високої доступності необхідно поставити перед ними балансувальник. Інакше зв'язок воркерів буде відбуватись за адресою першого майстра, на що вказує вивід попередньої команди. Для цього створимо додатковий вузол:
192.168.1.31 k8s-m-ha
На ньому встановимо HAProxy та запишемо такий конфігураційний файл:
$ vim /etc/haproxy/haproxy.cfg
global
...
defaults
...
frontend kubeAPI
bind :6443
mode tcp
default_backend kubeAPI_backend
frontend konnectivity
bind :8132
mode tcp
default_backend konnectivity_backend
frontend controllerJoinAPI
bind :9443
mode tcp
default_backend controllerJoinAPI_backend
backend kubeAPI_backend
mode tcp
server k8s-m1 192.168.1.11:6443 check check-ssl verify none
server k8s-m2 192.168.1.12:6443 check check-ssl verify none
server k8s-m3 192.168.1.13:6443 check check-ssl verify none
backend konnectivity_backend
mode tcp
server k8s-m1 192.168.1.11:8132 check check-ssl verify none
server k8s-m2 192.168.1.12:8132 check check-ssl verify none
server k8s-m3 192.168.1.13:8132 check check-ssl verify none
backend controllerJoinAPI_backend
mode tcp
server k8s-m1 192.168.1.11:9443 check check-ssl verify none
server k8s-m2 192.168.1.12:9443 check check-ssl verify none
server k8s-m3 192.168.1.13:9443 check check-ssl verify none
listen stats
bind *:9000
mode http
stats enable
stats uri /
Не забувайте перевантажити HAProxy. Оновимо конфігураційний файл k0sctl.yaml, куди додамо секцію із щойноствореним балансувальником. Врешті-решт він виглядатиме наступним чином (зверніть увагу на наведену жирним частину):
$ cat k0sctl.yaml
apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: k0s-cluster
spec:
hosts:
- ssh:
address: 192.168.1.11
user: ubuntu
port: 22
keyPath: null
role: controller
- ssh:
address: 192.168.1.12
user: ubuntu
port: 22
keyPath: null
role: controller
- ssh:
address: 192.168.1.13
user: ubuntu
port: 22
keyPath: null
role: controller
- ssh:
address: 192.168.1.21
user: ubuntu
port: 22
keyPath: null
role: worker
k0s:
version: 1.27.1+k0s.0
dynamicConfig: false
config:
spec:
api:
externalAddress: 192.168.1.31
sans:
- 192.168.1.31
telemetry:
enabled: false
Застосуємо зміни:
$ k0sctl apply --config k0sctl.yaml
Оновимо kubeconfig, тут має з'явитись адреса балансувальника https://192.168.1.31:6443:
$ k0sctl kubeconfig --config k0sctl.yaml > k0s.config
$ export KUBECONFIG=./k0s.config
$ kubectl cluster-info
Kubernetes control plane is running at https://192.168.1.31:6443
CoreDNS is running at https://192.168.1.31:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Є можливість використовувати HA-модель на кшталт тій, що в Kubespray, коли на кожній worker ноді працює HAProxy, що балансує запити між майстрами. Але в цьому випадку це вливає лише на високу доступність майстрів для трафіку від воркерів, а не зовнішнього трафіку до control plane. Мабуть можна користуватись одразу двома HA-моделями, але це ймовірно ускладнить розуміння роботи і обслуговування. До того ж цей функціонал поки перебуває в експериментальному стані.
2. CALICO, ADDITIONAL WORKER NODE
Якщо запал ще не вщух, можна кастомізувати кластер. Цього разу створимо (або оновимо попередній) кластер із наступними параметрами:
- додамо новий воркер k8s-s2
- замінимо CNI на Calico (k0s активує за замовчуванням VXLAN інкапсуляцію пакетів)
- режим роботи kube-proxy змінимо на IPVS (помітно продуктивніший, якщо кількість сервісів вища за 1000)
Якщо цього замало - то можна ознайомитись із додатковими можливостями кастомізації за посиланням, проект k0s доволі непогано документований.
Цього разу просто застосувати зміни буде мало, адже відбувається заміна
CNI. Тому спочатку скинемо всі налаштування кластеру (це повністю
очистить k8s вузли):
$ k0sctl reset --config k0sctl.yaml
k0sctl v0.15.0 Copyright 2022, k0sctl authors.
By continuing to use k0sctl you agree to these terms:
https://k0sproject.io/licenses/eula
? Going to reset all of the hosts, which will destroy all configuration and data, Are you sure? Yes
INFO ==> Running phase: Connect to hosts
INFO [ssh] 192.168.1.11:22: connected
INFO [ssh] 192.168.1.12:22: connected
INFO [ssh] 192.168.1.21:22: connected
INFO [ssh] 192.168.1.13:22: connected
INFO [ssh] 192.168.1.22:22: connected
INFO ==> Running phase: Detect host operating systems
INFO [ssh] 192.168.1.13:22: is running Ubuntu 22.04.2 LTS
INFO [ssh] 192.168.1.21:22: is running Ubuntu 22.04.2 LTS
INFO [ssh] 192.168.1.11:22: is running Ubuntu 22.04.2 LTS
INFO [ssh] 192.168.1.12:22: is running Ubuntu 22.04.2 LTS
INFO [ssh] 192.168.1.22:22: is running Ubuntu 22.04.2 LTS
INFO ==> Running phase: Acquire exclusive host lock
INFO ==> Running phase: Prepare hosts
INFO ==> Running phase: Gather k0s facts
INFO [ssh] 192.168.1.12:22: is running k0s controller version 1.27.1+k0s.0
INFO [ssh] 192.168.1.13:22: is running k0s controller version 1.27.1+k0s.0
INFO [ssh] 192.168.1.11:22: is running k0s controller version 1.27.1+k0s.0
INFO [ssh] 192.168.1.21:22: is running k0s worker version 1.27.1+k0s.0
INFO [ssh] 192.168.1.11:22: checking if worker has joined
INFO [ssh] 192.168.1.22:22: is running k0s worker version 1.27.1+k0s.0
INFO [ssh] 192.168.1.11:22: checking if worker has joined
INFO ==> Running phase: Reset workers
INFO [ssh] 192.168.1.22:22: reset
INFO [ssh] 192.168.1.21:22: reset
INFO ==> Running phase: Reset controllers
INFO [ssh] 192.168.1.11:22: reset
INFO [ssh] 192.168.1.12:22: reset
INFO [ssh] 192.168.1.13:22: reset
INFO ==> Running phase: Reset leader
INFO [ssh] 192.168.1.11:22: reset
INFO ==> Running phase: Release exclusive host lock
INFO ==> Running phase: Disconnect from hosts
INFO ==> Finished in 18s
Звісно для менше кардинальних змін reset кластеру робити не треба. Конфігураційний файл для поставлених вище цілей буде виглядати наступним чином:
$ cat k0sctl.yaml
apiVersion: k0sctl.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: k0s-cluster
spec:
hosts:
- ssh:
address: 192.168.1.11
user: ubuntu
port: 22
keyPath: null
role: controller
- ssh:
address: 192.168.1.12
user: ubuntu
port: 22
keyPath: null
role: controller
- ssh:
address: 192.168.1.13
user: ubuntu
port: 22
keyPath: null
role: controller
- ssh:
address: 192.168.1.21
user: ubuntu
port: 22
keyPath: null
role: worker
- ssh:
address: 192.168.1.22
user: ubuntu
port: 22
keyPath: null
role: worker
k0s:
version: 1.27.1+k0s.0
dynamicConfig: false
config:
spec:
api:
externalAddress: 192.168.1.31
sans:
- 192.168.1.31
telemetry:
enabled: false
network:
provider: calico
kubeProxy:
mode: ipvs
Де 192.168.1.22 - адреса нового вузла k8s-s2. Застосуємо новий конфігураційний файл:
$ k0sctl apply --config k0sctl.yaml
$ k0sctl kubeconfig --config k0sctl.yaml > k0s.config
$ export KUBECONFIG=./k0s.config
$ kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-55f8c7d5b4-rb9fv 1/1 Running 0 2m39s
calico-node-h72n5 1/1 Running 0 2m27s
calico-node-w48mq 1/1 Running 0 2m26s
coredns-878bb57ff-kwbmq 1/1 Running 0 2m39s
coredns-878bb57ff-n72vj 1/1 Running 0 2m24s
konnectivity-agent-dskzb 1/1 Running 0 2m24s
konnectivity-agent-nzm68 1/1 Running 0 2m23s
kube-proxy-kffbk 1/1 Running 0 2m27s
kube-proxy-pmm2t 1/1 Running 0 2m26s
metrics-server-7f86dff975-hxxlm 1/1 Running 0 2m34s
Посилання:
https://docs.k0sproject.io
https://reece.tech/posts/how-to-make-sure-the-kubernetes-controlplane-is-healthy/
https://medium.com/k0sproject/k0s-1-26-released-292db2c6948a
Немає коментарів:
Дописати коментар