En nuestro nuevo artículo traducido, ofrecemos una descripción general rápida de la nueva distribución de Kubernetes. Esperamos que el artículo sea de interés para los lectores de Habr.
Hace un par de días, un amigo me contó sobre una nueva distribución de Kubernetes de Mirantis llamada k0s . Todos conocemos y amamos los K8, ¿verdad? También nos cautivó K3s , un Kubernetes ligero desarrollado por Rancher Labs y entregado a CNCF hace algún tiempo. ¡Es hora de descubrir la nueva distribución de k0s!
Después de una breve introducción a k0s, crearemos un clúster de tres nodos siguiendo estos pasos:
- Preparando tres máquinas virtuales ( Multipass en acción)
- Instalando k0s en cada uno de ellos
- Configuración de un archivo de configuración de clúster k0s simple
- Inicialización del clúster
- Obtener acceso al clúster
- Agregar nodos trabajadores
- Agregar usuario
¿Qué es k0s?
k0s es la distribución de Kubernetes más nueva. La versión actual es 0.8.0. Se publicó en diciembre de 2020, y el primer compromiso de todo el proyecto ocurrió en junio de 2020.
k0s se envía como un único binario sin dependencias del sistema operativo. Por lo tanto, se define como una distribución de Kubernetes con características de cero fricción / cero deps / costo cero (facilidad de configuración / sin dependencias / gratis).
Última versión de k0s:
- Ofrece certificado (certificado por Internet Security Center) Kubernetes 1.19
- Utiliza containerd como tiempo de ejecución de contenedor predeterminado
- Admite arquitecturas Intel (x86-64) y ARM (ARM64)
- Utiliza intra- cluster etcd
- Utiliza el complemento de red Calico de forma predeterminada (activando así las políticas de red)
- Incluye controlador de acceso a la política de seguridad de pod
- Utiliza DNS con CoreDNS
- Proporciona métricas de clúster a través de Metrics Server
- Habilita la escala automática de pod horizontal (HPA).
En futuras versiones vendrán muchas características interesantes, que incluyen:
- Tiempo de ejecución de máquina virtual compacta (tengo muchas ganas de probar esta función)
- Actualización de clúster sin tiempo de inactividad
- Copia de seguridad y recuperación de clústeres
Impresionante, ¿no? A continuación, veremos cómo usar k0s para implementar un clúster de 3 nodos.
Preparando máquinas virtuales
Para empezar, crearemos tres máquinas virtuales, cada una de las cuales será un nodo en nuestro clúster. En este artículo, tomaré un camino rápido y fácil y usaré la excelente herramienta Multipass (me encanta) para preparar máquinas virtuales locales en MacOS.
Los siguientes comandos crean tres instancias de Ubuntu en xhyve. Cada máquina virtual tiene 5 GB de disco, 2 GB de RAM y 2 procesadores virtuales (vCPU):
for i in 1 2 3; do multipass launch -n node$i -c 2 -m 2G done
Luego podemos mostrar una lista de máquinas virtuales para asegurarnos de que todas funcionen correctamente:
$ multipass list Name State IPv4 Image node1 Running 192.168.64.11 Ubuntu 20.04 LTS node2 Running 192.168.64.12 Ubuntu 20.04 LTS node3 Running 192.168.64.13 Ubuntu 20.04 LTS
A continuación, instalaremos k0s en cada uno de estos nodos.
Instalación de la última versión de k0s
La última versión de k0s se puede descargar del repositorio de GitHub .
Tiene un conveniente script de instalación:
curl -sSLf get.k0s.sh | sudo sh
Usamos este script para instalar k0s en todos nuestros nodos:
for i in 1 2 3; do multipass exec node$i --bash -c "curl -sSLf get.k0s.sh | sudo sh" done
El script anterior instala k0s en / user / bin / k0 . Para obtener todos los comandos disponibles, debe ejecutar el binario sin argumentos.
Comandos k0s disponibles Podemos
comprobar la versión actual:
$ k0s version v0.8.0
Usaremos algunos de los comandos en los siguientes pasos.
Creando un archivo de configuración
Primero, debe definir un archivo de configuración que contenga la información que k0s necesita para crear un clúster. En el nodo1, podemos ejecutar el comando default-config para obtener la configuración predeterminada completa. Entre otras cosas, esto nos permite determinar:
ubuntu@node1:~$ k0s default-config
apiVersion: k0s.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: k0s
spec:
api:
address: 192.168.64.11
sans:
- 192.168.64.11
- 192.168.64.11
extraArgs: {}
controllerManager:
extraArgs: {}
scheduler:
extraArgs: {}
storage:
type: etcd
kine: null
etcd:
peerAddress: 192.168.64.11
network:
podCIDR: 10.244.0.0/16
serviceCIDR: 10.96.0.0/12
provider: calico
calico:
mode: vxlan
vxlanPort: 4789
vxlanVNI: 4096
mtu: 1450
wireguard: false
podSecurityPolicy:
defaultPolicy: 00-k0s-privileged
workerProfiles: []
extensions: null
images:
konnectivity:
image: us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent
version: v0.0.13
metricsserver:
image: gcr.io/k8s-staging-metrics-server/metrics-server
version: v0.3.7
kubeproxy:
image: k8s.gcr.io/kube-proxy
version: v1.19.4
coredns:
image: docker.io/coredns/coredns
version: 1.7.0
calico:
cni:
image: calico/cni
version: v3.16.2
flexvolume:
image: calico/pod2daemon-flexvol
version: v3.16.2
node:
image: calico/node
version: v3.16.2
kubecontrollers:
image: calico/kube-controllers
version: v3.16.2
repository: ""
telemetry:
interval: 10m0s
enabled: true
- Opciones de lanzamiento del servidor API, el administrador del controlador y el programador
- Almacenamiento que se puede utilizar para almacenar información del clúster ( etcd )
- Complemento de red y su configuración ( Calico )
- Versión de imágenes de contenedor con componentes de gestión
- Algunos esquemas de administración adicionales para implementar al iniciar un clúster
Podríamos guardar esta configuración en un archivo y adaptarla a nuestras necesidades. Pero para este artículo, usaremos una configuración muy simple y la guardaremos en /etc/k0s/k0s.yaml . Nota : Puesto que estamos inicializando el clúster en el nodo 1 , este nodo servirá el servidor API. La dirección IP de este nodo se utiliza en api.address y api.sans (nombres alternativos del sujeto) en el archivo de configuración anterior. Si tuviéramos nodos maestros adicionales y un balanceador de carga encima de ellos, también usaríamos api.sans en la configuración
apiVersion: k0s.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: k0s
spec:
api:
address: 192.168.64.11
sans:
- 192.168.64.11
network:
podCIDR: 10.244.0.0/16
serviceCIDR: 10.96.0.0/12
La dirección IP de cada host y equilibrador de carga (o el nombre de dominio correspondiente).
Inicialización del clúster
Primero, creamos una unidad systemd en node1 para administrar k0s.
[Unit] Description="k0s server" After=network-online.target Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/k0s server -c /etc/k0s/k0s.yaml --enable-worker Restart=always
El comando principal se enumera aquí en ExecStart ; inicia el servidor k0s con la configuración que guardamos en nuestro archivo en el paso anterior. También especificamos el parámetro --enable-worker para que este primer nodo maestro también funcione como trabajador.
Luego copiamos este archivo a /lib/systemd/system/k0s.service , reiniciamos systemd e iniciamos el servicio recién creado.
ubuntu@node1:~$ sudo systemctl daemon-reload ubuntu@node1:~$ sudo systemctl start k0s.service
Por curiosidad, puede consultar los procesos iniciados por el servidor k0s:
ubuntu@node1:~$ sudo ps aux | awk ‘{print $11}’ | grep k0s /usr/bin/k0s /var/lib/k0s/bin/etcd /var/lib/k0s/bin/konnectivity-server /var/lib/k0s/bin/kube-controller-manager /var/lib/k0s/bin/kube-scheduler /var/lib/k0s/bin/kube-apiserver /var/lib/k0s/bin/containerd /var/lib/k0s/bin/kubelet
En el resultado anterior, podemos ver que todos los componentes principales se están ejecutando ( kube-apiserver , kube-controller-manager , kube-Scheduler , etc.), así como componentes comunes a los nodos maestro y trabajador ( containerd , kubelet ). k0s es responsable de administrar todos estos componentes.
Ahora tenemos un clúster de 1 nodo. En el siguiente paso veremos cómo acceder a él.
Obtener acceso al clúster
Primero, necesitamos obtener el archivo kubeconfig generado durante la creación del clúster; fue creado en el nodo1 en /var/lib/k0s/pki/admin.conf . Este archivo debe usarse para configurar kubectl en la máquina local.
Primero, obtenemos el kubeconfig del clúster del nodo1 :
# Get kubeconfig file $ multipass exec node1 cat /var/lib/k0s/pki/admin.conf > k0s.cfg
A continuación, reemplazamos la dirección IP interna con la dirección IP externa node1 :
# Replace IP address $ NODE1_IP=$(multipass info node1 | grep IP | awk '{print $2}') sed -i '' "s/localhost/$NODE1_IP/" k0s.cfg
Luego configuramos nuestro cliente kubectl local para comunicarse con el servidor API k0s:
export KUBECONFIG=$PWD/k0s.cfg
Seguramente uno de los primeros comandos que ejecutamos al ingresar a un nuevo clúster es el que muestra una lista de todos los nodos disponibles; intentemos:
$ kubectl get no NAME STATUS ROLES AGE VERSION node1 Ready <none> 78s v1.19.4
Aquí no hay nada sorprendente. Después de todo, node1 no es solo el nodo principal, sino también el nodo de trabajo de nuestro primer clúster gracias a la bandera --enable-worker , que especificamos en el comando de inicio. Sin esta bandera, el nodo1 solo estaría funcionando y no aparecería en la lista de nodos aquí.
Agregar nodos trabajadores
Para agregar el nodo 2 y nodo3 al clúster , que primero tiene que crear una conexión token del nodo 1 (este es un paso bastante común ya que se utiliza en racimos acoplable Swarm y Kubernetes creados con kubeadm).
$ TOKEN=$(k0s token create --role=worker)
El comando anterior genera un token largo (muy largo). Gracias a él, podemos unir el nodo 2 y nodo3 al clúster :
ubuntu@node2:~$ k0s worker $TOKEN ubuntu@node3:~$ k0s worker $TOKEN
Nota: En un clúster real, usaríamos systemd (u otro supervisor) para administrar los procesos k0s para los nodos trabajadores, como hicimos para el nodo maestro.
Nuestro clúster de tres nodos está en funcionamiento, como podemos verificar mostrando la lista de nodos y enumerando los nodos nuevamente:
$ kubectl get no NAME STATUS ROLES AGE VERSION node1 Ready <none> 30m v1.19.4 node2 Ready <none> 35s v1.19.4 node3 Ready <none> 32s v1.19.4
También podemos comprobar los pods que se ejecutan en todos los espacios de nombres:
Lista de pods que se ejecutan en el clúster en todos los espacios de nombres
Hay algunas cosas a tener en cuenta aquí:
- Como de costumbre, vemos los pods de kube -proxy , los pods de complementos de red (basados en Calico) y también los pods de CoreDNS.
- api-server, scheduler controller-manager , , .
La versión 0.8.0 de K0s contiene el subcomando de usuario . Esto le permite crear un kubeconfig para un usuario / grupo adicional. Por ejemplo, el siguiente comando crea un archivo kubeconfig llamado demo para un nuevo usuario , que se encuentra dentro de un grupo imaginario llamado desarrollo .
Nota: En Kubernetes, los usuarios y grupos son administrados por un administrador fuera del clúster, lo que significa que no hay un recurso de usuario no grupo en K8.
$ sudo k0s user create demo --groups development > demo.kubeconfig
Para una mejor comprensión, extraeremos el certificado de cliente de este archivo kubeconfig y lo decodificaremos de la representación base64:
$ cat demo.kubeconfig | grep client-certificate-data | awk '{print $2}' | base64 --decode > demo.crt
Luego usamos el comando openssl para obtener el contenido del certificado:
ubuntu@node1:~$ openssl x509 -in demo.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
71:8b:a4:4d:be:76:70:8a:...:07:60:67:c1:2d:51:94
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = kubernetes-ca
Validity
Not Before: Dec 2 13:50:00 2020 GMT
Not After : Dec 2 13:50:00 2021 GMT
Subject: O = development, CN = demo
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:be:87:dd:15:46:91:98:eb:b8:38:34:77:a4:99:
da:4b:d6:ca:09:92:f3:29:28:2d:db:7a:0b:9f:91:
65:f3:11:bb:6c:88:b1:8f:46:6e:38:71:97:b7:b5:
9b:8d:32:86:1f:0b:f8:4e:57:4f:1c:5f:9f:c5:ee:
40:23:80:99:a1:77:30:a3:46:c1:5b:3e:1c:fa:5c:
- La propiedad del emisor es kubernetes-ca , que es la CA de nuestro clúster k0s.
- El tema es O = desarrollo, CN = demostración ; esta parte es importante ya que aquí es donde entra el nombre del usuario y el grupo. Dado que el certificado está firmado por la CA del clúster, el complemento en el api-server puede autenticar al usuario / grupo por el nombre común (CN) y la organización (O) en el asunto del certificado.
Primero, le indicamos a kubectl que use el contexto definido en este nuevo archivo kubeconfig :
$ export KUBECONFIG=$PWD/demo.kubeconfig
Luego, una vez más, mostramos la lista de nodos y enumeramos los nodos del clúster:
$ kubectl get no Error from server (Forbidden): nodes is forbidden: User “demo” cannot list resource “nodes” in API group “” at the cluster scope
Se esperaba este mensaje de error. Incluso si
api-server
el usuario está identificado (el certificado enviado con la solicitud del usuario fue firmado por la CA del clúster), no se le permite realizar ninguna acción en el clúster.
Se pueden agregar fácilmente permisos adicionales al crearlos
Role/ClusterRole
y asignarlos a un usuario con
RoleBinding/ClusterRoleBinding
, pero dejo esta tarea como un ejercicio para el lector.
Conclusión
k0s definitivamente vale la pena considerarlo. Este enfoque, cuando un solo archivo binario gestiona todos los procesos, es muy interesante.
Este artículo proporciona solo una breve descripción general de k0s, pero definitivamente seguiré su desarrollo y dedicaré artículos futuros a esta nueva y prometedora distribución de Kubernetes. Algunas de las funciones futuras parecen realmente prometedoras y espero probarlas.