Kubespray (ранее Kargo) — это набор Ansible ролей для установки и конфигурации системы оркестрации контейнерами Kubernetes. В качестве IaaS в этом случае могут выступать AWS, GCE, Azure, OpenStack или обычные виртуальные машины. Проект раньше назывался Kargo. Это проект с открытым исходным кодом и открытой моделью разработки, поэтому по желанию каждый может повлиять на его жизненный цикл.
На Хабре уже писали об установке Kubernetes с помощью Kubeadm, но в этом способе есть значительные недостатки: он до сих пор не поддерживает мультимастер конфигураций и, порой, не очень гибкий. Kubespray, хоть и использует Kubeadm под капотом, уже имеет функционал обеспечения высокой доступности как для мастера, так и для etcd на этапе инсталляции. О его сравнении с другими актуальными методами установки Kubernetes можно почитать по ссылке https://github.com/kubernetes-incubator/kubespray/blob/master/docs/comparisons.md
В этой статье мы создадим 5 серверов на ОС Ubuntu 16.04. В моем случае их перечень будет следующим:
192.168.20.10 k8s-m1.me
192.168.20.11 k8s-m2.me
192.168.20.12 k8s-m3.me
192.168.20.13 k8s-s1.me
192.168.20.14 k8s-s2.me
Добавляем их к /etc/hosts всех этих серверов, в том числе локальной системы, или же к dns-серверу. Фаервол и другие ограничения в сети этих хостов должны быть деактивированы. Кроме этого, необходимо разрешить IPv4 forwarding и каждый из хостов должен иметь свободный доступ к сети Интернет для загрузки docker-образов.
Копируем публичный rsa-ключ к каждому серверу из списка:
$ ssh-copy-id ubuntu@server.me
Указываем необходимого пользователя и ключ для подключения с локальной машины:
$ vim ~/.ssh/config
...
Host *.me
User ubuntu
ServerAliveInterval 60
IdentityFile ~/.ssh/id_rsa
Где ubuntu — пользователь, от имени которого будет происходить подключение к серверу, a id_rsa — приватный ключ. Более того, этот пользователь нуждается в возможности выполнения команд sudo без пароля.
Клонируем репозиторий Kubespray:
$ git clone https://github.com/kubernetes-incubator/kubespray.git
После копируем директорию inventory для редактирования ее содержимого:
$ cp -r inventory my_inventory
$ cd my_inventory
В качестве примера используем inventory.example:
$ mv inventory.example inventory
$ vim inventory
k8s-m1.me ip=192.168.20.10
k8s-m2.me ip=192.168.20.11
k8s-m3.me ip=192.168.20.12
k8s-s1.me ip=192.168.20.13
k8s-s2.me ip=192.168.20.14
[kube-master]
k8s-m1.me
k8s-m2.me
k8s-m3.me
[etcd]
k8s-m1.me
k8s-m2.me
k8s-m3.me
[kube-node]
k8s-s1.me
k8s-s2.me
[k8s-cluster:children]
kube-node
kube-master
Исходя из представленного выше, мы выполним установку HA инсталляции Kubernetes: etcd, хранилище параметров конфигурации кластера, будет состоять из 3-х узлов для присутствия кворума, а сервисы Kubernetes Master (kube-apiserver, controller-manager, scheduler и т.д.) будут продублированы трижды. Конечно, ничего не мешает вынести сервис etcd полностью отдельно.
На этом этапе хотелось бы немного подробнее рассказать о том, как реализован режим HA для мастеров. На каждом воркере Kubernetes (в нашем случае это k8s-s*.me) будет установлен Nginx в режиме балансировки, в upstream которого будут описаны все мастера Kubernetes:
stream {
upstream kube_apiserver {
least_conn;
server kube-master_ip1:6443;
server kube-master_ip2:6443;
server kube-master_ip3:6443;
}
server {
listen 127.0.0.1:6443;
proxy_pass kube_apiserver;
proxy_timeout 10m;
proxy_connect_timeout 1s;
}
Соответственно в случае падения одного из мастеров, Nginx исключит его из upstream и прекратит пересылать запросы на такой сервер.
Такая схема позволяет исключить единую точку отказа: в случае падения мастера его работу примет на себя другой мастер, а ответственный за переадресацию запросов Nginx работает на каждом воркере.
На этапе установки кластера есть возможность отключить этот внутренний балансировщик и уже заботиться обо всем самостоятельно. Это может быть, например, какой-то сторонний Nginx или HAProxy. Однако не стоит забывать, что для обеспечения высокой доступности они должны работать в паре, между членами которой при необходимости должен мигрировать Virtual IP. VIP может быть реализован с помощью различных технологий таких, как Keepalived, Heartbeat, Pacemaker и т.п.
На мастере kube-apiserver работает одновременно на 2-х портах: локальном 8080 без шифрования (для служб, работающих на одном сервере) и внешнем HTTPS 6443. Последний, как я уже упомянул, используется для связи с воркерами и может пригодиться, если сервисы одного мастера (kubelet, kube-proxy и др) необходимо вынести на другие хосты.
Продолжим работу по созданию тестового кластера. Отредактируем group_vars/all.yml:
$ vim group_vars/all.yml
...
bootstrap_os: ubuntu
...
kubelet_load_modules: true
Кроме Ubuntu 16.04 Kubespray также поддерживает инсталляцию на узлы с CoreOS, Debian Jessie, CentOS/RHEL 7, то есть на все основные актуальные дистрибутивы.
При необходимости следует также заглянуть в group_vars/k8s-cluster.yml, где можно указать необходимую версию Kubernetes, которая будет проинсталлирована, выбрать плагин для оверлейной сети (по-умолчанию это calico, но доступны и другие варианты), установить efk (elasticsearch/fluentd/kibana), helm, istio, netchecker и т.п.
Также рекомендую посмотреть roles/kubernetes/preinstall/tasks/verify-settings.yml. Здесь находятся базовые проверки, которые будут выполнены перед началом установки Kubernetes. Например, проверки наличия достаточного количества оперативной памяти (на данный момент, это не менее 1500MB для мастеров и 1000MB для нод), количества etcd серверов (для обеспечения кворума их должно быть нечетное количество) и прочее. В последних релизах Kubespray появилась дополнительное требование по swap-у: он должен быть выключен на всех узлах кластера.
Если Ansible еще отсутствует в локальной системе, установим его вместе с модулем netaddr:
# pip install ansible
# pip install netaddr
Важно обратить внимание на то, что модуль netaddr и ansible должны работать с той же версией Python.
После этого можем приступать к установке кластера Kubernetes:
$ ansible-playbook -i my_inventory/inventory cluster.yml -b -v
Как вариант, rsa-ключ и пользователя для подключения можно передать аргументами, например:
$ ansible-playbook -u ubuntu -i my_inventory/inventory cluster.yml -b -v --private-key=~/.ssh/id_rsa
Обычно установка кластера занимает около 15-20 мин, но все зависит также от вашего железа. После мы можем проверить корректно ли все работает, для чего необходимо подключиться к любому хосту кластера и выполнить следующее:
root@k8s-m1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m1 Ready master 28m v1.8.4+coreos.0
k8s-m2 Ready master 28m v1.8.4+coreos.0
k8s-m3 Ready master 28m v1.8.4+coreos.0
k8s-s1 Ready node 28m v1.8.4+coreos.0
k8s-s2 Ready node 28m v1.8.4+coreos.0
root@k8s-m1:~# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-node-2z6jz 1/1 Running 0 27m
kube-system calico-node-6d6q6 1/1 Running 0 27m
kube-system calico-node-96rgg 1/1 Running 0 27m
kube-system calico-node-nld9z 1/1 Running 0 27m
kube-system calico-node-pjcjs 1/1 Running 0 27m
kube-system kube-apiserver-k8s-m1 1/1 Running 0 27m
...
kube-system kube-proxy-k8s-s1 1/1 Running 0 26m
kube-system kube-proxy-k8s-s2 1/1 Running 0 27m
kube-system kube-scheduler-k8s-m1 1/1 Running 0 28m
kube-system kube-scheduler-k8s-m2 1/1 Running 0 28m
kube-system kube-scheduler-k8s-m3 1/1 Running 0 28m
kube-system kubedns-autoscaler-86c47697df-4p7b8 1/1 Running 0 26m
kube-system kubernetes-dashboard-85d88b455f-f5dm4 1/1 Running 0 26m
kube-system nginx-proxy-k8s-s1 1/1 Running 0 28m
kube-system nginx-proxy-k8s-s2 1/1 Running 0 28m
Как видим, по-умолчанию, сразу была установлена и веб-панель kubernetes-dashboard. Детали относительно ее работы можно найти по следующей ссылке https://github.com/kubernetes/dashboard
Исключительно для базовой проверки выльем под с двумя контейнерами:
$ vim first-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: first-pod
spec:
containers:
- name: sise
image: mhausenblas/simpleservice:0.5.0
ports:
- containerPort: 9876
resources:
limits:
memory: "64Mi"
cpu: "500m"
- name: shell
image: centos:7
command:
- "bin/bash"
- "-c"
- "sleep 10000"
$ kubectl apply -f first-pod.yaml
pod "first-pod" created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
first-pod 2/2 Running 0 16s
$ kubectl exec first-pod -c sise -i -t -- bash
[root@first-pod /]# curl localhost:9876/info
{"host": "localhost:9876", "version": "0.5.0", "from": "127.0.0.1"}
Это было тестовое приложение на языке Python с ресурса http://kubernetesbyexample.com/.
Довольно странно, но в качестве системы контейнеризации был установлен Docker 17.03.1-ce, хотя в официальной документации упоминается, что лучше всего использовать именно версию 1.13. Версия Docker, которая будет установлена, описанная в roles/docker/defaults/main.yml и, теоретически, ее можно перезаписать в файлах конфигурации выше или передать значение аргументом.
Ansible скрипты Kubespray также поддерживают масштабирование к-ва узлов кластера. Для этого обновим inventory, в котором добавим новую ноду (worker):
$ vim my_inventory/inventory
k8s-m1.me ip=192.168.20.10
k8s-m2.me ip=192.168.20.11
k8s-m3.me ip=192.168.20.12
k8s-s1.me ip=192.168.20.13
k8s-s2.me ip=192.168.20.14
k8s-s3.me ip=192.168.20.15
[kube-master]
k8s-m1.me
k8s-m2.me
k8s-m3.me
[etcd]
k8s-m1.me
k8s-m2.me
k8s-m3.me
[kube-node]
k8s-s1.me
k8s-s2.me
k8s-s3.me
[k8s-cluster:children]
kube-node
kube-master
Конечно, узел k8s-s3.me также должен быть соответствующим образом настроен, как и предыдущие ноды. Теперь можем запускать масштабирование кластера:
$ ansible-playbook -i my_inventory/inventory scale.yml -b -v
Согласно документации Kubespray, для этого можно использовать и предварительную процедуру с cluster.yml, однако с scale.yml это займет значительно меньше времени. В результате сейчас можем наблюдать новый узел через kubectl:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m1 Ready master 6h v1.8.4+coreos.0
k8s-m2 Ready master 6h v1.8.4+coreos.0
k8s-m3 Ready master 6h v1.8.4+coreos.0
k8s-s1 Ready node 6h v1.8.4+coreos.0
k8s-s2 Ready node 6h v1.8.4+coreos.0
k8s-s3 Ready node 19m v1.8.4+coreos.0
Вот и все. Так же эту статью можно прочитать на украинском языке по адресу http://blog.ipeacocks.info/2017/12/kubernetes-part-iv-setup-ha-cluster.html
PS. Обо всех ошибках лучше сразу писать в приват — оперативно исправим.
github.com/kubernetes-incubator/kubespray
github.com/kubernetes-incubator/kubespray/blob/master/docs/getting-started.md
github.com/kubernetes-incubator/kubespray/blob/master/docs/ansible.md
github.com/kubernetes-incubator/kubespray/blob/master/docs/ha-mode.md
dickingwithdocker.com/2017/08/deploying-kubernetes-vms-kubespray
medium.com/@olegsmetanin/how-to-setup-baremetal-kubernetes-cluster-with-kubespray-and-deploy-ingress-controller-with-170cdb5ac50d
Автор: Ipeacocks