Usługa Kubernetes odpowiada na innym porcie niż przypisany port

Dec 16 2020

Wdrożyłem kilka usług i zauważyłem, że jedna usługa zachowuje się inaczej niż inne. Skonfigurowałem go do nasłuchiwania na porcie 8090 (który wewnętrznie mapuje na 8443), ale żądanie działa tylko wtedy, gdy wyślę na port 8080. Oto mój plik yaml dla usługi (rozebrany do podstawowych) i jest wdrożenie, które hermetyzuje usługę i pojemnik

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

Po zainstalowaniu steru, kiedy uruchamiam kubectl get svc, otrzymuję następujący wynik

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

Jednak gdy ssh do jednego z innych działających kontenerów i wysyłam żądanie curl na 8090, otrzymuję komunikat „Odmowa połączenia”. Jeśli przechodzę do „http: // uisvc: 8080”, otrzymuję właściwą odpowiedź. W kontenerze działa aplikacja rozruchu sprężynowego, która domyślnie nasłuchuje na 8080. Jedyne wyjaśnienie, jakie mogłem wymyślić, to w jakiś sposób ignorowanie portu / targetPort w tej konfiguracji, a inne pody bezpośrednio docierają do usługi sprężynowej w środku.

Czy to zachowanie jest prawidłowe? Dlaczego nie słucha na 8090? Jak mam to zrobić w ten sposób?

Edycja: dane wyjściowe dla 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>

Odpowiedzi

1 thomas Dec 16 2020 at 20:39

Jest to oczekiwane zachowanie od czasu użycia headless service.

Usługi bezgłowe są używane do mechanizmu wykrywania usług, więc zamiast zwracać pojedynczy DNS A records, DNS serverzwróci wiele A recordsdla usługi, z których każdy wskazuje adres IP poszczególnych zasobników, które wspierają usługę. Wykonujesz więc proste DNS A recordswyszukiwanie i uzyskujesz adresy IP wszystkich podów, które są częścią usługi.

Ponieważ headless servicenie tworzy iptablesreguł, ale dns recordszamiast tego tworzy , możesz wchodzić w interakcje bezpośrednio ze swoim pod zamiast z serwerem proxy. Więc jeśli rozwiążesz <servicename:port>, otrzymasz, <podN_IP:port>a następnie połączenie zostanie bezpośrednio przesłane do kapsuły. Dopóki wszystko to znajduje się w tej samej przestrzeni nazw, nie rozwiążesz tego za pomocą pełnej nazwy DNS.

W przypadku kilku strąków DNS da ci je wszystkie i po prostu ustawi w kolejności losowej (lub w kolejności RR). Kolejność zależy od implementacji i ustawień serwera DNS.

Więcej informacji można znaleźć pod adresem:

  • Usługi-sieci / usługi-bez-głowy
  • Ten zestaw pytań ze świetną odpowiedzią wyjaśniający, jak działają usługi bezgłowe