Por que o endereço do ELB não pode ser usado para acessar cargas de trabalho em um cluster?
Sintoma
Em um cluster (em um nó ou em um contêiner), o endereço do ELB não pode ser usado para acessar cargas de trabalho.
Possível causa
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.

- 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. |
Solução
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":"traffic","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.
- 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":"traffic","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