
Hemos agregado la capacidad de lanzar Kubernetes de manera conveniente en el servicio Virtual Private Cloud en el modo de prueba beta inicial.
Esta funcionalidad será útil para los usuarios que necesitan una administración conveniente de una gran cantidad de aplicaciones que se ejecutan como contenedores. Kubernetes ofrece herramientas para escalar, autocuración, equilibrio de carga para contenedores que se ejecutan dentro de un clúster.
Dado que el servicio Virtual Private Cloud se basa en OpenStack, utilizamos uno de sus componentes: OpenStack Magnum . Le permite crear rápidamente grupos privados de Kubernetes con el número deseado de nodos.
Actualmente, cualquier usuario de nuestro servicio puede crear varios clústeres independientes en su proyecto. Como nodos de clúster, se utilizarán máquinas virtuales, cuya configuración se puede seleccionar y cambiar.
En este artículo, hablaremos sobre los objetos principales del clúster de Kubernetes y usaremos los ejemplos para ver el proceso de creación de un clúster con OpenStack Magnum.
Crear y administrar un clúster de Kubernetes
Actualmente, la creación de un clúster de Kubernetes solo es posible a través de las utilidades de consola o la API OpenStack en las zonas de disponibilidad ru-1a y ru-1b (San Petersburgo).
Para comenzar, necesitará:
- Cree uno nuevo o use un proyecto VPC existente;
- Cree un usuario con una clave SSH ;
- Agregue un usuario al proyecto creado en la página de administración del proyecto;
- Vaya al proyecto y obtenga el archivo de acceso en la pestaña Acceso ;
- Instale el cliente de consola openstack con la biblioteca python-magnumclient ;
- Instale el cliente de consola kubectl .
Para instalar el cliente de consola openstack , puede usar las instrucciones en el enlace , sin embargo, debe tener en cuenta que para este cliente también necesitará instalar la biblioteca python-magnumclient para admitir la creación de clústeres de Kubernetes.
El conjunto completo de comandos para instalar un cliente OpenStack con el complemento requerido para los sistemas operativos de la familia 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
El conjunto completo de comandos para instalar un cliente OpenStack con el complemento requerido para los sistemas operativos de la familia 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
Para administrar objetos Kubernetes, necesita el cliente de consola kubectl . Los métodos de instalación para varios sistemas operativos se describen en la documentación oficial .
Para crear un clúster, deberá crear o usar los existentes:
- Plantilla de clúster;
- Un conjunto de parámetros para la CPU y la RAM de las máquinas virtuales ( sabor ).
Puede crear plantillas de clúster y probarlas usted mismo, o usar plantillas públicas creadas previamente.
También deberá determinar la zona de disponibilidad, el tipo de discos para su clúster y la cantidad de nodos. Vale la pena considerar que todavía no admitimos la posibilidad de crear un clúster en varias zonas. Puede elegir cualquier tipo de unidad de red (rápida, universal o básica).
Puede obtener más información sobre los tipos de unidades en nuestra base de conocimientos .
El número de nodos puede ser diferente para los roles maestro y minion . En los nodos que desempeñan el rol maestro, se lanzarán los elementos de control del clúster: controlador-administrador , planificador , api . En los otros nodos, se lanzarán los servicios kubelet , kube-proxy y todos los contenedores de aplicaciones. Puede obtener más información sobre los componentes que se ejecutan en los nodos del clúster en la documentación oficial .
Para acceder a los nodos a través de SSH, deberá utilizar la clave SSH creada anteriormente. Los comandos de muestra usarán una clave llamada ssh-test .
Utilizaremos la plantilla y el sabor del clúster público, el tipo de disco rápido y la zona de disponibilidad ru-1b .
En nuestro clúster, se lanzarán inicialmente 2 nodos maestros y 3 nodos minion.
Para verificar estos parámetros, utilizamos los comandos openstackclient y el archivo de acceso descargado ( rc.sh ):
Por ejemplo, elegiremos la segunda plantilla de clúster; las direcciones flotantes de acceso público para cada uno de los nodos no se crearán a partir de ella. No los necesitaremos.
# 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
Tenga en cuenta que hemos elegido la misma configuración para diferentes nodos (parámetros maestro-sabor y sabor), puede elegir diferentes conjuntos de configuración según los requisitos del clúster. Su cambio es posible después de su creación.
También vale la pena considerar que al crear un clúster con varios nodos maestros, se creará automáticamente un equilibrador de carga para acceder a la API de Kubernetes.
Después de unos minutos, aparecerá un clúster de Kubernetes en su proyecto. En el panel de control del proyecto, verá nuevas máquinas virtuales, discos y objetos de red.
Puede verificar el estado de su clúster a través de openstackclient:
openstack coe cluster list -c name -c status +--------------+--------------------+ | name | status | +--------------+--------------------+ | test-cluster | CREATE_IN_PROGRESS | +--------------+--------------------+
Después de que el clúster ingrese al estado CREATE_COMPLETE, puede administrar sus objetos a través de la utilidad kubectl descargando el archivo de configuración utilizando los siguientes comandos:
$ mkdir -p ~/test-cluster $ openstack coe cluster config test-cluster --dir ~/test-cluster
Después de eso, puede trabajar con el clúster utilizando la utilidad 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
Si es necesario, puede aumentar o disminuir el número de nodos de súbditos en el clúster a través de openstackclient pasando el nuevo valor de cuenta_nodo:
$ openstack coe cluster update test-cluster replace node_count=4
Objetos clave de clúster de Kubernetes
Vainas
Aunque Kubernetes gestiona un conjunto de contenedores, la entidad subyacente que gestiona Kubernetes no es un contenedor, sino un Pod .
Pod es un conjunto de espacios de nombres de kernel de Linux y configuraciones de pila de red que le permiten ensamblar un conjunto de contenedores en una sola entidad.
La mayoría de las veces, un contenedor con la aplicación se inicia dentro de un Pod separado.
Si es necesario, puede ejecutar varios contenedores dentro de un Pod, esto puede ser útil cuando necesita proporcionar acceso de un contenedor a otro a través de la interfaz de red localhost, o por alguna otra razón ejecutar varios contenedores en el mismo host.
Todos los contenedores que se ejecutan en el mismo Pod tendrán un nombre de host, dirección IP, tabla de enrutamiento y discos.
Vale la pena señalar que al escalar el número de instancias de su aplicación dentro de Kubernetes, es necesario aumentar el número de Pods, y no el número de contenedores en un Pod específico.
Más detalles en la documentación oficial de Pods .
Por ejemplo, cree el Pod más simple con Nginx usando la descripción en formato yaml:
Para crear un Pod, podemos usar la utilidad kubectl .
Agregamos todos los ejemplos presentados en el artículo a nuestro grupo Github , por lo que no puede crear archivos en su computadora, pero use la URL del archivo desde el repositorio público:
$ kubectl create \ -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/pods/nginx-basic.yaml
Después de la creación, podemos solicitar información completa sobre el estado del Pod mediante el comando 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
Como puede ver, Pod comenzó en un nodo llamado test-cluster-nd5c5y6lsfxb-minion-0 y recibió una dirección IP interna de 10.100.88.9.
Desde la sección Eventos, puede ver los principales eventos de inicio: seleccionar un nodo para iniciar y descargar la imagen.
Podemos ingresar al Pod y verificar el estado de los procesos dentro del contenedor:
$ 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
Debe tenerse en cuenta que la dirección IP 10.100.88.9 no estará disponible para otras aplicaciones dentro y fuera del clúster de Kubernetes, el acceso al Nginx en ejecución solo será posible desde el propio 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
Además del hecho de que la dirección IP especificada solo es accesible desde el contenedor, tampoco es permanente. Esto significa que si este Pod se recrea, puede obtener una dirección IP diferente.
Para resolver estos problemas, puede usar un objeto llamado Servicio.
Servicios
El servicio le permite asignar direcciones IP permanentes para Pods, proporcionarles acceso desde redes externas y equilibrar solicitudes entre Pods.
Puede obtener más información sobre el Servicio en la documentación oficial .
Por ejemplo, necesitamos eliminar el Pod en ejecución:
$ kubectl delete pod nginx
Agregue a la descripción del Pod una etiqueta (Etiqueta), que se requiere para el Servicio:
También necesitaremos una descripción del servicio:
Crear pod y servicio:
$ 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
Como el Servicio creado es del tipo NodePort, el puerto 30001 indicado por nosotros en todas las interfaces de red se abrirá en todos los nodos del clúster.
Esto significa que si agregamos una dirección IP externa a cualquier nodo, podemos acceder al Pod en ejecución con Nginx desde una red externa.
Para no usar las direcciones externas de los nodos del clúster para acceder al Servicio, podemos usar el tipo LoadBalancer en lugar de NodePort.
Necesitaremos una nueva descripción del servicio:
Elimine el servicio actual y aplique la nueva descripción:
$ kubectl delete service nginx-service $ kubectl create \ -f https://raw.githubusercontent.com/selectel/kubernetes-examples/master/services/nginx-loadbalancer.yaml
Después de iniciar el servicio, Nginx estará disponible en el puerto TCP 80 desde una red externa, y no será necesario asignar y usar direcciones externas para los nodos del clúster. El servicio de tipo LoadBalancer asignará automáticamente una nueva dirección externa a su proyecto VPC y comenzará a usarlo.
Puede obtener información sobre la dirección externa resaltada usando kubectl:
$ kubectl get service nginx-service -o=custom-columns=IP:status.loadBalancer.ingress[0].ip IP xxx.xxx.xxx.xxx
En nuestros ejemplos, solo se lanzó un Pod con Nginx. Para escalar la aplicación a más Pods, podemos usar la implementación.
Implementaciones
La implementación es la esencia del clúster de Kubernetes, que le permite escalar Pods y actualizar o deshacer versiones para una gran cantidad de Pods.
En lugar de Implementación, también puede usar el objeto ReplicaSet, pero no lo tocaremos en nuestros ejemplos.
Puede obtener más información sobre la implementación en la documentación oficial .
Nuevamente necesitaremos eliminar Pod (no necesitamos eliminar el Servicio):
$ kubectl delete pod nginx
Agregue la siguiente descripción de implementación:
Crea la implementación especificada:
$ kubectl create -f \ https://raw.githubusercontent.com/selectel/kubernetes-examples/master/deployments/nginx-1.14.yaml
Elegimos 10 para el parámetro de réplicas, por lo que se crearán 10 Pods con la aplicación Nginx en nuestro clúster:
$ 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
Puede acceder a la aplicación en ejecución desde la red externa utilizando el Servicio creado en la sección anterior. El servicio equilibrará automáticamente las solicitudes de la red externa entre 10 instancias de Nginx.
Si es necesario, podemos actualizar la versión de Nginx. Actualice la descripción de implementación cambiando la versión de la imagen de 1.14-alpine a 1.15-alpine:
Para comenzar el proceso de actualización de Pods, utilizamos el comando kubectl. Preste atención al argumento --grabar, nos es útil para la posterior reversión conveniente de la versión de Nginx:
$ kubectl apply -f \ https://raw.githubusercontent.com/selectel/kubernetes-examples/master/deployments/nginx-1.15.yaml \ --record
Puede controlar el progreso de la actualización con el siguiente comando:
$ kubectl rollout status deployment nginx-deployment Waiting for rollout to finish: 4 out of 10 new replicas have been updated...
Kubernetes esperará 10 segundos después de una actualización exitosa de un Pod, ya que especificamos un valor de 10 para el parámetro minReadySeconds en la descripción de Implementación.
Una vez completada la actualización, todos los Pods para la implementación entrarán en estado activo:
$ kubectl get deployment --selector app=webservice NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 10 10 10 10 23m
Podemos revertir la versión de la aplicación si algo salió mal. Para hacer esto, debemos seleccionar la revisión de implementación deseada:
$ 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
Hay 2 revisiones en la salida del comando: la primera es la creación inicial de la implementación, la segunda es una actualización. Como utilizamos el argumento --record al actualizar, vemos el comando que creó la segunda revisión de Implementación.
Para revertir la versión, use el siguiente comando:
$ kubectl rollout undo deployment nginx-deployment --to-revision=1
De manera similar con la actualización, podemos monitorear la reversión de la versión usando el comando:
$ kubectl rollout status deployment nginx-deployment Waiting for rollout to finish: 6 out of 10 new replicas have been updated…
En todos nuestros ejemplos, utilizamos contenedores sin un almacén de datos persistente. En la siguiente sección lo arreglaremos.
Almacenamiento de datos
Por defecto, todos los datos de los contenedores que se ejecutan dentro de Pods son efímeros y se perderán cuando Pods se bloquee.
Puede usar el objeto PersistentVolumeClaim para ejecutar Pods con un almacén de datos persistente.
Crear un objeto de este tipo en un clúster es muy simple: solo agregue su descripción, similar a la forma en que creamos Pod, Servicio o Implementación en las secciones anteriores.
Se puede encontrar más información en la documentación oficial .
Descripción de ejemplo de PersistentVolumeClaim creando un disco de 10GB:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pv-claim spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi
Podemos conectarlo como un disco a nuestro Pod actualizando la descripción de Pod con Nginx creado anteriormente:
Sin embargo, para que se cree el disco, deberá especificar las propiedades del disco creado en forma de StorageClass. En el servicio "Virtual Private Cloud", puede utilizar unidades de red de tipos rápidos, universales y básicos como almacenamiento permanente de datos de Kubernetes Pod.
Por ejemplo, para crear una StorageClass que le permita usar discos rápidos en la zona de disponibilidad ru-1b, necesita la siguiente descripción:
Antes de crear los objetos especificados, elimine la implementación creada anteriormente:
$ kubectl delete deployment nginx-deployment
En primer lugar, creemos una StorageClass, para que se convierta en la clase predeterminada, y PersistentVolumeClaim creada más tarde la usará:
$ kubectl create -f \ https://raw.githubusercontent.com/selectel/kubernetes-examples/master/storageclasses/fast.ru-1b.yaml
Crear PersistentVolumeClaim y 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
Después de eso, se creará automáticamente un disco en su proyecto que se conectará a uno de los nodos minion del clúster. Cuando cae, el disco cambiará automáticamente a otro nodo.
Podemos ver el disco dentro del contenedor con 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
Puede conectar la unidad a la implementación. Un ejemplo correspondiente se puede encontrar en la documentación oficial .
Panel de control de Kubernetes
Puede usar el tablero incorporado de Kubernetes para ver el estado de los objetos del clúster y su administración.
Para acceder a todas las funciones del panel, deberá crear una cuenta con la función de administrador en su clúster.
Para hacer esto, necesitamos una descripción de la cuenta:
Y descripción del rol:
Crea los objetos especificados:
$ 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
A continuación, deberá averiguar el valor del token generado para esta cuenta.
Para hacer esto, busque el objeto secreto correspondiente en el clúster:
$ kubectl get secret --namespace=kube-system | grep "admin-user-token" admin-user-token-bkfhb kubernetes.io/service-account-token 3 22m
Y mire el valor del token del Secreto encontrado con el nombre admin-user-token-bkfhb:
$ kubectl describe secret admin-user-token-bkfhb --namespace=kube-system | grep "token:" token: XXXXXX...
En respuesta, recibirá el valor del token, guárdelo, nos será útil en el futuro.
Para obtener detalles sobre el control de acceso para los objetos de Kubernetes, consulte la documentación oficial .
En el caso de que haya creado un clúster a partir de una plantilla pública, Pod y Servicio ya existen en él para garantizar el funcionamiento del panel:
$ 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
Dado que el servicio es del tipo ClusterIP, estará disponible solo desde el propio clúster.
Puede acceder al panel desde su computadora en funcionamiento con el archivo de configuración del clúster utilizando el comando kubectl:
$ kubectl proxy Starting to serve on 127.0.0.1:8001
Pruebe el proxy abriendo la dirección especificada en el navegador:

Si ve una respuesta similar a la captura de pantalla, puede ir a la pantalla del panel de control con la siguiente dirección:
http://127.0.0.1:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
Al revisarlo, debería ver la pantalla de inicio de sesión en el panel:

Deberá especificar el token recibido anteriormente. Después de iniciar sesión, puede usar el panel de control:

Puede conocer todas las características del panel de control en la documentación oficial .
Supervisión de objetos de Kubernetes
Si usa la plantilla de clúster público, ejecutará automáticamente los componentes para recopilar y mostrar métricas: Prometheus y Grafana.
De manera similar al panel de control, ClusterIP se instala como el tipo de servicio; el acceso a él solo es posible desde el clúster o mediante el proxy kubectl. Puede acceder a Grafana desde la computadora de su trabajo en la siguiente dirección:
http://127.0.0.1:8001/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana:80

Conclusión
En este artículo, examinamos los objetos de Kubernetes más utilizados y observamos ejemplos de cómo iniciar y administrar un clúster con OpenStack Magnum.
En un futuro cercano, será posible usar las últimas versiones de Kubernetes, y la administración de clústeres estará disponible a través del panel de control .
Estaremos encantados si utiliza nuestro servicio en modo de prueba y proporciona comentarios.