Visão geral
Acesso direto a um pod
Depois que um pod é criado, os seguintes problemas podem ocorrer se você acessar diretamente o pod:
- O pod pode ser excluído e recriado a qualquer momento por um controlador, como um Deployment, e o resultado do acesso ao pod se torna imprevisível.
- O endereço IP do pod é alocado somente depois que o pod é iniciado. Antes de o pod ser iniciado, o endereço IP do pod é desconhecido.
- Uma aplicação é geralmente composta de vários pods que executam a mesma imagem. Acessar pods um por um não é eficiente.
Por exemplo, uma aplicação usa Deployments para criar o front-end e o back-end. O front-end chama o back-end para computação, conforme mostrado em Figura 1. Três pods estão sendo executados no back-end, que são independentes e substituíveis. Quando um pod de back-end é recriado, o novo pod é atribuído com um novo endereço IP, do qual o pod de front-end não tem conhecimento.
Usar Serviços para acesso a pods
Serviços do Kubernetes são usados para resolver os problemas anteriores de acesso ao pod. Um Serviço tem um endereço IP fixo. (Quando um cluster do CCE é criado, um bloco CIDR de Serviço é definido, que é usado para alocar endereços IP aos Serviços.) Um Serviço encaminha solicitações de acesso ao Serviço para pods com base em rótulos e, ao mesmo tempo, executa o balanceamento de carga para esses pods.
No exemplo anterior, um Serviço é adicionado para o pod de front-end acessar os pods de back-end. Dessa forma, o pod de front-end não precisa estar ciente das alterações nos pods de back-end, como mostrado em Figura 2.
Tipos de Serviço
O Kubernetes permite que você especifique um Serviço de um tipo obrigatório. Os valores e ações dos diferentes tipos de Serviços são os seguintes:
- ClusterIP
Um Serviço ClusterIP permite que cargas de trabalho no mesmo cluster usem seus nomes de domínio internos do cluster para acessar uns aos outros.
- NodePort
Um Serviço é exposto no endereço IP de cada nó em uma porta estática (NodePort). Um Serviço ClusterIP, para o qual o Serviço NodePort será roteado, é criado automaticamente. Solicitando <NodeIP>:<NodePort>, você pode acessar um Serviço NodePort de fora do cluster.
- LoadBalancer
Os Serviços LoadBalancer podem acessar cargas de trabalho da rede pública por meio de um balanceador de carga, que é mais confiável do que o acesso baseado em EIP. Os Serviços LoadBalancer são recomendados para acessar cargas de trabalho de fora do cluster.
- DNAT
Um gateway DNAT traduz endereços para nós de cluster e permite que vários nós de cluster compartilhem um EIP. Os Serviços NodePort fornecem maior confiabilidade do que os Serviços DNAT baseados em EIP. Você não precisa vincular um EIP a um único nó e as solicitações ainda podem ser distribuídas à carga de trabalho, mesmo que qualquer um dos nós internos esteja desativado.
externalTrafficPolicy (afinidade de serviço)
Para um Serviço NodePort e LoadBalancer, as solicitações são enviadas primeiro para a porta do nó, depois para o Serviço e, finalmente, para o pod que suporta o Serviço. O pod de apoio pode não estar localizado no nó que recebe as solicitações. Por padrão, a carga de trabalho de back-end pode ser acessada a partir de qualquer endereço IP de nó e porta de serviço. Se o pod não estiver no nó que recebe a solicitação, a solicitação será redirecionada para o nó onde o pod está localizado, o que pode causar perda de desempenho.
externalTrafficPolicy é um parâmetro de configuração do Serviço.
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
externalTrafficPolicy: Local
ports:
- name: service
nodePort: 30000
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: NodePort
Se o valor de externalTrafficPolicy for Local, as solicitações enviadas de Node IP address:Service port serão encaminhadas apenas para o pod no nó local. Se o nó não tiver um pod, as solicitações serão suspensas.
Se o valor de externalTrafficPolicy for Cluster, as solicitações serão encaminhadas dentro do cluster e a carga de trabalho de back-end poderá ser acessada a partir de qualquer endereço IP de nó e porta de serviço.
Se externalTrafficPolicy não estiver definido, o valor padrão Cluster será usado.
Você pode definir esse parâmetro ao criar um Serviço do tipo NodePort no console do CCE.
Os valores de externalTrafficPolicy são os seguintes:
- Cluster: os endereços IP e as portas de acesso de todos os nós em um cluster podem acessar a carga de trabalho associada ao Serviço. O acesso ao Serviço causará perda de desempenho devido ao redirecionamento de rota e o endereço IP de origem do cliente não pode ser obtido.
- Local: somente o endereço IP e a porta de acesso do nó onde a carga de trabalho está localizada podem acessar a carga de trabalho associada ao Serviço. O acesso ao Serviço não causará perda de desempenho devido ao redirecionamento de rota e o endereço IP de origem do cliente pode ser obtido. Neste cenário, os Serviços poderão não ser acedidos a partir do cluster. Para mais detalhes, consulte Por que um Serviço falha ao ser acessado de dentro do cluster.
Por que um Serviço falha ao ser acessado de dentro do cluster
upstream connect error or disconnect/reset before headers. reset reason: connection failure Or curl: (7) Failed to connect to 192.168.10.36 port 900: Connection refused
É comum que um balanceador de carga em um cluster não possa ser acessado. A razão é a seguinte: quando o Kubernetes cria um erviço, kube-proxy adiciona o endereço de acesso do balanceador de carga como um endereço IP externo (IP externo, como mostrado na saída do comando a seguir) ao iptables ou ao IPVS. Se um cliente dentro do cluster iniciar uma solicitação para acessar o balanceador de carga, o endereço será considerado como o endereço IP externo do Serviço e a solicitação será encaminhada diretamente pelo kube-proxy sem passar pelo balanceador de carga fora do cluster.
# kubectl get svc nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx LoadBalancer 10.247.76.156 123.**.**.**,192.168.0.133 80:32146/TCP 37s
- Para uma carga de trabalho com vários pods, certifique-se de que todos os pods estejam acessíveis. Caso contrário, existe a possibilidade de que o acesso à carga de trabalho falhe.
- Os clusters do CCE Turbo que usam a rede do Cloud Native 2.0 não oferecem suporte à afinidade de serviço no nível do nó.
Tipo de Serviço liberado no servidor |
Tipo de acesso |
Local de início da solicitação no cliente |
Cluster de rede de túnel (IPVS) |
Cluster de rede da VPC (IPVS) |
Cluster de rede de túnel (iptables) |
Cluster de rede da VPC (iptables) |
---|---|---|---|---|---|---|
Serviço NodePort |
Rede pública/privada |
Mesmo nó que o pod de serviço |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Diferentes nós do pod de serviço |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
O acesso é bem sucedido. |
O acesso é bem sucedido. |
||
Outros contêineres no mesmo nó do pod de serviço |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso é bem sucedido. |
O acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
O acesso falhou. |
||
Outros contêineres em diferentes nós do pod de serviço |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
Acesse o endereço IP e o NodePort no nó onde o servidor está localizado: o acesso é bem sucedido. Acesse o endereço IP e o NodePort em um nó diferente do nó onde o servidor está localizado: o acesso falhou. |
||
Serviço LoadBalancer usando um balanceador de carga dedicado |
Rede privada |
Mesmo nó que o pod de serviço |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
Outros contêineres no mesmo nó do pod de serviço |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
||
Serviço de gateway de DNAT |
Rede pública |
Mesmo nó que o pod de serviço |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
Diferentes nós do pod de serviço |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
||
Outros contêineres no mesmo nó do pod de serviço |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
||
Outros contêineres em diferentes nós do pod de serviço |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
||
Complemento nginx-ingress conectado a um balanceador de carga dedicado (Local) |
Rede privada |
Mesmo nó que pod de cceaddon-nginx-ingress-controller |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
Outros contêineres no mesmo nó do pod de cceaddon-nginx-ingress-controller |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
O acesso falhou. |
Os seguintes métodos podem ser usados para resolver este problema:
- (Recomendado) No cluster, use o Serviço ClusterIP ou o nome de domínio do serviço para acesso.
- Defina externalTrafficPolicy do Serviço como Cluster, o que significa afinidade de serviço no nível do cluster. Observe que isso afeta a persistência do endereço de origem.
apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Cluster ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer
- Aproveitar o recurso de passagem do Serviço, o kube-proxy é ignorado quando o endereço do ELB é usado para acesso. O balanceador de carga do ELB é acessado primeiro e, em seguida, a carga de trabalho. Para mais detalhes, consulte Configuração de rede de passagem para um Serviço de LoadBalancer.
- Em um cluster padrão do CCE, depois que a rede de passagem é configurada para um balanceador de carga dedicado, o endereço IP privado do balanceador de carga não pode ser acessado do nó onde o pod de carga de trabalho reside ou de outros contêineres no mesmo nó da carga de trabalho.
- A rede de passagem não é suportada para clusters de v1.15 ou anterior.
- No modo de rede IPVS, as configurações de passagem dos Serviços conectados ao mesmo balanceador de carga devem ser as mesmas.
- Se a afinidade de serviço em nível de nó (local) for usada, kubernetes.io/elb.pass-through será automaticamente definido como onlyLocal para ativar a passagem.
apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.pass-through: "true" kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Local ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer