Docker续集+Docker Compose

目录

Containerd

  1. 早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。和原先包含在DockerEngine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容
    器运行时管理的所有需求。
  2. containerd并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如Swarm, Kubernetes, Mesos等容器编排系统。
  3. containerd以Daemon的形式运行在系统上,通过暴露底层的gRPC API,上层系统可以通过这些API管理机器上的容器。
  4. 每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。
  5. 对于容器编排服务来说,运行时只需要使用containerd+runC,更加轻量,容易管理。
  6. 独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。

与docker的关系

Containerd和Docker是容器生态系统中相关但不同的组件。

  1. Docker:

    Docker是一种流行的平台,彻底改变了软件开发、发布和运行的方式。它提供了用户友好的界面和工具,用于创建、管理和部署容器。Docker允许开发人员将应用程序及其依赖项打包成容器,确保在不同环境中具有一致性。它提供了命令行界面(CLI)和图形用户界面(GUI),用于管理容器和镜像。

  2. Containerd:

    Containerd是一个业界标准的容器运行时,最初是Docker项目的一部分,但后来作为一个独立项目属于Cloud Native Computing Foundation(CNCF)。Containerd作为核心容器运行时负责在主机系统上运行和管理容器。它处理低层次的容器操作,比如容器的执行、镜像传输和存储,并支持containerd API以进行容器管理。

Containerd和Docker之间的关系:

Docker使用containerd作为其容器运行时。在Docker早期阶段,它拥有自己的容器运行时引擎,但随着容器生态系统的发展,决定将Docker模块化,并利用containerd作为底层运行时。这使得Docker能够更专注于高级别的功能和工具,同时利用containerd强大的容器运行时功能。

简而言之,Docker是一个全功能平台,包括CLI、GUI和其他用于容器管理的工具,而它依赖containerd作为容器运行时,在系统上执行和管理容器。Containerd是一个独立的、轻量级且高性能的容器运行时,被Docker和其他容器平台用于管理容器执行。

runC

runC是一个开源的容器运行时工具,用于执行符合Open Container Initiative (OCI) 标准的容器。OCI是一个由Docker、CoreOS和其他公司共同推动的开放标准,旨在定义容器格式和运行时的规范,以促进容器生态系统的互操作性和可移植性。

runC是containerd项目的核心组件之一,它负责实际运行和管理容器。具体来说,当你使用Docker或其他容器平台创建和启动容器时,它们会使用runC来实际创建和运行容器实例。

runC的设计理念是简单和模块化,它只关注容器的运行时生命周期,不处理高级别的容器管理任务,比如镜像构建、网络配置等。因此,runC通常与容器管理工具(比如containerd、Docker、cri-o等)一起使用,这些工具提供了更全面的容器管理功能。

通过使用OCI标准,runC可以保证在支持OCI规范的任何容器运行时中都可以运行容器,这有助于避免了锁定到特定的容器平台。这种开放标准化的方法有助于加强容器生态系统的稳定性和互操作性。

runC与Containerd的关联

  1. 功能范围:

    • runC:runC是一个独立的、轻量级的容器运行时工具,负责根据OCI(Open Container Initiative)标准来创建和运行容器。它专注于处理容器的生命周期,即容器的创建、启动、停止和销毁。
    • containerd:containerd是一个更大的容器守护进程,它充当着runC和高级容器管理工具(如Docker)之间的桥梁。containerd使用runC来实际执行容器,但同时提供了更多功能,比如镜像管理、容器存储、网络管理等。它是一个全功能的容器管理工具,而不仅仅是一个运行时。
  2. 复杂性:

    • runC:由于其专注于容器的运行时生命周期,runC相对较为简单,仅实现了OCI标准定义的最基本容器功能。
    • containerd:containerd相对复杂,因为它是一个完整的容器管理工具,包括支持多个容器运行时(包括runC、Kata Containers等),镜像管理、容器网络、存储管理等功能。
  3. 使用场景:

    • runC:通常在需要更轻量级、更简单容器运行时的场景中使用,或者作为其他容器管理工具的基础组件。
    • containerd:更适用于需要全功能容器管理的场景,特别是在生产环境中使用,可以与其他工具(如Kubernetes、Docker)结合使用。

虽然runC和containerd有不同的功能范围和复杂性,但它们通常会在一起使用。containerd使用runC来执行容器,这使得它可以利用runC的简单性和符合OCI标准的优势,并在此基础上提供更多的高级容器管理功能。

OCI协议

OCI(Open Container Initiative)是一个由Linux基金会支持的开放性项目,旨在为容器生态系统建立开放的行业标准。OCI的目标是定义容器格式和运行时的规范,以促进容器技术的互操作性和可移植性。

OCI项目涵盖了两个关键规范:

  1. OCI Image Specification(OCI镜像规范):

    这个规范定义了容器镜像的结构和内容。容器镜像是一个轻量级的、可移植的软件包,它包含了应用程序的代码、运行时所需的库文件、配置数据和其他依赖项。OCI Image Specification规定了镜像的存储格式、元数据和文件系统布局等,确保了不同容器运行时都能正确加载和执行这些镜像。

  2. OCI Runtime Specification(OCI运行时规范):

    这个规范定义了容器运行时的行为和接口。容器运行时是负责创建和管理容器的组件,它包括容器的生命周期管理、资源隔离、进程管理等功能。OCI Runtime Specification规定了容器配置、标准环境变量、容器状态等,使得不同容器运行时都能遵循统一的行为规范。

采用OCI规范的优势在于它促进了容器技术的标准化和互操作性。不同厂商和项目可以遵循OCI规范,保证其容器和工具在任何支持OCI标准的平台上都能够无缝运行。这种开放标准化的方法有助于加强容器生态系统的稳定性和可持续性,同时也降低了供应商锁定的风险。

目前,许多容器运行时和容器工具,包括Docker、containerd、cri-o等,都支持OCI规范,使得OCI成为了业界公认的容器标准。

Dockerfile多阶段构建(解决:如何让一个镜像变得更小 )

Docker 的⼝号是 Build,Ship,and Run Any App,Anywhere,在我们使⽤ Docker 的⼤部分时候,的确能感觉到其优越性,但是往往在我们 Build ⼀个应⽤的时候,是将我们的源代码也构建进去的,这对于类似于 golang 这样的编译型语⾔肯定是不⾏的,因为实际运⾏的时候我只需要把最终构建的⼆进制包给你就⾏,把源码也⼀起打包在镜像中,需要承担很多⻛险,即使是脚本语⾔,在构建的时候也可能需要使⽤到⼀些上线的⼯具,这样⽆疑也增⼤了我们的镜像体积。

⽐如我们现在有⼀个最简单的 golang 服务,需要构建⼀个最⼩的 Docker 镜像,源码如下:

go 复制代码
package main
import (
	"github.com/gin-gonic/gin"
	"net/http"
)
func main() {
	router := gin.Default()
	router.GET("/ping", func(c *gin.Context) {
		c.String(http.StatusOK, "PONG")
	})
	router.Run(":8080")
}

我们最终的⽬的都是将最终的可执⾏⽂件放到⼀个最⼩的镜像(⽐如 alpine )中去执⾏,怎样得到最终的编译好的⽂件呢?基于 Docker 的指导思想,我们需要在⼀个标准的容器中编译,⽐如在⼀个Ubuntu 镜像中先安装编译的环境,然后编译,最后也在该容器中执⾏即可。但是如果我们想把编译后的⽂件放置到 alpine 镜像中执⾏呢?我们就得通过上⾯的 Ubuntu 镜像将编译完成的⽂件通过 volume 挂载到我们的主机上,然后我们再将这个⽂件挂载到 alpine 镜像中去。

这种解决⽅案理论上肯定是可⾏的,但是这样的话在构建镜像的时候我们就得定义两步了,第⼀步是先⽤⼀个通⽤的镜像编译镜像,第⼆步是将编译后的⽂件复制到 alpine 镜像中执⾏,⽽且通⽤镜像编译后的⽂件在 alpine 镜像中不⼀定能执⾏。

定义编译阶段的 Dockerfile :(保存为Dockerfile.build)

bash 复制代码
FROM golang
WORKDIR /go/src/app
ADD . /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server

定义 alpine 镜像:(保存为Dockerfile.old)

bash 复制代码
FROM alpine:latest
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /root/
COPY app-server .
CMD ["./app-server"]

根据我们的执⾏步骤,我们还可以简单定义成⼀个脚本:(保存为build.sh)

bash 复制代码
#!/bin/sh
echo Building cnych/docker-multi-stage-demo:build
docker build -t cnych/docker-multi-stage-demo:build . -f Dockerfile.build
docker create --name extract cnych/docker-multi-stage-demo:build
docker cp extract:/go/src/app/app-server ./app-server
docker rm -f extract
echo Building cnych/docker-multi-stage-demo:old
docker build --no-cache -t cnych/docker-multi-stage-demo:old . -f Dockerfile.old
rm ./app-server
复制代码
`docker create`命令用于创建一个新的容器,但不会自动启动它。这个命令会返回一个容器的ID,可以将其用于后续操作,比如启动容器、进入容器等。

命令格式:
```
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
```

参数说明:
- `OPTIONS`: 可选参数,用于配置容器的各种选项,比如端口映射、数据卷挂载、环境变量等。
- `IMAGE`: 必需参数,指定要使用的镜像名称或ID来创建容器。
- `COMMAND`: 可选参数,可以指定容器启动后要执行的命令。
- `ARG...`: 可选参数,命令的参数,用于传递给容器中运行的命令。

使用示例:
```
docker create -p 8080:80 --name my_container nginx
```
上面的命令创建了一个名为`my_container`的容器,基于`nginx`镜像,将容器的80端口映射到主机的8080端口。

注意:`docker create`只是创建容器,容器并未运行。要启动容器,需要使用`docker start`命令。同时,如果想在容器内部执行命令,可以使用`docker exec`命令。

当我们执⾏完上⾯的构建脚本后,就实现了我们的⽬标。

多阶段构建

Docker 17.05版本以后,官⽅就提供了⼀个新的特性: Multi-stage builds (多阶段构建)。 使⽤多阶段构建,你可以在⼀个 Dockerfile中使⽤多个 FROM 语句。每个 FROM 指令都可以使⽤不同的基础镜像,并表示开始⼀个新的构建阶段。你可以很⽅便的将⼀个阶段的⽂件复制到另外⼀个阶段,在最终的镜像中保留下你需要的内容即

可。

bash 复制代码
FROM golang AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server

FROM alpine
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY --from=build-env /go/src/app/app-server /usr/local/bin/app-server
EXPOSE 8080
CMD [ "app-server" ]

现在我们只需要⼀个 Dockerfile ⽂件即可,也不需要拆分构建脚本了,只需要执⾏ build 命令即可:

bash 复制代码
docker build -t cnych/docker-multi-stage-demo:latest .

默认情况下,构建阶段是没有命令的,我们可以通过它们的索引来引⽤它们,第⼀个 FROM 指令从 0 开始,我们也可以⽤ AS 指令为阶段命令,⽐如我们这⾥的将第⼀阶段命名为 build-env ,然后在其他阶段需要引⽤的时候使⽤ --from=build-env 参数即可。

Images瘦身实践

  1. 选择最小的基础镜像

  2. 合并RUN环节的所有指令,少生成一些层

  3. RUN期间可能安装其他程序会生成临时缓存,要自行删除。如:

    bash 复制代码
    RUN apt-get update && apt-get install -y \
    bzr \
    cvs \
    git \
    mercurial \
    subversion \
    && rm -rf /var/lib/apt/lists/*
  4. 使用 .dockerignore 文件,排除上下文中无需参与构建的资源

  5. 使用多阶段构建

  6. 合理使用构建缓存加 速构建。(官方的例子:docker build --no-cache -f Dockerfile --target stage2 .

.dockerignore

.dockerignore是一个用于告诉Docker在构建镜像时忽略哪些文件和目录的配置文件。它类似于.gitignore文件,用于指定哪些文件不应包含在构建的Docker镜像中。

当使用docker build命令构建镜像时,Docker会将当前目录及其子目录中的所有文件发送给Docker引擎,以用于构建镜像。然而,并不是所有文件都应该包含在镜像中,比如一些临时文件、日志、不必要的依赖项等。通过使用.dockerignore文件,可以指定哪些文件和目录应该被忽略,不包含在构建的镜像中。

.dockerignore文件的格式和.gitignore类似,可以使用通配符和目录匹配规则。当Docker构建镜像时,会根据.dockerignore中的规则来过滤文件,并仅将未被忽略的文件包含在镜像中。

常见的.dockerignore示例:

复制代码
# 忽略所有的日志文件
*.log

# 忽略node_modules目录
node_modules/

# 忽略临时文件
temp*

# 忽略配置文件
config.json
secrets.ini

使用.dockerignore可以帮助减小Docker镜像的大小,避免将不必要的文件包含在镜像中,从而提高镜像构建的效率和镜像的推送下载速度。

Docker Compose

Docker Compose 是 Docker 官⽅编排(Orchestration)项⽬之⼀,负责快速的部署分布式应⽤。其代码⽬前在https://github.com/docker/compose上开源。Compose 定位是 「定义和运⾏多个 Docker 容器的应⽤(Defining and running multi-container Docker applications)」,其前身是开源项⽬ Fig 。

在⽇常⼯作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现⼀个 Web 项⽬,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器或者缓存服务容器,甚⾄还包括负载均衡容器等。Compose 恰好满⾜了这样的需求。它允许⽤户通过⼀个单独的 dockercompose.yml 模板⽂件(YAML 格式)来定义⼀组相关联的应⽤容器为⼀个项⽬(project)。

Compose 中有两个重要的概念:

  1. 服务 (service):⼀个应⽤的容器,实际上可以包括若⼲运⾏相同镜像的容器实例。
  2. 项⽬ (project):由⼀组关联的应⽤容器组成的⼀个完整业务单元,在 docker-compose.yml ⽂件中定义。

Compose 的默认管理对象是项⽬,通过⼦命令对项⽬中的⼀组容器进⾏便捷地⽣命周期管理。

Compose 项⽬由 Python 编写,实现上调⽤了 Docker 服务提供的 API 来对容器进⾏管理。所以只要所操作的平台⽀持 Docker API,就可以在其上利⽤ Compose 来进⾏编排管理。

目前 Docker 官方用 GO 语言 重写 了 Docker Compose,并将其作为了 docker cli 的子命令,称为 Compose V2。你可以参照官方文档安装,然后将熟悉的 docker-compose 命令替换为 docker compose,即可使用 Docker Compose。

快速开始Quick Start

Using Docker Compose is a three-step process:

  1. Define your app's environment with a Dockerfile so it can be reproduced anywhere.
  2. Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
  3. Lastly, run docker compose up and Compose will start and run your entire app.

A Compose file looks like this:

bash 复制代码
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
  redis:
    image: redis

Compose 命令

常用命令

bash 复制代码
Compose 常用命令 
docker-compose -h                           #  查看帮助 
docker-compose up                           #  启动所有 docker-compose服务 
docker-compose up -d                        #  启动所有 docker-compose服务 并后台运行 
docker-compose down                         #  停止并删除容器、网络、卷、镜像。 
docker-compose exec  yml里面的服务id                 # 进入容器实例内部  docker-compose exec  docker-compose.yml文件中写的服务id  /bin/bash 
docker-compose ps                      # 展示当前docker-compose编排过的运行的所有容器 
docker-compose top                     # 展示当前docker-compose编排过的容器进程 
 
docker-compose logs  yml里面的服务id     #  查看容器输出日志 
docker-compose config     #  检查配置 
docker-compose config -q  #  检查配置,有问题才有输出 
docker-compose restart   #  重启服务 
docker-compose start     #  启动服务 
docker-compose stop      #  停止服务 

命令说明

Compose 模板文件

模板文件是使用 Compose 的核心,涉及到的指令关键字也比较多。但这里面大部分指令跟 docker run 相关参数的含义都是类似的。

默认的模板文件名称为 docker-compose.yml,格式为 YAML 格式。

bash 复制代码
version: "3"

services:
  webapp:
    image: examples/web
    ports:
      - "80:80"
    volumes:
      - "/data"

注意每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)等来自动构建生成镜像。

如果使用 build 指令,在 Dockerfile 中设置的选项(例如:CMD, EXPOSE, VOLUME, ENV 等) 将会自动被获取,无需在 docker-compose.yml 中重复设置。

下面分别介绍各个指令的用法。

build

指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。

bash 复制代码
version: '3'
services:

  webapp:
    build: ./dir

你也可以使用 context 指令指定 Dockerfile 所在文件夹的路径。

使用 dockerfile 指令指定 Dockerfile 文件名。

使用 arg 指令指定构建镜像时的变量。

bash 复制代码
version: '3'
services:

  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1

使用 cache_from 指定构建镜像的缓存

bash 复制代码
build:
  context: .
  cache_from:
    - alpine:latest
    - corp/web_app:3.14

cap_add, cap_drop

指定容器的内核能力(capacity)分配。

例如,让容器拥有所有能力可以指定为:

bash 复制代码
cap_add:
  - ALL

去掉 NET_ADMIN 能力可以指定为:

bash 复制代码
cap_drop:
  - NET_ADMIN

command

覆盖容器启动后默认执行的命令,没什么卵用。

bash 复制代码
command: echo "hello world"

cgroup_parent

指定父 cgroup 组,意味着将继承该组的资源限制。

例如,创建了一个 cgroup 组名称为 cgroups_1。

bash 复制代码
cgroup_parent: cgroups_1

container_name

指定容器名称。默认将会使用 项目名称_服务名称_序号 这样的格式。

bash 复制代码
container_name: docker-web-container

注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。

devices

指定设备映射关系。

bash 复制代码
devices:
  - "/dev/ttyUSB1:/dev/ttyUSB0"

注意:不推荐使用该指令。

depends_on

解决容器的依赖、启动先后的问题。以下例子中会先启动 redis db 再启动 web

bash 复制代码
version: '3'

services:
  web:
    build: .
    depends_on:
      - db
      - redis

  redis:
    image: redis

  db:
    image: postgres

dns

自定义 DNS 服务器。可以是一个值,也可以是一个列表。

bash 复制代码
dns: 8.8.8.8

dns:
  - 8.8.8.8
  - 114.114.114.114

配置 DNS 搜索域。可以是一个值,也可以是一个列表。

bash 复制代码
dns_search: example.com

dns_search:
  - domain1.example.com
  - domain2.example.com

tmpfs

bash 复制代码
挂载一个 tmpfs 文件系统到容器。
tmpfs: /run
tmpfs:
  - /run
  - /tmp

env_file

从文件中获取环境变量,可以为单独的文件路径或列表。

如果通过 docker-compose -f FILE 方式来指定 Compose 模板文件,则 env_file 中变量的路径会基于模板文件路径。

如果有变量名称与 environment 指令冲突,则按照惯例,以后者为准。

bash 复制代码
env_file: .env

env_file:
  - ./common.env
  - ./apps/web.env
  - /opt/secrets.env

环境变量文件中每一行必须符合格式,支持 # 开头的注释行。

bash 复制代码
# common.env: Set development environment
PROG_ENV=development

environment

设置环境变量。你可以使用数组或字典两种格式。

只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。

bash 复制代码
environment:
  RACK_ENV: development
  SESSION_SECRET:

environment:
  - RACK_ENV=development
  - SESSION_SECRET

如果变量名称或者值中用到 true|false,yes|no 等表达 布尔 含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些特定词汇,包括

bash 复制代码
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF

expose

暴露端口,但不映射到宿主机,只被连接的服务访问。

仅可以指定内部端口为参数

bash 复制代码
expose:
 - "3000"
 - "8000"

注意:不建议使用该指令。

链接到 docker-compose.yml 外部的容器,甚至并非 Compose 管理的外部容器。

bash 复制代码
external_links:
 - redis_1
 - project_db_1:mysql
 - project_db_1:postgresql

extra_hosts

类似 Docker 中的 --add-host 参数,指定额外的 host 名称映射信息。

bash 复制代码
extra_hosts:
 - "googledns:8.8.8.8"
 - "dockerhub:52.1.157.61"

会在启动后的服务容器中 /etc/hosts 文件中添加如下两条条目。

bash 复制代码
8.8.8.8 googledns
52.1.157.61 dockerhub

healthcheck

通过命令检查容器是否健康运行。

bash 复制代码
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m30s
  timeout: 10s
  retries: 3

image

指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。

bash 复制代码
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd

labels

为容器添加 Docker 元数据(metadata)信息。例如可以为容器添加辅助说明信息。

bash 复制代码
labels:
  com.startupteam.description: "webapp for a startup team"
  com.startupteam.department: "devops department"
  com.startupteam.release: "rc3 for v1.0"

logging

配置日志选项。

bash 复制代码
logging:
  driver: syslog
  options:
    syslog-address: "tcp://192.168.0.42:123"

目前支持三种日志驱动类型。

bash 复制代码
driver: "json-file"
driver: "syslog"
driver: "none"

options 配置日志驱动的相关参数。

bash 复制代码
options:
  max-size: "200k"
  max-file: "10"

network_mode

设置网络模式。使用和 docker run 的 --network 参数一样的值。

bash 复制代码
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

networks

配置容器连接的网络。

bash 复制代码
version: "3"
services:

  some-service:
    networks:
     - some-network
     - other-network

networks:
  some-network:
  other-network:

pid

跟主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程 ID 来相互访问和操作。

bash 复制代码
pid: "host"

ports

暴露端口信息。

使用宿主端口:容器端口 (HOST:CONTAINER) 格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。

bash 复制代码
ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"

注意:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。

secrets

存储敏感数据,例如 mysql 服务密码。

bash 复制代码
version: "3.1"
services:

mysql:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
  secrets:
    - db_root_password
    - my_other_secret

secrets:
  my_secret:
    file: ./my_secret.txt
  my_other_secret:
    external: true

security_opt

指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)。例如配置标签的用户名和角色名。

bash 复制代码
security_opt:
    - label:user:USER
    - label:role:ROLE

stop_signal

设置另一个信号来停止容器。在默认情况下使用的是 SIGTERM 停止容器。

bash 复制代码
stop_signal: SIGUSR1

sysctls

配置容器内核参数。

bash 复制代码
sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0

ulimits

指定容器的 ulimits 限制值。

例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)。

bash 复制代码
  ulimits:
    nproc: 65535
    nofile:
      soft: 20000
      hard: 40000

volumes

数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER)或者数据卷名称(VOLUME:CONTAINER),并且可以设置访问模式 (HOST:CONTAINER:ro)。

该指令中路径支持相对路径。

bash 复制代码
volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro

如果路径为数据卷名称,必须在文件中配置数据卷。

bash 复制代码
version: "3"

services:
  my_src:
    image: mysql:8.0
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:  

其它指令

此外,还有包括 domainname, entrypoint, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir 等指令,基本跟 docker run 中对应参数的功能一致。

指定服务容器启动后执行的入口文件。

bash 复制代码
entrypoint: /code/entrypoint.sh

指定容器中运行应用的用户名。

bash 复制代码
user: nginx

指定容器中工作目录。

bash 复制代码
working_dir: /code

指定容器中搜索域名、主机名、mac 地址等。

bash 复制代码
domainname: your_website.com
hostname: test
mac_address: 08-00-27-00-0C-0A

允许容器中运行一些特权命令。

bash 复制代码
privileged: true

指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效,在生产环境中推荐配置为 always 或者 unless-stopped。

bash 复制代码
restart: always

以只读模式挂载容器的 root 文件系统,意味着不能对容器内容进行修改。

bash 复制代码
read_only: true

打开标准输入,可以接受外部输入。

bash 复制代码
stdin_open: true

模拟一个伪终端。

bash 复制代码
tty: true

案例(Docker容器监控之CAdvisor+InfluxDB+Granfana)

原生命令

bash 复制代码
docker stats命令的结果 

通过docker stats命令可以很方便的看到当前宿主机上所有容器的CPU,内存以及网络流量等数据, 一般小公司够用了。。。。 
但是
docker stats统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储、没有健康指标过线预警等功能 

docker compose 编排

bash 复制代码
version: '3.1' 

volumes: 
  grafana_data: {} 

services: 
 influxdb: 
  image: tutum/influxdb:0.9 
  restart: always 
  environment: 
    - PRE_CREATE_DB=cadvisor 
  ports: 
    - "8083:8083" 
    - "8086:8086" 
  volumes: 
    - ./data/influxdb:/data 

 cadvisor: 
  image: google/cadvisor 
  links: 
    - influxdb:influxsrv 
  command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086 
  restart: always 
  ports: 
    - "8080:8080" 
  volumes: 
    - /:/rootfs:ro 
    - /var/run:/var/run:rw 
    - /sys:/sys:ro 
    - /var/lib/docker/:/var/lib/docker:ro 

 grafana: 
  user: "104" 
  image: grafana/grafana 
  user: "104" 
  restart: always 
  links: 
    - influxdb:influxsrv 
  ports: 
    - "3000:3000" 
  volumes: 
    - grafana_data:/var/lib/grafana 
  environment: 
    - HTTP_USER=admin 
    - HTTP_PASS=admin 
    - INFLUXDB_HOST=influxsrv 
    - INFLUXDB_PORT=8086 
    - INFLUXDB_NAME=cadvisor 
    - INFLUXDB_USER=root 
    - INFLUXDB_PASS=root 

启动docker-compose文件:

shell 复制代码
docker compose up

查看三个服务容器是否启动

shell 复制代码
docker compose ps
相关推荐
Java陈序员1 天前
轻量强大!一款现代化的 Kubernetes 集群管理与监控工具!
云原生·容器·kubernetes
爱吃橘子橙子柚子2 天前
3CPU性能排查总结(超详细)【Linux性能优化】
运维·cpu
Sheffield3 天前
Docker的跨主机服务与其对应的优缺点
linux·网络协议·docker
Sheffield3 天前
Alpine是什么,为什么是Docker首选?
linux·docker·容器
马艳泽3 天前
win10下运行Start Broker and Proxy报错解决
docker
舒一笑4 天前
程序员效率神器:一文掌握 tmux(服务器开发必备工具)
运维·后端·程序员
NineData4 天前
数据库管理工具NineData,一年进化成为数万+开发者的首选数据库工具?
运维·数据结构·数据库
用户13573999256604 天前
Windows 从 0 搭建 WSL2 原生 AI 开发环境:Codex + Docker + VSCode
docker
vi_h4 天前
在 macOS 上通过 Docker 安装并运行 Ollama(详细可执行教程)
macos·docker·ollama
黑心老魔4 天前
通过 Docker 创建开发环境
docker·开发环境