Uso de scripts cloud-init de inicialización personalizados para configurar nodos gestionados

Descubra cómo escribir scripts de cloud-init personalizados para ejecutarlos en nodos de trabajador en clusters que ha creado mediante Container Engine for Kubernetes (OKE).

Cloud-init es el método estándar del sector para la inicialización de instancias en la nube, el aprovisionamiento de sistemas para la infraestructura de nube privada y las instalaciones con hardware dedicado. Está soportado en todos los principales proveedores de nube pública, incluido Oracle Cloud Infrastructure (consulte Datos de usuario). Cloud-init ejecuta scripts para inicializar y configurar instancias. Para obtener más información sobre cloud-init, consulte la documentación de cloud-init.

Container Engine for Kubernetes utiliza cloud-init para configurar las instancias informáticas que alojan nodos gestionados. Container Engine for Kubernetes instala un script de inicio por defecto en cada instancia que aloja un nodo gestionado. Cuando la instancia se inicia por primera vez, cloud-init ejecuta el script de inicio por defecto. El script de inicio por defecto contiene la siguiente lógica proporcionada por Container Engine for Kubernetes:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh

Puede personalizar el script de inicio predeterminado agregando su propia lógica al script, ya sea antes o después de la lógica predeterminada. La personalización de la secuencia de comandos de inicio predeterminada le permite, por ejemplo:

  • Configurar una política SELinux en todos los hosts de nodos de trabajador con fines de seguridad y conformidad
  • anular la asignación de una IP pública efímera de una instancia al inicio y reasignar la instancia a una IP pública reservada en su lugar
  • configurar un proxy corporativo
  • configurar proxies de yum personalizados
  • instalar software antivirus obligatorio y otras herramientas de seguridad

Si personaliza el script de inicio por defecto, no modifique la lógica proporcionada por Container Engine for Kubernetes.

Puede personalizar el script de inicio por defecto al crear un nuevo cluster, crear nuevos pools de nodos y modificar los pools de nodos existentes:

  • uso de la consola (al crear un nuevo cluster, utilice el flujo de trabajo "Creación personalizada")
  • uso de CLI
  • uso de la API

El script de inicio personalizado se ejecuta cuando una instancia que aloja un nodo de trabajador se inicia por primera vez. Después de personalizar el script de inicio por defecto, se recomienda ejecutar el script de Node Doctor para confirmar que los nodos de trabajador de las instancias recién iniciadas funcionan como se esperaba (consulte Solución de problemas de nodos para clusters de Kubernetes mediante el script de Node Doctor).

Ejemplos de casos de uso para scripts personalizados de Cloud-init

Ejemplo 1: Uso de un script cloud-init personalizado para configurar SELinux (Linux mejorado con seguridad) en nodos gestionados

Puede utilizar un script cloud-init personalizado para configurar SELinux en nodos gestionados. SELinux es una mejora de la seguridad de Linux que permite a los administradores restringir qué usuarios y aplicaciones pueden acceder a qué recursos según las reglas de una política. SELinux también agrega mayor granularidad a los controles de acceso.

SELinux puede estar en uno de dos estados, activado o desactivado. Cuando está activado, SELinux se puede ejecutar en uno de dos modos, ya sea forzado o permisivo.

Por defecto, SELinux está activado y definido para ejecutarse en modo permisivo en nodos de trabajador. Cuando se ejecuta en modo permisivo, SELinux no aplica reglas de acceso y solo realiza el registro.

Si desea que SELinux aplique reglas de acceso, puede definirlas para que se ejecuten en modo de aplicación. Al ejecutarse en modo de aplicación, SELinux bloquea las acciones que son contrarias a la política y registra un evento correspondiente en el log de auditoría.

Para definir SELinux para que se ejecute en modo de aplicación, utilice el siguiente script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh
setenforce 1
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config 

Para confirmar el estado y el modo de SELinux que se está ejecutando en un nodo de trabajador, conéctese al nodo de trabajador y utilice el comando getenforce. Cuando el script cloud-init anterior se ha ejecutado en nodos de trabajador, el comando getenforce devuelve Enforcing.

Ejemplo 2: Uso de un script de Cloud-init personalizado para definir NodeLocal DNSCache en nodos gestionados

Puede utilizar un script cloud-init personalizado para configurar NodeLocal DNSCache en nodos gestionados. NodeLocal DNSCache mejora el rendimiento de DNS de cluster mediante la ejecución de un agente de almacenamiento en caché de DNS en nodos de trabajador como un daemonset.

Si NodeLocal DNSCache no está activado, los pods en el modo DNS ClusterFirst se comunican con un serviceIP de kube-dns para consultas DNS. Mediante las reglas de iptables, esta solicitud se convierte en un punto final kube-dns/CoreDNS agregado por kube-proxy. Para obtener más información, consulte DNS para servicios y pods en la documentación de Kubernetes.

Si NodeLocal DNSCache está activado, los pods se comunican con un agente de almacenamiento en caché de DNS que se ejecuta en el mismo nodo de trabajador, lo que les permite omitir las reglas DNAT de iptables y el seguimiento de conexiones. El agente de almacenamiento en caché local consulta el servicio kube-dns/CoreDNS en busca de faltas de caché de los nombres de host del cluster (sufijo cluster.local por defecto).

Para configurar NodeLocal DNSCache, utilice el siguiente script cloud-init. Sustituya CLUSTER DNS por una dirección IP de recepción local que no colisione con nada en el cluster. Hay un rango local de enlace recomendado de 169.254.0.0/16 para IPv4 o del rango de direcciones locales únicas de fd00::/8 para IPv6.

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --cluster-dns "[CLUSTER DNS]"

Para confirmar que NodeLocal DNSCache se ha desplegado correctamente, conéctese a un nodo de trabajador y utilice el comando sudo systemctl status -l kubelet. Cuando el script cloud-init anterior se ha ejecutado en nodos de trabajador, el comando sudo systemctl status -l kubelet devuelve --cluster-dns como uno de los indicadores de kubelet, definido en una dirección de enlace local por defecto (por ejemplo, 169.254.20.10).

Después de crear nodos con el script cloud-init anterior, despliegue el agente de almacenamiento en caché de DNS siguiendo los pasos de Uso de NodeLocal DNSCache en clusters de Kubernetes en la documentación de Kubernetes. Una vez activado, un pod de node-local-dns se ejecuta en el espacio de nombres de kube-system en cada uno de los nodos del cluster. El pod node-local-dns ejecuta CoreDNS en modo de caché, de modo que todas las métricas CoreDNS expuestas por los diferentes plugins están disponibles por nodo.

Para probar la resolución de DNS, utilice uno o más de los siguientes comandos (consulte Depuración de la resolución de DNS en la documentación de Kubernetes). Los comandos deben funcionar y también generar la salida de la dirección IP definida por el indicador --cluster-dns en el script cloud-init personalizado:

kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
kubectl exec -it dnsutils – nslookup kubernetes.default
kubectl exec -it dnsutils – cat /etc/resolv.conf

Puede desactivar NodeLocal DNSCache eliminando el daemonset y suprimiendo el manifiesto nodelocaldns. También debe revertir los cambios realizados en la configuración de kubelet.

Ejemplo 3: Uso de un script cloud-init personalizado para definir kubelet-extra-args en nodos gestionados

Puede utilizar un script cloud-init personalizado para configurar una serie de opciones adicionales en el kubelet (el agente de nodo principal) en los nodos gestionados. Estas opciones adicionales a veces se denominan kubelet-extra-args. Una de estas opciones kubelet-extra-args es la opción para configurar el nivel de detalle del log de nivel de depuración.

Para configurar el nivel de detalle del log de nivel de depuración, utilice el siguiente script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --kubelet-extra-args "--v=4"

Para confirmar la configuración del nivel de detalle del log de nivel de depuración, conéctese a un nodo de trabajador y utilice el comando sudo systemctl status -l kubelet. Cuando el script cloud-init anterior se ha ejecutado en nodos de trabajador, el comando sudo systemctl status -l kubelet devuelve el nivel de detalle como 4. Los logs de kubelet también contienen más detalles.

Ejemplo 4: Uso de un script cloud-init personalizado para reservar recursos para Kubernetes y daemons del sistema operativo

Puede utilizar un script cloud-init personalizado para reservar recursos de CPU y memoria para los daemons del sistema Kubernetes (como kubelet y container runtime) y los daemons del sistema operativo (como sshd y systemd). Para reservar recursos para los daemons del sistema operativo y Kubernetes, incluya los indicadores de kubelet --kube-reserved y --system-reserved, respectivamente, como opciones kubelet-extra-args en un script cloud-init personalizado.

Para reservar recursos para los daemons del sistema operativo y Kubernetes, utilice el siguiente script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --kubelet-extra-args "--kube-reserved=cpu=500m,memory=1Gi --system-reserved=cpu=100m,memory=100Mi"

Para obtener más información y conocer los valores recomendados para los indicadores de kubelet --kube-reserved y --system-reserved, consulte Mejores prácticas: reserva de recursos para daemons del sistema operativo y Kubernetes.

Ejemplo 5: uso de una secuencia de comandos cloud-init personalizada y oci-growfs para aumentar el tamaño de la partición de volumen de inicio

Puede utilizar un script cloud-init personalizado para ampliar la partición del volumen de inicio de los nodos gestionados. Al crear y actualizar clusters y pools de nodos, puede especificar un tamaño personalizado para los volúmenes de inicio de nodos de trabajador. El tamaño del volumen de inicio personalizado que especifique debe ser mayor que el tamaño del volumen de inicio predeterminado de la imagen que seleccione. Al aumentar el tamaño del volumen de inicio, para aprovechar el mayor tamaño del volumen de inicio, también debe ampliar la partición del volumen de inicio.

Las imágenes de la plataforma Oracle Linux incluyen el paquete oci-utils. Puede utilizar el comando oci-growfs de ese paquete en una secuencia de comandos cloud-init para ampliar la partición raíz y, a continuación, aumentar el tamaño del sistema de archivos.

Para ampliar la partición del volumen de inicio, utilice el siguiente script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh
bash /usr/libexec/oci-growfs -y

Para obtener más información, consulte Ampliación de la partición para un volumen de inicio.

Creación de un script cloud-init personalizado

Para personalizar el script de inicio cloud-init por defecto que proporciona Container Engine for Kubernetes:

  1. Cree un nuevo archivo de script que contenga la lógica por defecto que proporciona Container Engine for Kubernetes. Puede hacerlo de dos formas:
    • Mediante la selección de la opción Descargar plantilla de script de Cloud-Init personalizada (en la sección Opciones avanzadas del pool de nodos) al utilizar el cuadro de diálogo Crear cluster personalizado, Agregar pool de nodos o Editar pool de nodos. El archivo que descarga contiene la lógica predeterminada.
    • Creando un nuevo archivo desde cero con un tipo de archivo soportado por cloud-init (como .yaml) y agregando la lógica por defecto que proporciona Container Engine for Kubernetes. Por ejemplo:
      #!/bin/bash
      curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
      bash /var/run/oke-init.sh
  2. Antes o después de la lógica por defecto proporcionada por Container Engine for Kubernetes, agregue su propia lógica personalizada al archivo de script. No modifique la lógica predeterminada.

    Por ejemplo, para configurar el nivel de detalle del log de nivel de depuración, puede agregar --kubelet-extra-args "--v=4" para que el archivo tenga el siguiente aspecto:

    #!/bin/bash
    curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
    bash /var/run/oke-init.sh --kubelet-extra-args "--v=4"

    Para ver otros ejemplos, consulte Ejemplos de scripts personalizados de Cloud-init.

  3. Guarde el archivo de script cloud-init personalizado que ha creado.
  4. Especifique el archivo de script cloud-init personalizado al crear un nuevo cluster, agregar un nuevo pool de nodos o modificar un pool de nodos existente:

Uso de la consola

Para utilizar la consola para proporcionar un script cloud-init personalizado para instancias que alojan nodos gestionados en un nuevo cluster, un nuevo pool de nodos o un pool de nodos existente:

  1. Cree un archivo cloud-init válido, en uno de los formatos (por ejemplo, cloud-config) y tipos de archivo (por ejemplo, un archivo .yaml) admitidos por cloud-init. Consulte Creación de un script de Cloud-init personalizado.
  2. Abra el menú de navegación y haga clic en Servicios para desarrolladores. En Contenedores y artefactos, haga clic en Clusters de Kubernetes (OKE).
  3. Seleccione un compartimento en el que tenga permiso para trabajar.
  4. Cree un nuevo cluster mediante el flujo de trabajo "Creación personalizada", agregue un nuevo pool de nodos a un cluster existente o modifique un pool de nodos existente.
  5. En la sección Opciones Avanzadas del pool de nodos del cuadro de diálogo Crear Cluster Personalizado, Agregar Pool de Nodos o Editar Pool de Nodos (según corresponda), especifique:
    • Script de inicialización: (opcional) script de cloud-init que se ejecuta en cada instancia que aloja nodos de trabajador cuando la instancia se inicia por primera vez. El script que especifique debe estar escrito en uno de los formatos admitidos por cloud-init (por ejemplo, cloud-config) y debe ser un tipo de archivo admitido (por ejemplo, .yaml). Especifique el script de la siguiente forma:
      • Seleccionar script Cloud-Init: seleccione un archivo que contenga el script cloud-init o arrastre y suelte el archivo en el cuadro.
      • Pegar script Cloud-Init: copie el contenido de un script cloud-init y péguelo en el cuadro.

      Si no ha escrito previamente scripts cloud-init para inicializar nodos de trabajador en clusters creados por Container Engine for Kubernetes, puede que le resulte útil hacer clic en Descargar plantilla de script cloud-Init personalizada. El archivo descargado contiene la lógica por defecto proporcionada por Container Engine for Kubernetes. Puede agregar su propia lógica personalizada antes o después de la lógica por defecto, pero no modifique la lógica por defecto. Para ver ejemplos, consulte Ejemplos de scripts personalizados de Cloud-init.

Uso de la CLI

Para obtener información sobre el uso de la CLI, consulte Interfaz de línea de comandos (CLI). Para obtener una lista completa de los indicadores y las opciones disponibles para los comandos de la CLI, consulte Referencia de la línea de comandos.

Para utilizar CLI para proporcionar un script cloud-init personalizado para las instancias que alojan nodos de trabajador en un nuevo pool de nodos o en un pool de nodos existente:

  1. Cree un archivo cloud-init válido, en uno de los formatos (por ejemplo, cloud-config) y tipos de archivo (por ejemplo, un archivo .yaml) admitidos por cloud-init. Consulte Creación de un script de Cloud-init personalizado.
  2. Abra un símbolo del sistema e introduzca uno de los siguientes comandos para crear un nuevo pool de nodos o actualizar un pool de nodos existente, según corresponda:
    • oci ce node-pool create
    • oci ce node-pool update
  3. Además de los parámetros obligatorios requeridos por el comando que está utilizando:
    1. Incluya el parámetro --node-image-id, incluso si no desea especificar una imagen personalizada.
    2. Incluya el parámetro opcional --node-metadata en el formato:
      --node-metadata '{"user_data": "'$(cat <cloud-init-file> | base64)'"}'
      donde:
      • <cloud-init-file> es el nombre del archivo cloud-init que ha creado
      • base64 especifica que el archivo va a estar codificado en base64

      Por ejemplo:

      --node-metadata '{"user_data": "'$(cat my-custom-cloud-init.yaml | base64)'"}'

Ejemplo

Este comando de ejemplo crea un nuevo pool de nodos denominado my-cloud-init-test-nodepool para un cluster existente, con un único nodo de Kubernetes 1.18.10 que tiene una unidad de VM 2.1 que ejecuta Oracle Linux. Cuando la instancia que aloja el nodo de trabajador en el nuevo pool de nodos se inicie por primera vez, se ejecutará un script cloud-init personalizado denominado my-custom-cloud-init.yaml:

oci ce node-pool create \
--cluster-id ocid1.cluster.oc1.iad.aaaa______m4w \
--name my-cloud-init-test-nodepool \
--node-image-id ocid1.image.oc1.iad.aaaa______zpq \
--compartment-id ocid1.tenancy.oc1..aaa______q4a \
--kubernetes-version v1.18.10 \
--node-shape VM.Standard2.1 \
--placement-configs "[   { \"availabilityDomain\": \"PKGK:US-ASHBURN-AD-1\", \"subnetId\": \"ocid1.subnet.oc1.iad.aaaa______kfa\"   }   ]" \
--size 1 \
--region us-ashburn-1 \
--node-metadata '{"user_data": "'$(cat my-custom-cloud-init.yaml | base64)'"}'