Kubernetes部署中的DNS无法按预期工作

时间:2019-05-09 20:48:43

标签: kubernetes minikube skaffold

我精通Docker,但是在使用K8时一定做错了。我正在skaffold上运行minikube,并试图在容器之间正常工作。这是我的部署:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-api
  labels:
    app: my-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-api
  template:
    metadata:
      name: my-api
      labels:
        app: my-api
    spec:
      containers:
      - name: my-api-postgres
        image: postgres:11.2-alpine
        env:
        - name: POSTGRES_USER
          value: "my-api"
        - name: POSTGRES_DB
          value: "my-api"
        - name: POSTGRES_PASSWORD
          value: "my-pass"
        ports:
        - containerPort: 5432
      - name: my-api-redis
        image: redis:5.0.4-alpine
        command: ["redis-server"]
        args: ["--appendonly", "yes"]
        ports:
        - containerPort: 6379
      - name: my-api-node
        image: my-api-node
        command: ["npm"]
        args: ["run", "start-docker-dev"]
        ports:
        - containerPort: 3000

但是,在这种情况下,my-api-node无法通过DNS主机名my-api-postgresmy-api-postgres联系。知道我在做什么错吗?

2 个答案:

答案 0 :(得分:2)

您已将所有3个容器定义为同一容器的一部分。 Pod具有一个公共的网络命名空间,因此在您当前的设置中(这是不正确的,稍后会详细介绍),您可以使用localhost:<port>与其他容器进行对话。

做到这一点的“正确”方法是为每个应用程序创建一个deployment,并使用services在这些部署之前。

您的示例将大致变为(未试用):

kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-api-node
  namespace: my-api
  labels:
    app: my-api-node
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-api-node
  template:
    metadata:
      name: my-api-node
      labels:
        app: my-api-node
    spec:
      containers:
      - name: my-api-node
        image: my-api-node
        command: ["npm"]
        args: ["run", "start-docker-dev"]
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  namespace: my-api
  name: my-api-node
spec:
  selector:
    app: my-api-node
  ports:
  - protocol: TCP
    port: 3000
    targetPort: 3000
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-api-redis
  namespace: my-api
  labels:
    app: my-api-redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-api-redis
  template:
    metadata:
      name: my-api-redis
      labels:
        app: my-api-redis
    spec:
      containers:
      - name: my-api-redis
        image: redis:5.0.4-alpine
        command: ["redis-server"]
        args: ["--appendonly", "yes"]
        ports:
        - containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  namespace: my-api
  name: my-api-redis
spec:
  selector:
    app: my-api-redis
  ports:
  - protocol: TCP
    port: 6379
    targetPort: 6379
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-api-postgres
  namespace: my-api
  labels:
    app: my-api-postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-api-postgres
  template:
    metadata:
      name: my-api-postgres
      labels:
        app: my-api-postgres
    spec:
      containers:
      - name: my-api-postgres
        image: postgres:11.2-alpine
        env:
        - name: POSTGRES_USER
          value: "my-api"
        - name: POSTGRES_DB
          value: "my-api"
        - name: POSTGRES_PASSWORD
          value: "my-pass"
        ports:
        - containerPort: 5432
---
apiVersion: v1
kind: Service
metadata:
  namespace: my-api
  name: my-api-postgres
spec:
  selector:
    app: my-api-postgres
  ports:
  - protocol: TCP
    port: 5432
    targetPort: 5432

DNS记录已为服务注册,因此您可以连接到这些记录并转发到其后面的Pod(简化)。如果您需要从外部访问节点应用程序,那是另外一回事,您应该查看LoadBalancer类型的服务或Ingress

答案 1 :(得分:0)

作为johnharris85 DNS的附加功能,当您分隔应用程序时,应在方案中执行此操作。

多容器Pod通常用于特定的用例,例如Sidecar容器,以帮助主容器完成某些特定任务或代理,桥和适配器,例如,提供到某些特定目标的连接性。

您可以轻松地将它们分开。在这种情况下,您有一个具有1个Pod的部署,其中有3个容器通过本地主机而不是如上所述的DNS名称相互通信。 之后,我建议您阅读Kubernetes内部的DNS,以及communication如何与逐步进入游戏的服务一起工作。 如果是广告连播,您可以阅读更多here