Information in this document may be out of date
This document has an older update date than the original, so the information it contains may be out of date. If you're able to read English, see the English version for the most up-to-date information: Network Policies
Si quieres controlar el tráfico de red a nivel de dirección IP o puerto (capa OSI 3 o 4), puedes considerar el uso de Kubernetes NetworkPolicies para las aplicaciones que corren en tu clúster. Las NetworkPolicies son una estructura enfocada en las aplicaciones que permite establecer cómo un Pod puede comunicarse con otras "entidades" (utilizamos la palabra "entidad" para evitar sobrecargar términos más comunes como "Endpoint" o "Service", que tienen connotaciones específicas de Kubernetes) a través de la red. Las NetworkPolicies se aplican a uno o ambos extremos de la conexión a un Pod, sin afectar a otras conexiones.
Las entidades con las que un Pod puede comunicarse son una combinación de estos 3 tipos:
Cuando se define una NetworkPolicy basada en Pods o Namespaces, se utiliza un Selector para especificar qué tráfico se permite desde y hacia los Pod(s) que coinciden con el selector.
Por otro lado, cuando se crean NetworkPolicies basadas en IP, se definen políticas basadas en bloques de IP (rangos CIDR).
Las políticas de red son implementadas por el plugin de red. Para usar políticas de red, debes estar utilizando una solución de red que soporte NetworkPolicy. Crear un recurso NetworkPolicy sin un controlador que lo habilite no tendrá efecto alguno.
Hay dos tipos de aislamiento para un Pod: el aislamiento para la salida y el aislamiento para la entrada. Estos se refieren a las conexiones que pueden establecerse. El término "Aislamiento" en el contexto de este documento no es absoluto, sino que significa "se aplican algunas restricciones". La alternativa, "no aislado para $dirección", significa que no se aplican restricciones en la dirección descrita. Los dos tipos de aislamiento (o no) se declaran independientemente, y ambos son relevantes para una conexión de un Pod a otro.
Por defecto, un Pod no está aislado para la salida; todas las conexiones salientes están permitidas. Un Pod está aislado para la salida si hay alguna NetworkPolicy con "Egress" en su policyTypes que seleccione el Pod; decimos que tal política se aplica al Pod para la salida. Cuando un Pod está aislado para la salida, las únicas conexiones permitidas desde el Pod son las permitidas por la lista egress de las NetworkPolicy que se apliquen al Pod para la salida. Los valores de esas listas egress se combinan de forma aditiva.
Por defecto, un Pod no está aislado para la entrada; todas las conexiones entrantes están permitidas. Un Pod está aislado para la entrada si hay alguna NetworkPolicy con "Ingress" en su policyTypes que seleccione el Pod; decimos que tal política se aplica al Pod para la entrada. Cuando un Pod está aislado para la entrada, las únicas conexiones permitidas en el Pod son las del nodo del Pod y las permitidas por la lista ingress de alguna NetworkPolicy que se apliquen al Pod para la entrada. Los valores de esas listas de direcciones se combinan de forma aditiva.
Las políticas de red no entran en conflicto; son aditivas. Si alguna política(s) se aplica a un Pod para una dirección determinada, las conexiones permitidas en esa dirección desde ese Pod son la unión de lo que permiten las políticas aplicables. Por lo tanto, el orden de evaluación no afecta al resultado de la política.
Para que se permita una conexión desde un Pod de origen a un Pod de destino, tanto la política de salida del Pod de origen como la de entrada del Pod de destino deben permitir la conexión. Si cualquiera de los dos lados no permite la conexión, ésta no se producirá.
Ver la referencia NetworkPolicy para una definición completa del recurso.
Un ejemplo de NetworkPolicy podría ser este:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
Campos Obligatorios: Como con todas las otras configuraciones de Kubernetes, una NetworkPolicy
necesita los campos apiVersion, kind, y metadata. Para obtener información general
sobre cómo funcionan esos archivos de configuración, puedes consultar
Configurar un Pod para usar un ConfigMap,
y Gestión de Objetos.
spec: NetworkPolicy spec contiene toda la información necesaria para definir una política de red dado un Namespace.
podSelector: Cada NetworkPolicy incluye un podSelector el cual selecciona el grupo de Pods en los cuales aplica la política. La política de ejemplo selecciona Pods con la etiqueta "role=db". Un podSelector vacío selecciona todos los Pods en un Namespace.
policyTypes: Cada NetworkPolicy incluye una lista de policyTypes la cual puede incluir Ingress, Egress, o ambas. Los campos policyTypes indican si la política aplica o no al tráfico de entrada hacia el Pod seleccionado, el tráfico de salida desde el Pod seleccionado, o ambos. Si no se especifican policyTypes en una NetworkPolicy, el valor Ingress se aplicará siempre por defecto y Egress se aplicará si la NetworkPolicy contiene alguna regla de salida.
ingress: Cada NetworkPolicy puede incluir una lista de reglas ingress permitidas. Cada regla permite el tráfico relacionado con los valores de las secciones from y ports. La política de ejemplo contiene una única regla, la cual se relaciona con el tráfico sobre un solo puerto, desde uno de los tres orígenes definidos, el primero especificado por el valor ipBlock, el segundo especificado por el valor namespaceSelector y el tercero especificado por el podSelector.
egress: Cada NetworkPolicy puede incluir una lista de reglas de egress permitidas. Cada regla permite el tráfico relacionado con los valores de las secciones to y ports. La política de ejemplo contiene una única regla, la cual se relaciona con el tráfico en un único puerto para cualquier destino en el rango de IPs 10.0.0.0/24.
Por lo tanto, la NetworkPolicy de ejemplo:
Ver el artículo de Declarar Network Policy para más ejemplos.
to y fromExisten cuatro tipos de selectores que pueden ser especificados en una sección ingress from o en una sección egress to:
podSelector: Este selector selecciona Pods específicos en el mismo Namespace que la NetworkPolicy para permitir el tráfico como origen de entrada o destino de salida.
namespaceSelector: Este selector selecciona Namespaces específicos para permitir el tráfico como origen de entrada o destino de salida.
namespaceSelector y podSelector: Una única entrada to/from que especifica tanto namespaceSelector como podSelector selecciona Pods específicos dentro de Namespaces específicos. Es importante revisar que se utiliza la sintaxis de YAML correcta. A continuación se muestra un ejemplo de esta política:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
contiene un elemento from permitiendo conexiones desde los Pods con el label role=client en Namespaces con el label user=alice. Por el contrario, esta política:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
contiene dos elementos en el array from, y permite conexiones desde Pods en los Namespaces con el label role=client, o desde cualquier Pod en cualquier Namespace con el label user=alice.
En caso de duda, utilice kubectl describe para ver cómo Kubernetes ha interpretado la política.
ipBlock: Este selector selecciona rangos CIDR de IP específicos para permitirlas como origen de entrada o destino de salida. Estas IPs deben ser externas al clúster, ya que las IPs de Pod son efímeras e impredecibles.
Los mecanismos de entrada y salida del clúster a menudo requieren reescribir la IP de origen o destino
de los paquetes. En los casos en los que esto ocurre, no está definido si esto ocurre antes o
después del procesamiento de NetworkPolicy, y el comportamiento puede ser diferente para diferentes
combinaciones de plugin de red, proveedor de nube, implementación de Service, etc.
En el caso de la entrada, esto significa que en algunos casos se pueden filtrar paquetes
entrantes basándose en la IP de origen real, mientras que en otros casos, la "IP de origen" sobre la que actúa la NetworkPolicy
puede ser la IP de un LoadBalancer o la IP del Nodo donde está el Pod involucrado, etc.
Para la salida, esto significa que las conexiones de los Pods a las IPs de Service que se reescriben a
IPs externas al clúster pueden o no estar sujetas a políticas basadas en ipBlock.
Por defecto, si no existen políticas en un Namespace, se permite todo el tráfico de entrada y salida hacia y desde los Pods de ese Namespace. Los siguientes ejemplos muestran cómo cambiar el comportamiento por defecto en ese Namespace.
Puedes crear una política que "por defecto" aisle a un Namespace del tráfico de entrada con la creación de una política que seleccione todos los Pods del Namespace pero no permite ningún tráfico de entrada en esos Pods.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
Esto asegura que incluso los Pods que no están seleccionados por ninguna otra NetworkPolicy también serán aislados del tráfico de entrada. Esta política no afecta el aislamiento en el tráfico de salida desde cualquier Pod.
Si quieres permitir todo el tráfico de entrada a todos los Pods en un Namespace, puedes crear una política que explícitamente permita eso.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
Con esta política en curso, ninguna política(s) adicional puede hacer que se niegue cualquier conexión entrante a esos Pods. Esta política no tiene efecto sobre el aislamiento del tráfico de salida de cualquier Pod.
Puedes crear una política que "por defecto" aisle el tráfico de salida para un Namespace, creando una NetworkPolicy que seleccione todos los Pods pero que no permita ningún tráfico de salida desde esos Pods.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
Esto asegura que incluso los Pods que no son seleccionados por ninguna otra NetworkPolicy no tengan permitido el tráfico de salida. Esta política no cambia el comportamiento de aislamiento para el tráfico de entrada de ningún Pod.
Si quieres permitir todas las conexiones desde todos los Pods de un Namespace, puedes crear una política que permita explícitamente todas las conexiones salientes de los Pods de ese Namespace.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
Con esta política en vigor, ninguna política(s) adicional puede hacer que se niegue cualquier conexión de salida desde esos Pods. Esta política no tiene efecto sobre el aislamiento para el tráfico de entrada a cualquier Pod.
Puedes crear una política que "por defecto" en un Namespace impida todo el tráfico de entrada y de salida creando la siguiente NetworkPolicy en ese Namespace.
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Esto asegura que incluso los Pods que no son seleccionados por ninguna otra NetworkPolicy no tendrán permitido el tráfico de entrada o salida.
Kubernetes v1.20 [stable]Como característica estable, está activada por defecto. Para deshabilitar SCTP a nivel de clúster, usted (o el administrador de su clúster) tiene que deshabilitar la feature gate SCTPSupport para el API Server con el flag --feature-gates=SCTPSupport=false,....
Cuando esta feature gate está habilitada, puede establecer el campo protocol de una NetworkPolicy como SCTP.
Kubernetes v1.22 [beta]Cuando se escribe una NetworkPolicy, se puede apuntar a un rango de puertos en lugar de un solo puerto.
Esto se puede lograr con el uso del campo endPort, como en el siguiente ejemplo:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: multi-port-egress
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 32000
endPort: 32768
La regla anterior permite que cualquier Pod con la etiqueta role=db en el Namespace default se comunique
con cualquier IP dentro del rango 10.0.0.0/24 sobre el protocolo TCP, siempre que el puerto
esté entre el rango 32000 y 32768.
Se aplican las siguientes restricciones al utilizar este campo:
endPort a nivel de clúster, usted (o su administrador de clúster) debe desactivar la feature gate NetworkPolicyEndPort--feature-gates=NetworkPolicyEndPort=false,....endPort debe ser igual o mayor que el campo port.endPort si también se define port.endPort en las especificaciones de NetworkPolicy.
Si su plugin de red
no soporta el campo endPort y usted especifica una NetworkPolicy que use este campo,
la política se aplicará solo para el campo port.Kubernetes 1.22 [stable]El plano de control de Kubernetes establece una etiqueta inmutable kubernetes.io/metadata.name en todos los
Namespaces, siempre que se haya habilitado la feature gate NamespaceDefaultLabelName.
El valor de la etiqueta es el nombre del Namespace.
Aunque NetworkPolicy no puede apuntar a un Namespace por su nombre con algún campo de objeto, puede utilizar la etiqueta estandarizada para apuntar a un Namespace específico.
Actualmente, en Kubernetes 1.35, la siguiente funcionalidad no existe en la API de NetworkPolicy, pero es posible que se puedan implementar soluciones mediante componentes del sistema operativo (como SELinux, OpenVSwitch, IPTables, etc.) o tecnologías de capa 7 (controladores Ingress, implementaciones de Service Mesh) o controladores de admisión. En caso de que seas nuevo en la seguridad de la red en Kubernetes, vale la pena señalar que las siguientes historias de usuario no pueden (todavía) ser implementadas usando la API NetworkPolicy.