¡Hola! Mi nombre es Sergey, soy DevOps en Surf. El departamento de DevOps en Surf tiene como objetivo no solo establecer la interacción entre especialistas e integrar los flujos de trabajo, sino también llevar a cabo investigaciones activas e implementar tecnologías actuales tanto en nuestra propia infraestructura como en la infraestructura del cliente.
A continuación, hablaré un poco sobre los cambios en el stack tecnológico para contenedores que encontramos al estudiar la distribución CentOS 8 y sobre qué es CRI-O y cómo configurar rápidamente un entorno de ejecución para Kubernetes.

Por qué Docker no está incluido en la instalación estándar de CentOS 8
Después de instalar las últimas versiones importantes RHEL 8 o CentOS 8 no se puede pasar por alto: en estas distribuciones y repositorios oficiales falta la aplicación Docker, que ideológicamente y funcionalmente son reemplazados por los paquetes Podman, Buildah (presentes por defecto en la distribución) y CRI-O. Esto está relacionado con la implementación práctica de estándares desarrollados, entre otros, por Red Hat en el marco del proyecto Open Container Initiative (OCI).
El objetivo de OCI, que es parte de The Linux Foundation, es crear estándares industriales abiertos para formatos y entornos de ejecución de contenedores que aborden varias tareas simultáneamente. Primero, no contradicen la filosofía de Linux (por ejemplo, en la parte donde cada programa debe realizar una única acción, mientras que Docker es una especie de multipropósito todo-en-uno). En segundo lugar, podrían eliminar todos los defectos existentes en el software Docker. En tercer lugar, serían completamente compatibles con los requisitos comerciales planteados por las principales plataformas comerciales para el despliegue, gestión y mantenimiento de aplicaciones en contenedores (por ejemplo, Red Hat OpenShift).
Desventajas Docker y las ventajas del nuevo software ya se han descrito bastante detalladamente en , y se puede obtener una descripción detallada de todo lo que se ofrece en el marco del proyecto OCI y sus características arquitectónicas en la documentación oficial y artículos tanto de Red Hat (buena en el blog de Red Hat), como en reseñas de terceros .
Es importante señalar qué funcionalidad tienen los componentes del stack propuesto:
- Podman — interacción directa con los contenedores y almacenamiento de imágenes a través del proceso runC;
- Buildah — construcción y carga de imágenes en el registro;
- CRI-O — entorno de ejecución para sistemas de orquestación de contenedores (por ejemplo, Kubernetes).
Creo que sería útil proporcionar aquí un esquema de las relaciones para entender el esquema general de interacción entre los componentes de la pila. Kubernetes c runC y bibliotecas de bajo nivel utilizando CRI-O:

CRI-O y Kubernetes siguen un ciclo de lanzamiento y soporte similar (la matriz de compatibilidad es muy simple: las versiones principales Kubernetes y CRI-O coinciden), y esto, considerando el enfoque en pruebas completas y exhaustivas del funcionamiento de esta pila por parte de los desarrolladores, nos da derecho a esperar la máxima estabilidad posible en su operación en cualquier escenario de uso (aquí también favorece la relativa ligereza CRI-O en comparación con Docker debido a la limitación intencionada de la funcionalidad).
Al instalar Kubernetes de la forma 'correcta' (según OCI, por supuesto) utilizando CRI-O en CentOS 8 tuvimos algunas dificultades menores, que, sin embargo, superamos con éxito. Estaré encantado de compartir con usted una guía de instalación y configuración, que en conjunto tomará solo 10 minutos.
Cómo implementar Kubernetes en CentOS 8 utilizando el entorno CRI-O
Requisitos previos: al menos un host (2 núcleos, 4 GB de RAM, almacenamiento de al menos 15 GB) con CentOS 8 (se recomienda el perfil de instalación 'Servidor'), así como una entrada correspondiente en el DNS local (en último caso, se puede utilizar una entrada en /etc/hosts). Y no olvides .
Todas las operaciones en el host se realizan bajo el usuario root, ten cuidado.
- En el primer paso configuraremos el SO, instalaremos y configuraremos las dependencias preliminares para CRI-O.
- Actualizaremos el SO:
dnf -y update
- A continuación, es necesario configurar el firewall y SELinux. Aquí dependerá de la configuración en la que nuestro host o hosts funcionarán. Puedes configurar el firewall según las recomendaciones de , o, si estás en una red confiable o utilizas un firewall externo, cambiar la zona predeterminada a confiable o desactivar el firewall:
firewall-cmd --set-default-zone trusted firewall-cmd --reloadPara desactivar el firewall, se puede usar el siguiente comando:
systemctl disable --now firewalldSELinux debe ser desactivado o puesto en modo 'permisivo':
setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
- cargaremos los módulos del núcleo y paquetes necesarios, configuraremos la carga automática del módulo 'br_netfilter' al iniciar el sistema:
modprobe overlay modprobe br_netfilter echo "br_netfilter" >> /etc/modules-load.d/br_netfilter.conf dnf -y install iproute-tc
- Para activar el reenvío de paquetes y procesar correctamente el tráfico, haremos las configuraciones correspondientes:
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 EOFAplicaremos las configuraciones realizadas:
sysctl --system
- Estableceremos la versión necesaria CRI-O (versión mayor CRI-O, como se mencionó anteriormente, coincide con la versión requerida Kubernetes), ya que la última versión estable Kubernetes en este momento es 1.18:
export REQUIRED_VERSION=1.18Agregaremos los repositorios necesarios:
dnf -y install 'dnf-command(copr)' dnf -y copr enable rhcontainerbot/container-selinux curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/CentOS_8/devel:kubic:libcontainers:stable.repo curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION/CentOS_8/devel:kubic:libcontainers:stable:cri-o:$REQUIRED_VERSION.repo
- Ahora podemos instalar CRI-O:
dnf -y install cri-oPresta atención al primer detalle que encontramos durante el proceso de instalación: es necesario editar la configuración CRI-O antes de iniciar el servicio, ya que el componente requerido conmon tiene una ubicación diferente a la indicada:
sed -i 's//usr/libexec/crio/conmon//usr/bin/conmon/' /etc/crio/crio.confAhora se puede activar y ejecutar el demonio CRI-O:
systemctl enable --now crioSe puede verificar el estado del demonio:
systemctl status crio
- Actualizaremos el SO:
- Instalación y activación Kubernetes.
- Añadiremos el repositorio requerido:
cat < /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl EOFAhora podemos instalar Kubernetes (versiones 1.18, como se mencionó anteriormente):
dnf install -y kubelet-1.18* kubeadm-1.18* kubectl-1.18* --disableexcludes=kubernetes
- Un segundo detalle importante: dado que no estamos usando el demonio Docker, sino que estamos usando el demonio CRI-O, antes de iniciar e inicializar Kubernetes es necesario realizar las configuraciones correspondientes en el archivo de configuración /var/lib/kubelet/config.yaml, creando previamente el directorio necesario:
mkdir /var/lib/kubelet cat < /var/lib/kubelet/config.yaml apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration cgroupDriver: systemd EOF
- Un tercer punto importante que encontramos durante la instalación: a pesar de que hemos indicado el controlador que se utilizará cgroup, y su configuración a través de argumentos enviados kubelet está obsoleta (lo cual está indicado claramente en la documentación), debemos agregar argumentos en el archivo, de lo contrario nuestro clúster no se inicializará:
cat /dev/null > /etc/sysconfig/kubelet cat < /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS=--container-runtime=remote --cgroup-driver=systemd --container-runtime-endpoint='unix:///var/run/crio/crio.sock' EOF
- Ahora podemos activar el demonio kubelet:
sudo systemctl enable --now kubeletPara configurar control-plane o worker nodos en unos pocos minutos, puede utilizar .
- Añadiremos el repositorio requerido:
- Es hora de inicializar nuestro clúster.
- Para inicializar el clúster, ejecute el comando:
kubeadm init --pod-network-cidr=10.244.0.0/16Asegúrese de anotar el comando para unirse al clúster 'kubeadm join ...', que se sugiere utilizar al final de la salida, o al menos los tokens indicados.
- Instalemos el complemento (CNI) para trabajar con la red de Pods. Recomiendo utilizar Calico. Es posible que el más popular Flannel tenga problemas de compatibilidad con nftables, y además Calico es la única implementación de CNI recomendada y completamente probada por el proyecto Kubernetes:
kubectl --kubeconfig /etc/kubernetes/admin.conf apply -f https://docs.projectcalico.org/v3.15/manifests/calico.yaml
- Para conectar el nodo worker a nuestro clúster, necesita configurarlo según los puntos de las instrucciones 1 y 2, o utilizar , luego ejecute el comando de la salida 'kubeadm init ...', que anotamos en la etapa anterior:
kubeadm join $CONTROL_PLANE_ADDRESS:6443 --token $TOKEN --discovery-token-ca-cert-hash $TOKEN_HASH
- Verificaremos que nuestro clúster se ha inicializado y ha comenzado a funcionar:
kubectl --kubeconfig=/etc/kubernetes/admin.conf get pods -A
¡Listo! Ya puede desplegar carga de trabajo en su clúster de K8s.
- Para inicializar el clúster, ejecute el comando:
Qué nos espera por delante
Espero que la guía anterior le haya ahorrado algo de tiempo y nervios.
El resultado de los procesos en la industria a menudo depende de cómo lo aceptan la mayoría de los usuarios finales y desarrolladores de otro software en el nicho correspondiente. Aún no está claro a qué resultado conducirán en unos años las iniciativas de OCI, pero estaremos encantados de seguir esto. Puede compartir su opinión ahora mismo en los comentarios.
¡Estén atentos!
Este artículo ha aparecido gracias a las siguientes fuentes:
- Sección sobre Container runtimes en
- del proyecto CRI-O en Internet
- Artículos en blogs de Red Hat: , y muchos otros
Fuente: habr.com
