13 Dcoker Compose

2023-12-13 12:02:27 浏览数 (2)

今天,我们将学习 Docker Compose,这是一个可以简化容器化应用程序的管理的强大工具。通过利用它,我们可以轻松编排和部署复杂的应用程序栈。

Docker Compose

Docker Compose 是一个命令行工具,允许我们定义和管理多容器应用程序。借助 Docker Compose,我们可以使用简单的 YAML 文件描述应用程序的服务,网络和数据卷。它提供了一种声明性方法来定义应用程序的基本架构要求,从而更轻松地在开发、测试和生产的不同阶段管理和重现我们的环境。

安装 Docker Compose

首先,我们需要确保我们的系统上安装了 Docker Compose。以下时在 Ubuntu 系统上安装 Docker Compose 的步骤:

  1. 更新包索引,并安装最新版本的 Docker Compose:
代码语言:javascript复制
sudo apt-get update
sudo apt-get install docker-compose-plugin
  1. 通过检查版本来验证 Docker Compose 是否已正确安装:
代码语言:javascript复制
docker compose version

如果安装成功,我们会看到 Docker Compose 的版本信息。

Docker Compose 命令行

docker-compose 命令提供了许多子命令来使用 docker-compose 管理 Docker 容器。下面我们来详细了解下各个子命令。

build

build 子命令用于为已定义构建的服务构建镜像。

代码语言:javascript复制
docker-compose build # 构建所有服务
docker-compose build web # 构建单个服务

up

用于在当前目录的docker-compose.yaml文件中创建具有可用服务的 docker 容器。使用-d参数以守护进程启动容器。

代码语言:javascript复制
docker-compose up -d # 创建所有容器
docker-compose up -d web # 创建单个容器

down

用于停止并删除配置文件中定义的服务的所有容器、网络和关联镜像。

代码语言:javascript复制
docker-compose down # 停止所有容器
docker-compose down web # 停止单个容器

ps

用于列出为配置文件中定义的服务创建的所有容器及其状态、端口绑定和命令。

代码语言:javascript复制
docker-compose ps

exec

用于对正在运行的容器执行命令。例如,列出与 Web 服务关联的容器中的文件。

代码语言:javascript复制
docker-compose exec web ls -l

start

用于启动配置文件中定义的服务的已停止容器。

代码语言:javascript复制
docker-compose start # 启动所有容器
docker-compose start web # 启动单个容器

stop

用于停止运行配置文件中定义的服务的容器。

代码语言:javascript复制
docker-compose stop # 停止所有容器
docker-compose stop web # 停止单个容器

restart

用于重新启动配置文件中定义的服务的容器。

代码语言:javascript复制
docker-compose restart # 重启所有容器
docker-compose restart web # 重启单个容器

pause

用于暂停配置文件中定义的服务的运行容器。

代码语言:javascript复制
docker-compose pause # 暂停所有容器
docker-compose pause web # 暂停单个容器

unpause

用于为配置文件中定义的服务启动暂停的容器。

代码语言:javascript复制
docker-compose pause # 启动所有暂停的容器
docker-compose pause # 启动单个暂停的容器

rm

用于删除配置文件中定义的服务的已停止的容器。

代码语言:javascript复制
docker-compose rm # 删除所有容器
docker-compose web # 删除单个容器

在没有 sudo 下运行 Docekr 命令

默认情况下,运行 Docker 命令需要 sudo 或 root 权限。但是,可以授予我们的用户在不适用 sudo 的情况下运行 Docker 命令的权限。以下时实现这一目标的方法:

  1. 通过运行以下命令将用户添加到docker组(将<username>替换为你的实际用户名):
代码语言:javascript复制
sudo usermod -aG docker <username>
  1. 将用户添加到docker组后,需要重新启动系统才能使更改生效。通过运行以下命令重新启动你的机器:
代码语言:javascript复制
sudo reboot

重新启动后,我们就能够在没有 sudo 的情况下运行 Docker 命令。

什么是 YAML

YAML,全程”YAML Ain't Markup Language“,是一种流行的数据序列化格式,广泛应用于 DevOps 领域,用于创建配置文件。它提供了人类可读且机器友好的语法,允许开发人员和系统管理员清晰,简洁地定义结构化数据。

DevOps 中 YAML 的主要用例之一是用于配置和定义应用程序设置和环境。例如,在 Docker Compose 中,YAML 文件用于指定运行多容器应用程序所需的服务、网络、数据卷和其他配置。

YAML 文件利用缩进和简单的语法来分层表示数据,使其易于理解和使用。这种可读性是 YAML 的关键优势之一,因为它使我们和机器能够轻松地解析和解释数据。

此外,YAML 支持各种数据类型,例如标量(字符串、数字、布尔值)、序列(数组、列表)和映射(键值对)。这种灵活性允许表示应用程序不同组件之间的复杂配置和关系。

实践一 创建 docker-compose.yaml

浏览以下docker-compose.yaml文件并了解它如何设置环境,配置服务,在容器之间建立链接以及使用环境变量:

代码语言:javascript复制
version: "3.3"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

  db:
    image: mysql
    ports:
      - "3306:3306"
    environment:
      - "MYSQL_ROOT_PASSWORD=test@123"
  • version: "3.3"行只当正在使用的 Docker Compose 文件语法的版本。
  • services部分下,定义了连个服务:webdb。每个服务代表一个容器。
  • web服务使用nginx: latest镜像,这是一个流行的 Web 服务器。它可以通过定义为ports: - "80:80"的端口映射来访问,其中容器的端口 80 映射到主机的端口 80。这语序通过主机上的 http://localhost访问容器内运行的 Web 服务器。
  • db服务使用mysql镜像,这是一个广泛使用的关系数据库管理系统,与web服务类似,它也将端口映射定义为ports: - "3306:3306",允许通过localhost在端口 3306 上访问容器内运行的 MySQL 数据库服务器主机。
  • 此外,db服务将 MYSQL_ROOT_PASSWORD环境变量设置为test@123。这会设置容器内 MySQL 数据库的 root 密码,以确保安全访问。

通过在docker-compose.yaml文件所在的目录中运行docker-compose up命令,Docker Compose 将创建并启动定义的服务。它自动管理容量之间的网络并设置执行的环境变量。

代码语言:javascript复制
root@huang-ubuntu:~/Codes/docker-compose-case# docker compose up
[ ] Running 11/11
 ✔ db 10 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                   266.6s
   ✔ 8e0176adc18c Pull complete                                                                        14.9s
   ✔ 2d2c52718f65 Pull complete                                                                         1.7s
   ✔ d88d03ce139b Pull complete                                                                         2.8s
   ✔ 4a7d7f11aa1e Pull complete                                                                         6.3s
   ✔ ce5949193e4c Pull complete                                                                         4.8s
   ✔ f7f024dfb329 Pull complete                                                                        11.1s
   ✔ 5fc3c840facc Pull complete                                                                        31.5s
   ✔ 509068e49488 Pull complete                                                                        12.9s
   ✔ cbc847bab598 Pull complete                                                                        46.1s
   ✔ 942bef62a146 Pull complete                                                                        17.5s
[ ] Running 3/3
 ✔ Network docker-compose-case_default  Created                                                         1.2s
 ✔ Container docker-compose-case-web-1  Created                                                         2.7s
 ✔ Container docker-compose-case-db-1   Created                                                         2.7s
Attaching to docker-compose-case-db-1, docker-compose-case-web-1
...

实践二 非 root 身份运行容器

从公共存储库(如 Docker Compose)中提取预先存在的 Docker 镜像并在本地计算机上运行。以非 root 身份运行容器。确保在授予用户权限后重新启动实例。

使用 docke pull 命令,后跟镜像名称和标签来拉取镜像。

代码语言:javascript复制
root@huang-ubuntu:~# docker pull nginx:latest
latest: Pulling from library/nginx
Digest: sha256:10d1f5b58f74683ad34eb29287e07dab1e90f10af243f151bb50aa5dbb4d62ee
Status: Image is up to date for nginx:latest
docker.io/library/nginx:latest

使用docker inspect <container-id>命令检查容器的运行进程和暴露的端口。

代码语言:javascript复制
root@huang-ubuntu:~# docker run -d -p 80:80 nginx
df803daffebe52cdac0f7dc1f08fb158f3fb8d9a20371f016f9a50f995c3b518
root@huang-ubuntu:~# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS         PORTS                               NAMES
df803daffebe   nginx     "/docker-entrypoint.…"   12 seconds ago   Up 9 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   vibrant_shannon
root@huang-ubuntu:~# docker inspect df803daffebe
[
    {
        "Id": "df803daffebe52cdac0f7dc1f08fb158f3fb8d9a20371f016f9a50f995c3b518",
        "Created": "2023-12-07T10:33:20.171973934Z",
        "Path": "/docker-entrypoint.sh",
        "Args": [
            "nginx",
            "-g",
            "daemon off;"
        ],
        "State": {
            "Status": "running",

使用docker logs <container-id>命令查看容器的日志输出。

代码语言:javascript复制
root@huang-ubuntu:~# docker logs df803daffebe
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/12/07 10:33:24 [notice] 1#1: using the "epoll" event method
2023/12/07 10:33:24 [notice] 1#1: nginx/1.25.3
2023/12/07 10:33:24 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/12/07 10:33:24 [notice] 1#1: OS: Linux 5.15.0-89-generic
2023/12/07 10:33:24 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/12/07 10:33:24 [notice] 1#1: start worker processes
2023/12/07 10:33:24 [notice] 1#1: start worker process 29

使用docker stop <container-id>docker start <container-id>命令来停止和启动容器。

代码语言:javascript复制
root@huang-ubuntu:~# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                               NAMES
df803daffebe   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp   vibrant_shannon
root@huang-ubuntu:~# docker stop df803daffebe
df803daffebe
root@huang-ubuntu:~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
root@huang-ubuntu:~# docker start df803daffebe
df803daffebe
root@huang-ubuntu:~# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                               NAMES
df803daffebe   nginx     "/docker-entrypoint.…"   6 minutes ago   Up 5 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   vibrant_shannon

完成后,使用docker rm <container-id>来删除容器,删除的前提使容器需要停止运行。

代码语言:javascript复制
root@huang-ubuntu:~# docker stop df803daffebe
df803daffebe
root@huang-ubuntu:~# docker rm df803daffebe
df803daffebe
root@huang-ubuntu:~# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

实践三 使用 compose 文件来创建 Jenkins 和 Portainer 容器

docker-composer.yaml 文件内容如下:

代码语言:javascript复制
version: "3.9"
services:
  portainer:
    container_name: portainer
    image: portainer/portainer-ce:latest
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    ports:
      - 9000:9000

  jenkins:
    container_name: jenkins
    image: jenkins/jenkins:lts
    restart: always
    volumes:
      - jenkins_data:/var/jenkins_home
    ports:
      - 8080:8080
      - 50000:50000

volumes:
  portainer_data:
  jenkins_data:
  • version字段指定正在使用的 Docker Compose 文件格式的版本。
  • services部分下,我们定义了两个服务:portainerJenkins
  • 对于portainer服务:
    • image字段指定要使用的 Portaine 镜像。
    • volumes字段挂在 Docker 套接字和用于 Portainer 数据持久化的数据卷。
    • ports字段将容器的端口 9000 映射到主机的端口 9000。
  • 对于jenkins服务:
    • image字段指定要使用的 Jenkins 镜像。
    • volumes字段挂在一个用于 Jenkins 数据持久化的数据卷。
  • ports字段将容器的端口 8080 和 50000 映射到主机上的相同端口。

这个示例设置 Portainer 来管理 Docker 容器,并设置 Jenkins 来实现持续集成和持续交付(CI/CD)流程。我们可以在主机的端口 9000 上访问 Portainer,在端口 8080 上访问 Jenkins。

0 人点赞