Serviço Kubernetes respondendo em uma porta diferente da porta atribuída

Dec 16 2020

Implantei alguns serviços e descobri que um serviço se comporta de maneira diferente dos outros. Eu o configurei para escutar na porta 8090 (que mapeia para 8443 internamente), mas a solicitação funciona apenas se eu enviar na porta 8080. Aqui está meu arquivo yaml para o serviço (reduzido ao essencial) e há uma implantação que encapsula o serviço e recipiente

apiVersion: v1
kind: Service
metadata:
  name: uisvc
  namespace: default
  labels:
    helm.sh/chart: foo-1
    app.kubernetes.io/name: foo
    app.kubernetes.io/instance: rb-foo
spec:
  clusterIP: None
  ports:
    - name: http
      port: 8090
      targetPort: 8080
  selector:
    app.kubernetes.io/component: uisvc

Depois de instalar o leme, quando eu corro kubectl get svc, obtenho o seguinte resultado

fooaccess       ClusterIP   None         <none>        8888/TCP   119m
fooset          ClusterIP   None         <none>        8080/TCP   119m
foobus          ClusterIP   None         <none>        6379/TCP   119m
uisvc           ClusterIP   None         <none>        8090/TCP   119m

No entanto, quando eu ssh em um dos outros contêineres em execução e emito uma solicitação curl no 8090, recebo "Conexão recusada". Se eu curvar para "http: // uisvc: 8080", estou recebendo a resposta certa. O contêiner está executando um aplicativo de inicialização do spring que, por padrão, escuta no 8080. A única explicação que consegui apresentar é que, de alguma forma, a porta / targetPort está sendo ignorada nesta configuração e outros pods estão alcançando diretamente o serviço do spring interno.

Este comportamento está correto? Por que não está ouvindo no 8090? Como devo fazer isso funcionar dessa maneira?

Editar: saída para kubectl describe svc uisvc

Name:              uisvc
Namespace:         default
Labels:            app.kubernetes.io/instance=foo-rba
                   app.kubernetes.io/managed-by=Helm
                   app.kubernetes.io/name=rba
                   helm.sh/chart=rba-1
Annotations:       meta.helm.sh/release-name: foo
                   meta.helm.sh/release-namespace: default
Selector:          app.kubernetes.io/component=uisvc
Type:              ClusterIP
IP:                None
Port:              http  8090/TCP
TargetPort:        8080/TCP
Endpoints:         172.17.0.8:8080
Session Affinity:  None
Events:            <none>

Respostas

1 thomas Dec 16 2020 at 20:39

Este é o comportamento esperado desde que você usou headless service.

Os serviços sem cabeça são usados ​​para o mecanismo de descoberta de serviço, portanto, em vez de retornar um único DNS A records, o DNS serverretornará vários A recordspara seu serviço, cada um apontando para o IP de um pod individual que dá suporte ao serviço. Portanto, você faz uma DNS A recordspesquisa simples e obtém o IP de todos os pods que fazem parte do serviço.

Como headless servicenão cria iptablesregras, mas sim cria dns records, você pode interagir diretamente com seu pod em vez de um proxy. Então, se resolver <servicename:port>você vai conseguir <podN_IP:port>e então sua conexão irá para o pod diretamente. Contanto que tudo isso esteja no mesmo namespace, você não precisa resolvê-lo com o nome DNS completo.

Com vários pods, o DNS fornecerá todos eles e apenas os colocará em ordem aleatória (ou em ordem RR). A ordem depende da implementação e configurações do servidor DNS.

Para mais leituras, visite:

  • Services-netowrking / headless-services
  • Esta pilha de perguntas com ótimas respostas explicando como os serviços sem cabeça funcionam