Запускаем кластер Kubernetes через Kubespray. А именно сделаем кластер на виртуальных нодах в следующей комплектации:
- 3 мастер ноды
- 4 рабочие ноды
- 2 ingress ноды
Kubernetes — проект с открытым исходным кодом для оркестрации кластера контейнеров Linux. Kubernetes управляет и запускает контейнеры Docker на большом количестве хостов, а так же обеспечивает совместное размещение и репликацию большого количества контейнеров.
Kubespray — проект с открытым исходным кодом, включающий в себя набор Ansible ролей для установки и конфигурации Kubernetes.
Подготовка к установке
Работать буду на Windows в окружении WSL2. Рабочая директория пусть будет /mnt/c/devops.
Создаём все виртуальные машины для кластера K8S.
Мастера:
- 10.17.119.40 ovel-k8s-master00.ev.local
- 10.12.119.42 ovel-k8s-master01.ev.local
- 10.12.119.43 ovel-k8s-master02.ev.local
Рабочие ноды:
- 10.12.119.44 ovel-k8s-worker01.ev.local
- 10.12.119.45 ovel-k8s-worker02.ev.local
- 10.12.119.46 ovel-k8s-worker03.ev.local
- 10.12.119.47 ovel-k8s-worker04.ev.local
Ingress:
- 10.12.119.48 ovel-k8s-ing01.ev.local
- 10.12.119.49 ovel-k8s-ing02.ev.local
Установка Kubespray
Клонируем себе git репозиторий Kubespray:
cd /mnt/c/devops
git clone https://github.com/kubernetes-sigs/kubespray.git
Теперь у нас есть папка с Kubespray.
/mnt/c/devops/kubespray
Для работы Kubespray нужен Ansible определённой версии и определённый набор зависимостей. Это минус, из-за которого я и работаю с виртуалки. Потому как моя версия Ansible, которой я обычно пользуюсь, не подошла. Необходимые зависимости перечислены в файле requirements.txt.
Установим нужные пакеты через pip.
pip install --user -r requirements.txt
Настройка кластера
В папке inventory/sample есть пример с набором ролей Ansible для создания кластера, скопируем его.
cd ./kubespray
cp -rfp inventory/sample inventory/mycluster
Редактируем inventory.ini.
[all]
ovel-k8s-master00.ev.local ansible_host=10.17.119.40 ip=10.17.119.40
ovel-k8s-master01.ev.local ansible_host=10.12.119.42 ip=10.12.119.42
ovel-k8s-master02.ev.local ansible_host=10.12.119.43 ip=10.12.119.43
ovel-k8s-worker01.ev.local ansible_host=10.12.119.44 ip=10.12.119.44
ovel-k8s-worker02.ev.local ansible_host=10.12.119.45 ip=10.12.119.45
ovel-k8s-worker03.ev.local ansible_host=10.12.119.46 ip=10.12.119.46
ovel-k8s-worker04.ev.local ansible_host=10.12.119.47 ip=10.12.119.47
ovel-k8s-ing01.ev.local ansible_host=10.12.119.48 ip=10.12.119.48
ovel-k8s-ing02.ev.local ansible_host=10.12.119.49 ip=10.12.119.49
[kube_control_plane]
ovel-k8s-master00.ev.local
ovel-k8s-master01.ev.local
ovel-k8s-master02.ev.local
[etcd]
ovel-k8s-master00.ev.local
ovel-k8s-master01.ev.local
ovel-k8s-master02.ev.local
[kube_node]
ovel-k8s-worker01.ev.local
ovel-k8s-worker02.ev.local
ovel-k8s-worker03.ev.local
ovel-k8s-worker04.ev.local
ovel-k8s-ing01.ev.local
ovel-k8s-ing02.ev.local
[kube_ingress]
ovel-k8s-ing01.ev.local
ovel-k8s-ing02.ev.local
[k8s_cluster:children]
kube_control_plane
kube_node
- В блоке [all] указываем список всех хостов.
- В блоке [kube_control_plane] список мастеров.
- В блоке [etcd] список хостов для etcd, в данном случае он совпадает со списком мастеров.
- В блоке [kube_node] указываем список нод и ingress-хостов. У нас ingress сервера по сути являются обычными рабочими нодами, но с помощью настроек мы сделаем так, чтобы на нодах ingress рабочие контейнеры не запускались, а работал только ingress.
- В блоке [kube_ingress] указываем список ingress-хостов.
- В блоке [k8s_cluster:children] указываем блоки с участниками кластера, а именно мастера и рабочие ноды: kube_control_plane и kube_node.
Отредактируем параметры кластера.
В inventory/mycluster/group_vars/all/all.yml добавляем:
kubelet_load_modules: true # автоматически загружает модули в ядро системы
kube_read_only_port: 10255 # порт для мониторинга кублетов, для prometeus
В inventory/mycluster/group_vars/all/docker.yml добавляем:
docker_storage_options: -s overlay2 # использовать overlay2 для докера
В inventory/mycluster/group_vars/all/etcd.yml добавляем:
etcd_memory_limit: 0 # снимаем ограничение 512 мб
В inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml добавляем:
kube_network_plugin: flannel
kube_proxy_mode: iptables
kubeconfig_localhost: true
Я буду использовать сетевой плагин flannel и iptables.
В inventory/mycluster/group_vars/k8s-cluster/k8s-net-flannel.yml добавляем:
flannel_interface_regexp: '10\\.(17|12)\\.119\\.\\d{1,3}'
flannel_backend_type: "host-gw"
Регулярное выражение правим под свои нужды, указывая подсети IP адресов, в которых размещены виртуальные машины. У меня две подсети:
- 10.12.119.0/24
- 10.17.119.0/24
Настраиваем ingress.
В inventory/mycluster/group_vars/k8s-cluster/addons.yml добавляем:
ingress_nginx_enabled: true
ingress_nginx_nodeselector:
node-role.kubernetes.io/ingress: "true" # указываем метку ноды ingress
ingress_nginx_tolerations:
- key: "node-role.kubernetes.io/ingress"
operator: "Exists"
ingress_nginx_configmap:
server-tokens: "False"
proxy-body-size: "2048M"
proxy-buffer-size: "16k"
worker-shutdown-timeout: "180"
Создаём inventory/mycluster/group_vars/kube-ingress.yml и добавляем:
node_labels:
node.kubernetes.io/ingress: "true" # всем серверам в группе kube-ingress ставить метку
node_taints:
- "node.kubernetes.io/ingress=:NoSchedule"
На ноды в группе kube-ingress ставится ограничение NoSchedule, чтобы на ноды не распределялись поды. Это ограничение могут преодолевать только только те, у кого в tolerations прописана метка ingress. Таким образом, на нодах ingress, кроме самого ingress ничего запускаться не будет.
Установка кластера Kubernetes
Приступаем к установке кластера K8S.
ansible-playbook -u root -k -i inventory/mycluster/inventory.ini -b --diff cluster.yml
Процесс долгий, у меня накатывалось почти час. В конце должно получиться так:
Ошибок быть не должно. У меня с первого раза без ошибок сделать не получилось. Одна ошибка была связана с resolv.conf:
Kubespray — The connections to the server localhost:8080 was refused
Ещё одна — с неправильными зависимостями ранее установленной версией ansible. Исправляем ошибки и заново запускаем playbook, пока всё не установится без ошибок.