A conectividade do Kubernetes trata quatro preocupações:
Contêineres em um Pod se comunicam via interface loopback.
A conectividade do cluster provê a comunicação entre diferentes Pods.
O recurso de Service permite a você expor uma aplicação executando em um Pod,
de forma a ser alcançável de fora de seu cluster.
Você também pode usar os Services para publicar serviços de consumo interno do
seu cluster.
1 - Ingress
Disponibilize seu serviço de rede HTTP ou HTTPS usando um mecanismo de configuração com reconhecimento de protocolo, que entende conceitos da Web como URIs, nomes de host, caminhos e muito mais. O conceito Ingress permite mapear o tráfego para diferentes backends com base nas regras definidas por meio da API do Kubernetes.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.19 [stable]
Um objeto da API (do inglês "Application Programming Interface") que gerencia o acesso externo aos serviços em um cluster, normalmente HTTP.
Um Ingress pode fornecer balanceamento de carga, terminação SSL e hospedagem
virtual baseada em nomes.
Terminologia
Para fins de clareza, este guia define os seguintes termos:
Nó: Uma máquina de trabalho no Kubernetes, parte de um cluster.
Cluster: Um conjunto de nós que executam aplicações em contêiner gerenciado pelo Kubernetes. Para este exemplo, e nas instalações mais comuns do Kubernetes, os nós no cluster não fazem parte da Internet pública.
Roteador de borda: Um roteador que impõe a política de firewall para o seu cluster. Isso pode ser um gateway gerenciado por um provedor de nuvem ou um hardware físico.
Rede do cluster: Um conjunto de links, lógicos ou físicos, que facilitam a comunicação dentro de um cluster de acordo com o modelo de rede do Kubernetes.
Serviço: Um objeto serviço do Kubernetes que identifica um conjunto de Pods usando seletores de label. Salvo indicação em contrário, assume-se que os Serviços tenham IPs virtuais apenas roteáveis dentro da rede de cluster.
O que é o Ingress?
O Ingress expõe rotas HTTP e HTTPS de fora do cluster para um serviço dentro do cluster.
O roteamento do tráfego é controlado por regras definidas no recurso Ingress.
Aqui está um exemplo simples em que o Ingress envia todo o seu tráfego para um serviço:
Um Ingress pode ser configurado para fornecer URLs acessíveis externamente aos serviços, balanceamento de carga de tráfego, terminação SSL/TLS e oferecer hospedagem virtual baseada em nome.
Um controlador Ingress é responsável por atender o Ingress, geralmente com um balanceador de carga, embora também possa configurar seu roteador de borda ou frontends adicionais para ajudar a lidar com o tráfego.
Um Ingress não expõe portas ou protocolos arbitrários.
Normalmente se usa um serviço do tipo Service.Type=NodePort ou Service.Type=LoadBalancer para expor serviços à Internet que não sejam HTTP e HTTPS.
Pré-requisitos
Você deve ter um controlador Ingress para satisfazer um Ingress.
Apenas a criação de um recurso Ingress não tem efeito.
Idealmente, todos os controladores Ingress devem se encaixar na especificação de referência.
Na realidade, os vários controladores Ingress operam de forma ligeiramente diferente.
Nota: Certifique-se de revisar a documentação do seu controlador Ingress para entender as ressalvas de escolhê-lo.
Um Ingress precisa dos campos apiVersion, kind, metadata e spec.
O nome de um objeto Ingress deve ser um nome de subdomínio DNS válido.
Para obter informações gerais sobre como trabalhar com arquivos de configuração, consulte como instalar aplicações, como configurar contêineres e como gerenciar recursos.
O Ingress frequentemente usa anotações para configurar opções dependendo do controlador Ingress. Um exemplo deste uso é a anotação rewrite-target.
Diferentes controladores Ingress suportam diferentes anotações.
Revise a documentação do seu controlador Ingress escolhido para saber quais anotações são suportadas.
A especificação Ingress tem todas as informações necessárias para configurar um balanceador de carga ou servidor proxy.
Mais importante ainda, ele contém uma lista de regras correspondentes a todas as solicitações recebidas.
O recurso Ingress suporta apenas regras para direcionar o tráfego HTTP(S).
Existem alguns controladores Ingress que funcionam sem a definição de uma IngressClass padrão.
Por exemplo, o controlador Ingress-NGINX pode ser configurado com uma flag--watch-ingress-without-class.
No entanto, recomenda-se especificar a IngressClass padrão, conforme mostrado abaixo.
Regras do Ingress
Cada regra HTTP contém as seguintes informações:
Um host opcional. Neste exemplo, nenhum host é especificado, portanto, a regra se aplica a todo o tráfego HTTP de entrada através do endereço IP especificado.
Se um host for fornecido (por exemplo, foo.bar.com), as regras se aplicam a esse host.
Uma lista de caminhos (por exemplo, /testpath), cada um com um backend associado definido com um service.name e um service.port.name ou service.port.number.
Tanto o host quanto o caminho devem corresponder ao conteúdo de uma solicitação recebida antes que o balanceador de carga direcione o tráfego para o serviço referenciado.
Um backend é uma combinação de nomes de serviço e porta, conforme descrito na documentação de Services ou um backend de recursos personalizados por meio de um CRD.
As solicitações HTTP e HTTPS para o Ingress que correspondem ao host e ao caminho da regra são enviadas para o backend listado.
Um defaultBackend geralmente é configurado em um controlador Ingress para atender a quaisquer solicitações que não correspondam a um caminho na especificação.
DefaultBackend
Um Ingress sem regras envia todo o tráfego para um único backend padrão e .spec.defaultBackend é o backend que deve lidar com as solicitações nesse caso.
O defaultBackend é convencionalmente uma opção de configuração do controlador Ingress e não é especificado em seus recursos Ingress.
Se nenhum .spec.rules for especificado, o .spec.defaultBackend deve ser especificado.
Se o defaultBackend não for definido, o tratamento de solicitações que não correspondem a nenhuma das regras ficará a cargo do controlador de Ingress (consulte a documentação do seu controlador de Ingress para descobrir como ele lida com esse caso).
Se nenhum dos hosts ou caminhos corresponder à solicitação HTTP nos objetos Ingress, o tráfego será roteado para o seu backend padrão.
Resource backends
Um Resource backend é um ObjectRef para outro recurso Kubernetes dentro do mesmo namespace que o objeto Ingress.
Um Resource é uma configuração mutuamente exclusiva com o serviço, e a validação irá falhar se ambos forem especificados.
Um uso comum para um Resource backend é inserir dados em um backend de armazenamento de objetos com ativos estáticos.
Cada caminho no Ingress deve ter um tipo de caminho correspondente.
Os caminhos que não incluem um pathType explícito falharão na validação.
Existem três tipos de caminho suportados:
ImplementationSpecific: Com esse tipo de caminho, a correspondência depende da IngressClass. As implementações podem tratar isso como um pathType separado ou tratá-lo de forma idêntica aos tipos de caminho Prefix ou Exact.
Exact: Corresponde exatamente ao caminho da URL podendo ser case-sensitive.
Prefix: Corresponde com base em um prefixo de caminho de URL dividido por /. A correspondência faz distinção entre maiúsculas e minúsculas e é feita em um caminho, elemento por elemento. Um elemento de caminho refere-se à lista de labels no caminho dividido pelo separador /. Uma solicitação é uma correspondência para o caminho p se cada p for um prefixo elementar de p do caminho da solicitação.
Nota: Se o último elemento do caminho for uma substring do último elemento no caminho da solicitação, não é uma correspondência (por exemplo: /foo/bar corresponde a /foo/bar/baz, mas não corresponde a /foo/barbaz).
Exemplos
Tipos
Caminho(s)
Caminho(s) de solicitação
Correspondências?
Prefix
/
(todos os caminhos)
Sim
Exact
/foo
/foo
Sim
Exact
/foo
/bar
Não
Exact
/foo
/foo/
Não
Exact
/foo/
/foo
Não
Prefix
/foo
/foo, /foo/
Sim
Prefix
/foo/
/foo, /foo/
Sim
Prefix
/aaa/bb
/aaa/bbb
Não
Prefix
/aaa/bbb
/aaa/bbb
Sim
Prefix
/aaa/bbb/
/aaa/bbb
Sim, ignora a barra final
Prefix
/aaa/bbb
/aaa/bbb/
Sim, combina com a barra final
Prefix
/aaa/bbb
/aaa/bbb/ccc
Sim, corresponde ao subcaminho
Prefix
/aaa/bbb
/aaa/bbbxyz
Não, não corresponde ao prefixo da string
Prefix
/, /aaa
/aaa/ccc
Sim, corresponde ao prefixo /aaa
Prefix
/, /aaa, /aaa/bbb
/aaa/bbb
Sim, corresponde ao prefixo /aaa/bbb
Prefix
/, /aaa, /aaa/bbb
/ccc
Sim, corresponde ao prefixo /
Prefix
/aaa
/ccc
Não, usa o backend padrão
Mixed
/foo (Prefix), /foo (Exact)
/foo
Sim, prefere o exact
Várias correspondências
Em alguns casos, vários caminhos dentro de uma entrada corresponderão a uma solicitação.
Nesses casos, a precedência será dada primeiro ao caminho correspondente mais longo.
Se dois caminhos ainda estiverem iguais, a precedência será dada aos caminhos com um tipo de caminho exato sobre o tipo de caminho de prefixo.
Hostname curingas
Os hosts podem ter correspondências precisas (por exemplo, “foo.bar.com”) ou um curinga (por exemplo, “*.foo.com”).
Correspondências precisas exigem que o cabeçalho do host HTTP corresponda ao campo host.
As correspondências curinga exigem que o cabeçalho do host HTTP seja igual ao sufixo da regra curinga.
Host
Host header
Corresponde?
*.foo.com
bar.foo.com
Correspondências baseadas no sufixo compartilhado
*.foo.com
baz.bar.foo.com
Sem correspondência, o curinga cobre apenas um único rótulo DNS
*.foo.com
foo.com
Sem correspondência, o curinga cobre apenas um único rótulo DNS
Os Ingress podem ser implementados por diferentes controladores, muitas vezes com diferentes configurações.
Cada Ingress deve especificar uma classe, uma referência a um recurso IngressClass que contém uma configuração adicional, incluindo o nome do controlador que deve implementar a classe.
O campo .spec.parameters de uma classe Ingress permite que você faça referência a outro recurso que fornece a configuração relacionada a essa classe Ingress.
O tipo específico de parâmetros a serem usados depende do controlador Ingress que você especificar no campo .spec.controller da classe Ingress.
Escopo da classe Ingress
Dependendo do seu controlador Ingress, os parâmetros definidos em todo o cluster ou apenas para um namespace poderão ser utilizados.
O escopo padrão para os parâmetros da classe Ingress é em todo o cluster.
Se você definir o campo .spec.parameters e não definir .spec.parameters.scope, ou se você definir .spec.parameters.scope como Cluster, então a classe Ingress se refere a um recurso com escopo de cluster.
O kind (em combinação com o apiGroup) dos parâmetros refere-se a uma API com escopo de cluster (possivelmente um recurso personalizado), e o name dos parâmetros identifica um recurso específico com escopo de cluster para essa API.
Por exemplo:
---apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:external-lb-1spec:controller:example.com/ingress-controllerparameters:# Os parâmetros para esta classe Ingress são especificados em um# ClusterIngressParameter (grupo de API k8s.example.net) nomeado# "external-config-1". Esta definição diz ao Kubernetes para# procurar um recurso de parâmetro com escopo de cluster. scope:ClusterapiGroup:k8s.example.netkind:ClusterIngressParametername:external-config-1
ESTADO DA FUNCIONALIDADE:Kubernetes v1.23 [stable]
Se você definir o campo .spec.parameters e definir .spec.parameters.scope como Namespace, a classe Ingress terá como referência um recurso com escopo de namespace.
Você também deve definir o campo namespace dentro de .spec.parameters para o namespace que contém os parâmetros que deseja usar.
O campo kind (em combinação com o campo apiGroup) dos parâmetros refere-se a uma API com namespace (por exemplo: ConfigMap), e o campo name dos parâmetros identifica um recurso específico no namespace que você especificou no campo namespace.
Os parâmetros com escopo de namespace ajudam o operador de cluster a delegar o controle sobre a configuração (por exemplo: configurações do balanceador de carga, definição de gateway API) que é usada para uma carga de trabalho.
Se você usou um parâmetro com escopo de cluster, então:
A equipe do operador do cluster precisa aprovar as alterações de uma equipe diferente toda vez que houver uma nova alteração de configuração sendo aplicada.
O operador de cluster deve definir controles de acesso específicos, como funções e vínculos RBAC, que permitem que a equipe do aplicativo faça alterações no recurso de parâmetros do escopo do cluster.
A própria API do IngressClass é sempre com escopo de cluster.
Aqui está um exemplo de uma classe Ingress que se refere a parâmetros com namespace:
---apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:external-lb-2spec:controller:example.com/ingress-controllerparameters:# The parameters for this IngressClass are specified in an# IngressParameter (API group k8s.example.com) named "external-config",# that's in the "external-configuration" namespace.scope:NamespaceapiGroup:k8s.example.comkind:IngressParameternamespace:external-configurationname:external-config
Anotação obsoleta
Antes que o recurso IngressClass e o campo ingressClassName fossem adicionados no Kubernetes 1.18, as classes Ingress foram especificadas com uma anotação kubernetes.io/ingress.class no Ingress.
Esta anotação nunca foi formalmente definida, mas foi amplamente apoiada pelos controladores Ingress.
O campo ingressClassName mais recente no Ingress é um substituto para essa anotação, mas não é um equivalente direto.
Embora a anotação tenha sido geralmente usada para fazer referência ao nome do controlador Ingress que deve implementar o Ingress, o campo é uma referência a um recurso IngressClass que contém a configuração Ingress adicional, incluindo o nome do controlador Ingress.
Classe Ingress Padrão
Você pode marcar uma classe Ingress específica como padrão para o seu cluster.
Definir a anotação ingressclass.kubernetes.io/is-default-class como true em um recurso IngressClass garantirá que novos Ingress sem um campo ingressClassName especificado sejam atribuídos a esta ingressClassName padrão.
Cuidado: Se você tiver mais de uma classe Ingress marcada como padrão para o seu cluster, o controlador de admissão impede a criação de novos objetos Ingress que não tenham um ingressClassName especificado.
Você pode resolver isso garantindo que no máximo uma classe Ingress seja marcada como padrão no seu cluster.
Existem alguns controladores Ingress que funcionam sem a definição de uma IngressClass padrão.
Por exemplo, o controlador Ingress-NGINX pode ser configurado com uma flag--watch-ingress-without-class.
No entanto, é recomendável especificar a IngressClass padrão:
No Kubernetes existem conceitos que permitem expor um único serviço (veja alternativas).
Você também pode fazer isso com um Ingress especificando um backend padrão sem regras.
Se você criá-lo usando kubectl apply -f, você deve ser capaz de visualizar o estado do Ingress que você adicionou:
kubectl get ingress test-ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress external-lb * 203.0.113.123 80 59s
Onde 203.0.113.123 é o IP alocado pelo controlador Ingress para satisfazer o Ingress.
Nota: Controladores Ingress e balanceadores de carga podem levar um ou dois minutos para alocar um endereço IP.
Até aquele momento, você costuma ver o endereço listado como <pending>.
Simples fanout
Uma configuração de fanout roteia o tráfego de um único endereço IP para mais de um serviço, com base na URI HTTP que está sendo solicitada.
Um Ingress permite que você mantenha o número de balanceadores de carga no mínimo.
Por exemplo, uma configuração como:
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
O controlador Ingress fornece um balanceador de carga específico de implementação que satisfaz o Ingress, desde que os serviços (service1, service2) existam.
Quando tiver feito isso, você pode ver o endereço do balanceador de carga no campo Address.
Nota: Dependendo do controlador Ingress que você está usando, talvez seja necessário criar um serviço de backend http padrão.
Hospedagem virtual baseada em nome
Os hosts virtuais baseados em nomes suportam o roteamento de tráfego HTTP para vários nomes de host no mesmo endereço IP.
O Ingress a seguir diz ao balanceador de carga de apoio para rotear solicitações com base no Host header.
Se você criar um recurso de Ingress sem nenhum host definido nas regras, qualquer tráfego da web para o endereço IP do seu controlador de Ingress pode ser correspondido sem que seja necessário um host virtual baseado em nome.
Por exemplo, o Ingress a seguir roteia o tráfego solicitado para first.bar.com para service1, second.bar.com para service2 e qualquer tráfego cujo cabeçalho de host de solicitação não corresponda a first.bar.com e second.bar.com para service3.
Você pode configurar o uso de TLS no Ingress especificando um Secret que contém uma chave privada e um certificado TLS.
O recurso Ingress suporta apenas uma única porta TLS, 443, e assume a terminação TLS no ponto de entrada (o tráfego para o Serviço e seus Pods não está criptografado o que é inseguro).
Se a seção de configuração TLS em um Ingress especificar hosts diferentes, eles serão multiplexados na mesma porta de acordo com o nome do host especificado através da extensão SNI TLS (desde que o controlador Ingress suporte SNI).
O objeto Secret do tipo TLS deve conter chaves chamadas tls.crt e tls.key que contêm o certificado e a chave privada a ser usada para TLS.
Fazer referência a esse segredo em um Ingress diz ao controlador Ingress para proteger o canal do cliente para o balanceador de carga usando TLS.
Você precisa ter certeza de que o objeto Secret do tipo TLS que você criou é originário de um certificado que contém um Nome Comum (Common
Name, CN), também conhecido como Nome de Domínio Totalmente Qualificado (Fully Qualified Domain Name, FQDN), tal como https-example.foo.com.
Nota: Tenha em mente que o TLS não funcionará na regra padrão porque os certificados teriam que ser emitidos para todos os subdomínios possíveis.
Portanto, os hosts na seção tls precisam corresponder explicitamente ao host na seção rules.
Nota: Há uma lacuna entre os recursos TLS suportados por vários controladores Ingress.
Consulte a documentação sobre nginx, GCE ou qualquer outro controlador Ingress específico da plataforma para entender como o TLS funciona em seu ambiente.
Balanceador de carga
Um controlador Ingress é inicializado com algumas configurações de política de balanceamento de carga que se aplicam a todos os Ingress, como o algoritmo de balanceamento de carga, esquema de peso de backend e outros.
Conceitos mais avançados de balanceamento de carga (por exemplo, sessões persistentes, pesos dinâmicos) ainda não estão expostos através do Ingress.
Em vez disso, você pode obter esses recursos através do balanceador de carga usado para um serviço.
Também vale a pena notar que, embora as verificações de integridade não sejam expostas diretamente através do Ingress, existem conceitos paralelos no Kubernetes, como readiness probes, que permitem alcançar o mesmo resultado final.
Revise a documentação específica do controlador para ver como eles lidam com as verificações de integridade (por exemplo: nginx ou GCE).
Atualizando um Ingress
Para atualizar um Ingress existente para adicionar um novo Host, você pode atualizá-lo editando o recurso:
kubectl describe ingress test
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 35s loadbalancer-controller default/test
kubectl edit ingress test
Isso abre um editor com a configuração existente no formato YAML.
Para incluir o novo host modifique:
Depois de salvar suas alterações, o kubectl atualizará o recurso no servidor API, que diz ao controlador Ingress para reconfigurar o balanceador de carga.
Verifique isso:
kubectl describe ingress test
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
bar.baz.com
/foo service2:80 (10.8.0.91:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 45s loadbalancer-controller default/test
Você pode alcançar o mesmo resultado invocando kubectl replace -f em um arquivo Ingress YAML modificado.
Falha nas zonas de disponibilidade
Técnicas para distribuir o tráfego entre domínios de falha diferem entre os provedores de nuvem.
Verifique a documentação do controlador Ingress para obter detalhes relevantes.
Alternativas
Você pode expor um serviço de várias maneiras que não envolve diretamente o recurso Ingress:
Se você deseja controlar o fluxo do tráfego de rede no nível do endereço IP ou de portas TCP e UDP
(camadas OSI 3 e 4) então você deve considerar usar Políticas de rede (NetworkPolicies) do Kubernetes para aplicações
no seu cluster. NetworkPolicy é um objeto focado em aplicações/experiência do desenvolvedor
que permite especificar como é permitido a um pod
comunicar-se com várias "entidades" de rede.
As entidades que um Pod pode se comunicar são identificadas através de uma combinação dos 3
identificadores à seguir:
Outros pods que são permitidos (exceção: um pod não pode bloquear a si próprio)
Namespaces que são permitidos
Blocos de IP (exceção: o tráfego de e para o nó que um Pod está executando sempre é permitido,
independentemente do endereço IP do Pod ou do Nó)
Quando definimos uma política de rede baseada em pod ou namespace, utiliza-se um selector
para especificar qual tráfego é permitido de e para o(s) Pod(s) que correspondem ao seletor.
Quando uma política de redes baseada em IP é criada, nós definimos a política baseada em blocos de IP (faixas CIDR).
Pré requisitos
As políticas de rede são implementadas pelo plugin de redes. Para usar
uma política de redes, você deve usar uma solução de redes que suporte o objeto NetworkPolicy.
A criação de um objeto NetworkPolicy sem um controlador que implemente essas regras não tem efeito.
Pods isolados e não isolados
Por padrão, pods não são isolados; eles aceitam tráfego de qualquer origem.
Os pods tornam-se isolados ao existir uma NetworkPolicy que selecione eles. Uma vez que
exista qualquer NetworkPolicy no namespace selecionando um pod em específico, aquele pod
irá rejeitar qualquer conexão não permitida por qualquer NetworkPolicy. (Outros pod no mesmo
namespace que não são selecionados por nenhuma outra NetworkPolicy irão continuar aceitando
todo tráfego de rede.)
As políticas de rede não conflitam; elas são aditivas. Se qualquer política selecionar um pod,
o pod torna-se restrito ao que é permitido pela união das regras de entrada/saída de tráfego definidas
nas políticas. Assim, a ordem de avaliação não afeta o resultado da política.
Para o fluxo de rede entre dois pods ser permitido, tanto a política de saída no pod de origem
e a política de entrada no pod de destino devem permitir o tráfego. Se a política de saída na
origem, ou a política de entrada no destino negar o tráfego, o tráfego será bloqueado.
O recurso NetworkPolicy
Veja a referência NetworkPolicy para uma definição completa do recurso.
Nota: Criar esse objeto no seu cluster não terá efeito a não ser que você escolha uma
solução de redes que suporte políticas de rede.
Campos obrigatórios: Assim como todas as outras configurações do Kubernetes, uma NetworkPolicy
necessita dos campos apiVersion, kind e metadata. Para maiores informações sobre
trabalhar com arquivos de configuração, veja
Configurando containeres usando ConfigMap,
e Gerenciamento de objetos.
spec: A spec contém todas as informações necessárias
para definir uma política de redes em um namespace.
podSelector: Cada NetworkPolicy inclui um podSelector que seleciona o grupo de pods
que a política se aplica. A política acima seleciona os pods com a label "role=db". Um podSelector
vazio seleciona todos os pods no namespace.
policyTypes: Cada NetworkPolicy inclui uma lista de policyTypes que pode incluir Ingress,
Egress ou ambos. O campo policyTypes indica se a política se aplica ao tráfego de entrada
com destino aos pods selecionados, o tráfego de saída com origem dos pods selecionados ou ambos.
Se nenhum policyType for definido então por padrão o tipo Ingress será sempre utilizado, e o
tipo Egress será configurado apenas se o objeto contiver alguma regra de saída. (campo egress a seguir).
ingress: Cada NetworkPolicy pode incluir uma lista de regras de entrada permitidas através do campo ingress.
Cada regra permite o tráfego que corresponde simultaneamente às sessões from (de) e ports (portas).
A política de exemplo acima contém uma regra simples, que corresponde ao tráfego em uma única porta,
de uma das três origens definidas, sendo a primeira definida via ipBlock, a segunda via namespaceSelector e
a terceira via podSelector.
egress: Cada política pode incluir uma lista de regras de regras de saída permitidas através do campo egress.
Cada regra permite o tráfego que corresponde simultaneamente às sessões to (para) e ports (portas).
A política de exemplo acima contém uma regra simples, que corresponde ao tráfego destinado a uma
porta em qualquer destino pertencente à faixa de IPs em 10.0.0.0/24.
Então a NetworkPolicy acima:
Isola os pods no namespace "default" com a label "role=db" para ambos os tráfegos de entrada
e saída (se eles ainda não estavam isolados)
(Regras de entrada/ingress) permite conexões para todos os pods no namespace "default" com a label "role=db" na porta TCP 6379 de:
qualquer pod no namespace "default" com a label "role=frontend"
qualquer pod em um namespace que tenha a label "project=myproject" (aqui cabe ressaltar que o namespace que deve ter a label e não os pods dentro desse namespace)
IPs dentro das faixas 172.17.0.0–172.17.0.255 e 172.17.2.0–172.17.255.255 (ex.:, toda 172.17.0.0/16 exceto 172.17.1.0/24)
(Regras de saída/egress) permite conexões de qualquer pod no namespace "default" com a label
"role=db" para a faixa de destino 10.0.0.0/24 na porta TCP 5978.
Existem quatro tipos de seletores que podem ser especificados nas sessões ingress.from ou
egress.to:
podSelector: Seleciona Pods no mesmo namespace que a política de rede foi criada, e que deve
ser permitido origens no tráfego de entrada ou destinos no tráfego de saída.
namespaceSelector: Seleciona namespaces para o qual todos os Pods devem ser permitidos como
origens no caso de tráfego de entrada ou destino no tráfego de saída.
namespaceSelectorepodSelector: Uma entrada to/from única que permite especificar
ambos namespaceSelector e podSelector e seleciona um conjunto de Pods dentro de um namespace.
Seja cuidadoso em utilizar a sintaxe YAML correta; essa política:
contém dois elementos no conjunto from e permite conexões de Pods no namespace local com
a labelrole=client, OU de qualquer outro Pod em qualquer outro namespace que tenha
a label user=alice.
Quando estiver em dúvida, utilize o comando kubectl describe para verificar como o
Kubernetes interpretou a política.
ipBlock: Isso seleciona um conjunto particular de faixas de IP a serem permitidos como
origens no caso de entrada ou destinos no caso de saída. Devem ser considerados IPs externos
ao cluster, uma vez que os IPs dos Pods são efêmeros e imprevisíveis.
Os mecanismos de entrada e saída do cluster geralmente requerem que os IPs de origem ou destino
sejam reescritos. Em casos em que isso aconteça, não é definido se deve acontecer antes ou
depois do processamento da NetworkPolicy que corresponde a esse tráfego, e o comportamento
pode ser diferente para cada plugin de rede, provedor de nuvem, implementação de Service, etc.
No caso de tráfego de entrada, isso significa que em alguns casos você pode filtrar os pacotes
de entrada baseado no IP de origem atual, enquanto que em outros casos o IP de origem que
a NetworkPolicy atua pode ser o IP de um LoadBalancer ou do Nó em que o Pod está executando.
No caso de tráfego de saída, isso significa que conexões de Pods para Services que são reescritos
para IPs externos ao cluster podem ou não estar sujeitos a políticas baseadas no campo ipBlock.
Políticas padrão
Por padrão, se nenhuma política existir no namespace, então todo o tráfego de entrada e saída é
permitido de e para os pods nesse namespace. Os exemplos a seguir permitem a você mudar o
comportamento padrão nesse namespace.
Bloqueio padrão de todo tráfego de entrada
Você pode criar uma política padrão de isolamento para um namespace criando um objeto NetworkPolicy
que seleciona todos os pods mas não permite o tráfego de entrada para esses pods.
Isso garante que mesmo pods que não são selecionados por nenhuma outra política de rede ainda
serão isolados. Essa política não muda o comportamento padrão de isolamento de tráfego de saída
nesse namespace.
Permitir por padrão todo tráfego de entrada
Se você deseja permitir todo o tráfego de todos os pods em um namespace (mesmo que políticas que
sejam adicionadas faça com que alguns pods sejam tratados como "isolados"), você pode criar
uma política que permite explicitamente todo o tráfego naquele namespace.
Você pode criar uma política de isolamento de saída padrão para um namespace criando uma
política de redes que selecione todos os pods, mas não permita o tráfego de saída a partir
de nenhum desses pods.
Isso garante que mesmo pods que não são selecionados por outra política de rede não seja permitido
tráfego de saída. Essa política não muda o comportamento padrão de tráfego de entrada.
Permitir por padrão todo tráfego de saída
Caso você queira permitir todo o tráfego de todos os pods em um namespace (mesmo que políticas sejam
adicionadas e cause com que alguns pods sejam tratados como "isolados"), você pode criar uma
política explicita que permite todo o tráfego de saída no namespace.
Isso garante que mesmo pods que não são selecionados por nenhuma outra política de redes não
possuam permissão de tráfego de entrada ou saída.
Selecionando uma faixa de portas
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [alpha]
Ao escrever uma política de redes, você pode selecionar uma faixa de portas ao invés de uma
porta única, utilizando-se do campo endPort conforme a seguir:
A regra acima permite a qualquer Pod com a label "role=db" no namespace default de se comunicar
com qualquer IP na faixa 10.0.0.0/24 através de protocolo TCP, desde que a porta de destino
esteja na faixa entre 32000 e 32768.
As seguintes restrições aplicam-se ao se utilizar esse campo:
Por ser uma funcionalidade "alpha", ela é desativada por padrão. Para habilitar o campo endPort
no cluster, você (ou o seu administrador do cluster) deve habilitar o feature gateNetworkPolicyEndPort no kube-apiserver com a flag --feature-gates=NetworkPolicyEndPort=true,....
O valor de endPort deve ser igual ou maior ao valor do campo port.
O campo endPort só pode ser definido se o campo port também for definido.
Ambos os campos port e endPort devem ser números.
Nota: Seu cluster deve utilizar um plugin CNI
que suporte o campo endPort na especificação da política de redes.
Selecionando um Namespace pelo seu nome
ESTADO DA FUNCIONALIDADE:Kubernetes 1.21 [beta]
A camada de gerenciamento do Kubernetes configura uma label imutável kubernetes.io/metadata.name em
todos os namespaces, uma vez que o feature gate esteja habilitado por padrão.
O valor dessa label é o nome do namespace.
Enquanto que um objeto NetworkPolicy não pode selecionar um namespace pelo seu nome através de
um campo específico, você pode utilizar essa label padrão para selecionar um namespace pelo seu nome.
O que você não pode fazer com NetworkPolicies (ao menos por enquanto!)
Por enquanto no Kubernetes 1.28 as funcionalidades a seguir não existem
mas você pode conseguir implementar de forma alternativa utilizando componentes do Sistema Operacional
(como SELinux, OpenVSwitch, IPtables, etc) ou tecnologias da camada 7 OSI (Ingress controllers, implementações de service mesh) ou ainda admission controllers.
No caso do assunto "segurança de redes no Kubernetes" ser novo para você, vale notar que as
histórias de usuário a seguir ainda não podem ser implementadas:
Forçar o tráfego interno do cluster passar por um gateway comum (pode ser implementado via service mesh ou outros proxies)
Qualquer coisa relacionada a TLS/mTLS (use um service mesh ou ingress controller para isso)
Políticas específicas a nível do nó kubernetes (você pode utilizar as notações de IP CIDR para isso, mas não pode selecionar nós Kubernetes por suas identidades)
Selecionar Services pelo seu nome (você pode, contudo, selecionar pods e namespaces por seus labels o que torna-se uma solução de contorno viável).
Criação ou gerenciamento
Políticas padrão que são aplicadas a todos os namespaces e pods (existem alguns plugins externos do Kubernetes e projetos que podem fazer isso, e a comunidade está trabalhando nessa especificação).
Ferramental de testes para validação de políticas de redes.
Possibilidade de logar eventos de segurança de redes (conexões bloqueadas, aceitas). Existem plugins CNI que conseguem fazer isso à parte.
Possibilidade de explicitamente negar políticas de rede (o modelo das NetworkPolicies são "negar por padrão e conforme a necessidade, deve-se adicionar regras que permitam o tráfego).
Bloquear o tráfego que venha da interface de loopback/localhost ou que venham do nó em que o Pod se encontre.