Кластеры Kubernetes в сервисе VPC

Мы добавили возможность удобного запуска Kubernetes в сервисе Виртуальное приватное облако в режиме раннего beta-тестирования.

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

Так как сервис Виртуальное приватное облако построен на базе OpenStack, мы используем один из его компонентов — OpenStack Magnum. Он позволяет быстро создавать приватные кластеры Kubernetes с нужным количеством нод.

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

В этой статье мы расскажем про основные объекты кластера Kubernetes и на примерах рассмотрим процесс создания кластера при помощи OpenStack Magnum.

Создание и управление кластером Kubernetes

В настоящее время создание кластера Kubernetes возможно только через консольные утилиты или OpenStack API в зонах доступности ru-1a и ru-1b (Санкт-Петербург).

Для начала работы вам понадобится:

  • Создать новый или использовать существующий проект VPC;
  • Создать пользователя с SSH-ключом;
  • Добавить пользователя в созданный проект на странице управления проектами;
  • Перейти в проект и получить файл доступа на вкладке Доступ;
  • Установить консольный клиент openstack с библиотекой python-magnumclient;
  • Установить консольный клиент kubectl.

Для установки консольного клиента openstack можно воспользоваться инструкцией по ссылке, однако, стоит иметь ввиду, что для данного клиента также потребуется установить библиотеку python-magnumclient, для поддержки создания Kubernetes кластеров.

Полный набор команд для установки openstack клиента с требуемым плагином для операционных систем семейства Ubuntu/Debian:

$ sudo apt update
$ sudo apt -y install curl python-pip python-dev python3-dev git libxml2-dev libxslt1-dev python-openssl python3-openssl python-pyasn1 libffi-dev libssl-dev build-essential
$ sudo pip install -UI pbr setuptools pytz
$ sudo pip install -UI git+https://github.com/openstack/python-openstackclient
$ sudo pip install -UI git+https://github.com/openstack/python-magnumclient

Полный набор команд для установки openstack клиента с требуемым плагином для операционных систем семейства Fedora/CentOS:

$ sudo yum -y install python-pip gcc libffi-devel python-devel libxslt-devel openssl-devel git libffi-devel
$ sudo pip install -UI pbr setuptools pytz
$ sudo pip install -UI git+https://github.com/openstack/python-openstackclient
$ sudo pip install -UI git+https://github.com/openstack/python-magnumclient

Для управления объектами Kubernetes вам потребуется консольный клиент kubectl. Способы установки для различных операционных систем описаны в официальной документации.

Для создания кластера вам потребуется создать или использовать существующие:

  • Шаблон кластера (cluster template);
  • Набор параметров для CPU и RAM виртуальных машин (flavor).

Вы можете создать cluster template и flavor самостоятельно, или использовать публичные заранее созданные шаблоны.

Также вам потребуется определиться с зоной доступности, типом дисков для вашего кластера и количеством нод. Стоит учесть, что в мы еще не поддерживаем возможность создания одного кластера в нескольких зонах. Вы можете выбрать любой тип сетевого диска (быстрый, универсальный или базовый).
Подробнее о типах дисков можно узнать из нашей базы знаний.

Количество нод может быть разное для master и для minion ролей. На нодах, выполняющих master роль, будут запущены управляющие элементы кластера — controller-manager, scheduler, api. На остальных нодах будут запущены сервисы kubelet, kube-proxy и все контейнеры приложений. Подробнее о компонентах, запускаемых на нодах кластера можно узнать из официальной документации.

Для доступа на ноды по SSH вам потребуется использовать SSH-ключ, созданный ранее. В примерах команд будет использован ключ с именем ssh-test.

Мы будем использовать публичные cluster template и flavor, быстрый тип диска, и зону доступности ru-1b.
В нашем кластере изначально будет запущено 2 master ноды и 3 minion ноды.

Для проверки указанных параметров воспользуемся командами openstackclient и скачанным файлом доступа (rc.sh):

# Запуск файла с доступом к проекту для установки требуемых параметров.
$ source rc.sh

# Конфигурация серверов, которую мы будем использовать для всех нод кластера
$ openstack flavor show BL1.2-4096 -c ram -c vcpus
+-------+-------+
| Field | Value |
+-------+-------+
| ram   | 4096  |
| vcpus | 2     |
+-------+-------+

# Быстрый тип диска в зоне доступности ru-1b
$ openstack volume type show fast.ru-1b -c name
+-------+------------+
| Field | Value      |
+-------+------------+
| name  | fast.ru-1b |
+-------+------------+

# Доступные шаблоны кластеров Kubernetes
$ openstack coe cluster template list -c name
+---------------------------------------+
| name                                  |
+---------------------------------------+
| kubernetes-nofloatingips-ru-1b-v1.9.3 |
| kubernetes-nofloatingips-ru-1b-v1.9.6 |
| kubernetes-nofloatingips-ru-1b-v1.9.9 |
| kubernetes-floatingips-ru-1b-v1.9.3   |
| kubernetes-floatingips-ru-1b-v1.9.6   |
| kubernetes-floatingips-ru-1b-v1.9.9   |
+---------------------------------------+

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

# Создание кластера Kubernetes с именем test-cluster
# В качестве keypair используется имя ключа, созданного ранее
$ openstack coe cluster create --cluster-template kubernetes-nofloatingips-ru-1b-v1.9.9 --master-count 2 --node-count 3 --keypair ssh-test --master-flavor BL1.2-4096 --flavor BL1.2-4096 test-cluster

Обратите внимание, что мы выбрали одинаковую конфигурацию для разных нод (параметры master-flavor и flavor), вы можете выбирать разные наборы конфигурации в зависимости от требований кластера. Их изменение возможно и после его создания.

Также стоит учесть, что при создании кластера с несколькими master нодами, автоматически будет создан балансировщик нагрузки для доступа к API Kubernetes.

Через несколько минут в вашем проекте появится кластер Kubernetes. В панели управления проектом вы увидите новые виртуальные машины, диски и сетевые объекты.

Вы можете проверить статус вашего кластера через openstackclient:

$ openstack coe cluster list
+--------------------------------------+--------------+----------+------------+--------------+--------------------+
| uuid                                 | name         | keypair  | node_count | master_count | status             |
+--------------------------------------+--------------+----------+------------+--------------+--------------------+
| fb363e6f-7530-44d9-ad12-88721a51732c | test-cluster | ssh-test |          2 |            3 | CREATE_IN_PROGRESS |
+--------------------------------------+--------------+----------+------------+--------------+--------------------+

После того как кластер перейдет в состояние CREATE_COMPLETE, вы сможете управлять его объектами через утилиту kubectl, скачав конфигурационный файл при помощи следующих команд:

$ mkdir -p ~/test-cluster
$ openstack coe cluster config test-cluster --dir ~/test-cluster

После этого можно работать с кластером при помощи утилиты kubectl:

$ export KUBECONFIG=~/test-cluster/config
$ kubectl get pods --all-namespaces
NAMESPACE     NAME                                               READY     STATUS    RESTARTS   AGE
kube-system   coredns-785dcf9c58-j4kj6                           1/1       Running   0          5m
kube-system   heapster-6846cdc674-6rt85                          1/1       Running   0          5m
kube-system   kube-dns-autoscaler-6b94f7bbf8-sskg5               1/1       Running   0          5m
kube-system   kubernetes-dashboard-747575c864-5st5l              1/1       Running   0          5m
kube-system   monitoring-grafana-84b4596dd7-brvp9                1/1       Running   0          5m
kube-system   monitoring-influxdb-c8486fc95-w4ltf                1/1       Running   0          5m
kube-system   node-exporter-test-cluster-s2zyasp62pii-minion-0   1/1       Running   0          2m

При необходимости вы можете увеличить или уменьшить количество minion нод в кластере через openstackclient, передав новое значение node_count:

$ openstack coe cluster update test-cluster replace node_count=4

Основные объекты кластера Kubernetes

Pods

Несмотря на то, что Kubernetes руководит набором контейнеров, базовой сущностью, которой управляет Kubernetes, является не контейнер, а Pod.

Pod представляет из себя набор пространства имен ядра Linux и настроек сетевого стека, которые позволяют собирать набор контейнеров в единую сущность.
Чаще всего, один контейнер с приложением запускается внутри одного отдельного Pod-а.
При необходимости, можно запускать и несколько контейнеров внутри одного Pod-а, это может быть полезно, когда вам необходимо предоставить доступ из одного контейнера в другой через сетевой интерфейс localhost, либо по каким-то другим причинам запускать несколько контейнеров на одном хосте.
Все контейнеры, запущенные в одном Pod-е будут иметь один хостнейм, IP-адрес, таблицу маршрутизации и диски.

Стоит заметить, что при масштабировании количества экземпляров вашего приложения внутри Kubernetes, необходимо увеличивать именно количество Pod-ов, а не количество контейнеров в одном конкретном Pod-е.
Подробнее в официальной документации Pods.

Для примера создадим максимально простой Pod с Nginx при помощи описания в формате yaml:

# nginx-basic.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: library/nginx:1.14-alpine
    ports:
    - containerPort: 80

Для создания Pod-а мы можем воспользоваться утилитой kubectl.
Мы добавили все примеры, изложенные в статье, в нашу группу Github, поэтому вы можете не создавать файлы у себя на компьютере, а использовать url-адрес файла из публичного репозитория :

$ kubectl create \
  -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/pods/nginx-basic.yaml

После создания мы можем запросить полную информацию о статусе Pod-а, используя команду kubectl describe:

$ kubectl describe pod nginx
Name:         nginx
Namespace:    default
Node:         test-cluster-nd5c5y6lsfxb-minion-0/10.0.0.5
Start Time:   Sun, 17 Jun 2018 12:29:03 +0000
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.100.88.9
Containers:
  nginx:
    Container ID:   docker://6ca6383b66686c05c61c1f690737110e0f8994eda393f44a7ebfbbf2b2026267
    Image:          library/nginx:1.14-alpine
    Image ID:       docker-pullable://docker.io/nginx@sha256:944b79ca7dbe456ce72e73e70816c1990e39967c8f010349a388c00b77ec519c
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sun, 17 Jun 2018 12:29:16 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-rp5ls (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          True
  PodScheduled   True
Volumes:
  default-token-rp5ls:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-rp5ls
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     <none>
Events:
  Type    Reason                 Age   From                                         Message
  ----    ------                 ----  ----                                         -------
  Normal  Scheduled              52s   default-scheduler                            Successfully assigned nginx to test-cluster-nd5c5y6lsfxb-minion-0
  Normal  SuccessfulMountVolume  51s   kubelet, test-cluster-nd5c5y6lsfxb-minion-0  MountVolume.SetUp succeeded for volume "default-token-rp5ls"
  Normal  Pulling                50s   kubelet, test-cluster-nd5c5y6lsfxb-minion-0  pulling image "library/nginx:1.14-alpine"
  Normal  Pulled                 39s   kubelet, test-cluster-nd5c5y6lsfxb-minion-0  Successfully pulled image "library/nginx:1.14-alpine"
  Normal  Created                39s   kubelet, test-cluster-nd5c5y6lsfxb-minion-0  Created container
  Normal  Started                39s   kubelet, test-cluster-nd5c5y6lsfxb-minion-0  Started container

Как можно заметить, Pod запустился на ноде с именем test-cluster-nd5c5y6lsfxb-minion-0 и получил внутренний IP-адрес 10.100.88.9.
Из раздела Events видно основные события запуска — выбор ноды для запуска и скачивание образа.

Мы можем попасть в Pod и проверить состояние процессов внутри контейнера:

$ kubectl exec -it nginx sh

ps aux
PID   USER     TIME   COMMAND
    1 root       0:00 nginx: master process nginx -g daemon off;
    7 nginx      0:00 nginx: worker process
   20 root       0:00 sh
   24 root       0:00 ps aux

exit

Следует иметь ввиду, что IP-адрес 10.100.88.9 не будет доступен другим приложениям внутри и вне Kubernetes кластера, доступ к запущенному Nginx будет возможен только изнутри самого Pod-а:

$ ping -c 1 10.100.88.9
PING 10.100.88.9 (10.100.88.9): 56 data bytes

--- 10.100.88.9 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

$ kubectl exec nginx -- ping -c1 10.100.88.9
PING 10.100.88.9 (10.100.88.9): 56 data bytes
64 bytes from 10.100.88.9: seq=0 ttl=64 time=0.075 ms

--- 10.100.88.9 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.075/0.075/0.075 ms

Вдобавок к тому, что указанный IP-адрес доступен только из контейнера, он также не является постоянным. Это значит, что если этот Pod будет пересоздан, то он может получить другой IP-адрес.

Чтобы решить эти проблемы, можно использовать объект под названием Service.

Services

Service позволяет назначать постоянные IP-адреса для Pod-ов, предоставлять им доступ из внешних сетей и балансировать запросы между Pod-ами.
Подробнее про Service можно узнать в официальной документации.

Для примера нам потребуется удалить запущенный Pod:

$ kubectl delete pod nginx

Добавим в описание Pod-а метку (Label), которая потребуется для Service:

# nginx-labeled.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: webservice
spec:
  containers:
  - name: nginx
    image: library/nginx:1.14-alpine
    ports:
    - containerPort: 80

Нам также потребуется описание Service:

# nginx-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
  labels:
    app: webservice
spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 30001
    protocol: TCP
  selector:
    app: webservice

Создадим Pod и Service:

$ kubectl create \
  -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/pods/nginx-labeled.yaml \
  -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/services/nginx-nodeport.yaml 

Так как созданный Service имеет тип NodePort, то на всех нодах кластера будет открыт указанный нами порт 30001 на всех сетевых интерфейсах.
Это значит, что если мы добавим к любой ноде внешний IP-адрес, то мы сможем получить доступ к запущенному Pod-у с Nginx из внешней сети.

Чтобы не использовать внешние адреса нод кластера для доступа к Service, мы можем использовать тип LoadBalancer вместо NodePort.
Нам понадобится новое описание сервиса:

# nginx-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-loadbalancer
  labels:
    app: webservice
spec:
  type: LoadBalancer
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: webservice

Удалим текущий сервис и применим новое описание:

$ kubectl delete service nginx-service
$ kubectl create \
  -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/services/nginx-loadbalancer.yaml

После запуска сервиса, Nginx станет доступен по TCP порту 80 из внешней сети, при этом не будет необходимости назначать и использовать внешние адреса для нод кластера. Service с типом LoadBalancer автоматически выделит новый внешний адрес в ваш проект VPC и начнет его использовать.

Вы можете получить информацию о выделенном внешнем адресе при помощи kubectl:

$ kubectl get service nginx-service -o=custom-columns=IP:status.loadBalancer.ingress[0].ip
IP
xxx.xxx.xxx.xxx

В наших примерах запускался только один Pod с Nginx. Чтобы масштабировать приложение на большее количество Pod-ов, мы можем использовать Deployment.

Deployments

Deployment представляет из себя сущность кластера Kubernetes, позволяющую масштабировать Pod-ы и производить удобное обновление или откат версий для большого количества Pod-ов.
Вместо Deployment можно также использовать объект ReplicaSet, однако мы не коснемся его в наших примерах.
Подробнее о Deployment можно узнать в официальной документации.

Нам снова потребуется удалить Pod (нам не требуется удалять Service):

$ kubectl delete pod nginx

Добавим следующее описание Deployment:

# nginx-1.14.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 10
  selector:
    matchLabels:
      app: webservice
 minReadySeconds: 10
 strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
 template:
    metadata:
      labels:
        app: webservice
   spec:
      containers:
      - name: nginx
        image: library/nginx:1.14-alpine
        ports:
        - containerPort: 80

Создадим указанный Deployment:

$ kubectl create -f \
  https://raw.githubusercontent.com/selectel/kubernetes-examples/master/deployments/nginx-1.14.yaml

Мы выбрали значение 10 для параметра replicas, поэтому в нашем кластере будут созданы 10 Pod-ов с приложением Nginx:

$ kubectl get pods --selector app=webservice
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-54bfdc4489-42rrb   1/1       Running   0          4m
nginx-deployment-54bfdc4489-5lvtc   1/1       Running   0          4m
nginx-deployment-54bfdc4489-g7rk2   1/1       Running   0          4m
nginx-deployment-54bfdc4489-h5rxp   1/1       Running   0          4m
nginx-deployment-54bfdc4489-l9l2d   1/1       Running   0          4m
nginx-deployment-54bfdc4489-pjpvg   1/1       Running   0          4m
nginx-deployment-54bfdc4489-q8dnp   1/1       Running   0          4m
nginx-deployment-54bfdc4489-s4wzf   1/1       Running   0          4m
nginx-deployment-54bfdc4489-tfxf9   1/1       Running   0          4m
nginx-deployment-54bfdc4489-xjzb5   1/1       Running   0          4m

Вы можете получить доступ из внешней сети к запущенному приложению, используя Service, созданный в предыдущем разделе. Service будет производить автоматическую балансировку запросов из внешней сети между 10 экземплярами Nginx.

При необходимости, мы можем обновить версию Nginx. Обновим описание Deployment, изменив версию образа с 1.14-alpine на 1.15-alpine:

# nginx-1.15.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 10
  selector:
    matchLabels:
      app: webservice
 minReadySeconds: 10
 strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
 template:
    metadata:
      labels:
        app: webservice
   spec:
      containers:
      - name: nginx
        image: library/nginx:1.15-alpine # <-- changed
        ports:
        - containerPort: 80

Для запуска процесса обновления Pod-ов, воспользуемся командой kubectl. Обратите внимание на аргумент —record, он нам пригодится для последующего удобного отката версии Nginx:

$ kubectl apply -f \
  https://raw.githubusercontent.com/selectel/kubernetes-examples/master/deployments/nginx-1.15.yaml \
  --record

Вы можете следить за ходом обновления при помощи следующей команды:

$ kubectl rollout status deployment nginx-deployment
Waiting for rollout to finish: 4 out of 10 new replicas have been updated...

Kubernetes будет ждать 10 секунд после успешного обновления одного Pod-а, так как мы указали значение 10 для параметра minReadySeconds в описании Deployment.

После завершения обновления все Pod-ы для Deployment перейдут в активное состояние:

$ kubectl get deployment --selector app=webservice
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   10        10        10           10          23m

Мы можем произвести откат версии приложения, если что-то пошло не так. Для этого нам потребуется выбрать нужную ревизию Deployment:

$ kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl apply --filename=https://raw.githubusercontent.com/selectel/kubernetes-examples/master/deployments/nginx-1.15.yaml --record=true

В выводе команды есть 2 ревизии — первая это изначальное создание Deployment, вторая это обновление. Так как мы использовали аргумент —record при обновлении, то мы видим команду, которая создала вторую ревизию Deployment.

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

$ kubectl rollout undo deployment nginx-deployment --to-revision=1

Аналогично с обновлением, мы можем следить за выполнением отката версии при помощи команды:

$ kubectl rollout status deployment nginx-deployment
Waiting for rollout to finish: 6 out of 10 new replicas have been updated…

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

Хранение данных

По умолчанию, все данные контейнеров запущенных внутри Pod-ов являются эфемерными и будут потеряны падении Pod-а.
Для запуска Pod-ов с постоянным хранилищем данных можно использовать объект PersistentVolumeClaim.
Создать такой объект в кластере очень просто — достаточно добавить его описание, по аналогии с тем, как мы создавали Pod, Service или Deployment в предыдущих разделах.
Подробнее можно узнать из официальной документации.

Пример описания PersistentVolumeClaim, создающего диск размером 10GB:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pv-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

Мы можем подключить его в виде диска к нашему Pod, обновив описание Pod c Nginx, созданного ранее:

# nginx-with-volume.yaml
apiVersion: v1
kind: Pod
metadata:
 name: nginx
spec:
  containers:
  - name: nginx
    image: library/nginx:1.14-alpine
    ports:
    - containerPort: 80
    volumeMounts:
      - mountPath: "/var/www/html"
        name: data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: my-pv-claim

Однако, для того, чтобы диск был создан, вам потребуется указать свойства создаваемого диска в виде StorageClass. В сервисе “Виртуальное приватное облако” можно использовать сетевые диски быстрого, универсального и базового типов в качестве постоянного хранилища данных Pod-ов Kubernetes.
К примеру, чтобы создать StorageClass, который позволит использовать быстрые диски в зоне доступности ru-1b, вам потребуется следующее описание:

# fast.ru-1b.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fast.ru-1b
  annotations:
    storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/cinder
parameters:
  type: fast.ru-1b
  availability: ru-1b

Перед созданием указанных объектов, удалим Deployment, созданный ранее:

$ kubectl delete deployment nginx-deployment

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

$ kubectl create -f \
https://raw.githubusercontent.com/selectel/kubernetes-examples/master/storageclasses/fast.ru-1b.yaml  

Создадим PersistentVolumeClaim и Pod:

$ kubectl create \
-f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/persistentvolumeclaims/my-pv-claim.yaml \
-f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/pods/nginx-with-volume.yaml

После этого в вашем проекте автоматически будет создан диск, который будет подключен к одной из minion-нод кластера. При её падении, диск будет автоматически переключен в другую ноду.

Мы можем увидеть диск внутри контейнера с Nginx:

$ kubectl exec -it nginx sh

mount | grep "/var/www/html"
/dev/sdc on /var/www/html type ext4 (rw,seclabel,relatime,data=ordered)

exit

Вы можете подключать диск и к Deployment. С соответствующим примером можно ознакомиться в официальной документации.

Панель управления Kubernetes

Вы можете использовать встроенную панель (dashboard) самого Kubernetes для просмотра состояния объектов кластера и их управления.

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

# admin-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system

И описание роли:

# cluster-admin.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

Создадим указанные объекты:

$ kubectl create \
  -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/accounts/admin-user.yaml \
  -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/clusterrolebindings/cluster-admin.yaml

Далее вам потребуется узнать значение сгенерированного токена для этого аккаунта.
Для этого требуется найти соответствующий объект типа Secret в кластере:

$ kubectl get secret --namespace=kube-system | grep "admin-user-token"
admin-user-token-bkfhb                   kubernetes.io/service-account-token   3         22m

И посмотреть значение токена у найденного Secret с именем admin-user-token-bkfhb:

$ kubectl describe secret admin-user-token-bkfhb --namespace=kube-system | grep "token:"
token:      XXXXXX...

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

В том случае, если вы создавали кластер из публичного шаблона, в нем уже существуют Pod и Service, обеспечивающие работу панели:

$ kubectl get svc kubernetes-dashboard --namespace=kube-system                                                                                                                                                              206ms  Tue Jun 19 14:35:19 2018
NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes-dashboard   ClusterIP   10.254.122.245   <none>        443/TCP   2d

$ kubectl get pod --namespace=kube-system --selector k8s-app=kubernetes-dashboard                                                                                                                                                   119ms  Tue Jun 19 14:36:48 2018
NAME                                    READY     STATUS    RESTARTS   AGE
kubernetes-dashboard-747575c864-jpxvt   1/1       Running   0          2d

Так как Service имеет тип ClusterIP, то он будет доступен только изнутри самого кластера.
Вы можете получить доступ к панели со своего рабочего компьютера с конфигурационным файлом кластера, используя команду kubectl:

$ kubectl proxy
Starting to serve on 127.0.0.1:8001

Проверьте работоспособность proxy, открыв указанный адрес в браузере:

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

http://127.0.0.1:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ 

Перейдя по нему, вы должны увидеть экран логина в панель:

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

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

Мониторинг объектов Kubernetes

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

Аналогично панели управления, в качестве типа Service установлен ClusterIP, доступ к нему возможен только изнутри кластера или посредством kubectl proxy. Вы можете получить доступ к Grafana со своего рабочего компьютера по следующему адресу:

http://127.0.0.1:8001/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana:80

Заключение

В этой статье мы изучили наиболее часто используемые объекты Kubernetes и рассмотрели примеры по запуску и управлению кластером при помощи OpenStack Magnum.

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

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