 Nota perev. : O autor do artigo - Reuven Harrison - tem mais de 20 anos de experiência em desenvolvimento de software e hoje é o diretor técnico e co-fundador da Tufin, uma empresa que cria soluções de gerenciamento de políticas de segurança. Considerando as políticas de rede do Kubernetes como uma ferramenta poderosa o suficiente para a segmentação de rede em um cluster, ele acredita que elas não são tão fáceis de aplicar na prática. Este material (bastante volumoso) foi projetado para melhorar o conhecimento dos especialistas nesta matéria e ajudá-los a criar as configurações necessárias.
Nota perev. : O autor do artigo - Reuven Harrison - tem mais de 20 anos de experiência em desenvolvimento de software e hoje é o diretor técnico e co-fundador da Tufin, uma empresa que cria soluções de gerenciamento de políticas de segurança. Considerando as políticas de rede do Kubernetes como uma ferramenta poderosa o suficiente para a segmentação de rede em um cluster, ele acredita que elas não são tão fáceis de aplicar na prática. Este material (bastante volumoso) foi projetado para melhorar o conhecimento dos especialistas nesta matéria e ajudá-los a criar as configurações necessárias. Hoje, muitas empresas estão cada vez mais escolhendo o Kubernetes para executar seus aplicativos. O interesse neste software é tão alto que alguns chamam o Kubernetes de "o novo sistema operacional do data center". Gradualmente, o Kubernetes (ou k8s) começa a ser percebido como uma parte crítica dos negócios, o que requer a organização de processos de negócios maduros, incluindo a segurança da rede.
Para profissionais de segurança que estão intrigados ao trabalhar com o Kubernetes, a política padrão dessa plataforma pode ser uma descoberta real: permita tudo.
Este guia o ajudará a entender a estrutura interna das políticas de rede; Entenda como eles diferem das regras para firewalls comuns. Algumas armadilhas também serão descritas e serão dadas recomendações que ajudarão a proteger aplicativos no Kubernetes.
Diretivas de rede Kubernetes
O mecanismo de diretiva de rede Kubernetes permite controlar a interação dos aplicativos implantados na plataforma no nível da rede (a terceira no modelo OSI). As políticas de rede carecem de alguns dos recursos avançados dos firewalls modernos, como o monitoramento OSI nível 7 e a detecção de ameaças, mas fornecem um nível básico de segurança de rede, que é um bom ponto de partida.
As políticas de rede controlam as comunicações entre os pods
As cargas de trabalho do Kubernetes são distribuídas entre os pods que consistem em um ou mais contêineres implantados juntos. O Kubernetes atribui a cada pod um endereço IP acessível a partir de outros pods. As políticas de rede do Kubernetes definem permissões para grupos de pods da mesma maneira que os grupos de segurança na nuvem são usados para controlar o acesso às instâncias da máquina virtual.
Definindo diretivas de rede
Como outros recursos do Kubernetes, as diretivas de rede são definidas no YAML. No exemplo abaixo, o 
balance é concedido acesso ao 
postgres :
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: podSelector: matchLabels: app: postgres ingress: - from: - podSelector: matchLabels: app: balance policyTypes: - Ingress 
 ( Nota : esta captura de tela, como todas as similares subsequentes, não foi criada usando as ferramentas nativas do Kubernetes, mas usando a ferramenta Tufin Orca, desenvolvida pela empresa do autor do artigo original e mencionada no final do artigo.)
( Nota : esta captura de tela, como todas as similares subsequentes, não foi criada usando as ferramentas nativas do Kubernetes, mas usando a ferramenta Tufin Orca, desenvolvida pela empresa do autor do artigo original e mencionada no final do artigo.)Definir sua própria política de rede exigirá conhecimento básico de YAML. Esse idioma é baseado no recuo (especificado por espaços, não por tabulações). Um elemento recuado pertence ao elemento recuado mais próximo acima dele. Um novo item da lista começa com um hífen, todos os outros itens têm 
valor-chave .
Depois de descrever a política no YAML, use o 
kubectl para criá-la no cluster:
 kubectl create -f policy.yaml 
Especificação de Diretiva de Rede
A especificação de diretiva de rede Kubernetes inclui quatro elementos:
- podSelector: define os pods afetados por esta política (metas) - obrigatórios;
- policyTypes: indica que tipos de política estão incluídos: entrada e / ou saída - opcional, no entanto, recomendo que você a registre explicitamente em todos os casos;
- ingress: define o tráfego de entrada permitido para os pods de destino - opcional;
- egress: define o tráfego de saída permitido dos pods de destino - opcional.
Um exemplo emprestado do site Kubernetes (substituí a 
role pelo 
app ) mostra como todos os quatro elementos são usados:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: # <<< matchLabels: app: 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 


Observe que todos os quatro elementos são opcionais. Somente o 
podSelector é 
podSelector , outros parâmetros podem ser usados conforme desejado.
Se você omitir 
policyTypes , a política será interpretada da seguinte maneira:
- Por padrão, assume-se que define o lado da entrada. Se a política não indicar isso explicitamente, o sistema considerará que todo o tráfego é proibido.
- O comportamento no lado da saída será determinado pela presença ou ausência do parâmetro de saída correspondente.
Para evitar erros, recomendo 
sempre especificar explicitamente policyTypes .
De acordo com a lógica acima, se os 
egress ingress e / ou 
egress forem omitidos, a política proibirá todo o tráfego (consulte "Regra de remoção" abaixo).
A política padrão é permitir
Se nenhuma política for definida, o Kubernetes por padrão permitirá todo o tráfego. Todos os pods são livres para trocar informações entre si. Do ponto de vista da segurança, isso pode parecer contra-intuitivo, mas lembre-se de que o Kubernetes foi originalmente criado por desenvolvedores para garantir a interoperabilidade do aplicativo. Políticas de rede foram adicionadas mais tarde.
Namespaces
Os espaços para nome são um mecanismo colaborativo do Kubernetes. Eles são projetados para isolar ambientes lógicos um do outro, enquanto a troca de dados entre espaços é permitida por padrão.
Como a maioria dos componentes do Kubernetes, as políticas de rede residem em um espaço para nome específico. No bloco de 
metadata , você pode especificar a qual espaço a política pertence:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: my-namespace # <<< spec: ... 
Se o espaço para nome não estiver escrito explicitamente nos metadados, o sistema usará o espaço para nome especificado no kubectl (por padrão, 
namespace=default ):
 kubectl apply -n my-namespace -f namespace.yaml 
Eu recomendo 
especificar explicitamente um espaço para nome, a menos que você esteja escrevendo uma política destinada a vários espaços para nome ao mesmo tempo.
O elemento 
podSelector principal em uma política selecionará pods do espaço de nomes ao qual a política pertence (é negado o acesso aos pods de outro espaço de nome).
Da mesma forma, os podSelectors 
nos blocos de entrada e saída podem selecionar os pods apenas no namespace, a menos que, é claro, você os combine com o 
namespaceSelector (isso será discutido na seção “Filtrando por namespace e pods”) .
Regras de nomeação de políticas
Os nomes das políticas são exclusivos em um único espaço para nome. Não pode haver duas políticas com o mesmo nome em um espaço, mas pode haver políticas com o mesmo nome em espaços diferentes. Isso é útil quando você deseja aplicar novamente a mesma política em vários espaços.
Eu gosto especialmente de uma maneira de nomear. Consiste em combinar o nome do espaço para nome com os pods de destino. Por exemplo:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres # <<< namespace: default spec: podSelector: matchLabels: app: postgres ingress: - from: - podSelector: matchLabels: app: admin policyTypes: - Ingress 

Etiquetas
Rótulos personalizados podem ser anexados aos objetos do Kubernetes, como pods e espaços para nome. Os rótulos são equivalentes às tags na nuvem. As políticas de rede do Kubernetes usam rótulos para selecionar os 
pods aos quais se aplicam:
 podSelector: matchLabels: role: db 
... ou 
os namespaces aos quais eles se aplicam. Neste exemplo, todos os pods nos espaços para nome com os rótulos correspondentes são selecionados:
 namespaceSelector: matchLabels: project: myproject 
Uma ressalva: ao usar o 
namespaceSelector verifique se os namespaceSelector para namespaceSelector selecionados contêm o rótulo desejado . Lembre-se de que os namespaces 
kube-system , como 
default e 
kube-system , não contêm rótulos por padrão.
Você pode adicionar um rótulo ao espaço da seguinte maneira:
 kubectl label namespace default namespace=default 
Nesse caso, o espaço para nome na seção de 
metadata deve se referir ao nome real do espaço, e não ao rótulo:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default # <<< spec: ... 
Origem e Destino
As políticas para firewalls consistem em regras com fontes e destinos. As diretivas de rede do Kubernetes são definidas para essa finalidade - um conjunto de pods aos quais são aplicadas e, em seguida, estabelecem regras para o tráfego de entrada (entrada) e / ou saída (saída). Em nosso exemplo, o destino da política será todos os pods no espaço para nome 
default com um rótulo com a chave do 
app e o valor 
db :
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: matchLabels: app: 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 


A subseção de 
ingress nesta política abre o tráfego de entrada para os pods de destino. Em outras palavras, a entrada é a fonte e o destino é o destinatário apropriado. Da mesma forma, a saída é o alvo, e o alvo é sua fonte.
 Isso é equivalente a duas regras para o firewall: Ingress → Target; Objetivo → Saída.
Isso é equivalente a duas regras para o firewall: Ingress → Target; Objetivo → Saída.Saída e DNS (importante!)
Ao limitar o tráfego de saída, 
preste atenção especial ao DNS - o Kubernetes usa esse serviço para mapear serviços para endereços IP. Por exemplo, a política a seguir não funcionará porque você não permitiu que o aplicativo de 
balance acesse o DNS:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres policyTypes: - Egress 

Você pode corrigi-lo, abrindo o acesso ao serviço DNS:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres - to: # <<< ports: # <<< - protocol: UDP # <<< port: 53 # <<< policyTypes: - Egress 

O elemento last to está vazio e, portanto, seleciona indiretamente 
todos os pods em todos os espaços de nomes , permitindo que o 
balance envie consultas DNS ao serviço Kubernetes correspondente (geralmente funciona no espaço do 
kube-system ).
Essa abordagem funciona, mas é 
excessivamente permissiva e insegura , porque permite direcionar consultas DNS fora do cluster.
Você pode aprimorá-lo em três etapas consecutivas.
1. Permita consultas DNS apenas 
dentro do cluster adicionando 
namespaceSelector :
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres - to: - namespaceSelector: {} # <<< ports: - protocol: UDP port: 53 policyTypes: - Egress 

2. Permita consultas DNS apenas no 
kube-system nome do 
kube-system .
Para fazer isso, adicione um rótulo ao 
kubectl label namespace kube-system namespace=kube-system kube-system kubectl label namespace kube-system namespace=kube-system : 
kubectl label namespace kube-system namespace=kube-system - e registre-o na política usando 
namespaceSelector :
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres - to: - namespaceSelector: # <<< matchLabels: # <<< namespace: kube-system # <<< ports: - protocol: UDP port: 53 policyTypes: - Egress 

3. Os paranóicos podem ir ainda mais longe e limitar as consultas DNS a um serviço DNS específico no 
kube-system . Na seção "Filtrar por namespaces e pods", explicaremos como conseguir isso.
Outra opção é resolver o DNS no nível do espaço para nome. Nesse caso, ele não precisará ser aberto para cada serviço:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.dns namespace: default spec: podSelector: {} # <<< egress: - to: - namespaceSelector: {} ports: - protocol: UDP port: 53 policyTypes: - Egress 
Um 
podSelector vazio seleciona todos os pods no espaço para nome.

Primeira partida e ordem das regras
Nos firewalls comuns, a ação ("Permitir" ou "Negar") para um pacote é determinada pela primeira regra a ser cumprida. 
Em Kubernetes, a ordem das políticas é irrelevante.Por padrão, quando as políticas não são definidas, as comunicações entre os pods são permitidas e elas podem trocar informações livremente. Assim que você começa a formular políticas, cada pod afetado por pelo menos um deles fica isolado de acordo com a disjunção (OR lógica) de todas as políticas que o escolheram. Os pods não afetados por nenhuma política permanecem abertos.
Você pode alterar esse comportamento usando a regra de remoção.
Regra de remoção (Negar)
As políticas de firewall geralmente proíbem qualquer tráfego explicitamente não autorizado.
O Kubernetes não tem uma ação de negação , no entanto, um efeito semelhante pode ser alcançado com uma política regular (de permissão) selecionando um grupo vazio de pods de origem (entrada):
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: default spec: podSelector: {} policyTypes: - Ingress 

Essa política seleciona todos os pods no espaço para nome e deixa a entrada indefinida, bloqueando todo o tráfego recebido.
Da mesma forma, você pode limitar todo o tráfego de saída do namespace:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-egress namespace: default spec: podSelector: {} policyTypes: - Egress 

Observe que 
qualquer política adicional que permita o tráfego de pods no espaço para nome terá precedência sobre essa regra (semelhante à adição de uma regra de permissão a uma regra de negação na configuração do firewall).
Permitir tudo (Qualquer-Qualquer-Qualquer-Permitir)
Para criar uma política Permitir Tudo, você deve adicionar a política proibitiva acima com um elemento de 
ingress vazio:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all namespace: default spec: podSelector: {} ingress: # <<< - {} # <<< policyTypes: - Ingress 

Ele permite o acesso de 
todos os pods em todos os namespaces (e todos os IPs) a quaisquer pods no namespace default . Esse comportamento é ativado por padrão, portanto, geralmente não precisa ser definido adicionalmente. No entanto, às vezes pode ser necessário desativar temporariamente algumas permissões específicas para diagnosticar o problema.
A regra pode ser restrita e permitida o acesso apenas a um 
conjunto específico de pods ( 
app:balance ) no espaço de nome 
default :
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-to-balance namespace: default spec: podSelector: matchLabels: app: balance ingress: - {} policyTypes: - Ingress 

A política a seguir permite todo o tráfego de entrada e saída, incluindo o acesso a qualquer IP fora do cluster:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} ingress: - {} egress: - {} policyTypes: - Ingress - Egress 


Combinando várias políticas
As políticas são combinadas usando OR lógico em três níveis; as permissões de cada pod são definidas de acordo com a disjunção de todas as políticas que o afetam:
1. Nos campos 
from e 
to , você pode definir três tipos de elementos (todos eles são combinados usando OR):
- namespaceSelector- seleciona o espaço para nome inteiro;
- podSelector- seleciona pods;
- ipBlock- seleciona uma sub-rede.
Ao mesmo tempo, o número de elementos (mesmo o mesmo) nas subseções 
from / 
to não é limitado. Todos eles serão combinados por OR lógico.
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer - podSelector: matchLabels: app: admin podSelector: matchLabels: app: postgres policyTypes: - Ingress 

2. Dentro da política, a seção de 
ingress pode ter muitos elementos (combinados por OR lógico). Da mesma forma, a seção de 
egress pode incluir muitos elementos (também unidos por uma cláusula):
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer - from: - podSelector: matchLabels: app: admin podSelector: matchLabels: app: postgres policyTypes: - Ingress 

3. Várias políticas também são combinadas por OR lógico
Mas, ao combiná-los, há uma limitação que 
Chris Cooney apontou : o Kubernetes só pode combinar políticas com diferentes 
policyTypes políticas ( 
Ingress ou 
Egress ). As políticas que definem entrada (ou saída) serão substituídas uma pela outra.
O relacionamento entre namespaces
Por padrão, a troca de informações entre espaços para nome é permitida. Isso pode ser alterado usando uma política proibitiva que restrinja o tráfego de saída e / ou entrada para o espaço para nome (consulte "Regra de remoção" acima).
Ao bloquear o acesso ao espaço para nome (consulte "Regra de remoção" acima), você pode fazer exceções à política restritiva, permitindo conexões de um espaço para nome específico usando o 
namespaceSelector :
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: database.postgres namespace: database spec: podSelector: matchLabels: app: postgres ingress: - from: - namespaceSelector: # <<< matchLabels: namespace: default policyTypes: - Ingress 

Como resultado, todos os pods no namespace 
default terão acesso aos pods do 
postgres no namespace do 
database . Mas e se você deseja abrir o acesso ao 
postgres apenas para pods específicos no espaço para nome 
default ?
Filtrar por namespaces e pods
O Kubernetes versão 1.11 e superior permite combinar os operadores 
namespaceSelector e 
podSelector usando o lógico I. É assim:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: database.postgres namespace: database spec: podSelector: matchLabels: app: postgres ingress: - from: - namespaceSelector: matchLabels: namespace: default podSelector: # <<< matchLabels: app: admin policyTypes: - Ingress 

Por que é interpretado como AND em vez do OR usual?
Observe que o 
podSelector não inicia com um hífen. No YAML, isso significa que 
podSelector e o 
namespaceSelector em frente a ele se referem ao mesmo item da lista. Portanto, eles são combinados pelo lógico I.
Adicionar um hífen na frente do 
podSelector resultará em um novo item da lista que será combinado com o 
namespaceSelector anterior usando um OR lógico.
Para selecionar pods com um rótulo específico 
em todos os espaços para nome , insira um 
namespaceSelector vazio
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: database.postgres namespace: database spec: podSelector: matchLabels: app: postgres ingress: - from: - namespaceSelector: {} podSelector: matchLabels: app: admin policyTypes: - Ingress 

Vários rótulos combinam com AND
As regras para um firewall com muitos objetos (hosts, redes, grupos) são combinadas usando um OR lógico. A regra a seguir funcionará se a origem do pacote corresponder ao 
Host_1 OU 
Host_2 :
 | Source | Destination | Service | Action | | ----------------------------------------| | Host_1 | Subnet_A | HTTPS | Allow | | Host_2 | | | | | ----------------------------------------| 
Por outro lado, no Kubernetes, vários rótulos no 
podSelector ou 
namespaceSelector são combinados pelo lógico I. Por exemplo, a regra a seguir seleciona os pods que possuem os dois rótulos, 
role=db AND 
version=v2 :
 podSelector: matchLabels: role: db version: v2 
A mesma lógica se aplica a todos os tipos de operadores: seletores de objetivos de política, seletores de pod e seletores de namespace.
Sub-redes e endereços IP (IPBlocks)
Os firewalls usam VLANs, endereços IP e sub-redes para segmentar uma rede.
No Kubernetes, os endereços IP são atribuídos aos pods automaticamente e podem ser alterados com frequência; portanto, os rótulos são usados para selecionar pods e namespaces nas políticas de rede.
ipBlocks ( 
ipBlocks ) são usadas para controlar as conexões externas de entrada (entrada) ou saída (saída) (norte-sul). Por exemplo, esta política concede a todos os pods do espaço de nomes 
default acesso ao serviço DNS do Google:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-dns namespace: default spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 8.8.8.8/32 ports: - protocol: UDP port: 53 

O seletor de pod vazio neste exemplo significa "selecionar todos os pods no espaço para nome".
Esta política fornece acesso apenas ao 8.8.8.8; o acesso a qualquer outro IP é negado. Portanto, em essência, você bloqueou o acesso ao serviço DNS interno do Kubernetes. Se você ainda deseja abri-lo, especifique-o explicitamente.
Normalmente, os 
ipBlocks e 
podSelectors são mutuamente exclusivos, pois os endereços IP internos dos pods não são usados nos 
ipBlocks . 
Ao especificar 
os pods IP internos , você realmente permitirá conexões de / para pods com esses endereços. Na prática, você não saberá qual endereço IP usar, e é por isso que eles não devem ser usados para selecionar pods.
Como um contra-exemplo, a política a seguir inclui todos os IPs e, portanto, permite o acesso a todos os outros pods:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-any namespace: default spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 0.0.0.0/0 

Você pode abrir o acesso apenas a IPs externos excluindo os endereços IP internos dos pods. Por exemplo, se a sub-rede do seu pod for 10.16.0.0/14:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-any namespace: default spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 0.0.0.0/0 except: - 10.16.0.0/14 

Portas e protocolos
Geralmente, os pods escutam em uma porta. Isso significa que você pode simplesmente omitir números de porta nas políticas e deixar tudo como padrão. No entanto, é recomendável que as políticas sejam feitas o mais restritivo possível, portanto, em alguns casos, você ainda pode especificar portas:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer - podSelector: matchLabels: app: admin ports: # <<< - port: 443 # <<< protocol: TCP # <<< - port: 80 # <<< protocol: TCP # <<< podSelector: matchLabels: app: postgres policyTypes: - Ingress 

Observe que o seletor de 
ports se aplica a todos os elementos no bloco 
from ou 
from ele contém. Para especificar portas diferentes para diferentes conjuntos de elementos, divida a 
ingress ou 
egress em várias subseções com ou 
from e liste suas portas em cada:
 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer ports: # <<< - port: 443 # <<< protocol: TCP # <<< - from: - podSelector: matchLabels: app: admin ports: # <<< - port: 80 # <<< protocol: TCP # <<< podSelector: matchLabels: app: postgres policyTypes: - Ingress 

As portas padrão funcionam:
- Se você omitir completamente a definição de portas, isso significa todos os protocolos e todas as portas;
- Se você omitir a definição de protocolo, isso significa TCP;
- Se você omitir a definição de uma porta, isso significa todas as portas.
Prática recomendada: não confie nos valores padrão, especifique o que você precisa explicitamente.
Observe que é necessário usar portas de pod, não serviços (mais sobre isso no próximo parágrafo).
As políticas são definidas para pods ou serviços?
Geralmente, os pods no Kubernetes se comunicam por meio de um serviço - um balanceador de carga virtual que redireciona o tráfego para os pods que implementam o serviço. Você pode pensar que as políticas de rede controlam o acesso aos serviços, mas não é assim. 
As políticas de rede do Kubernetes funcionam com portas de pod, não com serviços., 80- , 8080 pod', 8080.
: ( pod') .
Service Mesh 
(, . Istio — . .) .
Ingress, Egress?
— , pod pod' , ( egress-), pod ( , , ingress-).
, .
pod- 
egress -, . pod'- 
. pod - , (egress) .
pod'- 
, 
ingress -, . pod'-. pod - , (ingress) .
. «Stateful Stateless» .
Kubernetes . , , .
Kubernetes (DNS) egress. , IP- ( aws.com).
. Kubernetes . kubectl Kubernetes , , . Kubernetes . :
 kubernetes get networkpolicy <policy-name> -o yaml 
, Kubernetes .
Kubernetes , API-, , Container Networking Interface (CNI). Kubernetes CNI . CNI , Kubernetes, 
( — . .) , , CNI .
, Kubernetes , CNI.
Stateful Stateless?
CNI Kubernetes, , (, Calico Linux conntrack). pod' TCP- . Kubernetes, (statefulness).
Kubernetes:
- Service Mesh sidecar- . Istio .
- CNI , Kubernetes.
- Tufin Orca Kubernetes.
Tufin Orca Kubernetes ( , ).
Informações Adicionais
Conclusão
Kubernetes , . , - . .
, , .
PS do tradutor
Leia também em nosso blog: