【问题标题】:Create a single container instead of 3 different containers创建一个容器而不是 3 个不同的容器
【发布时间】:2021-02-23 14:11:38
【问题描述】:

我看到您正在设置一个 Docker-compose 文件,但它创建了 3 个不同的容器,但希望将这 3 个容器组合成一个容器/映像,而不是在部署系统中将其设置为多个容器。

我目前的容器列表如下:

  1. 我的主容器包含我使用 Docker 文件构建的代码
  2. rest 2 是 Redis 和 Postress 的容器,但想将它们合并到 1 中。

有什么办法吗?

【问题讨论】:

  • 您真的不想将它们合并到一个容器中。这使得很多事情变得更加困难——例如,这会阻止你使用 postgres 和 redis 的官方图像,这只会给你带来一堆额外的工作而没有任何好处。
  • 你能描述你为什么要这样做的问题吗?也许我们可以帮助您解决真正的问题。请记住,关注点分离是一个基本原则,它来自于容器化甚至不是一件事的时代,但容器化遵循并建立在该原则之上。

标签: docker kubernetes docker-compose dockerfile docker-machine


【解决方案1】:

首先,在一个容器中运行redis、postgres 和"main container" 是不是最佳做法。 通常,您应该有 3 个独立的容器(每个容器一个应用程序)通过网络进行通信。有时我们想在同一个容器中运行两个或多个轻量级服务,但 redis 和 postgres 不是这样的服务。
我推荐阅读:best practices for building containers。


但是,使用supervisord 进程管理系统可以在同一个 docker 容器中拥有多个服务。
我将在一个 docker 容器中同时运行 redis 和 postgres 服务(这与您的问题类似)来说明它是如何工作的。仅用于演示目的。

这是一个目录结构,我们只需要Dockerfile和supervisor.conf(supervisord配置文件):

$ tree example_container/
example_container/
├── Dockerfile
└── supervisor.conf

首先,我创建了一个supervisord 配置文件,其中定义了redis 和postgres 服务:

$ cat example_container/supervisor.conf
[supervisord]
nodaemon=true

[program:redis] 
command=redis-server # command to run redis service
autorestart=true
stderr_logfile=/dev/stdout
stderr_logfile_maxbytes = 0
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes = 0


[program:postgres]
command=/usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12/main/ -c config_file=/etc/postgresql/12/main/postgresql.conf # command to run postgres service
autostart=true
autorestart=true
stderr_logfile=/dev/stdout
stderr_logfile_maxbytes = 0
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes = 0
user=postgres
environment=HOME="/var/lib/postgresql",USER="postgres"

接下来我创建了一个简单的Dockerfile:

$ cat example_container/Dockerfile
FROM ubuntu:latest
ARG DEBIAN_FRONTEND=noninteractive

# Installing redis and postgres
RUN apt-get update && apt-get install -y supervisor redis-server postgresql-12

# Copying supervisor configuration file to container
ADD supervisor.conf /etc/supervisor.conf

# Initializing redis and postgres services using supervisord
CMD ["supervisord","-c","/etc/supervisor.conf"]

然后我构建了 docker 镜像:

$ docker build -t example_container:v1 .

最后我使用上图运行并测试了 docker 容器:

$ docker run --name multi_services -dit example_container:v1
472c7b2eac7441360126f8fcd0cc80e0e63ac3039f8195715a3a400f6288a236


$ docker exec -it multi_services bash
root@472c7b2eac74:/# ps aux   
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.7  0.1  27828 23372 pts/0    Ss+  10:04   0:00 /usr/bin/python3 /usr/bin/supervisord -c /etc/supervisor.conf
postgres       8  0.1  0.1 212968 28972 pts/0    S    10:04   0:00 /usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12/main/ -c config_file=/etc/postgresql/12/main/postgresql.conf
root           9  0.1  0.0  47224  6216 pts/0    Sl   10:04   0:00 redis-server *:6379
...

root@472c7b2eac74:/# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      9/redis-server *:6
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      8/postgres
tcp6       0      0 :::6379                 :::*                    LISTEN      9/redis-server *:6

如您所见,可以在一个容器中拥有多个服务,但这是一种不推荐的方法,应该仅用于测试。

【讨论】:

    【解决方案2】:

    关于 Kubernetes,您可以将容器分组到一个 pod 中,作为一个部署单元。

    Pod 是您可以在 Kubernetes 中创建和管理的最小可部署计算单元。
    它是一组一个或多个容器,具有共享的存储和网络资源,以及如何运行容器的规范。

    Pod 的内容始终处于同一位置和共同调度,并在共享上下文中运行。

    这比尝试将容器合并到一个容器中更有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-10
      • 2021-08-19
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多