Контейнеры в капсуле не разговаривают друг с другом в Kubernetes

У меня есть три контейнера в pod: nginx, redis, пользовательское приложение django. Кажется, что ни один из них не общается друг с другом с помощью kubernetes. В docker compose они общаются, но я не могу использовать docker compose в продакшене.

Контейнер django получает эту ошибку: [2022-06-20 21:45:49,420: ERROR/MainProcess] consumer: Cannot connect to redis://redis:6379/0: Error 111 connecting to redis:6379. Connection refused... Повторная попытка через 32.00 секунды... (16/100)

и контейнер nginx запускается, но не показывает никакого трафика. Попытка подключения к localhost:8000 не получает ответа.

Есть идеи, что не так с моим yml файлом?

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  creationTimestamp: null
  name: djangonetwork
spec:
  ingress:
    - from:
        - podSelector:
            matchLabels:
              io.kompose.network/djangonetwork: "true"
  podSelector:
    matchLabels:
      io.kompose.network/djangonetwork: "true"
---
apiVersion: v1
data:
  DB_HOST: db
  DB_NAME: django_db
  DB_PASSWORD: password
  DB_PORT: "5432"
  DB_USER: user
kind: ConfigMap
metadata:
  creationTimestamp: null
  labels:
    io.kompose.service: web
  name: envs--django
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    io.kompose.service: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: web
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        io.kompose.network/djangonetwork: "true"
        io.kompose.service: web
    spec:
      containers:
        - image: nginx:alpine
          name: nginxcontainer
          ports:
            - containerPort: 8000
        - image: redis:alpine
          name: rediscontainer
          ports:
            - containerPort: 6379
          resources: {}
        - env:
            - name: DB_HOST
              valueFrom:
                configMapKeyRef:
                  key: DB_HOST
                  name: envs--django
            - name: DB_NAME
              valueFrom:
                configMapKeyRef:
                  key: DB_NAME
                  name: envs--django
            - name: DB_PASSWORD
              valueFrom:
                configMapKeyRef:
                  key: DB_PASSWORD
                  name: envs--django
            - name: DB_PORT
              valueFrom:
                configMapKeyRef:
                  key: DB_PORT
                  name: envs--django
            - name: DB_USER
              valueFrom:
                configMapKeyRef:
                  key: DB_USER
                  name: envs--django
          image: localhost:5000/integration/web:latest
          name: djangocontainer
          ports:
            - containerPort: 8000
          resources: {}
      restartPolicy: Always
status: {}
---
apiVersion: v1
kind: Service
metadata:
  labels:
    io.kompose.service: web
  name: web
spec:
  ports:
    - name: "8000"
      port: 8000
      targetPort: 8000
  selector:
    io.kompose.service: web



Вы поместили все три контейнера в один Pod. Обычно такой подход не является предпочтительным: это означает, что вы не можете перезапустить один из контейнеров без перезапуска всех контейнеров (любое обновление кода вашего приложения требует удаления кэша Redis) и вы не можете индивидуально масштабировать составные части (если вам нужно пять копий вашего приложения, нужно ли вам также пять обратных прокси и можете ли вы с пользой использовать пять Redis?).

Вместо этого предпочтительным подходом является разделение их на три отдельных Deployments (или, возможно, использование StatefulSet для Redis с постоянством). Каждый из них имеет соответствующую службу, а затем имена этих служб могут быть использованы в качестве имен DNS.

Очень минимальный пример для Redis может выглядеть следующим образом:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  template:
    metadata:
      labels:
        service: web
        component: redis
    spec:
      containers:
        - name: redis
          image: redis
          ports:
            - name: redis
              containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis # <-- this name will be a DNS name
spec:
  selector: # matches the template: { metadata: { labels: } }
    service: web
    component: redis
  ports:
    - name: redis
      port: 6379
      targetPort: redis # matches a containerPorts: [{ name: }]
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  ...
    env:
      - name: REDIS_HOST
        value: redis # matches the Service

Если все три части находятся в одном Pod, то Служба не может отличить, с какой частью она разговаривает. В принципе, между этими контейнерами общее сетевое пространство имен, и они должны разговаривать друг с другом как localhost; containers: [{ name: }] не имеют практического эффекта.

Вернуться на верх