Установка Kubernetes кластера в Unix/Linux
Kubernetes (часто так же используется обозначение «K8s», название образовано от греческого κυβερνήτης, — «кормчий»,»рулевой», по русски — Кубернетес или Кубернетис) — открытое программное обеспечение для автоматизации развёртывания, масштабирования и управления контейнеризированными приложениями. Оригинальная версия была разработана компанией Google. Впоследствии Kubernetes был передан под управление Cloud Native Computing Foundation. Предназначение Kubernetes — предоставить «платформу для автоматического развёртывания, масштабирования, управления приложениями на кластерах или отдельных хостах». Кубернетис поддерживает различные технологии контейнеризации, включая Docker, VMWare и ряд других.
Kenernetes используется фондом Wikimedia Foundation, инфраструктура которого мигрировала на это приложение с самостоятельно разработанного ПО для организации кластеров.
Установка Kubernetes кластера в Unix/Linux
Я рассказывал об установке kubernetes-а ранее в моей статье, — Установка Kubernetes в Unix/Linux. По этому — я немного опущу установку ПО и расскажу как можно собрать полноценный кластер с «блэкджеком и куртизанками», т.е — собрать все воедино. Добавлять автоматически ноды, мониторить их и так же — выполнять деплой приложений, скейлинг в зависимости от нужд.
И так дано:
- 192.168.13.219 — Нода kubernetes-master-1 на CentOS 7.
- 192.168.13.230 — Нода kubernetes-worker-1 наDebian 8.
- 192.168.13.147 — Нода kubernetes-worker-2 на Debian 8.
Кластерная диаграмма кубернетес кластера, выглядит следующим образом:
- Мастер отвечает за управление кластером. Master узлы будут координировать всю деятельность, происходящую в вашем кластере, например, приложения для планирования, сохранение желаемого состояния, масштабирование приложений и обновление апликейщенов.
- Узел (node) представляет собой виртуальную машину или физический компьютер, который используется в качестве рабочего компьютера в кластере Kubernetes. Каждый узел из кластера управляется мастером. На типичном узле вы будете иметь инструменты для обработки операций с контейнерами (например, Docker, rkt) и Kubelet, агента для управления узлом. Кластер Kubernetes, который обрабатывает ПРОД, должен иметь минимум три узла в кластере.
Когда мы развертываем приложения на Kubernetes, мы говорим мастеру, чтобы он запускал контейнеры и планировал их запуск на других нодах. Связь между мстером и воркерами(нодами) осуществляется через API — мастером. Тот же API доступен для пользователей, чтобы облегчить взаимодействие с кластером.
Хватит теории, перейдем к установке и настройке самого кластера!
Установка kubernetes-master-1 на CentOS 7
Установлю хостнейм:
# hostnamectl set-hostname kubernetes-master-1
Это не столь важно, но для примера — будет красиво!
Т.к у меня нет DNS-сервера (я строю кластер локально, на виртуальных машинах), то нужно прописать:
# vim /etc/hosts
Следующее:
192.168.13.219 kubernetes-master-1 192.168.13.233 kubernetes-worker-1 192.168.13.234 kubernetes-worker-2
Это поможет резолвить ноды между собой.
Обновлю ОС:
# yum update -y && yum upgrade -y
Не забываем выключить SELinux, а то он может наломать вам дров:
# setenforce 0 && sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
Как вы знаете, в centOS 7 имеется firewalld и по этому — стоит пробрасывать правила (но в моем случае — нету смысла) или просто выключить его:
# systemctl stop firewalld && systemctl disable firewalld
Добавим репозиторий с kubernetes:
# cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg EOF
Собственно, выполняем установку докера и кубика:
# yum install docker kubectl kubeadm etcd ebtables ethtool -y
Добавялем докер-службу в автозагрузку ОС и запускаем сервис:
# systemctl enable docker && systemctl restart docker
Some users on RHEL/CentOS 7 have reported issues with traffic being routed incorrectly due to iptables being bypassed. You should ensure net.bridge.bridge-nf-call-iptables is set to 1 in your sysctl config, e.g.
# cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF
и применяем:
# sysctl --system
Насчет etcd, я не уверен что нужно сувать его в автозагрузку ОС. Но можно это сделать вот так:
# systemctl enable etcd && systemctl restart etcd
Инициализируем мастер:
# kubeadm init --ignore-preflight-errors=all --pod-network-cidr=10.244.0.0/16
Где:
- kubeadm init — Инициализируем кубернетес.
- —ignore-preflight-errors=all — Скипаю все ошибки (но лучше не использовать этот параметр если не уверены).
- —pod-network-cidr=10.244.0.0/16 — Задаем подсеть для будущего кубо-кластера (не обязательная опция).
- —apiserver-advertise-address=192.168.13.231 — Можно задать данный параметр для установки IP адреса самого API сервера (не обязательная опция).
- —kubernetes-version $(kubeadm version -o short) — Чтобы задать версию кубика (не обязательная опция).
- —token=YOUR_TOKEN — Используется чтобы задать токен (не обязательная опция).
Добавялем кубернетес-службу в автозагрузку ОС и запускаем сервис:
# systemctl enable kubelet
Я не буду добавлять пользователя для кубика, буду использовать — root. Вносим изменения небольшие:
# mkdir -p $HOME/.kube # cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # chown $(id -u):$(id -g) $HOME/.kube/config
Так же, незабываем сохранить команду для добавления нод в мастер, у меня это:
# kubeadm join --token 86669e.c66ab92be6dc5817 192.168.13.219:6443 --discovery-token-ca-cert-hash sha256:f8905cc439b0498eeb3a0de4bf7937640c96cb7063a2bc99f917433a994c4559
Смотрим что вышло:
# kubectl get nodes NAME STATUS ROLES AGE VERSION kubernetes-master-1 NotReady master 4m v1.9.3
PS: Можно получить следующую ошибку:
Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
Решил:
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config && chown $(id -u):$(id -g) $HOME/.kube/config
Как видим, у меня — уже просетапался кубик-мастер нода. Но статус не готов, смотрим что не так:
# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system etcd-kubernetes-master-1 1/1 Running 0 27m kube-system kube-apiserver-kubernetes-master-1 1/1 Running 0 27m kube-system kube-controller-manager-kubernetes-master-1 1/1 Running 0 28m kube-system kube-dns-6f4fd4bdf-rtkjt 0/3 Pending 0 28m kube-system kube-proxy-vs44m 1/1 Running 0 28m kube-system kube-scheduler-kubernetes-master-1 1/1 Running 0 27m
Такс, нет DNS резолвера, — фиксаем:
# export kubever=$(kubectl version | base64 | tr -d '\n') # kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$kubever" serviceaccount "weave-net" created clusterrole "weave-net" created clusterrolebinding "weave-net" created daemonset "weave-net" created
Различные сети поддерживаются в k8s и зависят от выбора пользователя. Создание сети, занимает определенное время (пару минут точно), через время — проверяем:
[root@kubernetes-master-1 ~]# kubectl get nodes && kubectl get pods --all-namespaces NAME STATUS ROLES AGE VERSION kubernetes-master-1 Ready master 33m v1.9.3 NAMESPACE NAME READY STATUS RESTARTS AGE kube-system etcd-kubernetes-master-1 1/1 Running 0 32m kube-system kube-apiserver-kubernetes-master-1 1/1 Running 0 32m kube-system kube-controller-manager-kubernetes-master-1 1/1 Running 0 32m kube-system kube-dns-6f4fd4bdf-rtkjt 0/3 ContainerCreating 0 32m kube-system kube-proxy-vs44m 1/1 Running 0 32m kube-system kube-scheduler-kubernetes-master-1 1/1 Running 0 32m kube-system weave-net-pzpxk 2/2 Running 0 45s [root@kubernetes-master-1 ~]#
Идем дальше — необходимо установить и добавить воркеры в созданный мастер!
Установка kubernetes-worker-1 на Debian 8
Установлю хостнейм:
# hostname kubernetes-worker-1
Это не столь важно, но для примера — будет красиво!
Т.к у меня нет DNS-сервера (я строю кластер локально, на виртуальных машинах), то нужно прописать:
# vim /etc/hosts
Следующее:
192.168.13.219 kubernetes-master-1 192.168.13.233 kubernetes-worker-1 192.168.13.234 kubernetes-worker-2
Это поможет резолвить ноды между собой.
Ставим нужные зависимости:
# apt-get install -y \ apt-transport-https \ ca-certificates \ curl \ software-properties-common
Устанавливаем докер:
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - add-apt-repository \ "deb https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \ $(lsb_release -cs) \ stable"
Этой командой, добавляем репку, и для установки — выполняем:
# apt-get update && apt-get install -y docker-ce=$(apt-cache madison docker-ce | grep 17.03 | head -1 | awk '{print $3}')
Добавляем докер в автозагрузку ОС, запускаем его и смотрим статус:
# systemctl start docker && systemctl enable docker && systemctl status docker
Добавляем ключ:
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
Прописываем репо-лист:
# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb http://apt.kubernetes.io/ kubernetes-xenial main EOF
Сейчас, ставим кубик:
# apt-get update && apt-get install -y kubelet kubeadm kubectl
Добавляем kubelet в автозагрузку ОС, запускаем его и смотрим статус:
# systemctl start kubelet && systemctl enable kubelet && systemctl status kubelet
Все готово, можно добавлять ноду в кластер:
# kubeadm join --token c4de10.ff1831543e2e223a 192.168.13.219:6443 --discovery-token-ca-cert-hash sha256:f75e564824bb87a906a83f11fabc74b31c759a206dae75401448980e64d0953e
Где:
- kubeadm join — Команда для добавления узлов к мастеру.
- —token c4de10.ff1831543e2e223a — Токен для добавления.
- 192.168.13.219:6443 — Хост и порт от мастер-ноды.
- —discovery-token-ca-cert-hash sha256:f75e564824bb87a906a83f11fabc74b31c759a206dae75401448980e64d0953e — Дискавер токен.
- —discovery-token-unsafe-skip-ca-verification — Можно использовать данную опцию для использывания обхода проверки токена обнаружения. Поскольку этот токен генерируется динамически, мы не могли включить его в действия. При создании ПРОД машин, укажите токен, предоставленный kubeadm init.
Получил ошибку:
CGROUPS_MEMORY: missing [WARNING FileExisting-crictl]: crictl not found in system path [preflight] Some fatal errors occurred: [ERROR SystemVerification]: missing cgroups: memory [preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
Фиксим так, для начала — добавляем:
# echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab
Потом, открываем файл:
# vim /etc/default/grub
Находим строку «GRUB_CMDLINE_LINUX» и приводим к виду:
GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
Потом, выполняем:
# update-grub && reboot
Немного о cgroups:
Установка cgroups в Unix/Linux
И потом, можно запускать (добавляем воркер к мастеру):
# kubeadm join --token 86669e.c66ab92be6dc5817 192.168.13.219:6443 --discovery-token-ca-cert-hash sha256:f8905cc439b0498eeb3a0de4bf7937640c96cb7063a2bc99f917433a994c4559
На kubernetes-master-1, запускаем:
# kubectl get nodes
Идем дальше — необходимо установить и добавить еще один воркер в созданный мастер!
Установка kubernetes-worker-2 на Debian 8
Аналогичные действия, проделываю и для kubernetes-worker-2. Но только с другим хостнеймом.
Установка kubernetes-worker-n на CenOS 7/Redhat 7
Можно добавлять другие воркеры по аналогии как я описывал ранее для kubernetes-master-1, но без инициализации мастера (что логично, не правдали?).
Деплой Kubernetes кластера в Unix/Linux
Приведу наглядный скриншот того, как выглядит развертывание первого приложения на Kubernetes:
Образ контейнера развертывается, а так же — количество реплик определяются во время создания деплоя, но могут быть изменены после.
Когда все ноды будут добавлены в кластер, должно получится что-то типа:
[root@kubernetes-master-1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION kubernetes-master-1 Ready master 8m v1.9.3 kubernetes-worker-1 Ready <none> 54s v1.9.3 kubernetes-worker-2 NotReady <none> 40s v1.9.3 [root@kubernetes-master-1 ~]#
Как видно что 2-й воркер не успел кодключится еще к кластеру. Через время подключится. Нужно пару минут подождать. Ну, пол работы сделано — осталось научится деплоить, мониторить и может чет еще упустил…
-=== СПОСОБ 1 ===-
Деплоим:
# kubectl create deployment nginx --image=nginx
Смотрим какие деплойменты имеются:
# kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx 1 1 1 1 41s
Можно получить дополнительную инфу, выполнив:
# kubectl describe deployment nginx
Получаем что-то типа:
Name: nginx Namespace: default CreationTimestamp: Tue, 13 Mar 2018 14:18:29 +0200 Labels: app=nginx Annotations: deployment.kubernetes.io/revision=1 Selector: app=nginx Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 1 max unavailable, 1 max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable OldReplicaSets: <none> NewReplicaSet: nginx-7d7cbfc4f (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-7d7cbfc4f to 1
Делаем контейнер доступным в интернете:
# kubectl create service nodeport nginx --tcp=80:80
Смотрим статус:
# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26m nginx NodePort 10.103.16.105 <none> 80:32564/TCP 23s
Проверяем работу контейнеров:
# curl kubernetes-worker-1:32564 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20body%20%7B%0A%20%20%20%20%20%20%20%20width%3A%2035em%3B%0A%20%20%20%20%20%20%20%20margin%3A%200%20auto%3B%0A%20%20%20%20%20%20%20%20font-family%3A%20Tahoma%2C%20Verdana%2C%20Arial%2C%20sans-serif%3B%0A%20%20%20%20%7D%0A%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
На 2-м воркере:
# curl kubernetes-worker-2:32564 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20body%20%7B%0A%20%20%20%20%20%20%20%20width%3A%2035em%3B%0A%20%20%20%20%20%20%20%20margin%3A%200%20auto%3B%0A%20%20%20%20%20%20%20%20font-family%3A%20Tahoma%2C%20Verdana%2C%20Arial%2C%20sans-serif%3B%0A%20%20%20%20%7D%0A%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
На мастере я не запускал воркер, по этому — смысла проверять, — нет.
Можно посмотреть сколько реплик имеется:
[root@kubernetes-master-1 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE kubernetes-bootcamp-69d869bf78 1 1 1 1d nginx-7d7cbfc4f 1 1 1 1d [root@kubernetes-master-1 ~]#
Чтобы проверить поды, выполняем:
[root@kubernetes-master-1 ~]# kubectl get pods<br> NAME READY STATUS RESTARTS AGE kubernetes-bootcamp-69d869bf78-84mvw 1/1 Running 0 1d nginx-7d7cbfc4f-9s5dd 1/1 Running 0 1d [root@kubernetes-master-1 ~]#
Ролбэк Kubernetes кластера в Unix/Linux
Можно выполнять ролбэки:
# kubectl rollout status deployments nginx
Можно проверить хистори всех ролбеков:
[root@kubernetes-master-1 ~]# kubectl rollout history deployment/nginx<br> deployments "nginx" REVISION CHANGE-CAUSE 1 <none> [root@kubernetes-master-1 ~]#
Теперь я выполню откат к предыдущей версии:
# kubectl rollout undo deployment/nginx
Где:
- —to-revision=2 — С данной опцией, можно задать до какой ревизии делаем откат.
Масштабирование Kubernetes кластера в Unix/Linux
Выполняем масштабирование:
# kubectl scale deployment nginx --replicas=5 deployment "nginx" scaled
Или:
# kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
Проверяем:
# kubectl get deploy NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE kubernetes-bootcamp 1 1 1 1 1d nginx 5 5 5 5 1d [root@kubernetes-master-1 ~]#
Можно выводить много полезной инфы вот так:
# kubectl get deployment,svc,pods,pvc
Все гениальное — просто. Но нужно время чтобы понять.
Мониторинг Kubernetes кластера в Unix/Linux
Дополню когда пойму как можно это сделать автоматически. У меня есть как минимум, 3 способа реализации. Но 1 из них — не очень хорошее решение.
- Можно заюзать zabbix и просетапать все kubernetes ноды, zabbix-агентами. Это реально будет работать, но как по мне — не ТРУЪ!
- Можно использовать consul для этого дела — это лучше решение чем заббикс.
- Так же, можно использовать prometheus
Но об этом немного позже. Я дополню эту часть, обязательно!
Удаление Kubernetes кластера в Unix/Linux
Чтобы удалить ноду с кластера, на мастере, выполните:
# kubectl delete node your_node_for_delete
Если же нужно удалить вообще все — то обратное действие — установки.
Для удаления деплоймента, используйте:
# kubectl delete deployment nginx
Теоретически, данный кластер можно поднять минут за 10-15. Но я потратил больше времени, — выплывали всякие косяки. Вывод — данная цтилита, довольно прикольная и юзабельная, но как по мне — нужна доработка. Так же, хотелось отметить, что мой кластер работает, но его нужно оптимизировать/автоматизировать. Нужно больше времени чтобы понять как я могу это сделать.
Вот и все, статья «Установка Kubernetes кластера в Unix/Linux» завершена.