0

我精通 Docker,但在这里用 K8 肯定做错了什么。我正在运行skaffoldminikube试图让容器之间的 DNS 正常工作。这是我的部署:

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无法my-api-postgres通过 DNS 主机名联系my-api-postgres。知道我做错了什么吗?

4

2 回答 2

2

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

这样做的“正确”方法是为每个应用程序创建一个部署,并在这些部署前面加上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

于 2019-05-10T00:08:36.050 回答
0

作为 johnharris85 DNS 的补充,当您将应用程序分开时,您应该在您的场景中这样做。

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

在您的情况下,您可以轻松地将它们分开。在这种情况下,您有一个包含 1 个 Pod 的部署,其中有 3 个容器通过 localhost 而不是前面提到的 DNS 名称相互通信。之后,我建议您阅读 Kubernetes 内部的 DNS 以及通信如何与进入游戏的服务一起工作。如果是豆荚,您可以在此处阅读更多信息。

于 2019-05-10T15:33:43.920 回答