【问题标题】:Redis doesn't start as a service inside a docker containerRedis 不会作为 docker 容器内的服务启动
【发布时间】:2018-12-14 06:23:03
【问题描述】:

我对 docker 很陌生,所以我按照他们的官方教程并尝试了适用于我的工作项目的“快捷方式”。我有以下 docker-compose.yml:

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: my_image
    deploy:
      replicas: 5
      restart_policy:
        condition: on-failure
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
    ports:
      - "4000:80"
    networks:
      - webnet
  redis:
    image: redis
    ports:
      - "6379:6379"
    volumes:
      - "/home/docker/data:/data"
    command: redis-server --appendonly yes
    networks:
      - webnet
networks:
  webnet:

my_image 是一个简单的烧瓶应用程序,它启动 Flask 和 Redis,然后打印访问次数:

from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
    try:
        visits = redis.incr("counter")
    except RedisError:
        visits = "<i>cannot connect to Redis, counter disabled</i>"

    html = "<h3>Hello {name}!</h3>" \
           "<b>Hostname:</b> {hostname}<br/>" \
           "<b>Visits:</b> {visits}"
    return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

Dockerfile here

当我像这样开始集群时:

sudo docker swarm init --advertise-addr <ip>
sudo docker stack deploy -c docker-compose.yml flask_with_redis

my_image 映像启动良好,我可以看到它在 127.0.0.1:4000 上运行,但 Redis 从未启动。 我怀疑我的docker-compose.yml 有问题,尤其是redis 服务,因为my_image 运行良好。 通过运行requirements.py,Redis 和 Flask 也肯定会添加到my_image。 有没有人经历过类似的事情?你能帮我吗?

【问题讨论】:

    标签: docker redis docker-swarm


    【解决方案1】:

    您的 compose 看起来正确,并且您的烧瓶应用服务/图像与作为成功服务启动的 redis 图像无关。

    1. docker stack ps flask_with_redisdocker service logs flask_with_redis_redis 说什么?

    2. 我建议您在部署堆栈时观看docker events,看看它尝试使用 redis 服务做什么。

    【讨论】:

      【解决方案2】:

      它对我有用,我已经对 docker-compose 文件进行了很少的更改,例如将 my_image 映像添加到私有注册表和部署模式作为 redis 的全局,因为我正在执行 swarm 模式( 1 个管理器 2 个工作节点)。请找到以下步骤。

      使用以下命令创建本地注册表。

      docker service create registry --name registry --publish published=5003,target=5000 registry:2
      

      更新镜像和构建标签,如下所述。还将部署模式更新为 redis 的全局模式。

      注意:如果您在 docker swarm 上运行,请确保您在所有节点上都创建了路径 /home/docker/data。

      version: "3"
      services:
        web:
          # replace username/repo:tag with your name and image details
          image: 127.0.0.1:5003/my_image:latest
          build: .
          deploy:
            replicas: 5
            restart_policy:
              condition: on-failure
            resources:
              limits:
                cpus: "0.1"
                memory: 50M
          ports:
            - "4000:80"
          networks:
            - webnet
        redis:
          image: redis
          deploy:
            mode: global
          ports:
            - "6379:6379"
          volumes:
            - "/home/docker/data:/data"
          command: redis-server --appendonly yes
          networks:
            - webnet
      networks:
        webnet:
      

      在所有工件(Dockerfile、docker-compose.yml、requirements.txt app.py)存在的地方执行以下命令。

      运行以下命令来构建镜像。

      docker-compose up -d
      

      运行以下命令删除容器。

      docker-compose down
      

      运行以下命令将创建的 my_image 映像推送到私有注册表。

      docker-compose push
      

      运行以下命令以使用相同的 compose 文件创建堆栈。

      docker stack deploy --compose-file docker-compose.yml redisapp
      

      为您的参考截图。

      希望对您有所帮助,如果您需要任何帮助,请告诉我。

      【讨论】:

        【解决方案3】:

        感谢 Prathis 和 Bret Fisher 的帮助。 事实证明,解决方案更简单:我只需要“坚持”Docker 教程,然后离开

        placement:
           constraints: [node.role == manager]
        

        所以完整的(工作的)docker-compile.yml 看起来像这样:

        version: "3"
        services:
          web:
            # replace username/repo:tag with your name and image details
            image: my_image
            deploy:
              replicas: 5
              restart_policy:
                condition: on-failure
              resources:
                limits:
                  cpus: "0.1"
                  memory: 50M
            ports:
              - "4000:80"
            networks:
              - webnet
          redis:
            image: redis:latest
            deploy:
              placement:
                constraints: [node.role == manager]
            ports:
              - "6379:6379"
            command: redis-server --appendonly yes
            networks:
              - webnet
        networks:
          webnet:
        

        这个容器运行 Redis 很好

        【讨论】:

          【解决方案4】:

          我的情况是,它不起作用,因为出于某种原因,我从 docker-compose.yml 中省略了 networks: - webnet。我的理解是,这告诉服务使用其他人正在使用的同一网络,这就是 python 代码中的“host=redis”如何正确解析到 redis 服务器的方式。

          【讨论】:

            猜你喜欢
            • 2018-03-29
            • 2019-10-25
            • 2014-09-02
            • 1970-01-01
            • 2018-10-31
            • 1970-01-01
            • 2020-07-03
            • 1970-01-01
            • 2020-03-27
            相关资源
            最近更新 更多