как настроить обе на двух виртуальных машинах

1656513257 kak nastroit obe na dvuh virtualnyh mashinah

Чжуовей Чжан

1_JCzYiffzwccc3lXj_9V3YA

Я установил Docker Swarm и Kubernetes на две виртуальные машины. Я обнаружил, что Docker Swarm очень легко установить и настроить, тогда как Kubernetes немного труднее настроить, но все еще прост в использовании.

Введение

Я хотел попробовать контейнеры годами: ручная настройка серверов занимает время, она не воспроизводится и, вероятно, внесет различия между моей локальной средой тестирования и производством. Контейнеры предлагают решение всех этих проблем и значительно упрощают запуск большего количества экземпляров программы. Это может сделать службу более масштабированной.

Чтобы запустить масштабируемый сервис, вам необходим механизм оркестрирования контейнеров, чтобы распределить нагрузку, запуская контейнеры на нескольких компьютерах и отправляя запросы каждому экземпляру программы. Согласно New Relic, два популярных механизма оркестровки – Docker Swarm и Kubernetes. Я решил попробовать оба, развернув ту же программу для каждого двигателя.

Создание контейнера

Я решил использовать Samba для тестовой программы. Samba – популярный файловый сервер, позволяющий компьютерам Linux обмениваться файлами с компьютерами Windows. Он общается посредством TCP на порту 445.

Я в первый раз работаю с Docker, поэтому я изменил готовый контейнер Samba, чтобы включить файл, который я хотел обслуживать.

Следуя учебнику Docker, я вручную запустил контейнер из командной строки, чтобы убедиться, что он работает:

docker build -t sambaonly-v1 .
docker run --init -p 445:445 -i sambaonly-v1

и действительно, я смог подключиться к серверу Samba в контейнере с smbclient:

zhuowei@dora:~$ smbclient \\\\localhost\\workdir -U %
WARNING: The "syslog" option is deprecated
Try "help" to get a list of possible commands.
smb: \> ls
.                               D        0  Fri Oct  5 12:14:43 2018
..                              D        0  Sun Oct  7 22:09:49 2018
hello.txt                       N       13  Fri Oct  5 11:17:34 2018
102685624 blocks of size 1024. 72252576 blocks available
smb: \>

Теперь, когда я знаю, что контейнер работает, я могу использовать его в механизме оркестрирования контейнеров.

Подготовка виртуальных машин

Я создал две виртуальные машины под управлением Ubuntu 18.04 в VirtualBox.

Я добавил дополнительную сетевую карту к каждой виртуальной машине, настроенную для внутренней сети, чтобы они могли общаться друг с другом.

1_chCjRdcU_mV9ioAyQ7oB5A

Затем я добавил сервер DHCP для назначения IP-адресов для каждой виртуальной машины:

VBoxManage dhcpserver add --netname intnet --ip 10.133.7.99 --netmask 255.255.255.0 --lowerip 10.133.7.100 --upperip 10.133.7.200 --enable

Теперь виртуальные машины могут общаться друг с другом. Это дает моей главной виртуальной машине IP-адрес 10.133.7.100.

Docker Swarm

Docker Swarm — это механизм оркестрирования контейнеров, интегрированный в сам Docker. Когда я нашел его, я был настроен скептически: зачем использовать его вместо гораздо более известный Kubernetes? Ответ: Docker Swarm сосредоточен на простоте, а не на конфигурации. Это походило на iOS двигателей оркестрирования контейнеров по сравнению с Android Kubernetes.

Настройка Docker Swarm

Docker Swarm приятно просто настроить: все, что мне необходимо установить, это Docker и docker-compose. Затем, следуя официальному руководству, я запустил единственную команду, необходимую для запуска узла менеджера, передав IP-адрес текущей виртуальной машины:

zhuowei@dora:~$ docker swarm init --advertise-addr 10.133.7.100 
Swarm initialized: current node (abcdefghijklmnopqrstuvwxy) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx-abcdefghijklmnopqrstuvwxy 10.133.7.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Вот и все: двигатель Docker теперь работает в режиме Swarm.

Далее я развернул частный реестр Docker, чтобы другие узлы могли получать изображения, снова следуя инструкциям по настройке:

docker service create --name registry --publish published=5000,target=5000 registry:2

Развертывание программы

Docker Swarm использует формат Docker Compose для определения контейнеров для запуска и экспортируемых портов.

После учебника Docker Compose я создал этот манифест Docker Compose:

version: '3.7'
services:
  samba:
    image: 127.0.0.1:5000/samba
    build: sambaonly
    init: true
    stdin_open: true
    ports:
      - "445:445"

Это предписывает Docker Compose создать файл Docker из каталога «sambaonly», загрузить/вытащить встроенные контейнеры в мой недавно настроенный частный реестр и экспортировать порт 445 из контейнера.

Чтобы развернуть этот манифест, я придерживался руководства Docker Swarm. Я впервые использовал Docker Compose для создания и загрузки контейнера в частный реестр:

docker-compose build

docker-compose push

После создания контейнера приложение можно развернуть с помощью docker stack deploy команда, указывая название службы:

$ docker stack deploy --compose-file docker-compose.yml samba-swarm
Ignoring unsupported options: build
Creating network samba-swarm_default
Creating service samba-swarm_samba
zhuowei@dora:~/Documents/docker$ docker stack services samba-swarm
ID           NAME                  MODE       REPLICAS IMAGE PORTS
yg8x8yfytq5d samba-swarm_samba     replicated 1/1

Теперь приложение работает под управлением Samba Swarm. Я проверил, что он все еще работает smbclient:

zhuowei@dora:~$ smbclient \\\\localhost\\workdir -U %
WARNING: The "syslog" option is deprecated
Try "help" to get a list of possible commands.
smb: \> ls
.                               D        0  Fri Oct  5 12:14:43 2018
..                              D        0  Sun Oct  7 22:09:49 2018
hello.txt                       N       13  Fri Oct  5 11:17:34 2018

102685624 blocks of size 1024. 72252576 blocks available
smb: \>

Добавление еще одного узла

Снова простота Docker Swarm проявляется здесь. Чтобы настроить второй узел, я сначала установил Docker, а затем запустил команду, которую мне дал Docker, когда я настроил рой:

ralph:~# docker swarm join --token SWMTKN-1-abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx-abcdefghijklmnopqrstuvwxy 10.133.7.100:2377

This node joined a swarm as a worker.

Чтобы запустить свое приложение на обоих узлах, я запустил Docker Swarm scale команда на узле менеджера:

zhuowei@dora:~/Documents/docker$ docker service scale samba-swarm_samba=2
samba-swarm_samba scaled to 2 overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>] verify: Service converged

На новом рабочем узле появился новый контейнер:

ralph:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7539549283bd 127.0.0.1:5000/samba:latest "/usr/sbin/smbd -FS …" 20 seconds ago Up 18 seconds 445/tcp samba-swarm_samba.1.abcdefghijklmnopqrstuvwxy

Тестирование балансировки нагрузки

Docker Swarm включает в себя встроенный балансировщик нагрузки, который называется Mesh Router: запросы, сделанные в IP-адрес любого узла, автоматически распределяются по Swarm.

Чтобы проверить это, я сделал 1000 подключений к IP-адресу узла менеджера с помощью nc:

print("#!/bin/bash")
for i in range(1000):
    print("nc -v 10.133.7.100 445 &")
print("wait")

Samba порождает один новый процесс для каждого соединения, поэтому если балансировка нагрузки сработает, я ожидаю около 500 процессов Samba на каждом узле в Swarm. Это действительно то, что происходит.

После того, как я запустил сценарий, чтобы сделать 1000 подключений, я проверил количество процессов Samba на диспетчере (10.133.7.100):

zhuowei@dora:~$ ps -ef|grep smbd|wc
506 5567 42504

и на рабочем узле (10.133.7.50):

ralph:~# ps -ef|grep smbd|wc
506 3545 28862

Таким образом, ровно половина запросов, сделанных к узлу менеджера, была волшебным образом перенаправлена ​​на первый рабочий узел, показывая, что кластер Swarm работает должным образом.

Я обнаружил, что Docker Swarm очень легко настроить, и он хорошо работал под небольшим нагрузкой.

Kubernetes

Kubernetes становится отраслевым эталоном для оркестровки контейнеров. Он значительно гибче, чем Docker Swarm, но это также усложняет его настройку. Я обнаружил, что это не так также тяжело, однако.

Для этого эксперимента вместо использования предварительно созданной среды разработчика Kubernetes, например minikubeя решил настроить свой кластер, используя Kubeadm, WeaveNet и MetalLB.

Настройка Kubernetes

Kubernetes имеет репутацию сложного в настройке: вы, возможно, слышали о сложном многоэтапном процессе из учебника Kubernetes The Hard Waytutorial.

Эта репутация больше не точная: разработчики Kubernetes автоматизировали почти каждый шаг в очень простой в использовании сценарий настройки под названием kubeadm.

К сожалению, поскольку Kubernetes настолько гибок, в учебнике все еще есть несколько шагов kubeadm не охватывает, поэтому мне пришлось выяснить, какую сеть и балансировщик нагрузки использовать самому.

Вот что я в итоге побежал.

Сначала мне пришлось выключить Swap на каждом узле:

root@dora:~# swapoff -a
root@dora:~# systemctl restart kubelet.service

Далее я настраиваю главный узел (10.133.7.100) с помощью такой команды:

sudo kubeadm init --pod-network-cidr=10.134.0.0/16 --apiserver-advertise-address=10.133.7.100 --apiserver-cert-extra-sans=10.0.2.15

The --pod-network-cidr Параметр назначает адрес внутренней сети всем узлам сети, используемым для внутренней связи в Kubernetes.

The --apiserver-advertise-address и --apiserver-cert-extra-sansпараметры были добавлены по прихоти в моих настройках VirtualBox: основная виртуальная сетевая карта на виртуальных машинах (имеющая IP 10.0.2.15) может получить доступ только в Интернет. Мне пришлось объяснить, что другие узлы должны получить доступ к главному с помощью IP-адреса 10.133.7.100.

После выполнения этой команды Kubeadm опубликовал некоторые инструкции:

Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:

You can now join any number of machines by running the following on each node as root:

kubeadm join 10.133.7.100:6443 --token abcdefghijklmnopqrstuvw --discovery-token-ca-cert-hash sha256:abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl

Я пропустил эти инструкции в первый раз, поэтому действительно не завершил настройки. Я тогда потратил целую неделя Интересно, почему ни один из моих контейнеров не работал!

Разработчики Kubernetes должны быть следующими:

После того, как я наконец-то прочитал инструкцию, мне пришлось сделать еще три вещи:

  • Во-первых, я должен был выполнить команды, данные от kubeadm для настройки файла конфигурации.
  • По умолчанию Kubernetes не планирует контейнеры на головном узле, а только на рабочих узлах. Поскольку сейчас у меня есть только один узел, учебник показал мне эту команду, чтобы разрешить запускать контейнеры на единственном узле:
kubectl taint nodes --all node-role.kubernetes.io/master-
  • Наконец-то мне пришлось выбрать сеть для своего кластера.

Установка сети

В отличие от Docker Swarm, который должен использовать свой уровень маршрутизации сетки как для сети, так и для балансировки нагрузки, Kubernetes предлагает несколько вариантов для работы в сети и балансировки нагрузки.

Сетевой компонент позволяет контейнерам общаться друг с другом внутри. Я провел некоторые исследования, и эта сравнительная статья предложила Flannel или WeaveNet, поскольку их легко настроить. Поэтому я решил попробовать WeaveNet. Я следовал инструкциям из учебника kubeadm, чтобы применить конфигурацию WeaveNet:

kubectl apply -f " version | base64 | tr -d '\n')"

Далее, чтобы разрешить контейнерам общаться с внешним миром, мне нужен балансировщик нагрузки. Из своего исследования у меня создалось впечатление, что большинство реализаций балансировщика нагрузки Kubernetes сосредоточены только на HTTP-сервисах, а не на необработанном TCP. К счастью, я нашел MetalLB, недавний (летний) проект, заполняющий этот пробел.

Чтобы установить MetalLB, я следовал его учебнику с начала работы и сначала развернул MetalLB:

kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.7.3/manifests/metallb.yaml

Далее я выделил диапазон IP 10.133.7.200–10.133.7.230 для MetalLB, создав и используя этот файл конфигурации:

kubectl apply -f metallb-config.yaml

Развертывание программы

Из-за гибкости Kubernetes файлы конфигурации службы более подробны, чем у Docker Swarm. В дополнение к определению контейнера для запуска, например Docker Swarm, я должен указать, как следует обрабатывать каждый порт.

Прочитав учебник Kubernetes, я придумал эту конфигурацию Kubernetes, состоящую из одной службы и одного развертывания.

# 
kind: Service
apiVersion: v1
metadata:
  name: samba
  labels:
    app: samba
spec:
  ports:
    - port: 445
      protocol: TCP
      targetPort: 445
  selector:
    app: samba
  type: LoadBalancer

---

Эта служба сообщает Kubernetes об экспорте TCP-порта 445 из наших контейнеров Samba к балансировщику нагрузки.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: samba
  labels:
    app: samba
spec:
  selector:
    matchLabels:
      app: samba
  replicas: 1
  template:
    metadata:
      labels:
        app: samba
    spec:
      containers:
        - image: 127.0.0.1:5000/samba:latest
          name: samba
          ports:
            - containerPort: 445
          stdin: true

Этот объект развертывания предписывает Kubernetes запустить мой контейнер и экспортировать порт для обработки службы.

Обратите внимание на replicas: 1 – именно столько экземпляров контейнера я хочу запустить.

Я могу развернуть эту службу в Kubernetes с помощью kubectl apply:

zhuowei@dora:~/Documents/docker$ kubectl apply -f kubernetes-samba.yaml
service/samba configured
deployment.apps/samba configured

и после перезагрузки моей виртуальной машины несколько раз, развертывание наконец-то начало работать:

zhuowei@dora:~/Documents/docker$ kubectl get pods
NAME                   READY STATUS  RESTARTS AGE
samba-57945b8895-dfzgl 1/1   Running 0        52m
zhuowei@dora:~/Documents/docker$ kubectl get service samba
NAME  TYPE         CLUSTER-IP     EXTERNAL-IP  PORT(S)       AGE
samba LoadBalancer 10.108.157.165 10.133.7.200 445:30246/TCP 91m

Моя служба теперь доступна на внешнем IP-адресе, назначенном MetalLB:

zhuowei@dora:~$ smbclient \\\\10.133.7.200\\workdir -U %
WARNING: The "syslog" option is deprecated
Try "help" to get a list of possible commands.
smb: \> ls
.                               D        0  Fri Oct  5 12:14:43 2018
..                              D        0  Sun Oct  7 22:09:49 2018
hello.txt                       N       13  Fri Oct  5 11:17:34 2018

102685624 blocks of size 1024. 72252576 blocks available
smb: \>

Добавление еще одного узла

Добавить еще один узел в кластер Kubernetes гораздо проще: мне просто нужно было запустить команду, предоставленную by kubeadm на новой машине:

zhuowei@davy:~$ sudo kubeadm join 10.133.7.100:6443 --token abcdefghijklmnopqrstuvw --discovery-token-ca-cert-hash sha256:abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl

(snip...)

This node has joined the cluster:* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

Странные прихоти моей настройки

Мне пришлось внести две изменения через настройки VirtualBox:

Во-первых, поскольку моя виртуальная машина имеет две сетевые карты, я должен вручную указать Kubernetes IP-адрес моей машины. В соответствии с этим вопросом мне пришлось отредактировать

/etc/systemd/system/kubelet.service.d/10-kubeadm.conf

и изменить одну строку на

Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml --node-ip=10.133.7.101"

перед перезапуском Kubernetes:

root@davy:~# systemctl daemon-reload
root@davy:~# systemctl restart kubelet.service

Другая настройка касается реестра Docker: поскольку новый узел не может получить доступ к моему частному реестру на головном узле, я решил сделать ужасный излом и поделиться реестром из моего главного узла на новой машине с помощью ssh:

zhuowei@davy:~$ ssh dora.local -L 5000:localhost:5000

Это переадресовывает порт 5000 из головного узла, dora (запускающий мой реестр Docker) на localhost, где Kubernetes может найти его на этой машине.

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

Масштабирование программы

Во время второй настройки машины я изменил свое первоначальное развертывание, чтобы добавить другой экземпляр программы:

replicas: 2

После многократной перезагрузки главного и рабочего устройства новый экземпляр моей программы наконец-то вышел CreatingContainer статус и начал выполняться:

zhuowei@dora:~/Documents/docker$ kubectl get pods
NAME                   READY STATUS  RESTARTS AGE
samba-57945b8895-dfzgl 1/1   Running 0        62m
samba-57945b8895-qhrtl 1/1   Running 0        12m

Тестирование балансировки нагрузки

Я использовал ту же процедуру, чтобы открыть 1000 подключений к Samba, работающей на Kubernetes. Результат интересен.

Мастер:

zhuowei@dora$ ps -ef|grep smbd|wc
492 5411 41315

работник:

zhuowei@davy:~$ ps -ef|grep smbd|wc
518 5697 43499

Kubernetes/MetalLB также сбалансировал нагрузку на две машины, но главная машина получила несколько меньше подключений, чем рабочая. Интересно почему.

Во всяком случае, это показывает, что мне наконец-то удалось настроить Kubernetes после кучи обходных путей. Когда я увидел, что контейнеры работают, я чувствовал себя этим парнем.

Сравнение и заключение

Общие для обеих черт: оба могут управлять контейнерами и интеллектуальными запросами баланса нагрузки в одной программе TCP на двух разных виртуальных машинах. Оба имеют хорошую документацию для начальной настройки.

Сильные стороны Docker Swarm: простая настройка без необходимости настройки, тесная интеграция с Docker.

Сильные стороны Kubernetes: гибкие компоненты, множество доступных ресурсов и дополнений.

Kubernetes против Docker Swarm – это компромисс между простотой и гибкостью.

Мне стало легче настроить Docker Swarm, но я не могу, например, просто заменить балансировщик нагрузки другим компонентом – нет способа его настроить: мне придется выключить это все вместе.

В Kubernetes поиск правильной настройки занял у меня некоторое время благодаря огромному количеству вариантов, но я могу заменить части своего кластера при необходимости, и я могу легко установить приложения, такие как модная информационная панель.

Если вы просто хотите попробовать Kubernetes без всех этих настроек, я предлагаю воспользоваться minikubeкоторый предлагает готовую кластерную виртуальную машину Kubernetes, настройки не требуется.

Наконец, я удивлен тем, что оба механизма поддерживают необработанные услуги TCP: другие поставщики инфраструктуры как услуги, такие как Heroku или Glitch, поддерживают только хостинг веб-сайтов HTTP(s). Наличие служб TCP означает, что можно развернуть свои серверы баз данных, серверы кэша и даже серверы Minecraft, используя те же инструменты для развертывания веб-приложений, что делает управление оркестрацией контейнеров очень полезным навыком.

В заключение: если бы я создавал кластер, я бы использовал Docker Swarm. Если бы я кому-то платил другое чтобы создать кластер для меня, я бы попросил Kubernetes.

Что я научился

  • Как работать с контейнерами Docker
  • Как настроить кластер Docker Swarm с двумя узлами
  • Как настроить кластер Kubernetes с двумя узлами и какие варианты подойдут для программы на основе TCP
  • Как развернуть приложение в Docker Swarm и Kubernetes
  • Как исправить что-нибудь, перезагрузив компьютер достаточное количество раз, как будто я все еще использую Windows 98
  • Kubernetes и Docker Swarm не так страшны, как кажутся

Авторы изображения

Добавить комментарий

Ваш адрес email не будет опубликован.