El servicio de Kubernetes responde en un puerto diferente al puerto asignado

Dec 16 2020

Implementé pocos servicios y descubrí que un servicio se comporta de manera diferente a los demás. Lo configuré para escuchar en el puerto 8090 (que se asigna a 8443 internamente), pero la solicitud funciona solo si envío en el puerto 8080. Aquí está mi archivo yaml para el servicio (reducido a lo esencial) y hay una implementación que encapsula el servicio y contenedor

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

Después de instalar el timón, cuando ejecuto kubectl get svc, obtengo el siguiente 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

Sin embargo, cuando accedo a uno de los otros contenedores en ejecución y emito una solicitud curl en 8090, aparece "Conexión rechazada". Si me curvo a "http: // uisvc: 8080", entonces obtengo la respuesta correcta. El contenedor está ejecutando una aplicación de arranque de primavera que, por defecto, escucha en 8080. La única explicación que se me ocurre es que de alguna manera el puerto / targetPort está siendo ignorado en esta configuración y otros pods están llegando directamente al servicio de primavera en el interior.

¿Es este comportamiento correcto? ¿Por qué no escucha en 8090? ¿Cómo debo hacer que funcione de esta manera?

Editar: Salida 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>

Respuestas

1 thomas Dec 16 2020 at 20:39

Este es el comportamiento esperado desde que usó headless service.

Los servicios sin cabeza se utilizan para el mecanismo de descubrimiento de servicios, por lo que en lugar de devolver uno solo DNS A records, DNS serverdevolverán varios A recordspara su servicio, cada uno apuntando a la IP de un pods individual que respalda el servicio. Entonces, realiza una DNS A recordsbúsqueda simple y obtiene la IP de todos los pods que forman parte del servicio.

Dado headless serviceque no crea iptablesreglas, sino que crea en su dns recordslugar, puede interactuar directamente con su pod en lugar de un proxy. Entonces, si resuelves <servicename:port>, obtendrás <podN_IP:port>y luego tu conexión irá directamente al pod. Mientras todo esto esté en el mismo espacio de nombres, no tiene que resolverlo con el nombre completo de DNS.

Con varios pods, DNS te los dará todos y los pondrá en orden aleatorio (o en orden RR). El orden depende de la implementación y la configuración del servidor DNS.

Para leer más, visite:

  • Servicios-netowrking / headless-services
  • Esta pila de preguntas con una gran respuesta que explica cómo funcionan los servicios sin cabeza