O GKE em Bare Metal é compatível com a rede de pilha dupla IPv4/IPv6. Isso significa que um cluster pode aceitar tráfego de dispositivos externos que usam a versão 4 do Protocolo de Internet (IPv4) ou a versão 6 do Protocolo de Internet (IPv6).
A rede de pilha dupla atribui endereços IPv4 e IPv6 a pods e nós. Um serviço do Kubernetes pode ter um endereço IPv4, um endereço IPv6 ou ambos.
Todos os clusters de pilha dupla usam o modo simples para IPv6. Por padrão, um cluster de pilha dupla usa o modo de ilha para IPv4, mas é possível configurá-lo para usar o modo simples para IPv4.
Para criar um cluster de pilha dupla, sua rede subjacente precisa estar ativada. Se a rede subjacente for IPv4 ou IPv6 de pilha única, não será possível iniciar um cluster de pilha dupla.
Antes de começar
Se os nós do cluster estiverem executando o CentOS ou RedHat Enterprise Linux e tiverem o SELinux ativado, em cada nó:
Em
/etc/firewalld/firewalld.conf
, definaIPv6_rpfilter=no
.Execute
systemctl restart firewalld
.
Visão geral da criação de um cluster de pilha dupla
É possível ativar a rede de pilha dupla ao criar um novo cluster, mas não é possível ativá-la em um cluster atual.
Siga as instruções em um dos documentos de criação de cluster.
No arquivo de configuração, inclua manifestos para:
- um recurso de namespace;
- um recurso de cluster;
- um ou mais recursos do NodePool;
- um ou mais recursos ClusterCIDRConfig.
Preencha o manifesto de namespace e os manifestos de NodePool como faria para um cluster de pilha única.
No manifesto do cluster, em clusterNetwork.services.cidrBlocks
, especifique um intervalo CIDR IPv4 e um intervalo CIDR IPv6. Esse é o critério de ativação para um
cluster de pilha dupla. Ou seja, se você fornecer intervalos CIDR de serviço para IPv4
e IPv6, o cluster terá uma rede de pilha dupla.
No manifesto do cluster, em clusterNetwork.pods.cidrBlocks
, especifique um intervalo
CIDR IPv4, mas não um intervalo CIDR IPv6. Os intervalos CIDR IPv6 para pods
são especificados nos manifestos ClusterCIDRConfig.
Se você estiver usando o balanceamento de carga em pacote, forneça os endereços IPv4 e IPv6
na seção loadBalancer.addressPools
do manifesto do cluster.
Os recursos de ClusterCIDRConfig são para especificar intervalos CIDR IPv4 e IPv6 para pods. É possível usar um único recurso ClusterCIDRConfig para especificar intervalos CIDR em todo o cluster. Ou seja, os endereços do pod IPv4 para todos os nós são tomados de um único intervalo CIDR, e os endereços do pod IPv6 para todos os nós são tomados de um único intervalo CIDR. Outra opção é usar vários recursos ClusterCIDRConfig para especificar intervalos CIDR que se aplicam a um determinado pool de nós ou a um nó específico.
Acessibilidade para endereços IP do pod
Um cluster de pilha dupla usa o modo plano para redes IPv6. O exemplo mostrado neste documento é para um cluster que usa rede estática de modo plano para IPv6. Ou seja, o cluster não está configurado para usar o protocolo de gateway de borda (BGP, na sigla em inglês).
Para um cluster que usa rede estática de modo plano, é necessário especificar os endereços IP do nó e do pod que fazem parte da mesma sub-rede. Isso possibilita que clientes fora do cluster, mas no mesmo domínio da camada 2 (L2) que os nós do cluster, enviem pacotes diretamente aos endereços IP do pod.
Por exemplo, suponha que os nós do cluster e algumas outras máquinas estejam no mesmo domínio L2. Veja uma maneira de especificar os intervalos de endereços:
Motivo | Intervalo | Número de endereços |
---|---|---|
Todo o domínio L2 | fd12::/108 | 2^20 |
Pods | fd12::1:0/112 | 2^16 |
Nós | fd12::2:0/112 | 2^16 |
Outras máquinas | fd12::3:0/112 | 2^16 |
VIPs | fd12::4:0/112 | 2^16 |
Sobre o exemplo anterior, é importante entender os pontos abaixo:
Todos os endereços de nós, pods e máquinas estão no intervalo grande "fd12::/108".
Os endereços IP do pod estão em um subconjunto de um intervalo grande.
Os endereços IP do nó estão em um subconjunto diferente do intervalo grande.
Os endereços IP de outras máquinas estão em um subconjunto diferente do intervalo grande.
Todos os intervalos de subconjuntos são diferentes uns dos outros.
No exemplo anterior, cada máquina no domínio L2, incluindo os nós do cluster, precisa ter uma regra de encaminhamento para o intervalo maior. Exemplo:
inet fd12::/108 scope global eth0
Exemplo: criar um cluster de pilha dupla
Ao criar um cluster de pilha dupla, você tem várias opções. Por exemplo, é possível ter intervalos CIDR em todo o cluster ou aplicáveis a pools de nós específicos. É possível combinar uma rede plana IPv6 com uma rede no modo ilha IPv4. Ou suas redes IPv4 e IPv6 podem ser simples. É possível usar o balanceamento de carga em pacote ou manual.
Nesta seção, mostramos um exemplo de como criar um cluster de pilha dupla. O cluster neste exemplo tem as seguintes características:
- Uma rede IPv4 no modo de ilha
- Uma rede IPv6 no modo simples
- Um intervalo de CIDR IPv4 para pods em todo o cluster
- Um intervalo de CIDR IPv6 para pods em todo o cluster
- Um intervalo CIDR de IPv4 para Serviços em todo o cluster
- Um intervalo CIDR para IPv6 para serviços em todo o cluster
- Um pool de endereços IPv4 a ser usado para serviços do tipo
LoadBalancer
- Um pool de endereços IPv6 a ser usado para serviços do tipo
LoadBalancer
- Balanceamento de carga em pacote
Para ver mais exemplos de configuração, consulte Variações no uso do Cluster CIDRConfig.
Preencher um arquivo de configuração
Siga as instruções em um dos documentos de criação de cluster.
No arquivo de configuração, no manifesto Cluster
:
Para
clusterNetwork.pods.cidrBlocks
, forneça um único intervalo CIDR IPv4.Para
clusterNetwork.services.cidrBlocks
, forneça dois intervalos CIDR: um para IPv4 e outro para IPv6.Para
loadBalancer.addressPools
, forneça dois intervalos de endereços: um para IPv4 e outro para IPv6. Quando você cria um Serviço do tipoLoadBalancer
, os endereços IP externos do Serviço são escolhidos nesses intervalos.
Veja um exemplo que mostra as partes relevantes de um manifesto de cluster:
apiVersion: baremetal.cluster.gke.io/v1 kind: Cluster metadata: name: "dual-stack" namespace: "cluster-dual-stack" spec: clusterNetwork: pods: cidrBlocks: - "192.168.0.0/16" services cidrBlocks: - "172.16.0.0/20" - "fd12::5:0/116" ... loadBalancer: mode: "bundled" ... addressPools: - name: "pool-1" addresses: - "10.2.0.212-10.2.0.221" - "fd12::4:101-fd12::4:110"
No mesmo arquivo de configuração, inclua um manifesto para uma ClusterCIDRConfig
.
Defina
ipv4.cidr
com o mesmo intervalo CIDR fornecido no manifestoCluster
. Esse é um requisito se o IPv4 estiver no modo Ilha.Defina
namespace
com o mesmo valor fornecido no manifestoCluster
.Defina
ipv6.cidr
como um intervalo CIDR IPv6 para pods.Para cada intervalo CIDR, forneça um valor para
perNodeMaskSize
para especificar quantos endereços de pod serão atribuídos a cada nó. O número de endereços IPv4 atribuídos a cada nó precisa ser igual ao número de endereços IPv6 atribuídos a cada nó. Defina seus valores paraperNodeMaskSize
de acordo. Por exemplo, se você quiser 2^8 endereços por nó, defina seus valores deperNodeMaskSize
da seguinte maneira:ipv4.perNodeMaskSize: 24
# (32 - 8 = 24)ipv6.perNodeMaskSize: 120
# (128 - 8 = 120)
Veja um exemplo de um manifesto ClusterCIDRConfig:
apiVersion: baremetal.cluster.gke.io/v1alpha1 kind: ClusterCIDRConfig metadata: name: "cluster-wide-ranges" namespace: "cluster-dual-stack" # Must be the same as the Cluster namespace. spec: ipv4: cidr: "192.168.0.0/16" # For island mode, must be the same as the Cluster CIDR. perNodeMaskSize: 24 ipv6: cidr: "fd12::1:0/112" perNodeMaskSize: 120
No exemplo anterior:
O intervalo de CIDR do pod IPv4 tem 2^(32-16) = 2^16 endereços. O tamanho da máscara por nó é 24, portanto, o número de endereços atribuídos a cada nó é 2^(32-24) = 2^8.
O intervalo CIDR de pod do IPv6 tem 2^(128-112) = 2^16 endereços. O tamanho da máscara por nó é 120. Portanto, o número de endereços atribuídos a cada nó é 2^(128-120) = 2^8.
Exemplo: arquivo de configuração
Concluir a criação do cluster
Conclua a criação do cluster conforme descrito no documento de criação do cluster.
Ver nós e pods do cluster
Liste os nós do cluster:
kubectl --kubeconfig CLUSTER_KUBECONFIG get nodes --output yaml
Substitua CLUSTER_KUBECONFIG
pelo caminho do seu arquivo kubeconfig do
cluster.
Na saída, é possível ver os endereços IPv4 e IPv6 de cada nó. Também é possível ver os intervalos de endereços IPv4 e IPv6 para pods no nó. Exemplo:
- apiVersion: v1 kind: Node ... spec: podCIDR: 192.168.1.0/24 podCIDRs: - 192.168.1.0/24 - fd12::1:100/120 providerID: baremetal://10.2.0.5 status: addresses: - address: 10.2.0.5 type: InternalIP - address: fd12::2:5 type: InternalIP
Liste os pods no cluster:
kubectl --kubeconfig CLUSTER_KUBECONFIG get pods --all-namespaces
Escolha um pod e liste os detalhes. Exemplo:
kubectl --kubeconfig CLUSTER_KUBECONFIG get pod gke-metrics-agent-b9qrv \ --namespace kube-system \ -- output yaml
Na saída, é possível ver os endereços IPv4 e IPv6 do pod. Exemplo:
apiVersion: v1 kind: Pod metadata: ... name: gke-metrics-agent-b9qrv namespace: kube-system ... status: ... podIPs: - ip: 192.168.1.146 - ip: fd12::1:11a
Variações no uso de ClusterCIDRConfig
O exemplo anterior usou um objeto ClusterCIDRConfig para especificar intervalos CIDR de pod em todo o cluster. Ou seja, um único intervalo CIDR IPv4 é usado para todos os pods no cluster. E um único intervalo CIDR IPv6 é usado para todos os pods no cluster.
Em determinadas situações, talvez você não queira usar um único intervalo CIDR para todos os pods em um cluster. Por exemplo, é possível especificar um intervalo CIDR separado para cada pool de nós ou um intervalo CIDR separado para cada nó.
Por exemplo, o ClusterCIDRConfig a seguir especifica um intervalo CIDR para um pool de
nós chamado "workers"
.
apiVersion: baremetal.cluster.gke.io/v1alpha1 kind: ClusterCIDRConfig metadata: name: "worker-pool-ccc" namespace: "cluster-dual-stack" spec: ipv4: cidr: "192.168.0.0/16" perNodeMaskSize: 24 ipv6: cidr: "fd12::1:0/112" perNodeMaskSize: 120 nodeSelector: matchLabels: baremetal.cluster.gke.io/node-pool: "workers"
O ClusterCIDRConfig a seguir especifica um intervalo CIDR para um único nó que tem o endereço IP 10.2.0.5:
apiVersion: baremetal.cluster.gke.io/v1alpha1 kind: ClusterCIDRConfig metadata: name: "range-node1" namespace: "cluster-dual-stack" spec: ipv4: cidr: "192.168.1.0/24" perNodeMaskSize: 24 ipv6: cidr: "fd12::1:0/120" perNodeMaskSize: 120 nodeSelector: matchLabels: baremetal.cluster.gke.io/k8s-ip: "10.2.0.5"
Crie um serviço de pilha dupla do tipo ClusterIP
Veja o manifesto de uma implantação:
apiVersion: apps/v1 kind: Deployment metadata: name: "my-deployment" spec: selector: matchLabels: app: "try-dual-stack" replicas: 3 template: metadata: labels: app: "try-dual-stack" spec: containers: - name: "hello" image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
Salve o manifesto em um arquivo denominado my-deployment.yaml
e crie a implantação:
kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-deployment.yaml
Substitua CLUSTER_KUBECONFIG
pelo caminho do seu arquivo kubeconfig do
cluster.
Veja um manifesto para um Service do tipo ClusterIP
:
apiVersion: v1 kind: Service metadata: name: "my-service" spec: selector: app: "try-dual-stack" type: "ClusterIP" ipFamilyPolicy: "RequireDualStack" ipFamilies: - "IPv6" - "IPv4" ports: - port: 80 targetPort: 8080
No contexto deste exercício, estes são os pontos principais para entender sobre o manifesto de serviço anterior:
O campo
ipFamilyPolicy
está definido comoRequireDualStack
. Isso significa que os endereçosClusterIP
e IPv6 são alocados para o serviço.O campo
ipFamilies
especifica a família IPv6 primeiro e, em seguida, a segunda família de IPv4. Isso significa quespec.ClusterIP
para o serviço será um endereço IPv6 escolhido declusterNetwork.services.cidrBlocks
no manifesto do cluster.
Salve o manifesto em um arquivo chamado my-cip-service.yaml
e crie o Serviço:
kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-cip-service.yaml
Liste os detalhes do Serviço:
kubectl --kubeconfig CLUSTER_KUBECONFIG get service my-service --output yaml
Na saída, é possível ver os endereços IP do cluster do Serviço. Exemplo:
apiVersion: v1 kind: Service metadata: name: my-service … spec: clusterIP: fd12::5:9af clusterIPs: - fd12::5:9af - 172.16.12.197
Em um nó de cluster, chame o Serviço:
curl IPV4_CLUSTER_IP curl [IPV6_CLUSTER_IP]
A saída vai mostrar a mensagem "Hello world":
Hello, world! Version: 2.0.0 Hostname: my-deployment-xxx
Crie um serviço de pilha dupla do tipo LoadBalancer
Veja um manifesto para um Service do tipo LoadBalancer
:
apiVersion: v1 kind: Service metadata: name: "my-lb-service" spec: selector: app: "try-dual-stack" type: "LoadBalancer" ipFamilyPolicy: "RequireDualStack" ipFamilies: - "IPv6" - "IPv4" ports: - port: 80 targetPort: 8080
Salve o manifesto em um arquivo chamado my-lb-service.yaml
e crie o Serviço:
kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-lb-service.yaml
Lembre-se de que, no manifesto do cluster, você especificou um intervalo de endereços IPv6 e
um intervalo de endereços IPv4 a serem usados para serviços do tipo LoadBalancer
:
loadBalancer: mode: "bundled" ... addressPools: - name: "pool-1" addresses: - "10.2.0.112-10.2.0.221" - "fd12::4:101-fd12::4:110"
Seu serviço receberá um endereço IPv4 externo escolhido no intervalo IPv4 e um endereço IPv6 externo escolhido no intervalo IPv6.
Lista de detalhes do Serviço:
kubectl --kubeconfig CLUSTER_KUBECONFIG get service my-lb-service --output yaml
Na saída, é possível ver os endereços externos do Serviço. Exemplo:
apiVersion: v1 kind: Service metadata: name: my-lb-service ... status: loadBalancer: ingress: - ip: 10.2.0.213 - ip: fd12::4:101
Valores possíveis para ipFamilyPolicy
Ao criar um serviço de pilha dupla, é possível definir ipFamilyPolicy
como um destes
valores:
SingleStack
: o controlador aloca um endereço IP de cluster para o serviço escolhido no primeiro intervalo especificado pelo manifesto do cluster emclusterNetwork.services.cidrBlocks
.PreferDualStack
: o controlador aloca endereços IP do cluster IPv4 e IPv6 para o serviço, escolhidos entre os intervalos especificados no manifesto do cluster emclusterNetwork.services.cidrBlocks
. Se não for um cluster de pilha dupla, o comportamento será o mesmo deSingleStack
.RequireDualStack
: o controlador aloca endereços IP do cluster IPv4 e IPv6 para o serviço, escolhidos nos intervalos especificados no manifesto do cluster emclusterNetwork.services.cidrBlocks
. Ele define o valor despec.clusterIP
com base na primeira família de endereços especificada no manifesto do Serviço emipFamilies
.
Mais informações
Para mais informações sobre como criar serviços de pilha dupla, consulte Opções de pilha dupla em novos serviços.