Tutorial

Pasos recomendados para proteger un clúster de Kubernetes de DigitalOcean

SecurityKubernetesDigitalOcean Managed Kubernetes

El autor seleccionó Open Sourcing Mental Illness para recibir una donación como parte del programa Write for DOnations.

Introducción

Kubernetes, la plataforma de orquestación de contenedores de código abierto, se está convirtiendo en la solución preferida para automatizar, escalar y administrar clústeres de alta disponibilidad. Como resultado de su creciente popularidad, la seguridad en ella se ha vuelto cada vez más relevante.

Tomando en cuenta los elementos móviles que intervienen en Kubernetes y la variedad de escenarios de implementación, proteger Kubernetes a veces puede ser un proceso complejo. Debido a esto, el objetivo de este artículo es proporcionar una base de seguridad sólida para un clúster de Kubernetes de DigitalOcean (DOKS). Tenga en cuenta que este tutorial contempla las medidas básicas de seguridad para Kubernetes y está pensado para ser un punto de partida más que una guía exhaustiva. Para hallar pasos adicionales, consulte la documentación oficial de Kubernetes.

A través de esta guía, completará pasos básicos para proteger su clúster de Kubernetes de DigitalOcean. Configurará la autenticación local segura con certificados TLS y SSL, concederá permisos a los usuarios locales con controles de acceso basados en roles (RBAC), concederá permisos a aplicaciones e implementaciones de Kubernetes con cuentas de servicio y establecerá límites de recursos con los controladores de admisión ResourceQuota y LimitRange.

Requisitos previos

Para completar este tutorial, necesitará lo siguiente:

  • Un clúster administrado por DigitalOcean de Kubernetes (DOKS) con 3 nodos estándares configurados cada uno con al menos 2 GB de RAM y 1 vCPU. Para hallar instrucciones detalladas sobre cómo crear un clúster DOKS, consulte nuestra guía de inicio rápido de Kubernetes. En este tutorial se utiliza DOKS 1.16.2-do.1.
  • Un cliente local configurado para administrar el clúster DOKS, con un archivo de configuración de clúster descargado del panel de control de DigitalOcean y guardado como ~/.kube/config. Para hallar instrucciones detalladas sobre cómo configurar la administración remota de DOKS, lea nuestra guía Cómo establecer conexión con un clúster de Kubernetes de DigitalOcean. En particular, necesitará lo siguiente:
    • La interfaz de línea de comandos kubectl instalada en su computadora local. Puede obtener más información sobre cómo instalar y configurar kubectl en su documentación oficial. En este tutorial, usaremos la versión 1.17.0-00 de kubectl.
    • La herramienta de línea de comandos oficial de DigitalOcean, doctl. Para hallar instrucciones sobre cómo instalar esto, consulte la página sobre doctl de GitHub. En este tutorial, se usará la versión 1.36.0 de doctl.

Paso 1: Habilitar la autenticación remota de usuarios

Una vez completados los requisitos previos, obtendrá un superusuario de Kubernetes que se autentica a través de un token de portador de DigitalOcean predefinido. Sin embargo, compartir esas credenciales no es una práctica de seguridad recomendada, ya que en esta cuenta se pueden ocasionar cambios a gran escala y posiblemente destructivos para su clúster. Para reducir esta posibilidad, puede configurar usuarios adicionales que se autentiquen desde sus respectivos clientes locales.

En esta sección, autenticará nuevos usuarios en el clúster DOKS remoto de los clientes locales usando certificados SSL y TLS seguros. Será un proceso de tres pasos: primero, creará solicitudes de firma de certificados (CSR) para cada usuario. Luego, aprobará esos certificados directamente en el clúster a través de kubectl. Por último, creará para cada usuario un archivo kubeconfig con los certificados correspondientes. Para obtener más información sobre los métodos de autenticación adicionales compatibles con Kubernetes, consulte la documentación de autenticación de Kubernetes.

Crear solicitudes de firma de certificados para nuevos usuarios

Antes de comenzar, compruebe la conexión del clúster DOKS desde la máquina local configurada en los requisitos previos:

  • kubectl cluster-info

Dependiendo de su configuración, el resultado será similar a este:

Output
Kubernetes master is running at https://a6616782-5b7f-4381-9c0f-91d6004217c7.k8s.ondigitalocean.com CoreDNS is running at https://a6616782-5b7f-4381-9c0f-91d6004217c7.k8s.ondigitalocean.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Esto significa que está conectado al clúster DOKS.

A continuación, cree una carpeta local para los certificados de cliente. A los efectos de esta guía, se usará ~/certs para almacenar todos los certificados:

  • mkdir ~/certs

En este tutorial, para acceder al clúster autorizaremos un nuevo usuario llamado sammy. Puede cambiarlo por un usuario que elija. Usando la biblioteca OpenSSL de SSL y TLS, genere una nueva clave privada para su usuario con el siguiente comando:

  • openssl genrsa -out ~/certs/sammy.key 4096

Con el indicador -out se creará el archivo de salida ~/certs/sammy.key, y con 4096 se fija la clave en 4096 bits. Para obtener más información sobre OpenSSL, consulte nuestra guía Aspectos básicos de OpenSSL.

A continuación, cree un archivo de configuración de la solicitud de firma de certificados. Abra el siguiente archivo con un editor de texto (para este tutorial, usaremos nano):

  • nano ~/certs/sammy.csr.cnf

Añada el siguiente contenido al archivo sammy.csr.cnf para especificar en el tema el nombre de usuario deseado como nombre común (CN) y el grupo como organización (O):

~/certs/sammy.csr.cnf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[ dn ]
CN = sammy
O = developers
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth

En el archivo de configuración de la solicitud de firma de certificados se incluyen toda la información necesaria, la identidad del usuario y los parámetros de uso adecuados para el usuario. El ltimo argumento extendedKeyUsage=serverAuth,clientAuth permitirá que los usuarios autentiquen sus clientes locales con el clúster DOKS usando el certificado una vez que se haya firmado.

A continuación, cree la solicitud de firma de certificados sammy:

  • openssl req -config ~/certs/sammy.csr.cnf -new -key ~/certs/sammy.key -nodes -out ~/certs/sammy.csr

Con -config se le permite especificar el archivo de configuración para la CSR, y -new indica que creará una nueva CSR para la clave especificada por -key.

Puede verificar la solicitud de firma de certificados ejecutando el siguiente comando:

  • openssl req -in ~/certs/sammy.csr -noout -text

Se pasa la CSR con -in y se utiliza -text para imprimir la solicitud del certificado en texto.

En el resultado, se mostrará la solicitud del certificado, cuyo comienzo tendrá un aspecto similar a este:

Output
Certificate Request: Data: Version: 1 (0x0) Subject: CN = sammy, O = developers Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) ...

Repita el mismo procedimiento para crear CSR para cualquier usuario adicional. Una vez que tenga todas las solicitudes de firma de certificados guardadas en la carpeta del administrador ~/certs, proceda con el paso siguiente para aprobarlas.

Administrar solicitudes de firma de certificados con la API de Kubernetes

Puede aprobar o negar certificados TLS emitidos para la API de Kubernetes usando la herramienta de línea de comandos kubectl. Con esto, tendrá la capacidad de garantizar que el acceso solicitado sea apropiado para el usuario en cuestión. En esta sección, enviará la solicitud de certificado para sammy y la aprobará.

Para enviar una CSR al clúster DOKS, utilice el siguiente comando:

cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: sammy-authentication
spec:
  groups:
  - system:authenticated
  request: $(cat ~/certs/sammy.csr | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - server auth
  - client auth
EOF

Mediante un here document de Bash, este comando utiliza cat para pasar la solicitud de certificado a kubectl apply.

Veamos con más detalle la solicitud de certificado:

  • Con name: sammy-authentication, se crea un identificador de metadatos llamado en este caso sammy-authentication.
  • Con request: $(cat ~/certs/sammy.csr | base64 | tr -d '\n') se envía la solicitud de firma de certificados sammy.csr al clúster, codificado como base64.
  • Con server auth y client auth se especifica el uso previsto del certificado. En este caso, el propósito es autenticar el usuario.

El resultado tendrá un aspecto similar a este:

Output
certificatesigningrequest.certificates.k8s.io/sammy-authentication created

Puede verificar el estado de la solicitud de firma de certificados usando el siguiente comando:

  • kubectl get csr

Dependiendo de la configuración de su clúster, el resultado será similar a este:

Output
NAME AGE REQUESTOR CONDITION sammy-authentication 37s your_DO_email Pending

A continuación, apruebe la CSR usando el siguiente comando:

  • kubectl certificate approve sammy-authentication

Verá un mensaje que confirmará la operación:

Output
certificatesigningrequest.certificates.k8s.io/sammy-authentication approved

Nota: Como administrador, también puede negar una CSR usando el comando kubectl certificate deny sammy-authentication. Para obtener más información sobre la administración de certificados TLS, consulte la documentación oficial de Kubernetes.

Ahora que se aprobó la CSR, puede descargarla a la máquina local ejecutando lo siguiente:

  • kubectl get csr sammy-authentication -o jsonpath='{.status.certificate}' | base64 --decode > ~/certs/sammy.crt

Con este comando, se decodifica el certificado de Base64 para que kubectl lo use correctamente; luego se guarda como ~/certs/sammy.crt.

Una vez firmado el el certificado sammy, podrá crear el archivo kubeconfig del usuario.

Crear Kubeconfig para usuarios remotos

A continuación, creará un archivo kubeconfig específico para el usuario sammy. Esto le proporcionará más control sobre el acceso del usuario a su clúster.

El primer paso para crear un nuevo kubeconfig es hacer una copia del archivo kubeconfig actual. A los efectos de esta guía, el nuevo archivo kubeconfig recibirá el nombre config-sammy:

  • cp ~/.kube/config ~/.kube/config-sammy

A continuación, edite el nuevo archivo:

  • nano ~/.kube/config-sammy

Conserve las primeras ocho líneas de este archivo, ya que contienen la información necesaria para la conexión SSL y TLS con el clúster. Luego, empezando por el parámetro de user, sustituya el texto por las siguientes líneas resaltadas de modo que el archivo tenga un aspecto similar al siguiente:

config-sammy
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: certificate_data
  name: do-nyc1-do-cluster
contexts:
- context:
    cluster: do-nyc1-do-cluster
    user: sammy
  name: do-nyc1-do-cluster
current-context: do-nyc1-do-cluster
kind: Config
preferences: {}
users:
- name: sammy
  user:
    client-certificate: /home/your_local_user/certs/sammy.crt
    client-key: /home/your_local_user/certs/sammy.key

Nota: Tanto para client-certificate como client-key, utilice la ruta absoluta hacia las ubicaciones de sus certificados correspondientes. De lo contrario, en kubectl se producirá un error.

Guarde el archivo y ciérrelo.

Puede probar la conexión del usuario nuevo usando kubectl cluster-info:

  • kubectl --kubeconfig=/home/your_local_user/.kube/config-sammy cluster-info

Verá un error similar a este:

Output
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. Error from server (Forbidden): services is forbidden: User "sammy" cannot list resource "services" in API group "" in the namespace "kube-system"

Este error se espera, ya que el usuario sammy no tiene autorización para enumerar ningún recurso en el clúster. En el siguiente paso, se cubrirá la concesión de autorización a los usuarios. Por ahora, en el resultado se confirma que la conexión SSL y TLS fue exitosa y la API de Kubernetes aceptó las credenciales de autenticación de sammy.

Paso 2: Autorizar usuarios a través del control de acceso basado en roles (RBAC)

Una vez que un usuario se autentica, en la API se determinan sus permisos usando el modelo integrado de control de acceso basado en roles (RBAC) de Kubernetes. El RBAC es un método eficaz para restringir derechos de usuarios en función del rol asignado. Desde el punto de vista de la seguridad, con RBAC se permite la personalización avanzada de permisos para limitar, en el caso de los usuarios, el acceso a datos confidenciales o la ejecución de comandos en el nivel del superusuario. Para obtener más información sobre los roles de usuario, consulte la documentación de RBAC de Kubernetes.

En este paso, usará kubectl para asignar el rol predefinido edit al usuario sammy en el espacio de nombres default. En un entorno de producción, es posible que quiera usar roles personalizados o vinculaciones de estos roles.

Conceder permisos

En Kubernetes, conceder permisos implica asignar el rol deseado a un usuario. Asigne los permisos edit al usuario sammy en el espacio de nombres default usando el siguiente comando:

  • kubectl create rolebinding sammy-edit-role --clusterrole=edit --user=sammy --namespace=default

Con esto, se mostrará un resultado similar al siguiente:

Output
rolebinding.rbac.authorization.k8s.io/sammy-edit-role created

Analizaremos este comando en mayor detalle:

  • Con create rolebinding sammy-edit-role se crea un nueva vinculación de rol, en este caso llamada sammy-edit-role.
  • Con --clusterrole=edit se asigna el rol predefinido edit en un ámbito global (rol de clúster).
  • Con --user=sammy se especifica el usuario con el que se vinculará el rol.
  • Con --namespace=default se conceden al usuario los permisos del rol dentro del espacio de nombres especificado; en este caso, default.

A continuación, verifique los permisos del usuario enumerando pods en el espacio de nombres default. Puede comprobar si la autorización de RBAC funciona como se espera si no se muestran errores.

  • kubectl --kubeconfig=/home/your_local_user/.kube/config-sammy auth can-i get pods

Verá el siguiente resultado:

Output
yes

Ahora que asignó permisos a sammy, en la siguiente sección puede practicar la revocación de esos permisos.

Revocar permisos

La revocación de permisos en Kubernetes se realiza eliminando la vinculación de rol del usuario.

Para este tutorial, elimine el rol edit del usuario sammy ejecutando el siguiente comando:

  • kubectl delete rolebinding sammy-edit-role

Verá el siguiente resultado:

Output
rolebinding.rbac.authorization.k8s.io "sammy-edit-role" deleted

Verifique si los permisos del usuario se revocaron como se esperaba enumerando los pods del espacio de nombres default:

  • kubectl --kubeconfig=/home/localuser/.kube/config-sammy --namespace=default get pods

Obtendrá el siguiente error:

Output
Error from server (Forbidden): pods is forbidden: User "sammy" cannot list resource "pods" in API group "" in the namespace "default"

Esto muestra que se revocó la autorización.

Desde el punto de vista de la seguridad, con el modelo de autorización de Kubernetes se brinda a los administradores la flexibilidad necesaria para cambiar los derechos de los usuarios a pedido, según sea necesario. Además, el control de acceso basado en roles no se limita a un usuario físico; también puede conceder y eliminar permisos a servicios de clústeres, como se explicará en la siguiente sección.

Para obtener más información sobre la autorización de RBAC y la manera de crear roles personalizados, consulte la documentación oficial.

Paso 3: Administrar permisos de aplicación con cuentas de servicio

Como se mencionó en la sección anterior, los mecanismos de autorización de RBAC van más allá de los usuarios humanos. Los usuarios de clústeres no humanos, como las aplicaciones, los servicios y los procesos que se ejecutan dentro de pods, se autentican con el servidor de API usando lo que en Kubernetes se conoce como cuentas de servicio. Cuando se crea un pod dentro de un espacio de nombres, puede permitir que se utilice la cuenta de servicio default o definir una cuenta de servicio que elija. La capacidad de asignar cuentas de servicio individuales a aplicaciones y procesos brinda a los administradores la libertad de conceder o revocar permisos según sea necesario. Además, se considera una buena práctica de seguridad asignar cuentas de servicio específicas a aplicaciones críticas para la producción. Debido a que las cuentas de servicio (SA) se utilizan para la autenticación, y por lo tanto para realizar comprobaciones de autorización de RBAC, los administradores de clústeres pueden contener las amenazas de seguridad cambiando los derechos de acceso de las cuentas de servicio y aislando el proceso delictivo.

Para ofrece una demostración de las SA, en este tutorial utilizaremos un servidor web Nginx como una aplicación de ejemplo.

Antes de asignar una SA en particular a su aplicación, deberá crear dicha SA. Cree una nueva cuenta de servicio llamada nginx-sa en el espacio de nombres default:

  • kubectl create sa nginx-sa

Obtendrá este resultado:

Output
serviceaccount/nginx-sa created

Verifique que la cuenta de servicio se haya creado ejecutando lo siguiente:

  • kubectl get sa

Esto le proporcionará una lista de sus cuentas de servicios:

Output
NAME SECRETS AGE default 1 22h nginx-sa 1 80s

A continuación, asignará un rol a la cuenta de servicio nginx-sa. Para este ejemplo, conceda a nginx-sa los mismos permisos que al usuario sammy:

  • kubectl create rolebinding nginx-sa-edit \
  • --clusterrole=edit \
  • --serviceaccount=default:nginx-sa \
  • --namespace=default

Al ejecutar esto, obtendrá el siguiente resultado:

Output
rolebinding.rbac.authorization.k8s.io/nginx-sa-edit created

En este comando se utiliza el mismo formato que para el usuario sammy, a excepción del indicador --serviceaccount=default:nginx-sa, donde asigna la cuenta de servicio nginx-sa en el espacio de nombres default.

Compruebe que la vinculación del rol se haya realizado correctamente usando este comando:

  • kubectl get rolebinding

Esto generará el siguiente resultado:

Output
NAME AGE nginx-sa-edit 23s

Una vez que haya confirmado que la vinculación del rol para la cuenta del servicio se configuró correctamente, podrá asignar la cuenta de servicio a una aplicación. Asignar una cuenta de servicio particular a una aplicación le permitirá administrar sus derechos de acceso en tiempo real y, por lo tanto, mejorar la seguridad del clúster.

A los efectos de este tutorial, un pod de nginx servirá como la aplicación de muestra. Cree el nuevo pod y especifique la cuenta de servicio nginx-sa con el siguiente comando:

  • kubectl run nginx --image=nginx --port 80 --serviceaccount="nginx-sa"

En la primera parte del comando se crea un nuevo pod ejecutando un servidor web nginx en el puerto :80, y en la última parte en --serviceaccount="nginx-sa" se indica que en este pod se debe usar la cuenta de usuarionginx-sa y no la SA default.

Con esto, se mostrará un resultado similar al siguiente:

Output
deployment.apps/nginx created

Verifique que en la nueva aplicación se utilice la cuenta de servicio usando kubectl describe:

  • kubectl describe deployment nginx

Con esto se mostrará una descripción extensa de los parámetros de implementación. En la sección de Pod Template, verá un resultado similar al siguiente:

Output
... Pod Template: Labels: run=nginx Service Account: nginx-sa ...

En esta sección, creó la cuenta de servicio nginx-sa en el espacio de nombres default y la asignó al servidor web nginx. Ahora puede controlar los permisos de nginx en tiempo real cambiando sus roles según sea necesario. También puede agrupar aplicaciones asignando la misma cuenta de servicio a cada una y luego aplicar cambios en bloque a los permisos. Finalmente, puede aislar aplicaciones críticas asignándoles una cuenta de usuario única.

En resumen, la idea de asignar roles a sus aplicaciones e implementaciones es ajustar los permisos. En los entornos de producción reales, es posible que tenga varias implementaciones que requieran diferentes permisos, que abarcan desde privilegios de solo lectura a privilegios administrativos completos. Con el uso del RBAC se le proporciona la flexibilidad necesaria para restringir el acceso al clúster según sea necesario.

A continuación, establecerá los controladores de admisión para controlar los recursos y protegerse de los ataques de agotamiento de recursos.

Paso 4: Configurar controladores de admisión

Los controladores de admisión de Kubernetes son complementos opcionales que se compilan en el binario kube-apiserver para ampliar las opciones de seguridad. Los controladores de admisión interceptan solicitudes una vez que superan la fase de autenticación y autorización. Cuando interceptan una solicitud, los controladores de admisión ejecutan el código especificado justo antes de que esta se aplique.

Si bien el resultado de una verificación de autenticación o autorización es un booleano con el que se permite o deniega la solicitud, los controladores de admisión pueden ser mucho más diversos. Los controladores de admisión pueden validar las solicitudes de la misma forma que la autenticación, pero también pueden mutar o cambiar las solicitudes y modificar los objetos antes de su admisión.

En este paso, usará los controladores de admisión ResourceQuota y LimitRange para proteger su clúster mediante la mutación de las solicitudes que podrían contribuir a un ataque de agotamiento de recursos o denegación de servicio. Con el controlador de admisión ResourceQuota se permite a los administradores restringir los recursos informáticos y de almacenamiento, y la cantidad de cualquier objeto dentro de un espacio de nombres, mientras que el controlador de admisión LimitRange limita el número de recursos que los contenedores utilizan. Utilizar estos dos controladores de admisión juntos protegerá su clúster contra ataques que hacen que sus recursos no estén disponibles.

Para demostrar cómo funciona ResourceQuota, implementará algunas restricciones en el espacio de nombres default. Comience creando un nuevo archivo de objeto ResourceQuota:

  • nano resource-quota-default.yaml

Añada la siguiente definición de objeto para establecer restricciones para el consumo de recursos en el espacio de nombres default. Puede ajustar los valores según sea necesario dependiendo de los recursos físicos de sus nodos:

resource-quota-default.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: resource-quota-default
spec:
  hard:
    pods: "2"
    requests.cpu: "500m"
    requests.memory: 1Gi
    limits.cpu: "1000m"
    limits.memory: 2Gi
    configmaps: "5"
    persistentvolumeclaims: "2"
    replicationcontrollers: "10"
    secrets: "3"
    services: "4"
    services.loadbalancers: "2"

En esta definición se utiliza la palabra clave hard para establecer restricciones estrictas, como el número máximo de pods, configmaps, PersistentVolumeClaims, ReplicationControllers, secrets, services y loadbalancers. Con esto también se establecen restricciones en los recursos de proceso, como las siguientes:

  • requests.cpu fija el valor de CPU máximo de solicitudes en milliCPU o una milésima parte de un núcleo de CPU.
  • requests.memory fija el valor de memoria máximo de solicitudes en bytes.
  • limits.cpu fija el valor máximo de CPU de los límites en milliCPU.
  • limits.memory fija el valor máximo de memoria de los límites en bytes.

Guarde el archivo y ciérrelo.

Ahora, cree el objeto en el espacio de nombres ejecutando el siguiente comando:

  • kubectl create -f resource-quota-default.yaml --namespace=default

Obtendrá el siguiente resultado:

Output
resourcequota/resource-quota-default created

Tenga en cuenta que usará el indicador -f para marcar en Kubernetes la ubicación del archivo ResourceQuota y el indicador --namespace para especificar el espacio de nombres que se actualizará.

Una vez creado el objeto, ResourceQuota estará activo. Puede verificar las cuotas del espacio de nombres default con describe quota:

  • kubectl describe quota --namespace=default

El resultado será similar al siguiente, con los límites estrictos que estableció en el archivo resource-quota-default.yaml:

Output
Name: resource-quota-default Namespace: default Resource Used Hard -------- ---- ---- configmaps 0 5 limits.cpu 0 1 limits.memory 0 2Gi persistentvolumeclaims 0 2 pods 1 2 replicationcontrollers 0 10 requests.cpu 0 500m requests.memory 0 1Gi secrets 2 3 services 1 4 services.loadbalancers 0 2

Las ResourceQuotas se expresan en unidades absolutas. Por ello, añadir nodos no aumentará automáticamente los valores definidos aquí. Si se añaden nodos, deberá editar manualmente los valores aquí para equilibrar los recursos. Las ResourceQuotas pueden modificarse tanta veces como lo necesite, pero no pueden eliminarse a menos que se quite todo el espacio de nombres.

Si necesita modificar una ResourceQuota en particular, actualice el archivo .yaml correspondiente y aplique los cambios usando el siguiente comando:

  • kubectl apply -f resource-quota-default.yaml --namespace=default

Para obtener más información sobre el controlador de admisión ResourceQuota, consulte la documentación oficial.

Ahora que su ResourceQuota está establecido, procederá con la configuración del controlador de admisión LimitRange. Así como ResourceQuota impone límites para los espacios de nombres, de forma similar LimitRange aplica las limitaciones declaradas validando y mutando contenedores.

Siguiendo un procedimiento similar al que usó antes, comience creando el archivo objeto:

  • nano limit-range-default.yaml

Ahora, puede usar el objeto LimitRange para restringir el uso de recursos según sea necesario. Añada el siguiente contenido como ejemplo de un caso de uso típico:

limit-ranges-default.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limit-range-default
spec:
  limits:
  - max:
      cpu: "400m"
      memory: "1Gi"
    min:
      cpu: "100m"
      memory: "100Mi"
    default:
      cpu: "250m"
      memory: "800Mi"
    defaultRequest:
      cpu: "150m"
      memory: "256Mi"
    type: Container

Con los valores de ejemplo utilizados en limit-ranges-default.yaml se restringe la memoria del contenedor a un máximo de 1Gi y se limita el uso del CPU a un máximo de 400m, lo cual es una métrica de Kubernetes equivalente a 400 milliCPU. Esto implica que el uso del contenedor se limita a casi la mitad de su núcleo.

A continuación, implemente el objeto en el servidor de API usando el siguiente comando:

  • kubectl create -f limit-range-default.yaml --namespace=default

Esto generará el siguiente resultado:

Output
limitrange/limit-range-default created

Ahora puede verificar los nuevos límites con el siguiente comando:

  • kubectl describe limits --namespace=default

El resultado tendrá un aspecto similar a este:

Output
Name: limit-range-default Namespace: default Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container cpu 100m 400m 150m 250m - Container memory 100Mi 1Gi 256Mi 800Mi -

Para ver LimitRanger en acción, implemente un contenedor estándar nginx con el siguiente comando:

  • kubectl run nginx --image=nginx --port=80 --restart=Never

Esto generará el siguiente resultado:

Output
pod/nginx created

Ejecutando el siguiente comando, compruebe la forma en que el controlador de admisión mutó el contenedor:

  • kubectl get pod nginx -o yaml

Esto generará muchas líneas de resultado. Busque en la sección de especificaciones de los contenedores para encontrar los límites de recursos especificados en el controlador de admisión LimitRange.

Output
... spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: nginx ports: - containerPort: 80 protocol: TCP resources: limits: cpu: 250m memory: 800Mi requests: cpu: 150m memory: 256Mi ...

Esto sería lo mismo que declarar manualmente resources y requests en la especificación del contenedor.

En este paso, usó los controladores de admisión ResourceQuota y LimitRange para protegerse de los ataques malintencionados contra los recursos de su clúster. Para obtener más información sobre el controlador de admisión LimitRange, consulte la documentación oficial.

Conclusión

A través de esta guía, configuró una plantilla básica de seguridad de Kubernetes. Con esto, se establecieron la autenticación y autorización de usuarios, los privilegios de aplicaciones y la protección de los recursos de clústeres. Combinando todas las sugerencias de este artículo, tendrá una base sólida para una implementación de un clúster de Kubernetes de producción. A partir de ahí, puede comenzar a reforzar aspectos individuales de su clúster dependiendo de su escenario.

Si desea obtener más información sobre Kubernetes, consulte nuestra página de recursos de Kubernetes o complete nuestro curso de aprendizaje por cuenta propia de Kubernetes para desarrolladores “full-stack”.

0 Comments

Creative Commons License