company_banner

Kubernetes на голом железе за 10 минут

https://blog.alexellis.io/kubernetes-in-10-minutes/
  • Перевод


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.


Ссылки:


  1. Оригинал: Kubernetes on bare-metal in 10 minutes.
Southbridge 74,40
Обеспечиваем стабильную работу серверов
Поделиться публикацией
Комментарии 31
  • 0
    Digital Ocean так-то дешевле, можно за $5 почувствовать себя DevOps«ом
    • +1

      В Scaleway за 2.99 и машинка получше

      • 0
        За 2.99€ будет 2GB памяти, что должно хватить, но вот CPU там слабые, сильно уступают даже DO за 5$. Чистая установка master сервера отъедает большинство ресурсов, а загрузка CPU в простое около 40-50% (на все обслуживающие kubernates процессы, docker, плагин сети). Для обычной kubernates будет нормально, но вот для master нет.
        Kubernates еще удобно устанавливать с помощью Juju, но к сожалению в дефолтное ядро не включен один модуль, из-за чего приходится собирать свой образ.
        • 0
          Scaleway к машине за 3 евро цепляют винт на 50Gb, стоимостью больше самой машины. Пришлось экстренно оттуда бежать.
          • –1

            Вообще то нет. Один вольюм 50гб в комплекте. Дополнительные 50 стоит 1 евро

          • 0
            2.99 евро
        • 0
          Ещё бы было что-то такое же, но чтобы был мультьмастер.
          Может мне кто-то пояснит, как это делается в продуктивных кластерах, ведь если вылетит мастер, то тогда кластер всё. Как выглядит обычная практика? Делают много мастеров?
          Я пытался по информации вот отсюда поставит несколько мастеров. Но не работает.
          • 0
            В k8s все сервисы кластера stateless, мультимастера нет. Обычно вертят сверху HA решения, чтобы обращения шли на «общий» ipшник. Однако, имеет смысл сделать несколько инстансов etcd, поскольку этот сервис как раз использует k8s для хранения конфигурации кластера.
            • 0
              Ну т.е. компоненты мастера сделать НА возможно, но не все элементы. Верно?
              • 0
                ну под мультимастером я имел ввиду, что теперь есть два etcd и kube-api.
                Я, по совету ниже, поставил кластер через kubesprey, удобная вещь оказалась.
              • 0
                > Ещё бы было что-то такое же, но чтобы был мультимастер.

                Попробуйте Mesos/Marathon/DSOS, там он есть.
              • +1
                А можно инструкцию по установке, но на примере CentOs?
                • 0

                  Ставите kubectl и kubeadm из соответствующего репозитория и дальше все то же самое. Полный гайд для центоси и убунты есть в документации

                  • +2
                    Самое удобное и универсальное средство, которое мне удалось найти — это kubespray. По сути это набор ansible скриптов. Поддерживает множество операционных систем, в тч atomic. Умеет и мультимастер поднять.
                    • 0
                      +1, тоже поднимаю с kubespray, не понимаю почему все статьи про kubeadm, он же еще не умеет мультимастер
                      • 0
                        Потому как kubeadm, если я верно понял, решение, которое предоставляет сам проект и, как результат, умеет поднимать кластер на последних версиях всего. Да, и, кажется, самый простой вариант.
                        • 0

                          Ну… на голую убунту будет поставлен docker 1.8

                          • 0
                            Ну примером сейчас кубеспрей выливает Кубернетис версии v1.6.7, когда через месяц уже будет 1.8. И еще:

                            > The easiest way to run the deployement is to use the kubespray-cli tool.

                            И паралельно в доках Кубернетис написано

                            > kubespray-cli is no longer actively maintained.
                            • 0

                              А еще там написано, что на продакшн рекомендуется собирать from scratch

                              • 0
                                Ну по комитах действительно kubespray-cli не активно девелопится.

                                > А еще там написано, что на продакшн рекомендуется собирать from scratch

                                А вот такого не видел. Ссылку?
                                • 0

                                  Не совсем точно выразился


                                  WARNING: kubeadm is in beta, please do not use it for production clusters.

                                  Гласит документация и сам kubeadm

                                  • 0
                                    Да, это видел. И вообще у них много способов засетапать Кубернетис, но половина из них не первой свежести, kubeadm в бете и т.п. Что вообще лучше всего использовать и как его сетапать? Я говорю о bare-metal.
                        • 0
                          Вроде как мультимастер с kubeadm должны реализовать. Об этом есть в доках.
                  • 0
                    Однажды провозился с установкой локально на виртуалочки с центосью — потратил 3 дня собрал половину тикетов на SO и бросил это дело.
                    • +1

                      Тут можно учить Kubernetes в интерактивном режиме бесплатно и без смс.

                      • 0
                        На убунте не запустится. Будет ошибка нод.
                        runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
                        • 0

                          запустите flannel и будет вам счастье

                          • 0
                            Спасибо, мне не будет. Я, как и предыдущий комментатор, в это забагованное поделие наигрался.
                            А вот для тех, у кого много свободного вренмени, можно было бы и дописать эту строчку.
                            • 0
                              раньше надо было cni в ручную устнавливать при такой ошибке, там немного в принципе, надо только небольшой json в /etc/cni.d записать.
                              Та версия с которой я сейчас работаю(1.7.3) такой ошибки уже не имеет, точнее говоря она есть, но как-только сеть установишь, то она исправляется.
                        • 0
                          В моем случае для создания SSH туннеля сработала такая команда:

                          ssh -N -L 8001:127.0.0.1:8001 username@remotehost

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое