Контейнеры в капсуле не разговаривают друг с другом в 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: }]
не имеют практического эффекта.