Модули Kubernetes не могут взаимодействовать внутри

#postgresql #tomcat #kubernetes #kubernetes-service

#postgresql #tomcat #kubernetes #kubernetes-service

Вопрос:

В моем кластере K8 у меня есть два развертывания в одном пространстве имен. Одно развертывание предназначено для базы данных-Postgres, а другое — для Tomcat. Tomcat должен быть доступен извне, поэтому я настроил службу «NodePort», а для внутренней связи я создал службу «ClusterIP», предоставив порт Postgres (т.е. 5432). Как только все будет развернуто, я хочу, чтобы модуль Tomcat взаимодействовал с модулем Postgres. Но когда я «curl postgres-service: 5432» из модуля Tomcat, я получаю сообщение «отказано в подключении». Есть ли какие-либо неправильные настройки?

 apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  namespace: application
  labels:
    app: application-tomcat
spec:
  type: NodePort
  ports:
  - name: tomcat-port
    targetPort: 80
    port: 80
  selector:
    app: application-tomcat

---

apiVersion: v1
kind: Service
metadata:
  name: postgres-service
  namespace: application
  labels:
    app: application-postgres
spec:
  ports:
  - port: 5432
    name: postgres-port
  selector:
    app: application-postgres

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: application-tomcat-deployment
  namespace: application
  labels:
    app: application-tomcat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: application-tomcat
  template:
    metadata:
      labels:
        app: application-tomcat
    spec:
      containers:
      - name: application-container
        image: tomcat
        command:
          - sleep
          - "infinity"
        ports:
        - containerPort: 80
     
---

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: application
  name: application-postgres-deployment
  labels:
    app: application-postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: application-postgres
  template:
    metadata:
      labels:
        app: application-postgres
    spec:
      containers:
      - name: postgres
        image: postgres
        command:
          - sleep
          - "infinity"
        ports:
        - containerPort: 5432
          name: postgredb
 

Модуль Postgres прослушивает порт ‘5432’, и база данных запущена.

 Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
tcp6       0      0 :::5432                 :::*                    LISTEN      -
 

Ресурсы в пространстве имен

 $ kubectl get all -n application
NAME                                                   READY   STATUS    RESTARTS   AGE
pod/application-postgres-deployment-694869cd5d-wrhzr   1/1     Running   0          9m9s
pod/application-tomcat-deployment-6db75ffb6d-ds8fr     1/1     Running   0          9m9s

NAME                       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
service/postgres-service   ClusterIP   10.32.0.207   <none>        5432/TCP       9m9s
service/tomcat-service     NodePort    10.32.0.59    <none>        80:31216/TCP   9m9s

NAME                                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/application-postgres-deployment   1/1     1            1           9m9s
deployment.apps/application-tomcat-deployment     1/1     1            1           9m9s

NAME                                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/application-postgres-deployment-694869cd5d   1         1         1       9m9s
replicaset.apps/application-tomcat-deployment-6db75ffb6d     1         1         1       9m9s
 

Комментарии:

1. Вам не нужно создавать Service тип ClusterIP of вручную / явно. Служба NodePort создает службу внутри ClusterIP , которая может использоваться для внутренней связи.

2. Я опустил службу типа ClusterIP, но тогда она создаст только службу NodePort. Итак, как я могу указать имя хоста в Tomcat для связи с модулем Postgres? Тогда какое имя я должен использовать для «curl» из модуля Tomcat?

3. вы можете получить доступ к модулям, используя имя службы как curl http:servicename/

4. пожалуйста, отредактируйте вопрос, чтобы добавить туда подробности.

5. Почему ваши контейнеры запускаются command: [sleep, infinity] ? Это определенно приведет к ошибке «отказано в подключении», поскольку процессы базы данных и веб-сервера фактически не выполняются.

Ответ №1:

Вы переопределили значение по умолчанию ENTRYPOINT в образе postgresql, указав deployment.spec.template.containers[0].command . Итак, теперь единственный процесс, который выполняется внутри модуля развертывания nginx-statefulset sleep infinity , — это postgres, и он не запущен. Удаление командного поля и добавление POSTGRES_PASSWORD POSTGRES_HOST_AUTH_METHOD=trust переменной среды или должно устранить проблему. Используйте следующий манифест для nginx-statefulset

 apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-statefulset
  namespace: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      BIZID: nginx
  template:
    metadata:
      labels:
        BIZID: nginx
    spec:
      containers:
      - name: postgres
        image: postgres
        env:
        - name: POSTGRES_PASSWORD
          value: admin
        ports:
        - containerPort: 5432
          name: postgredb
 

Вы должны установить переменную env POSTGRES_PASSWORD или POSTGRES_HOST_AUTH_METHOD=trust . Без этого модуль завершит цикл сбоя со следующим сообщением об ошибке:

 Error: Database is uninitialized and superuser password is not specified.
       You must specify POSTGRES_PASSWORD to a non-empty value for the
       superuser. For example, "-e POSTGRES_PASSWORD=password" on "docker run".

       You may also use "POSTGRES_HOST_AUTH_METHOD=trust" to allow all
       connections without a password. This is *not* recommended.

       See PostgreSQL documentation about "trust":
       https://www.postgresql.org/docs/current/auth-trust.html
 

Комментарии:

1. Я обновил вопрос. Не могли бы вы проверить еще раз?

2. Интересно. Я попытался использовать ваш манифест локально в своем кластере kind и заметил, что postgres не запущен. Где работает ваш кластер k8s? Можете ли вы поделиться командой, которую вы выполнили для вывода открытых подключений?

3. Я использую вычислительные механизмы GCP и установил там K8. Я использовал команду «netstat -tulpn» и для проверки запущенного процесса использовал «ps aux»

4. Служба состоит из 2 компонентов: запись dns, которая сопоставляет запрос postgres-service с IP-адресом кластера (в вашем случае 10.32.0.207), правила iptables на узле k8s, которые перехватывают трафик на ip-адрес кластера и выполняют dnat с фактическими IP-адресами pod. Вместо того, чтобы выполнять «curl postgres-service: 5432», попробуйте выполнить curl для фактического IP-адреса модуля postgres.

5. Я смог заставить это работать. Установленный пакет «ebtables» и загруженный модуль ядра — modprobe br_netfilter»

Ответ №2:

Глядя на ваши yamls, кажется, что ваше развертывание tomcat находится в пространстве имен с именем «test», тогда как ваше развертывание postgres находится в пространстве имен «по умолчанию».

Итак, чтобы обеспечить взаимодействие между пространствами имен, вам нужно будет добавить пространство имен к домену службы. Этот модуль — если он выполняется из модуля tomcat — должен работать:

 curl http://postgres-service.default:5432
 

В качестве альтернативы просто разверните tomcat в пространство имен «по умолчанию».

Комментарии:

1. Но они находятся в одном пространстве имен

2. Если вы все еще используете те же yamls, которые вы опубликовали, tomcat развертывается в «тестовом» пространстве имен, а postgres — в пространстве имен по умолчанию. Если нет, то, пожалуйста, соответствующим образом обновите вопрос.

3. да, я пропустил пространство имен. Но когда я применяю файл Yaml, я явно использую команду —namespace . «kubectl create -f data.yml -n тест»

4. Таким образом, все они находятся в одном пространстве имен. Я отредактирую вопрос

5. К вашему СВЕДЕНИЮ: если я попытаюсь перезаписать пространство имен, определенное в yaml, с помощью kubectl, я получаю сообщение об ошибке «пространство имен не соответствует». Это связано с kubectl 1.20.