单节点 Kubernetes 集群 - 不同 Pod 中的容器无法相互通信

时间:2021-05-04 14:54:18

标签: docker kubernetes redis

我有一个反复出现的问题,不同 Pod 中的容器无法相互通信。 为简单起见,我创建了一个集群,在不同的 pod 中只有 2 个容器:

  1. 只做一件事的应用:连接到 redis 服务器。
  2. redis-server 容器

长话短说:尝试从应用程序连接到 redis 时,我不断收到“连接被拒绝”的消息:

$ kubectl logs app-deployment-86f848b46f-n7672

> app@1.0.0 start
> node ./app.js

LATEST
Error: connect ECONNREFUSED 10.104.95.63:6379
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1133:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '10.104.95.63',
  port: 6379
}

app成功识别redis-service但连接失败

$ kubectl get services
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
app-service     ClusterIP   10.107.18.112   <none>        4000/TCP   2m42s
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP    29h
redis-service   ClusterIP   10.104.95.63    <none>        6379/TCP   29h

应用代码:

const redis = require("redis");
const bluebird = require("bluebird");
bluebird.promisifyAll(redis);
console.log('LATEST');
const host = process.env.HOST;
const port = process.env.PORT;
const client = redis.createClient({ host, port });

client.on("error", function (error) {
    console.error(error);
}); 

应用的 docker 文件:

FROM node
WORKDIR "/app"
COPY ./package.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]

对于redis服务器,我尝试了redis的默认镜像,当它不起作用时,我使用了一个定制的镜像,没有绑定到特定的ip,也没有保护模式。

redis dockerfile:

FROM redis:latest
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

最后,我使用受人尊敬的 ClusterIP 服务创建了 2 个部署:

应用部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: app
  template:
    metadata:
      labels:
        component: app
    spec: 
      containers:
      - name: app
        image: user/redis-app:latest
        ports:
          - containerPort: 4000
        env:
          - name: HOST
            valueFrom:
              configMapKeyRef:
                name: app-env
                key: HOST
          - name: PORT
            valueFrom:
              configMapKeyRef:
                name: app-env
                key: PORT

应用服务:

apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  type: ClusterIP
  selector:
    component: app
  ports:
    - port: 4000
      targetPort: 4000

环境文件:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-env
data:
   PORT: "6379"
   HOST: "redis-service.default"

redis 部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      db: redis
  template:
    metadata:
      labels:
        db: redis
    spec: 
      containers:
        - name: redis
          image: user/custome-redis:latest
          ports:
            - containerPort: 6379

redis 服务:

apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  type: ClusterIP
  selector:
    component: redis
  ports:
  - protocol: TCP
    port: 6379
    targetPort: 6379

最初,我使用带有 WSL2 的 Windows 环境和运行在 Docker 上并安装了 Docker 桌面的 Kubernetes。当它失败时,我在 virtualbox 上配置了一个 centos8 vm 并使用 minikube 安装了 kubernets - 得到了相同的结果..

有什么想法吗?....

1 个答案:

答案 0 :(得分:1)

在 David Maze 发现问题后发表评论中的答案(添加为社区维基,随时编辑)

在 pod、部署、服务和其他元素之间匹配标签非常重要。

在上面的示例中,redis 服务使用了不同的标签:

component: redisdb: redis 导致此问题。