【问题标题】:What is the equivalent for depends_on in kubernetesKubernetes中depends_on的等价物是什么
【发布时间】:2018-08-28 07:30:48
【问题描述】:

我有一个包含以下条目的 docker compose 文件


version: '2.1'

services:
  mysql:
    container_name: mysql 
    image: mysql:latest 
    volumes:
      - ./mysqldata:/var/lib/mysql 
    environment: 
      MYSQL_ROOT_PASSWORD: 'password' 
    ports: 
      - '3306:3306' 
    healthcheck: 
        test: ["CMD", "curl", "-f", "http://localhost:3306"] 
        interval: 30s 
        timeout: 10s 
        retries: 5 

  test1: 
    container_name: test1 
    image: test1:latest 
    ports: 
      - '4884:4884' 
      - '8443' 
    depends_on: 
      mysql: 
        condition: service_healthy 
    links: 
     - mysql 

Test-1 容器依赖于 mysql,需要启动并运行。

在 docker 中,这可以使用健康检查和 depends_on 属性来控制。 kubernetes 中的健康检查等效项是我已经创建的 readinessprobe,但是我们如何控制 pod 中的容器启动??????

非常感谢任何有关这方面的指导。

我的 Kubernetes 文件:

apiVersion: apps/v1beta1 
kind: Deployment 
metadata: 
  name: deployment 
spec: 
  replicas: 1 
  template: 
    metadata: 
      labels: 
        app: deployment 

    spec: 
      containers: 
      - name: mysqldb 
        image: "dockerregistry:mysqldatabase" 
        imagePullPolicy: Always 
        ports: 
        - containerPort: 3306 
        readinessProbe: 
          tcpSocket: 
            port: 3306 
          initialDelaySeconds: 15 
          periodSeconds: 10 
      - name: test1 
        image: "dockerregistry::test1" 
        imagePullPolicy: Always 
        ports: 
        - containerPort: 3000 

【问题讨论】:

    标签: kubernetes kubectl kubernetes-helm kubeadm


    【解决方案1】:

    虽然除了this link (k8s-AppController) 之外我不知道您的问题的直接答案,但我认为对数据库和应用程序使用相同的部署并不明智。因为您将您的数据库与应用程序紧密耦合,并失去了很棒的 k8s 选项来根据需要扩展其中任何一个。此外,如果您的 db pod 死亡,您的数据也会丢失。

    我个人会做的是有一个单独的StatefulSetPersistent Volume 用于数据库和部署应用程序,并使用Service 来确保他们的通信。
    是的,我必须运行几个不同的命令,并且可能需要至少两个单独的部署文件,但这样我可以将它们解耦并可以根据需要对其进行扩展。而且我的数据也是持久的!

    【讨论】:

      【解决方案2】:

      在 Kubernetes 术语中,您的 docker-compose 集是 Pod

      所以,那里没有 depends_on 等价物。 Kubernetes 将检查 pod 中的所有容器,并且它们都必须处于活动状态才能将 pod 标记为健康,并且始终一起运行它们。

      在您的情况下,您需要像这样准备 Deployment 的配置:

       apiVersion: extensions/v1beta1
       kind: Deployment
       metadata:
         name: my-app
       spec:
         replicas: 1
         template:
           metadata:
             labels:
               app: app-and-db
           spec:
             containers:
               - name: app
                 image: nginx
                 ports:
                   - containerPort: 80
               - name: db
                 image: mysql
                 ports:
                   - containerPort: 3306
      

      pod 启动后,您的数据库将在您的应用程序的localhost 接口上可用,因为network conception

      pod 中的容器共享一个 IP 地址和端口空间,并且可以通过 localhost 找到彼此。它们还可以使用标准的进程间通信(如 SystemV 信号量或 POSIX 共享内存)相互通信。

      但是,正如@leninhasda 所提到的,在您的 pod 中运行数据库和应用程序并且没有 Persistent Volume 并不是一个好主意。这是一个关于如何运行stateful application in the Kubernetes 的好教程。

      【讨论】:

        【解决方案3】:

        如前所述,您应该在单独的 pod 中运行数据库和应用程序容器,并将它们与服务连接。

        很遗憾,Kubernetes 和 Helm 都没有提供与您所描述的功能类似的功能。我们遇到了很多问题并尝试了一些方法,直到我们决定开发一个小型实用程序来为我们解决这个问题。

        这是我们开发的工具的链接:https://github.com/Opsfleet/depends-on

        您可以根据它们的 readinessProbe 配置让 pod 等到其他 pod 准备就绪。它非常接近 Docker 的 depends_on 功能。

        【讨论】:

          【解决方案4】:

          在 kubernetes 中没有与 docker swarm depends_on 等价的东西。 这种情况的解决方案是使用helm charts 进行 kubernetes 部署 在 Helm 中,您可以指定依赖项列表。 Helm 现在越来越受欢迎,是管理复杂 kubernetes 部署的绝佳工具。

          https://helm.sh/

          【讨论】:

          • Helm 只是管理依赖和创建 Pod,它不保证运行时的任何顺序。这意味着它可能会创建 2 个 pod,但数据库一个需要 20 秒才能启动,而您的应用程序会在 2 秒内完成,而 helm 不在乎。
          • 不回答问题
          【解决方案5】:

          这是故意遗漏的。原因是应用程序应该负责它们的连接/重新连接逻辑,以连接到数据库等服务。这超出了 Kubernetes 的范围。

          【讨论】:

          • initContainers 与dependsOn 的等效项非常接近,因此提及initContainers 是一个更好的解决方案。
          • depends_on 等效项被故意省略,但 initContainers 是合法的。设计逻辑似乎有点武断。
          【解决方案6】:

          这就是 Docker Compose 和 Docker Swarm 的美妙之处……它们的简单性。

          在部署 ELK 堆栈时,我们也遇到了同样的 Kubernetes 缺点。 我们通过使用 side-car (initContainer) 解决了这个问题,它只是在同一个 pod 中首先运行的另一个容器,当它完成时,kubernetes 会自动启动 [main] 容器。我们使它成为一个简单的 shell 脚本,它一直在循环中,直到 Elasticsearch 启动并运行,然后它退出并启动 Kibana 的容器。

          以下是等待 Grafana 准备就绪的边车示例。

          在 Pod 中的其他容器上方添加这个“initContainer”块:

          spec:
                initContainers:
                - name: wait-for-grafana
                  image: darthcabs/tiny-tools:1
                  args:
                  - /bin/bash
                  - -c
                  - >
                    set -x;
                    while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://grafana:3000/login)" != "200" ]]; do 
                      echo '.'
                      sleep 15;
                    done
                containers:
                    .
                    .
            (your other containers)
                    .
                    .
          

          【讨论】:

          • 等待超时怎么样?例如多 10 分钟是刹车?
          • 如果所有的 elasticsearch 和 kibana pod 都关闭了怎么办?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-08
          • 2014-06-12
          • 1970-01-01
          • 2022-11-28
          • 2021-06-19
          • 2012-07-20
          相关资源
          最近更新 更多