Kubernetes — это предназначенный для контейнерной оркестровки фреймворк с открытым исходным кодом. Он был создан с учетом богатейшего опыта Google в области создания сред управления контейнерами и позволяет выполнять контейнеризованные приложения в готовом к промышленной эксплуатации кластере. В механизме Kubernetes много движущихся частей и способов их настройки — это различные системные компоненты, драйверы сетевого транспорта, утилиты командной строки, не говоря уже о приложениях и рабочих нагрузках.
По ходу этой статьи мы установим Kubernetes 1.6 на реальную (не виртуальную) машину под управлением Ubuntu 16.04 примерно за 10 минут. В результате у вас появится возможность начать изучать взаимодействие с Kubernetes посредством его CLI
kubectl
.
Обзор Kubernetes:
Компоненты Kubernetes, автор Julia Evans
Что нам понадобится
Для развертывания кластера я предлагаю использовать физическую машину от сервиса Packet. Вы также можете проделать описанные мною шаги в виртуальной машине или на домашнем компьютере, если на них в качестве операционной системы установлена Ubuntu 16.04.
Зайдите на Packet.net и создайте новый проект. Для целей этой статьи нам хватит хоста Type 0 (4 ядра Atom и 8GB RAM за 0,05$/час).
При настройке хоста не забудьте выбрать в качестве ОС Ubuntu 16.04. В отличие от Docker Swarm Kubernetes лучше работает с проверенными временем релизами Docker. К счастью, репозиторий Ubuntu apt содержит Docker 1.12.6.
- Установите Docker.
$ apt-get update && apt-get install -qy docker.io
Не обновляйте Docker на этом хосте. Использовать более свежие версии для сборки образов можно в инструментарии CI или на ноутбуке.
Установка
- Установите apt-репозиторий Kubernetes.
$ apt-get update && apt-get install -y apt-transport-https
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
OK
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
Теперь обновите список пакетов командой apt-get update
.
- Установите
kubelet
,kubeadm
иkubernetes-cni
.
kubelet
отвечает за выполнение контейнеров на хостах кластера. kubeadm
является удобной утилитой для настройки различных компонентов, составляющих кластер, а kubernetes-cni
нужен для работы с сетевыми компонентами.
CNI расшифровывается как Container Networking Interface и представляет из себя спецификацию, определяющую взаимодействие сетевых драйверов с Kubernetes.
$ apt-get update
$ apt-get install -y kubelet kubeadm kubernetes-cni
- Инициализируйте кластер с помощью
kubeadm
.
Из документации:
kubeadm предназначен для создания сразу «из коробки» безопасного кластера с помощью таких механизмов, как RBAC.
В Docker Swarm по умолчанию есть драйвер оверлейной сети, но с kubeadm
решение остается за нами. Команда все еще работает над обновлением инструкций, поэтому я покажу, как использовать драйвер, наиболее похожий на докеровский, — flannel от CoreOS.
Flannel
Flannel позволяет организовать программно определяемую сеть (Software Defined Network, SDN), используя для этого модули ядра Linux overlay
и ipvlan
.
В Packet машина подключается к двум сетям: первая — это сеть дата-центра, которая соединяет хосты, входящие в определенный регион и проект, а вторая — это выход в Интернет. Брандмауэр по умолчанию не настроен, поэтому при желании ограничить сетевую активность придется настроить iptables
или ufw
вручную.
Внутренний IP-адрес можно выяснить с помощью ifconfig
:
root@kubeadm:~# ifconfig bond0:0
bond0:0 Link encap:Ethernet HWaddr 0c:c4:7a:e5:48:d4
inet addr:10.80.75.9 Bcast:255.255.255.255 Mask:255.255.255.254
UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1
Воспользуемся этим внутренним IP-адресом для трансляции Kubernetes API.
$ kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=10.80.75.9 --skip-preflight-checks --kubernetes-version stable-1.6
--pod-network-cidr
необходим драйверу flannel и определяет адресное пространство для контейнеров.--apiserver-advertise-address
определяет IP-адрес, который Kubernetes будет афишировать в качестве своего API-сервера.--skip-preflight-checks
позволяетkubeadm
не проверять ядро хоста на наличие требуемых функций. Это нужно из-за отсутствия метаданных ядра на хостах Packet.--kubernetes-version stable-1.6
жестко определяет версию кластера (в данном случае 1.6); при желании использовать, например, Kubernetes 1.7 пропустите этот флаг.
Вот что мы должны получить на выходе:
[init] Using Kubernetes version: v1.6.6
[init] Using Authorization mode: RBAC
[preflight] Skipping pre-flight checks
[certificates] Generated CA certificate and key.
[certificates] Generated API server certificate and key.
[certificates] API Server serving cert is signed for DNS names [kubeadm kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.80.75.9]
[certificates] Generated API server kubelet client certificate and key.
[certificates] Generated service account token signing key and public key.
[certificates] Generated front-proxy CA certificate and key.
[certificates] Generated front-proxy client certificate and key.
[certificates] Valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[apiclient] Created API client, waiting for the control plane to become ready
[apiclient] All control plane components are healthy after 36.795038 seconds
[apiclient] Waiting for at least one node to register
[apiclient] First node has registered after 3.508700 seconds
[token] Using token: 02d204.3998037a42ac8108
[apiconfig] Created RBAC rules
[addons] Created essential addon: kube-proxy
[addons] Created essential addon: kube-dns
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run (as a regular user):
sudo cp /etc/kubernetes/admin.conf $HOME/
sudo chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
http://kubernetes.io/docs/admin/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join --token 02d204.3998037a42ac8108 10.80.75.9:6443
- Создайте непривилегированного пользователя.
В установке Ubuntu от Packet нет обычного пользователя, поэтому давайте создадим его.
# useradd packet -G sudo -m -s /bin/bash
# passwd packet
- Настройте переменные окружения для нового пользователя.
Теперь, используя приведенное выше сообщение о создании кластера, можно настроить переменные окружения.
Войдите под учетной записью нового пользователя: sudo su packet
.
$ cd $HOME
$ sudo whoami
$ sudo cp /etc/kubernetes/admin.conf $HOME/
$ sudo chown $(id -u):$(id -g) $HOME/admin.conf
$ export KUBECONFIG=$HOME/admin.conf
$ echo "export KUBECONFIG=$HOME/admin.conf" | tee -a ~/.bashrc
- Примените конфигурацию сети для подов (flannel).
Теперь с помощью kubectl
и двух записей из документации flannel мы применим к кластеру конфигурацию сети:
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel-rbac.yml
clusterrole "flannel" created
clusterrolebinding "flannel" created
$ kubectl create -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
serviceaccount "flannel" created
configmap "kube-flannel-cfg" created
daemonset "kube-flannel-ds" created
Сеть для подов сконфигурирована.
- Разрешите использование однохостового (single-host) кластера.
Обычно в кластер Kubernetes входит несколько хостов, поэтому по умолчанию контейнеры не могут быть запущены на мастере. Но поскольку у нас только одна нода, разрешим на ней запуск контейнеров с помощью операции taint
.
$ kubectl taint nodes --all node-role.kubernetes.io/master-
В качестве альтернативы можно было бы добавить в кластер вторую машину, используя
join token
из выводаkubeadm
.
- Проверьте работоспособность кластера.
Многие компоненты Kubernetes выполняются в виде контейнеров кластера в скрытом пространстве имен kube-system
. Вывести информацию о них можно следующим образом:
$ kubectl get all --namespace=kube-system
NAME READY STATUS RESTARTS AGE
po/etcd-kubeadm 1/1 Running 0 12m
po/kube-apiserver-kubeadm 1/1 Running 0 12m
po/kube-controller-manager-kubeadm 1/1 Running 0 13m
po/kube-dns-692378583-kqvdd 3/3 Running 0 13m
po/kube-flannel-ds-w9xvp 2/2 Running 0 1m
po/kube-proxy-4vgwp 1/1 Running 0 13m
po/kube-scheduler-kubeadm 1/1 Running 0 13m
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kube-dns 10.96.0.10 <none> 53/UDP,53/TCP 14m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deploy/kube-dns 1 1 1 1 14m
NAME DESIRED CURRENT READY AGE
rs/kube-dns-692378583 1 1 1 13m
Как видно из листинга, все сервисы находятся в состоянии Running
, значит, с кластером все в порядке. Если эти компоненты находятся в состоянии загрузки из Интернет, они могут быть еще не запущены.
Запустите контейнер
Теперь в кластере можно запустить контейнер. В Kubernetes контейнеры организованы в поды (Pods), которые используют общий IP-адрес, привязаны к одной и той же ноде (хосту) и могут использовать общие тома.
Проверьте, что сейчас у вас нет запущенных подов (контейнеров):
$ kubectl get pods
Теперь с помощью kubectl run
запустите контейнер. Мы развернем Node.js- и Express.js-микросервис, генерирующий идентификаторы GUID по HTTP.
Этот код был изначально написан для руководства по Docker Swarm. Соответствующие исходники можно найти по этой ссылке: Scale a real microservice with Docker 1.12 Swarm Mode
$ kubectl run guids --image=alexellis2/guid-service:latest --port 9000
deployment "guids" created
Теперь в колонке Name
можно увидеть, какое имя было назначено новому поду и когда он был запущен:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
guids-2617315942-lzwdh 0/1 Pending 0 11s
Используйте Name
для проверки состояния пода:
$ kubectl describe pod guids-2617315942-lzwdh
...
Pulling pulling image "alexellis2/guid-service:latest"
...
Раз у нас есть работающей контейнер, можно взять его IP-адрес и получать сгенерированные идентификаторы с помощью curl
:
$ kubectl describe pod guids-2617315942-lzwdh | grep IP:
IP: 10.244.0.3
$ curl http://10.244.0.3:9000/guid ; echo
{"guid":"4659819e-cf00-4b45-99d1a9f81bdcf6ae","container":"guids-2617315942-lzwdh"}
$ curl http://10.244.0.3:9000/guid ; echo
{"guid":"1604b4cb-88d2-49e2-bd38-73b589da0469","container":"guids-2617315942-lzwdh"}
Для просмотра логов пода можно использовать следующую команду:
$ kubectl logs guids-2617315942-lzwdh
listening on port 9000
Очень полезной функцией для отладки контейнеров является возможность подключаться к их консоли и выполнять там различные команды:
$ kubectl exec -t -i guids-2617315942-lzwdh sh
/ # head -n3 /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.5.2
/ # exit
- Панель инструментов (Dashboard).
Панель инструментов Kubernetes также устанавливается в качестве пода, к которому мы потом сможем обратиться на локальной машине. Поскольку мы не открывали Kubernetes выход в Интернет, для доступа к панели инструментов воспользуемся SSH-туннелем.
$ kubectl create -f https://git.io/kube-dashboard
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
Теперь создадим туннель на хост Packet и откроем в веб-браузере страницу http://localhost:8001/ui/.
$ ssh -L 8001:127.0.0.1:8001 -N
Более подробную информацию можно получить здесь: Dashboard check it out on Github.
Подведем итоги
Вы создали кластер Kubernetes и запустили свой первый микросервис. Теперь вы можете начать изучать компоненты кластера, используя в работе интерфейс командной строки kubectl
.
- Учитесь на примерах.
Руководство Kubernetes by Example, созданное Michael Hausenblas, показалось мне детальным и доступным.
- Добавьте больше нод.
Состоящий из одной ноды кластер у нас теперь есть, можно начинать добавлять еще ноды Type 0
, используя join token
, полученный от kubeadm
.
- Сравните с Docker Swarm.
Docker Swarm — это встроенный в Docker CE и EE инструмент оркестровки. Кластер Docker Swarm может быть поднят одной командой. Более подробную информацию можно почерпнуть из моих уроков по Docker Swarm.
Благодарности:
Спасибо @mhausenblas, @_errm и @kubernetesonarm за обратную связь и советы по настройке кластера Kubernetes.
Ссылки:
- Оригинал: Kubernetes on bare-metal in 10 minutes.
Автор: Southbridge