Серия вебинаров: развертывание сервисов с контролем состояния в Kubernetes

Вступление

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

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

В последнем выпуске этой серии руководств вы развернете высокодоступный MongoDB ReplicaSet в Kubernetes как StatefulSet, используя Helm, популярный менеджер пакетов с открытым исходным кодом для Kubernetes.

Предпосылки

Для завершения этого урока вам понадобится:

  • Активный кластер Kubernetes, работающий в DigitalOcean, установленный через StackPointCloud, что можно сделать, следуя учебному руководству https://www.digitalocean.com/community/tutorials/webinar-series-getting- началось с kubernetes [Начало работы с Kubernetes].

  • Пример веб-приложения, представленного в учебном пособии Deploying and Scaling Microservices in Kubernetes, который основан на Node.js и MongoDB расширены для обеспечения высокой доступности базы данных. Подробнее о дизайне приложения см. Учебник Building Containerized Applications.

  • Активная учетная запись Docker Hub для хранения образа Docker для приложения.

  • Локальный компьютер с установленным Git

  • Если вы используете macOS, убедитесь, что у вас установлен Homebrew.

Шаг 1 - Установка Helm Client на компьютере разработчика

С Helm администраторы могут развертывать сложные приложения Kubernetes с помощью одной команды. Приложения упаковываются как Charts, которые определяют, устанавливают и обновляют приложения Kubernetes. Диаграммы предоставляют абстракцию над объектами Kubernetes, такими как Pod, Deployments и Services.

У Helm есть два компонента - сервер и клиент. Серверная сторона Helm работает в Kubernetes как сервис под названием Tiller. Клиент - это инструмент командной строки, который взаимодействует с Tiller.

Поскольку вы собираетесь развернуть диаграмму Helm MongoDB ReplicaSet, вам нужен CLI, который взаимодействует с Tiller, компонентом Helm на стороне сервера. StackPointCloud, который вы использовали для настройки Kubernetes в DigitalOcean, поставляется с предустановленным Tiller.

Предполагая, что Homebrew установлен и настроен на вашем Mac, выполните следующую команду для установки Helm:

brew install kubernetes-helm
Output==> Downloading https://homebrew.bintray.com/bottles/kubernetes-helm-2.8.2.high_sierra.bottle.tar.gz
...
==> Summary
🍺  /usr/local/Cellar/kubernetes-helm/2.8.2: 50 files, 121.7MB

После установки Helm убедитесь, что вы можете запустить его, проверив его текущую версию.

helm version
OutputClient: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}

Это подтверждает, что клиент установлен правильно и может общаться с Tiller.

На следующем шаге мы будем использовать Helm для развертывания MongoDB ReplicaSet в Kubernetes.

Шаг 2 - Развертывание набора реплик MongoDB в Kubernetes

StorageClass в Kubernetes предоставляет администраторам возможность описать «классы» хранилища, которые они предлагают. Например, когда пользователи запрашивают том хранилища, StorageClass определяет, какой класс хранилища для них предоставляется. Классы могут включать в себя стандартный жесткий диск и более быстрый SSD. За кулисами StorageClass взаимодействует с базовой инфраструктурой, такой как API облачного провайдера, для предоставления хранилища.

Поскольку вам необходимо постоянное хранилище для хранения данных MongoDB, вы можете присоединить том блочного хранилища DigitalOcean к рабочему узлу и указать блоку MongoDB, чтобы использовать том хранилища для постоянного хранения.

В этом случае StorageClass действует как интерфейс между модулем Pod и службой блочного хранения DigitalOcean. Когда вы запрашиваете объем хранилища блоков, StorageClass связывается с предварительно сконфигурированным драйвером, который знает, как выделить том хранилища блоков.

StackPointCloud устанавливает драйвер хранилища DigitalOcean и регистрирует StorageClass в Kubernetes во время установки. Это избавляет нас от шагов, связанных с установкой и настройкой драйвера и StorageClass.

Прежде чем мы развернем кластер MongoDB, давайте убедимся, что тома StorageClass для DigitalOcean настроены:

kubectl get storageclass

Вывод подтверждает, что StorageClass настроен и готов.

[secondary_label Output
NAME                     PROVISIONER                            AGE
digitalocean (default)   digitalocean/flex-volume-provisioner   1d

Затем вы сконфигурируете и развернете MongoDB ReplicaSet на основе DigitalOcean StorageClass.

Создайте новый каталог для вашего проекта и переключитесь на новый каталог:

mkdir ~/mongo-rs
cd ~/mongo-rs

Клонируйте хранилище Helm Chart от GitHub:

git clone https://github.com/kubernetes/charts.git

Перейдите в каталог MongoDB ReplicaSet (+ charts / stable / mongodb-replicaset / +) и убедитесь, что файл + values.yaml + существует.

cd charts/stable/mongodb-replicaset/
ls values.yaml
Outputvalues.yaml

Этот файл содержит параметры и конфигурацию для диаграммы. Вам нужно изменить этот файл, чтобы сконфигурировать MongoDB ReplicaSet для использования DigitalOcean StorageClass.

Отредактируйте + values.yaml +:

nano values.yaml

Найдите и раскомментируйте следующий раздел:

values.yaml

...
# storageClass: "-"
...

Замените " - " на " digitalocean ", вот так:

values.yaml

...
storageClass:
...

Сохраните файл и выйдите из редактора.

Теперь перейдите в папку + ~ / mongo-rs +.

cd ~/mongo-rs

Теперь вы готовы к развертыванию ReplicaSet MongoDB в своем кластере Kubernetes на основе блочного хранилища DigitalOcean. Выполните следующую команду, чтобы запустить кластер базы данных.

helm install --name= -f charts/stable/mongodb-replicaset/values.yaml stable/mongodb-replicaset

В предыдущей команде + - name + относится к имени диаграммы Хелма. Переключатель + -f + указывает на настройки конфигурации, хранящиеся в + values.yaml +.

Вы сразу увидите вывод, подтверждающий, что создание графика началось.

OutputNAME:   todo
LAST DEPLOYED: Sat Mar 31 10:37:06 2018
NAMESPACE: default
STATUS:

RESOURCES:
==> v1/Service
NAME                     TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)    AGE
 ClusterIP  None        <none>       27017/TCP  1s

==> v1beta1/StatefulSet
NAME                     DESIRED  CURRENT  AGE
 3        1        0s

==> v1/Pod(related)
NAME                       READY  STATUS    RESTARTS  AGE
 0/1    Init:0/2  0         0s

==> v1/ConfigMap
NAME                           DATA  AGE
       1     1s
 1     1s


NOTES:
1. After the statefulset is created completely, one can check which instance is primary by running:

   $ for ((i = 0; i < 3; ++i)); do kubectl exec --namespace default todo-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done

2. One can insert a key into the primary instance of the mongodb replica set by running the following:
   MASTER_POD_NAME must be replaced with the name of the master found from the previous step.

   $ kubectl exec --namespace default MASTER_POD_NAME -- mongo --eval="printjson(db.test.insert({key1: 'value1'}))"

3. One can fetch the keys stored in the primary or any of the slave nodes in the following manner.
   POD_NAME must be replaced by the name of the pod being queried.

   $ kubectl exec --namespace default POD_NAME -- mongo --eval="rs.slaveOk(); db.test.find().forEach(printjson)"

Давайте теперь запустим ряд команд для отслеживания состояния кластера.

Сначала посмотрите на StatefulSet:

kubectl get statefulset

Эта команда подтверждает, что MongoDB ReplicaSet был создан как Kubernetes StatefulSet.

OutputNAME                      DESIRED   CURRENT   AGE
  3         2         2m

Теперь изучите стручки:

kubectl get pods

Количество модулей и их соглашение об именах указывает, что MongoDB ReplicaSet успешно настроен:

OutputNAME                        READY     STATUS        RESTARTS   AGE
  1/1       Running       0          3m
  1/1       Running       0          1m
  1/1       Running       0          54s

Обратите внимание, что каждый Pod имеет суффикс, который заканчивается порядковым номером, который является отличительной чертой StatefulSet.

Давайте теперь проверим, обмениваются ли экземпляры MongoDB друг с другом. Мы сделаем это, запустив команду в оболочке MongoDB в одном из модулей.

Используйте + kubectl для запуска консоли` + mongo` на одном из хостов:

kubectl exec -it  mongo

После подключения вы окажетесь в оболочке MongoDB:

OutputMongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
Welcome to the MongoDB shell.
For interactive help, type "help".
...

2018-03-31T05:08:20.239+0000 I CONTROL  [initandlisten]

Проверьте конфигурацию ReplicaSet с помощью следующей команды:

rs.conf()

Вывод подтверждает, что существует три экземпляра MongoDB, работающего как ReplicaSet.

Output{
   "_id" : "rs0",
   "version" : 3,
   "protocolVersion" : NumberLong(1),
   "members" : [
       {
           "_id" : 0,
           "host" : ",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       },
       {
           "_id" : 1,
           "host" : "",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       },
       {
           "_id" : 2,
           "host" : "",
           "arbiterOnly" : false,
           "buildIndexes" : true,
           "hidden" : false,
           "priority" : 1,
           "tags" : {

           },
           "slaveDelay" : NumberLong(0),
           "votes" : 1
       }
   ],
   "settings" : {
       "chainingAllowed" : true,
       "heartbeatIntervalMillis" : 2000,
       "heartbeatTimeoutSecs" : 10,
       "electionTimeoutMillis" : 10000,
       "catchUpTimeoutMillis" : -1,
       "catchUpTakeoverDelayMillis" : 30000,
       "getLastErrorModes" : {

       },
       "getLastErrorDefaults" : {
           "w" : 1,
           "wtimeout" : 0
       },
       "replicaSetId" : ObjectId("5abdb4f61d952afc4b0b8218")
   }
}

Выход из консоли MongoDB:

exit

Это также отключит вас от вашего удаленного хоста.

Давайте переключимся и проверим контрольную панель DigitalOcean на наличие томов хранилища блоков, связанных с кластером. Войдите в свою учетную запись DigitalOcean и выберите вкладку * Volumes *:

изображение: https: //assets.digitalocean.com/articles/webinar_6_stateful_services/IcNUFQb.jpg [Панель инструментов, показывающая объемы]

Вы можете видеть, что три тома по 10 ГБ каждый подключены к рабочим узлам Kubernetes. Каждый модуль MongfulDB StatefulSet хранит данные в одном из блочных томов хранения. Размер 10 ГБ определяется в + values.yaml + в разделе + persistentVolume +.

values.yaml

persistentVolume:
 enabled: true
 ## mongodb-replicaset data Persistent Volume Storage Class
 ## If defined, storageClassName: <storageClass>
 ## If set to "-", storageClassName: "", which disables dynamic provisioning
 ## If undefined (the default) or set to null, no storageClassName spec is
 ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
 ##   GKE, AWS & OpenStack)
 ##
 storageClass: digitalocean
 accessModes:
   - ReadWriteOnce

 annotations: {}

Вы успешно настроили высокодоступный набор реплик MongoDB, работающий в Kubernetes.

Теперь давайте развернем веб-приложение, которое взаимодействует с кластером MongoDB.

Шаг 3 - Развертывание и масштабирование веб-приложения в Kubernetes

Давайте расширим приложение ToDo Node.js, которое мы использовали в предыдущих частях этой серии руководств, чтобы использовать преимущества кластера MongoDB.

Начните с создания нового рабочего каталога:

mkdir ~/web-app
cd ~/web-app

Затем клонируйте репозиторий приложения ToDo, содержащий код и артефакты Kubernetes.

git clone https://github.com/janakiramm/todo.git

Перейдите в каталог + todo-app / kubernetes +, в котором находятся файлы конфигурации Kubernetes.

cd todo-app/kubernetes

Откройте файл + web-rs-ss.yaml + в вашем редакторе.

nano web-rs-ss.yaml

Обратите внимание на раздел + env + в файле YAML.

веб-RS-ss.yaml

     containers:
     - name: web
       image: janakiramm/todo



       ports:
       - containerPort: 3000

Это передает строку подключения к базе данных приложению во время выполнения в качестве переменной среды. Вместо того, чтобы указывать приложение на простой Pod MongoDB, эта версия приложения использует созданный вами StatefulSet. Каждая запись в разделе + value + ссылается на один из модулей MongoDB StatefulSet.

Используйте + kubectl + для развертывания + web + ReplicaSet вместе со службой + web +

kubectl create -f web-rs-ss.yaml -f web-service.yaml

Вы увидите, что оба созданы:

Outputreplicaset "web" created
service "web" created

Перечислите стручки снова:

kubectl get pods

Теперь вы видите все модули, принадлежащие MongoDB и веб-приложению.

OutputNAME                        READY     STATUS    RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running   0          26m
todo-mongodb-replicaset-1   1/1       Running   0          24m
todo-mongodb-replicaset-2   1/1       Running   0          23m



Let’s check out the Kubernetes services

​```command
kubectl get svc
OutputNAME                      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
kubernetes                ClusterIP   10.3.0.1     <none>        443/TCP          1d
todo-mongodb-replicaset   ClusterIP   None         <none>        27017/TCP        27m

Модули + web + взаимодействуют с кластером MongoDB через службу + todo-mongodb-replicaset +. Веб-приложение доступно через сервис + web + на NodePort + 31201 +.

Доступ к этому порту на любом из рабочих узлов показывает веб-приложение.

изображение: https: //assets.digitalocean.com/articles/webinar_6_stateful_services/b6yZ4sD.jpg [приложение для просмотра списка текущих задач]

Вы можете масштабировать веб-приложение, увеличив число модулей в ReplicaSet.

kubectl scale rs/web --replicas=10
Outputreplicaset "web" scaled

Затем вы можете масштабировать приложение обратно до двух модулей.

kubectl scale rs/web --replicas=2
Outputreplicaset "web" scaled

Теперь давайте проведем несколько тестов на доступность.

Шаг 4 - Тестирование набора реплик MongoDB для высокой доступности

Одним из преимуществ использования StatefulSet является высокая доступность рабочих нагрузок. Давайте проверим это, удалив один из модулей в StatefulSet MongoDB.

kubectl delete pod todo-mongodb-replicaset-2
Outputpod "todo-mongodb-replicaset-2" deleted

Проверьте количество стручков:

kubectl get pods

Вы увидите, что + todo-mongodb-replica set-2 + завершается:

OutputNAME                        READY     STATUS        RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running       0          33m
todo-mongodb-replicaset-1   1/1       Running       0          32m

web-t5zzk                   1/1       Running       0          8m
web-x6dh8                   1/1       Running       0          8m

Через несколько минут вы увидите, что Kubernetes инициализирует другой Pod для замены удаленного.

kubectl get pods

Вы увидите, что + todo-mongodb-replica set-2 + инициализирует:

NAME                        READY     STATUS     RESTARTS   AGE
todo-mongodb-replicaset-0   1/1       Running    0          34m
todo-mongodb-replicaset-1   1/1       Running    0          33m

web-t5zzk                   1/1       Running    0          8m
web-x6dh8                   1/1       Running    0          8m

Теперь, когда вы знаете, что все работает, вы можете навести порядок.

Удалите все объекты, созданные в этом уроке, с помощью следующих команд:

helm delete --purge todo
kubectl delete -f web-rs-ss.yaml -f web-service.yaml
Outputreplicaset "web" deleted
service "web" deleted

Чтобы удалить сам кластер Kubernetes, зайдите на StackPointCloud и сделайте это через панель управления.

Заключение

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

Related