

 **Ajudar a melhorar esta página** 

Para contribuir com este guia de usuário, escolha o link **Editar esta página no GitHub**, disponível no painel direito de cada página.

# Conceitos do Kubernetes para nós híbridos
<a name="hybrid-nodes-concepts-kubernetes"></a>

Esta página detalha os principais conceitos do Kubernetes que fundamentam a arquitetura do sistema do EKS Hybrid Nodes.

## Ambiente de gerenciamento do EKS na VPC
<a name="hybrid-nodes-concepts-k8s-api"></a>

Os IPs das ENIs do ambiente de gerenciamento do EKS são armazenados no objeto de `Endpoints` do `kubernetes` no namespace `default`. Quando o EKS cria novas ENIs ou remove as mais antigas, o EKS atualiza esse objeto para que a lista de IPs esteja sempre atualizada.

Você pode usar esses endpoints por meio do serviço do `kubernetes`, e também no namespace `default`. Esse serviço, do tipo `ClusterIP`, sempre tem atribuído o primeiro IP do CIDR de serviço do cluster. Por exemplo, para o CIDR do serviço `172.16.0.0/16`, o IP do serviço será `172.16.0.1`.

Geralmente, é assim que os pods (independentemente de serem executados na nuvem ou em nós híbridos) acessam o servidor de API do Kubernetes para EKS. Os pods usam o IP do serviço como o IP de destino, que é convertido para os IPs reais de uma das ENIs do ambiente de gerenciamento do EKS. A principal exceção é o `kube-proxy`, pois ele configura a conversão.

## Endpoint do servidor de API do EKS
<a name="hybrid-nodes-concepts-k8s-eks-api"></a>

O IP do serviço do `kubernetes` não é a única maneira de acessar o servidor de API do EKS. O EKS também criará um nome DNS do Route 53 quando você criar o cluster. Este é o campo do `endpoint` do seu cluster do EKS ao chamar a ação da API `DescribeCluster` do EKS.

```
{
    "cluster": {
        "endpoint": "https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com",
        "name": "my-cluster",
        "status": "ACTIVE"
    }
}
```

Em um acesso ao endpoint público ou em um cluster de acesso ao endpoint público e privado, seus nós híbridos resolverão esse nome DNS para um IP público por padrão, roteável pela internet. Em um cluster de acesso de endpoint privado, o nome DNS é resolvido para os IPs privados das ENIs do ambiente de gerenciamento do EKS.

É assim que o `kubelet` e o `kube-proxy` acessam o servidor de API do Kubernetes. Se você quiser que todo o tráfego do cluster do Kubernetes flua pela VPC, você precisa configurar o cluster no modo de acesso privado ou modificar o servidor DNS on-premises para resolver o endpoint do cluster do EKS para os IPs privados das ENIs do ambiente de gerenciamento do EKS.

## Endpoint do `kubelet`
<a name="hybrid-nodes-concepts-k8s-kubelet-api"></a>

O `kubelet` expõe vários endpoints REST, permitindo que outras partes do sistema interajam e coletem informações de cada nó. Na maioria dos clusters, a maior parte do tráfego para o servidor do `kubelet` vem do ambiente de gerenciamento, mas determinados agentes de monitoramento também podem interagir com ele.

Por meio dessa interface, o `kubelet` processa várias solicitações: busca de logs (`kubectl logs`), execução de comandos dentro de contêineres (`kubectl exec`) e tráfego de encaminhamento de portas (`kubectl port-forward`). Cada uma dessas solicitações interage com o runtime do contêiner subjacente por meio do `kubelet`, parecendo perfeita para administradores e desenvolvedores de clusters.

O consumidor mais comum dessa API é o servidor de API do Kubernetes. Quando você usa qualquer um dos comandos do `kubectl` mencionados anteriormente, o `kubectl` faz uma solicitação de API ao servidor de API, que então chama a API do `kubelet` do nó em que o pod está sendo executado. Este é o principal motivo pelo qual o IP do nó precisa estar acessível no ambiente de gerenciamento do EKS e por que, mesmo que seus pods estejam em execução, você não conseguirá acessar seus logs ou `exec` se a rota do nó estiver configurada incorretamente.

 **IPs de nós** 

Quando o ambiente de gerenciamento do EKS se comunica com um nó, ele usa um dos endereços informados no status do objeto do `Node` (`status.addresses`).

Com os nós de nuvem do EKS, é comum que o kubelet informe o IP privado da instância do EC2 como um `InternalIP` durante o registro do nó. Esse IP é então validado pelo Cloud Controller Manager (CCM), certificando-se de que ele pertença à instância do EC2. Além disso, o CCM normalmente adiciona os IPs públicos (como `ExternalIP`) e os nomes DNS (`InternalDNS` e `ExternalDNS`) da instância ao status do nó.

No entanto, não há um CCM para nós híbridos. Quando você registra um nó híbrido com a CLI do EKS Hybrid Nodes (`nodeadm`), ele configura o kubelet para informar o IP da máquina diretamente no status do nó, sem o CCM.

```
apiVersion: v1
kind: Node
metadata:
  name: my-node-1
spec:
  providerID: eks-hybrid:///us-west-2/my-cluster/my-node-1
status:
  addresses:
  - address: 10.1.1.236
    type: InternalIP
  - address: my-node-1
    type: Hostname
```

Caso a máquina tenha vários IPs, o kubelet selecionará um deles seguindo sua própria lógica. Você pode controlar o IP selecionado com o sinalizador `--node-ip`, que pode ser passado no config `nodeadm` em `spec.kubelet.flags`. Somente o IP informado no objeto do `Node` precisa de uma rota da VPC. As máquinas podem ter outros IPs que não podem ser acessados pela nuvem.

## `kube-proxy`
<a name="hybrid-nodes-concepts-k8s-kube-proxy"></a>

 O `kube-proxy` é responsável por implementar a abstração do serviço na camada de rede de cada nó. Ele atua como um proxy de rede e um balanceador de carga para o tráfego destinado aos serviços do Kubernetes. Ao observar continuamente o servidor de API do Kubernetes em busca de alterações relacionadas a serviços e endpoints, o `kube-proxy` atualiza dinamicamente as regras de rede do host subjacente para garantir que o tráfego seja direcionado adequadamente.

No modo `iptables`, o `kube-proxy` programa várias cadeias de `netfilter` para processar o tráfego do serviço. As regras formam a seguinte hierarquia:

1.  **Cadeia KUBE-SERVICES**: o ponto de entrada para todo o tráfego de serviços. Ele tem regras que correspondem a cada porta e `ClusterIP` do serviço.

1.  **Cadeias KUBE-SVC-XXX**: cadeias específicas de serviços que têm regras de balanceamento de carga para cada serviço.

1.  **Cadeias KUBE-SEP-XXX**: cadeias específicas de endpoints que têm as regras reais de `DNAT`.

Vamos examinar o que acontece com um serviço de `test-server` no namespace `default`: \$1 ClusterIP do serviço: `172.16.31.14` \$1 Porta de serviço: `80` \$1 Pods de backup: `10.2.0.110`, `10.2.1.39` e `10.2.2.254` 

Quando inspecionamos as regras de `iptables` (usando `iptables-save 0 grep -A10 KUBE-SERVICES`):

1. Na cadeia **KUBE-SERVICES**, encontramos uma regra correspondente ao serviço:

   ```
   -A KUBE-SERVICES -d 172.16.31.14/32 -p tcp -m comment --comment "default/test-server cluster IP" -m tcp --dport 80 -j KUBE-SVC-XYZABC123456
   ```
   + Essa regra corresponde aos pacotes destinados a 172.16.31.14:80
   + O comentário indica para que serve essa regra: `default/test-server cluster IP` 
   + Pacotes correspondentes vão para a cadeia `KUBE-SVC-XYZABC123456`

1. A cadeia **KUBE-SVC-XYZABC123456** tem regras de balanceamento de carga baseadas em probabilidade:

   ```
   -A KUBE-SVC-XYZABC123456 -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-POD1XYZABC
   -A KUBE-SVC-XYZABC123456 -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-POD2XYZABC
   -A KUBE-SVC-XYZABC123456 -j KUBE-SEP-POD3XYZABC
   ```
   + Primeira regra: 33,3% de chance de ir para `KUBE-SEP-POD1XYZABC` 
   + Segunda regra: 50% de chance de o tráfego restante (33,3% do total) ir para `KUBE-SEP-POD2XYZABC` 
   + Última regra: todo o tráfego restante (33,3% do total) vai para `KUBE-SEP-POD3XYZABC` 

1. As cadeias **KUBE-SEP-XXX** individuais executam o DNAT (NAT de destino):

   ```
   -A KUBE-SEP-POD1XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.0.110:80
   -A KUBE-SEP-POD2XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.1.39:80
   -A KUBE-SEP-POD3XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.2.254:80
   ```
   + Essas regras de DNAT regravam o IP e a porta de destino para direcionar o tráfego para pods específicos.
   + Cada regra processa cerca de 33,3% do tráfego, fornecendo um balanceamento de carga uniforme entre `10.2.0.110`, `10.2.1.39` e `10.2.2.254`.

Essa estrutura de cadeia de vários níveis permite que o `kube-proxy` implemente com eficiência o balanceamento e o redirecionamento da carga de serviço por meio da manipulação de pacotes no nível do kernel, sem exigir um processo de proxy no caminho dos dados.

### Impacto nas operações do Kubernetes
<a name="hybrid-nodes-concepts-k8s-operations"></a>

Uma falha no `kube-proxy` em um nó impede que esse nó roteie o tráfego do serviço adequadamente, causando tempos limite ou falhas nas conexões dos pods que dependem dos serviços do cluster. Isso pode ser especialmente disruptivo quando um nó é registrado pela primeira vez. A CNI precisa se comunicar com o servidor de API do Kubernetes para obter informações, como o CIDR do pod do nó, antes de poder configurar qualquer rede de pods. Para fazer isso, ela usa o IP do serviço do `kubernetes`. No entanto, se o `kube-proxy` não pôde iniciar ou não conseguiu definir as regras corretas de `iptables`, as solicitações que irão para o IP do serviço do `kubernetes` não serão convertidas para os IPs reais das ENIs do ambiente de gerenciamento do EKS. Como consequência, a CNI entrará em um loop de falha e nenhum dos pods será executado corretamente.

Sabemos que os pods usam o IP do serviço do `kubernetes` para se comunicar com o servidor de API do Kubernetes, mas o `kube-proxy` precisa primeiro definir as regras de `iptables` para que isso funcione.

Como o `kube-proxy` se comunica com o servidor de API?

O `kube-proxy` deve ser configurado para usar os IPs reais do servidor de API do Kubernetes ou um nome DNS que os determine. No caso do EKS, ele configura o `kube-proxy` padrão para apontar para o nome DNS do Route 53 que o EKS cria quando você cria o cluster. Você pode ver esse valor no ConfigMap do `kube-proxy` no namespace do `kube-system`. O conteúdo desse ConfigMap é um `kubeconfig` que é injetado no pod do `kube-proxy`, portanto, localize o campo `clusters0.cluster.server`. Esse valor corresponderá ao campo do `endpoint` do cluster do EKS (ao chamar a API `DescribeCluster` do EKS).

```
apiVersion: v1
data:
  kubeconfig: |-
    kind: Config
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        server: https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com
      name: default
    contexts:
    - context:
        cluster: default
        namespace: default
        user: default
      name: default
    current-context: default
    users:
    - name: default
      user:
        tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
kind: ConfigMap
metadata:
  name: kube-proxy
  namespace: kube-system
```

## CIDRs de pods remotos roteáveis
<a name="hybrid-nodes-concepts-k8s-pod-cidrs"></a>

A página [Conceitos de rede para nós híbridos](hybrid-nodes-concepts-networking.md) detalha os requisitos para executar webhooks em nós híbridos ou para que os pods executados em nós de nuvem se comuniquem com os pods executados em nós híbridos. O principal requisito é que o roteador on-premises precisa saber qual nó é responsável por um determinado IP de pod. Há várias maneiras de fazer isso, incluindo o Protocolo de Gateway da Borda (BGP), rotas estáticas e o proxy Address Resolution Protocol (ARP). Essas formas são abordadas nas próximas seções.

 **Protocolo de Gateway da Borda (BGP)** 

Se a CNI for compatível (como Cilium e Calico), você poderá usar o modo BGP da CNI para propagar rotas para os CIDRs de pods por nó dos nós para o roteador local. Ao usar o modo BGP da CNI, a CNI atua como um roteador virtual, então o roteador local acha que o CIDR do pod pertence a outra sub-rede e seu nó é o gateway para essa sub-rede.

![\[Roteamento BGP para nós híbridos\]](http://docs.aws.amazon.com/pt_br/eks/latest/userguide/images/hybrid-nodes-bgp.png)


 **Rotas estáticas** 

Como alternativa, é possível configurar rotas estáticas no roteador local. Esta é a maneira mais simples de rotear o CIDR do pod on-premises para a VPC, mas também é a mais propensa a erros e difícil de manter. Você precisa garantir que as rotas estejam sempre atualizadas com os nós existentes e seus CIDRs de pods atribuídos. Se o número de nós for pequeno e a infraestrutura for estática, esta é uma opção viável e elimina a necessidade de suporte do BGP em seu roteador. Se você optar por isso, recomendamos configurar a CNI com a parcela do CIDR do pod que você deseja atribuir a cada nó, em vez de deixar que o IPAM decida.

![\[Roteamento estático para nós híbridos\]](http://docs.aws.amazon.com/pt_br/eks/latest/userguide/images/hybrid-nodes-static-routes.png)


 **Proxy Address Resolution Protocol (ARP)** 

O proxy ARP é outra abordagem para tornar os IPs de pods on-premises roteáveis, particularmente útil quando os nós híbridos estão na mesma rede de camada 2 do roteador local. Com o proxy ARP habilitado, um nó responde às solicitações de ARP dos IPs de pods que ele hospeda, mesmo que esses IPs pertençam a outra sub-rede.

Quando um dispositivo em sua rede local tenta acessar um IP de pod, ele primeiro envia uma solicitação ao ARP perguntando: “quem tem este IP?”. O nó híbrido que hospeda esse pod responderá com seu próprio endereço MAC, dizendo: “eu posso processar o tráfego desse IP”. Isso cria um caminho direto entre os dispositivos na rede local e os pods sem precisar da configuração do roteador.

Para que isso funcione, a CNI deve ser compatível com a funcionalidade do proxy ARP. O Cilium tem suporte integrado para o proxy ARP que você pode habilitar por meio da configuração. A principal consideração é que o CIDR do pod não deve se sobrepor a nenhuma outra rede em seu ambiente, pois isso pode causar conflitos de roteamento.

Essa abordagem traz diversas vantagens: \$1 Não é necessário configurar o roteador com BGP ou manter rotas estáticas \$1 Funciona bem em ambientes em que você não tem controle sobre a configuração do roteador

![\[Proxy ARP para nós híbridos\]](http://docs.aws.amazon.com/pt_br/eks/latest/userguide/images/hybrid-nodes-arp-proxy.png)


## Encapsulamento pod-to-pod
<a name="hybrid-nodes-concepts-k8s-pod-encapsulation"></a>

Em ambientes on-premises, as CNIs normalmente usam protocolos de encapsulamento para criar redes de sobreposição que possam operar na rede física sem a necessidade de reconfigurá-la. Esta seção explica como esse encapsulamento funciona. Observe que alguns dos detalhes podem variar dependendo da CNI que você está usando.

O encapsulamento compacta os pacotes de rede do pod original dentro de outro pacote de rede que pode ser roteado pela rede física subjacente. Isso permite que os pods se comuniquem entre os nós que executam a mesma CNI sem exigir que a rede física saiba como rotear esses CIDRs de pod.

O protocolo de encapsulamento mais comum usado com o Kubernetes é o Virtual Extensible LAN (VXLAN), embora outros (como o `Geneve`) também estejam disponíveis, dependendo da sua CNI.

### Encapsulamento VXLAN
<a name="_vxlan_encapsulation"></a>

O VXLAN encapsula os quadros do Layer 2 Ethernet em pacotes do UDP. Quando um pod envia tráfego para outro pod em um nó diferente, a CNI faz o seguinte:

1. A CNI intercepta pacotes do pod A

1. A CNI compacta o pacote original em um cabeçalho VXLAN

1. Esse pacote compactado é então enviado pela pilha de rede regular do nó para o nó de destino

1. A CNI no nó de destino descompacta o pacote e o entrega ao pod B

Verifique o que acontece com a estrutura do pacote durante o encapsulamento VXLAN:

Pacote original de pod-to-pod:

```
+-----------------+---------------+-------------+-----------------+
| Ethernet Header | IP Header     | TCP/UDP     | Payload         |
| Src: Pod A MAC  | Src: Pod A IP | Src Port    |                 |
| Dst: Pod B MAC  | Dst: Pod B IP | Dst Port    |                 |
+-----------------+---------------+-------------+-----------------+
```

Após o encapsulamento VXLAN:

```
+-----------------+-------------+--------------+------------+---------------------------+
| Outer Ethernet  | Outer IP    | Outer UDP    | VXLAN      | Original Pod-to-Pod       |
| Src: Node A MAC | Src: Node A | Src: Random  | VNI: xx    | Packet (unchanged         |
| Dst: Node B MAC | Dst: Node B | Dst: 4789    |            | from above)               |
+-----------------+-------------+--------------+------------+---------------------------+
```

O VXLAN Network Identifier (VNI) distingue entre diferentes redes de sobreposição.

### Cenários de comunicação do pod
<a name="_pod_communication_scenarios"></a>

 **Pods no mesmo nó híbrido** 

Quando pods no mesmo nó híbrido se comunicam, normalmente nenhum encapsulamento é necessário. A CNI configura rotas locais que direcionam o tráfego entre os pods por meio das interfaces virtuais internas do nó:

```
Pod A -> veth0 -> node's bridge/routing table -> veth1 -> Pod B
```

O pacote nunca sai do nó e não requer encapsulamento.

 **Pods em diferentes nós híbridos** 

A comunicação entre pods em diferentes nós híbridos requer encapsulamento:

```
Pod A -> CNI -> [VXLAN encapsulation] -> Node A network -> router or gateway -> Node B network -> [VXLAN decapsulation] -> CNI -> Pod B
```

Isso permite que o tráfego do pod atravesse a infraestrutura física da rede sem exigir que a rede física saiba o roteamento IP do pod.