Мы добавили возможность удобного запуска 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-nofloatingips-ru-1a-v1.9.3 |
| kubernetes-nofloatingips-ru-1a-v1.9.6 |
| kubernetes-nofloatingips-ru-1a-v1.9.9 |
| kubernetes-floatingips-ru-1a-v1.9.3 |
| kubernetes-floatingips-ru-1a-v1.9.6 |
| kubernetes-floatingips-ru-1a-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 -c name -c status
+--------------+--------------------+
| name | status |
+--------------+--------------------+
| test-cluster | 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 -o=custom-columns=NAME:.metadata.name,STATUS:.status.phase
NAME STATUS
coredns-785dcf9c58-6gnfp Running
heapster-6846cdc674-rm4k6 Running
kube-dns-autoscaler-6b94f7bbf8-x5clt Running
kubernetes-dashboard-747575c864-wlg6p Running
monitoring-grafana-84b4596dd7-zf5rx Running
monitoring-influxdb-c8486fc95-bqqb6 Running
node-exporter-test-cluster-robvp4cvwpt7-minion-0 Running
При необходимости вы можете увеличить или уменьшить количество 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, а управление кластером будет доступно через панель управления.
Будем рады, если вы воспользуетесь нашим сервисом в режиме тестирования и предоставите обратную связь.
Автор: Андрей Озеров