Utilización de una política de grupo de seguridad para un Pod de Amazon EKS - Amazon EKS

Utilización de una política de grupo de seguridad para un Pod de Amazon EKS

Para usar grupos de seguridad con Pods, debe tener un grupo de seguridad existente. En los siguientes pasos se muestra cómo utilizar la política de grupo de seguridad para un Pod. A menos que se indique lo contrario, complete todos los pasos del mismo terminal ya que en los siguientes pasos se utilizan variables que no persisten en los terminales.

Si tiene un Pod con instancias de Amazon EC2, debe configurar el complemento antes de utilizar este procedimiento. Para obtener más información, consulte Configuración del Amazon VPC CNI plugin for Kubernetes con grupos de seguridad para los Pods de Amazon EKS.

  1. Cree un espacio de nombres de Kubernetes en el que implementar los recursos. Puede reemplazar my-namespace por el nombre del espacio de nombres que desee usar.

    kubectl create namespace my-namespace
  2. Implemente una SecurityGroupPolicy de Amazon EKS en su clúster.

    1. Copie los siguientes contenidos en su dispositivo. Puede reemplazar podSelector por serviceAccountSelector si prefiere seleccionar Pods en función de las etiquetas de cuenta de servicio. Debe especificar un selector o el otro. Un podSelector vacío (ejemplo: podSelector: {}) selecciona todos los Pods del espacio de nombres. Puede cambiar my-role por el nombre de su rol. Un serviceAccountSelector vacío selecciona todas las cuentas de servicio del espacio de nombres. Puede reemplazar my-security-group-policy por un nombre para su SecurityGroupPolicy y my-namespace por el espacio de nombres en el que desea crear la SecurityGroupPolicy.

      Debe reemplazar my_pod_security_group_id por el ID de un grupo de seguridad existente. Si no dispone de un grupo de seguridad existente, debe crear uno. Para obtener más información, consulte Grupos de seguridad de Amazon EC2 para instancias de Linux en la Guía del usuario de Amazon EC2. Puede especificar de uno a cinco ID de grupo de seguridad. Si especifica más de un ID, la combinación de todas las reglas de todos los grupos de seguridad será efectiva para los Pods seleccionados.

      cat >my-security-group-policy.yaml <<EOF apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: my-security-group-policy namespace: my-namespace spec: podSelector: matchLabels: role: my-role securityGroups: groupIds: - my_pod_security_group_id EOF
      importante

      El grupo o los grupos de seguridad que especifique para sus Pods debe cumplir los siguientes criterios:

      • Deben existir. Si no existen, entonces, cuando implementa un Pod que coincida con el selector, el Pod permanece atascado en el proceso de creación. Si describe el Pod, verá un mensaje de error similar al siguiente: An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID 'sg-05b1d815d1EXAMPLE' does not exist.

      • Deben permitir la comunicación entrante desde el grupo de seguridad de clúster aplicado a sus nodos (para kubelet) a través de los puertos para los que haya configurado sondeos.

      • Deben permitir la comunicación saliente a través de los puertos TCP y UDP 53 a un grupo de seguridad asignado a los Pods (o los nodos en los que los Pods se ejecutan) que ejecutan CoreDNS. El grupo de seguridad de sus Pods de CoreDNS debe permitir el tráfico entrante del puerto TCP y UDP 53 del grupo de seguridad que especifique.

      • Deben tener las reglas entrantes y salientes necesarias para comunicarse con otros Pods con los que deben comunicarse.

      • Deben tener reglas que permitan a los Pods comunicarse con el plano de control de Kubernetes si utilizan el grupo de seguridad con Fargate. La forma más sencilla de hacerlo es especificar el grupo de seguridad de clúster como uno de los grupos de seguridad.

      Las políticas de grupos de seguridad solo se aplican a los nuevos Pods programados. No afectan a los Pods en ejecución.

    2. Implemente la política.

      kubectl apply -f my-security-group-policy.yaml
  3. Implemente una aplicación de muestra con una etiqueta que coincida con el valor my-role para podSelector que especificó en un paso anterior.

    1. Copie los siguientes contenidos en su dispositivo. Reemplace los valores de ejemplo por los suyos y, a continuación, ejecute el comando modificado. Si reemplaza my-role, asegúrese de que sea igual al valor que especificó para el selector en un paso anterior.

      cat >sample-application.yaml <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 4 selector: matchLabels: app: my-app template: metadata: labels: app: my-app role: my-role spec: terminationGracePeriodSeconds: 120 containers: - name: nginx image: public.ecr.aws/nginx/nginx:1.23 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-app namespace: my-namespace labels: app: my-app spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 EOF
    2. Implemente la aplicación con el siguiente comando. Cuando implementa la aplicación, el Amazon VPC CNI plugin for Kubernetes coincide con la etiqueta de role y los grupos de seguridad que especificó en el paso anterior se aplican al Pod.

      kubectl apply -f sample-application.yaml
  4. Vea los Pods implementados con la aplicación de muestra. En el resto de este tema, se hace referencia a este terminal como TerminalA.

    kubectl get pods -n my-namespace -o wide

    Un ejemplo de salida sería el siguiente.

    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-5df6f7687b-4fbjm 1/1 Running 0 7m51s 192.168.53.48 ip-192-168-33-28.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-j9fl4 1/1 Running 0 7m51s 192.168.70.145 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-rjxcz 1/1 Running 0 7m51s 192.168.73.207 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-zmb42 1/1 Running 0 7m51s 192.168.63.27 ip-192-168-33-28.region-code.compute.internal <none> <none>
    nota

    Pruebe estos consejos si algún Pods está atascado.

    • Si hay Pods atascados en estado Waiting, ejecute kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace . Si ve Insufficient permissions: Unable to create Elastic Network Interface., confirme que agregó la política de IAM al rol de clúster de IAM en un paso anterior.

    • Si algún Pods se encuentra atascado en estado Pending, confirme que el tipo de instancia del nodo aparece en limits.go y que el producto del número máximo de interfaces de red de ramificación admitidas por el tipo de instancia multiplicado por el número de nodos del grupo de nodos aún no se ha alcanzado. Por ejemplo, una instancia m5.large admite nueve interfaces de red de ramificación. Si el grupo de nodos tiene cinco nodos, se puede crear un máximo de 45 interfaces de red de ramificación para el grupo de nodos. El Pod 46 que intente implementar se establecerá en el estado Pending hasta que se elimine otro Pod que tenga grupos de seguridad asociados.

    Si ejecuta kubectl describe pod my-deployment-xxxxxxxxxx-xxxxx -n my-namespace y ve un mensaje similar al siguiente mensaje, puede ignorarlo de forma segura. Este mensaje puede aparecer cuando el Amazon VPC CNI plugin for Kubernetes intenta configurar las redes de host y falla mientras se crea la interfaz de red. El complemento registra este evento hasta que se crea la interfaz de red.

    Failed to create Pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "e24268322e55c8185721f52df6493684f6c2c3bf4fd59c9c121fd4cdc894579f" network for Pod "my-deployment-5df6f7687b-4fbjm": networkPlugin cni failed to set up Pod "my-deployment-5df6f7687b-4fbjm-c89wx_my-namespace" network: add cmd: failed to assign an IP address to container

    No puede exceder el número máximo de Pods que se pueden ejecutar en el tipo de instancia. Para obtener una lista del número máximo de Pods que puede ejecutar en cada tipo de instancia, consulte eni-max-pods.txt en GitHub. Cuando elimina un Pod que tiene grupos de seguridad asociados o elimina el nodo en el que se ejecuta el Pod, el controlador de recursos de VPC elimina la interfaz de red de ramificación. Si elimina un clúster con Pods mediante Pods para grupos de seguridad, el controlador no elimina las interfaces de red de ramificación, por lo que deberá eliminarlas por su cuenta. A fin de obtener más información sobre las interfaces de red, consulte Eliminar una interfaz de red en la Guía del usuario de Amazon EC2.

  5. En un terminal separado, se inserta en uno de los Pods. En el resto de este tema, se hace referencia a este terminal como TerminalB. Reemplace 5df6f7687b-4fbjm por el ID de uno de los Pods que obtuvo en la salida del paso anterior.

    kubectl exec -it -n my-namespace my-deployment-5df6f7687b-4fbjm -- /bin/bash
  6. Desde el intérprete de comandos de TerminalB, confirme que la aplicación de ejemplo funciona.

    curl my-app

    Un ejemplo de salida sería el siguiente.

    <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> [...]

    Recibió el resultado porque todos los Pods que se ejecutan en la aplicación están asociados al grupo de seguridad que creó. Ese grupo contiene una regla que permite todo el tráfico entre todos los Pods al que está asociado el grupo de seguridad. Se permite el tráfico DNS saliente de ese grupo de seguridad al grupo de seguridad del clúster, lo que está asociado a los nodos. Los nodos ejecutan los Pods CoreDNS, en los que sus Pods realizó una búsqueda de nombre.

  7. Desde TerminalA, elimine las reglas del grupo de seguridad que permita la comunicación DNS al grupo de seguridad del clúster del grupo de seguridad. Si no agregó las reglas DNS al grupo de seguridad del clúster en un paso anterior, sustituya $my_cluster_security_group_id con el ID del grupo de seguridad en el que creó las reglas.

    aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_tcp_rule_id aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_udp_rule_id
  8. Desde TerminalB, intente acceder de nuevo a la aplicación.

    curl my-app

    Un ejemplo de salida sería el siguiente.

    curl: (6) Could not resolve host: my-app

    El intento falla porque el Pod ya no puede acceder a los Pods CoreDNS, que tienen asociado el grupo de seguridad del clúster. El grupo de seguridad del clúster ya no tiene las reglas del grupo de seguridad que permiten la comunicación DNS desde el grupo de seguridad asociado a su Pod.

    Si intenta acceder a la aplicación utilizando las direcciones IP devueltas para uno de los Pods en un paso anterior, sigue recibiendo una respuesta dado que todos los puertos están permitidos entre Pods que tienen el grupo de seguridad asociado a ellos y no es necesaria una búsqueda de nombres.

  9. Una vez que haya terminado de experimentar, puede eliminar la política de grupo de seguridad, la aplicación y el grupo de seguridad de ejemplo que creó. Ejecute los siguientes comandos desde la TerminalA.

    kubectl delete namespace my-namespace aws ec2 revoke-security-group-ingress --group-id $my_pod_security_group_id --security-group-rule-ids $my_inbound_self_rule_id wait sleep 45s aws ec2 delete-security-group --group-id $my_pod_security_group_id