Docker续集+Docker Compose
目录
- Containerd
- 与docker的关系
- runC
- runC与Containerd的关联
- OCI协议
- Dockerfile多阶段构建(解决:如何让一个镜像变得更小 )
- 多阶段构建
- Images瘦身实践
- .dockerignore
- Docker Compose
- 快速开始Quick Start
- Compose 命令
- 常用命令
- 命令说明
- Compose 模板文件
- build
- cap_add, cap_drop
- command
- cgroup_parent
- container_name
- devices
- links
- depends_on
- dns
- dns_search
- tmpfs
- env_file
- environment
- expose
- external_links
- extra_hosts
- healthcheck
- image
- labels
- logging
- network_mode
- networks
- pid
- ports
- secrets
- security_opt
- stop_signal
- sysctls
- ulimits
- volumes
- 其它指令
- 案例(Docker容器监控之CAdvisor+InfluxDB+Granfana)
- 原生命令
- docker compose 编排
Containerd
- 早在2016年3月,Docker 1.11的Docker Engine里就包含了containerd,而现在则是把containerd从Docker Engine里彻底剥离出来,作为一个独立的开源项目独立发展,目标是提供一个更加开放、稳定的容器运行基础设施。和原先包含在DockerEngine里containerd相比,独立的containerd将具有更多的功能,可以涵盖整个容
器运行时管理的所有需求。 - containerd并不是直接面向最终用户的,而是主要用于集成到更上层的系统里,比如Swarm, Kubernetes, Mesos等容器编排系统。
- containerd以Daemon的形式运行在系统上,通过暴露底层的gRPC API,上层系统可以通过这些API管理机器上的容器。
- 每个containerd只负责一台机器,Pull镜像,对容器的操作(启动、停止等),网络,存储都是由containerd完成。具体运行容器由runC负责,实际上只要是符合OCI规范的容器都可以支持。
- 对于容器编排服务来说,运行时只需要使用
containerd+runC
,更加轻量,容易管理。 - 独立之后containerd的特性演进可以和Docker Engine分开,专注容器运行时管理,可以更稳定。
与docker的关系
Containerd和Docker是容器生态系统中相关但不同的组件。
-
Docker:
Docker是一种流行的平台,彻底改变了软件开发、发布和运行的方式。它提供了用户友好的界面和工具,用于创建、管理和部署容器。Docker允许开发人员将应用程序及其依赖项打包成容器,确保在不同环境中具有一致性。它提供了命令行界面(CLI)和图形用户界面(GUI),用于管理容器和镜像。 -
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的关联
-
功能范围:
- runC:runC是一个独立的、轻量级的容器运行时工具,负责根据OCI(Open Container Initiative)标准来创建和运行容器。它专注于处理容器的生命周期,即容器的创建、启动、停止和销毁。
- containerd:containerd是一个更大的容器守护进程,它充当着runC和高级容器管理工具(如Docker)之间的桥梁。containerd使用runC来实际执行容器,但同时提供了更多功能,比如镜像管理、容器存储、网络管理等。它是一个全功能的容器管理工具,而不仅仅是一个运行时。
-
复杂性:
- runC:由于其专注于容器的运行时生命周期,runC相对较为简单,仅实现了OCI标准定义的最基本容器功能。
- containerd:containerd相对复杂,因为它是一个完整的容器管理工具,包括支持多个容器运行时(包括runC、Kata Containers等),镜像管理、容器网络、存储管理等功能。
-
使用场景:
- runC:通常在需要更轻量级、更简单容器运行时的场景中使用,或者作为其他容器管理工具的基础组件。
- containerd:更适用于需要全功能容器管理的场景,特别是在生产环境中使用,可以与其他工具(如Kubernetes、Docker)结合使用。
虽然runC和containerd有不同的功能范围和复杂性,但它们通常会在一起使用。containerd使用runC来执行容器,这使得它可以利用runC的简单性和符合OCI标准的优势,并在此基础上提供更多的高级容器管理功能。
OCI协议
OCI(Open Container Initiative)是一个由Linux基金会支持的开放性项目,旨在为容器生态系统建立开放的行业标准。OCI的目标是定义容器格式和运行时的规范,以促进容器技术的互操作性和可移植性。
OCI项目涵盖了两个关键规范:
-
OCI Image Specification(OCI镜像规范):
这个规范定义了容器镜像的结构和内容。容器镜像是一个轻量级的、可移植的软件包,它包含了应用程序的代码、运行时所需的库文件、配置数据和其他依赖项。OCI Image Specification规定了镜像的存储格式、元数据和文件系统布局等,确保了不同容器运行时都能正确加载和执行这些镜像。 -
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 镜像,源码如下:
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)
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)
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)
#!/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 指令都可以使⽤不同的基础镜像,并表示开始⼀个新的构建阶段。你可以很⽅便的将⼀个阶段的⽂件复制到另外⼀个阶段,在最终的镜像中保留下你需要的内容即
可。
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-serverFROM 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 命令即可:
docker build -t cnych/docker-multi-stage-demo:latest .
默认情况下,构建阶段是没有命令的,我们可以通过它们的索引来引⽤它们,第⼀个 FROM 指令从 0 开始,我们也可以⽤ AS 指令为阶段命令,⽐如我们这⾥的将第⼀阶段命名为 build-env ,然后在其他阶段需要引⽤的时候使⽤ --from=build-env 参数即可。
Images瘦身实践
-
选择最小的基础镜像
-
合并RUN环节的所有指令,少生成一些层
-
RUN期间可能安装其他程序会生成临时缓存,要自行删除。如:
RUN apt-get update && apt-get install -y \ bzr \ cvs \ git \ mercurial \ subversion \ && rm -rf /var/lib/apt/lists/*
-
使用 .dockerignore 文件,排除上下文中无需参与构建的资源
-
使用多阶段构建
-
合理使用构建缓存加 速构建。(官方的例子:
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 中有两个重要的概念:
- 服务 (service):⼀个应⽤的容器,实际上可以包括若⼲运⾏相同镜像的容器实例。
- 项⽬ (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:
- Define your app’s environment with a Dockerfile so it can be reproduced anywhere.
- Define the services that make up your app in docker-compose.yml so they can be run together in an isolated environment.
- Lastly, run docker compose up and Compose will start and run your entire app.
A Compose file looks like this:
services:web:build: .ports:- "5000:5000"volumes:- .:/coderedis:image: redis
Compose 命令
常用命令
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 格式。
version: "3"services:webapp:image: examples/webports:- "80:80"volumes:- "/data"
注意每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)等来自动构建生成镜像。
如果使用 build 指令,在 Dockerfile 中设置的选项(例如:CMD, EXPOSE, VOLUME, ENV 等) 将会自动被获取,无需在 docker-compose.yml 中重复设置。
下面分别介绍各个指令的用法。
build
指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。
version: '3'
services:webapp:build: ./dir
你也可以使用 context 指令指定 Dockerfile 所在文件夹的路径。
使用 dockerfile 指令指定 Dockerfile 文件名。
使用 arg 指令指定构建镜像时的变量。
version: '3'
services:webapp:build:context: ./dirdockerfile: Dockerfile-alternateargs:buildno: 1
使用 cache_from 指定构建镜像的缓存
build:context: .cache_from:- alpine:latest- corp/web_app:3.14
cap_add, cap_drop
指定容器的内核能力(capacity)分配。
例如,让容器拥有所有能力可以指定为:
cap_add:- ALL
去掉 NET_ADMIN 能力可以指定为:
cap_drop:- NET_ADMIN
command
覆盖容器启动后默认执行的命令,没什么卵用。
command: echo "hello world"
cgroup_parent
指定父 cgroup 组,意味着将继承该组的资源限制。
例如,创建了一个 cgroup 组名称为 cgroups_1。
cgroup_parent: cgroups_1
container_name
指定容器名称。默认将会使用 项目名称_服务名称_序号
这样的格式。
container_name: docker-web-container
注意: 指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称。
devices
指定设备映射关系。
devices:- "/dev/ttyUSB1:/dev/ttyUSB0"
links
注意:不推荐使用该指令。
depends_on
解决容器的依赖、启动先后的问题。以下例子中会先启动 redis db 再启动 web
version: '3'services:web:build: .depends_on:- db- redisredis:image: redisdb:image: postgres
dns
自定义 DNS 服务器。可以是一个值,也可以是一个列表。
dns: 8.8.8.8dns:- 8.8.8.8- 114.114.114.114
dns_search
配置 DNS 搜索域。可以是一个值,也可以是一个列表。
dns_search: example.comdns_search:- domain1.example.com- domain2.example.com
tmpfs
挂载一个 tmpfs 文件系统到容器。
tmpfs: /run
tmpfs:- /run- /tmp
env_file
从文件中获取环境变量,可以为单独的文件路径或列表。
如果通过 docker-compose -f FILE 方式来指定 Compose 模板文件,则 env_file 中变量的路径会基于模板文件路径。
如果有变量名称与 environment 指令冲突,则按照惯例,以后者为准。
env_file: .envenv_file:- ./common.env- ./apps/web.env- /opt/secrets.env
环境变量文件中每一行必须符合格式,支持 # 开头的注释行。
# common.env: Set development environment
PROG_ENV=development
environment
设置环境变量。你可以使用数组或字典两种格式。
只给定名称的变量会自动获取运行 Compose 主机上对应变量的值,可以用来防止泄露不必要的数据。
environment:RACK_ENV: developmentSESSION_SECRET:environment:- RACK_ENV=development- SESSION_SECRET
如果变量名称或者值中用到 true|false,yes|no 等表达 布尔 含义的词汇,最好放到引号里,避免 YAML 自动解析某些内容为对应的布尔语义。这些特定词汇,包括
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数
expose:- "3000"- "8000"
external_links
注意:不建议使用该指令。
链接到 docker-compose.yml 外部的容器,甚至并非 Compose 管理的外部容器。
external_links:- redis_1- project_db_1:mysql- project_db_1:postgresql
extra_hosts
类似 Docker 中的 --add-host 参数,指定额外的 host 名称映射信息。
extra_hosts:- "googledns:8.8.8.8"- "dockerhub:52.1.157.61"
会在启动后的服务容器中 /etc/hosts 文件中添加如下两条条目。
8.8.8.8 googledns
52.1.157.61 dockerhub
healthcheck
通过命令检查容器是否健康运行。
healthcheck:test: ["CMD", "curl", "-f", "http://localhost"]interval: 1m30stimeout: 10sretries: 3
image
指定为镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd
labels
为容器添加 Docker 元数据(metadata)信息。例如可以为容器添加辅助说明信息。
labels:com.startupteam.description: "webapp for a startup team"com.startupteam.department: "devops department"com.startupteam.release: "rc3 for v1.0"
logging
配置日志选项。
logging:driver: syslogoptions:syslog-address: "tcp://192.168.0.42:123"
目前支持三种日志驱动类型。
driver: "json-file"
driver: "syslog"
driver: "none"
options 配置日志驱动的相关参数。
options:max-size: "200k"max-file: "10"
network_mode
设置网络模式。使用和 docker run 的 --network 参数一样的值。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
networks
配置容器连接的网络。
version: "3"
services:some-service:networks:- some-network- other-networknetworks:some-network:other-network:
pid
跟主机系统共享进程命名空间。打开该选项的容器之间,以及容器和宿主机系统之间可以通过进程 ID 来相互访问和操作。
pid: "host"
ports
暴露端口信息。
使用宿主端口:容器端口 (HOST:CONTAINER) 格式,或者仅仅指定容器的端口(宿主将会随机选择端口)都可以。
ports:- "3000"- "8000:8000"- "49100:22"- "127.0.0.1:8001:8001"
注意:当使用 HOST:CONTAINER 格式来映射端口时,如果你使用的容器端口小于 60 并且没放到引号里,可能会得到错误结果,因为 YAML 会自动解析 xx:yy 这种数字格式为 60 进制。为避免出现这种问题,建议数字串都采用引号包括起来的字符串格式。
secrets
存储敏感数据,例如 mysql 服务密码。
version: "3.1"
services:mysql:image: mysqlenvironment:MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_passwordsecrets:- db_root_password- my_other_secretsecrets:my_secret:file: ./my_secret.txtmy_other_secret:external: true
security_opt
指定容器模板标签(label)机制的默认属性(用户、角色、类型、级别等)。例如配置标签的用户名和角色名。
security_opt:- label:user:USER- label:role:ROLE
stop_signal
设置另一个信号来停止容器。在默认情况下使用的是 SIGTERM 停止容器。
stop_signal: SIGUSR1
sysctls
配置容器内核参数。
sysctls:net.core.somaxconn: 1024net.ipv4.tcp_syncookies: 0sysctls:- net.core.somaxconn=1024- net.ipv4.tcp_syncookies=0
ulimits
指定容器的 ulimits 限制值。
例如,指定最大进程数为 65535,指定文件句柄数为 20000(软限制,应用可以随时修改,不能超过硬限制) 和 40000(系统硬限制,只能 root 用户提高)。
ulimits:nproc: 65535nofile:soft: 20000hard: 40000
volumes
数据卷所挂载路径设置。可以设置为宿主机路径(HOST:CONTAINER)或者数据卷名称(VOLUME:CONTAINER),并且可以设置访问模式 (HOST:CONTAINER:ro)。
该指令中路径支持相对路径。
volumes:- /var/lib/mysql- cache/:/tmp/cache- ~/configs:/etc/configs/:ro
如果路径为数据卷名称,必须在文件中配置数据卷。
version: "3"services:my_src:image: mysql:8.0volumes:- mysql_data:/var/lib/mysqlvolumes:mysql_data:
其它指令
此外,还有包括 domainname, entrypoint, hostname, ipc, mac_address, privileged, read_only, shm_size, restart, stdin_open, tty, user, working_dir 等指令,基本跟 docker run 中对应参数的功能一致。
指定服务容器启动后执行的入口文件。
entrypoint: /code/entrypoint.sh
指定容器中运行应用的用户名。
user: nginx
指定容器中工作目录。
working_dir: /code
指定容器中搜索域名、主机名、mac 地址等。
domainname: your_website.com
hostname: test
mac_address: 08-00-27-00-0C-0A
允许容器中运行一些特权命令。
privileged: true
指定容器退出后的重启策略为始终重启。该命令对保持服务始终运行十分有效,在生产环境中推荐配置为 always 或者 unless-stopped。
restart: always
以只读模式挂载容器的 root 文件系统,意味着不能对容器内容进行修改。
read_only: true
打开标准输入,可以接受外部输入。
stdin_open: true
模拟一个伪终端。
tty: true
案例(Docker容器监控之CAdvisor+InfluxDB+Granfana)
原生命令
docker stats命令的结果 通过docker stats命令可以很方便的看到当前宿主机上所有容器的CPU,内存以及网络流量等数据, 一般小公司够用了。。。。
但是
docker stats统计结果只能是当前宿主机的全部容器,数据资料是实时的,没有地方存储、没有健康指标过线预警等功能
docker compose 编排
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文件:
docker compose up
查看三个服务容器是否启动
docker compose ps
相关文章:

Docker续集+Docker Compose
目录 Containerd与docker的关系 runCrunC与Containerd的关联 OCI协议Dockerfile多阶段构建(解决:如何让一个镜像变得更小 )多阶段构建Images瘦身实践.dockerignore Docker Compose快速开始Quick StartCompose 命令常用命令命令说明 Compose 模…...

k8s deployment(k8s经典版)|PetaExpress
Deployment是什么? Deployment是指在软件开发中将应用程序或系统部署到目标环境中的过程。它包括将代码编译、配置、打包并安装到目标服务器或设备上的步骤。k8s deployment是(k8s经典版)中用来管理发布的控制器,在开发的过程中使…...

uni-app如何生成正式的APK
第一步: 进入dcloud官网https://dcloud.io/,点击开发者后台进入登录注册页面 第二步:登录之后跳到项目列表,选择自己想要打包的项目 点击进去如果没有生成证书,点击生成证书,如果显示证书已生成就不用管了…...

低代码开发平台源码:可视化敏捷开发工具,拖拽式自定义表单界面
低代码开发平台源码 低代码管理系统源码 无需代码或通过少量代码就可以快速生成应用程序的开发平台。 本套低代码管理后台可以支持多种企业应用场景,包括但不限于CRM、ERP、OA、BI、IoT、大数据等。无论是传统企业还是新兴企业,都可以使用管理后台快速构…...

利用读时建模等数据分析能力,实现网络安全态势感知的落地
摘要:本文提出一种基于鸿鹄数据平台的网络安全态势感知系统,系统借助鸿鹄数据平台读时建模、时序处理、数据搜索等高效灵活的超大数据存储和分析处理能力,支持海量大数据存储、分类、统计到数据分析、关联、预测、判断的网络安全态势感知能力…...

六、代理模式
文章目录 一、代理模式1、代理模式的好处和缺点1.1 代理模式理解加深 一、代理模式 为什么要学习代理模式? 代理模式是Spring AOP 以及 Spring MVC 的底层!!并且还是 JAVA 的23种设计模式之一!! 代理模式的分类&#…...

Easy Glide
题意:给出起点终点坐标,然后给出可以经过的几个点,未经过这几个点的时候以v1的速度前进,一旦经过这些点就可以在3秒内以v2的速度前进,3秒之后恢复v1,问从起点到终点所需的最短时间 思路:最短路…...

ppt怎么压缩到10m以内?分享好用的压缩方法
PPT是一种常见的演示文稿格式,有时候文件过大,我们会遇到无法发送、上传的现象,这时候简单的解决方法就是压缩其大小,那怎么才能将PPT压缩到10M以内呢? PPT文件大小受到影响的主要因素就是以下几点: 1、图…...

VBA技术资料MF35:VBA_在Excel中过滤数据
【分享成果,随喜正能量】好马好在腿,好人好在嘴。不会烧香得罪神,不会讲话得罪人。慢慢的你就会发现,一颗好心,永远比不上一张好嘴。。 我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了&#…...

Debian12中为python3配置虚拟环境及在Pycharm中使用虚拟环境
在Debian 12中,python默认为python 3.11。 基于应用,现需设置虚拟环境。 1.安装venv模块 从python3.3开始,配置python虚拟环境,可用venv模块,更加方便了。 执行命令: #apt install python3.11-venv 2.…...

android app控制ros机器人一
android开发app,进而通过控制ros机器人,记录开发过程 查阅资料: rosjava使用较多,已经开发好的app也有开源的案例 rosjava GitHub https://github.com/ros-autom/RobotCA https://github.com/ROS-Mobile/ROS-Mobile-Android…...

二十章:基于弱监督语义分割的亲和注意力图神经网络
0.摘要 弱监督语义分割因其较低的人工标注成本而受到广泛关注。本文旨在解决基于边界框标注的语义分割问题,即使用边界框注释作为监督来训练准确的语义分割模型。为此,我们提出了亲和力注意力图神经网络(A2GNN)。按照先前的做法&a…...

webpack5 学习之路
1.视频 01-课程介绍_哔哩哔哩_bilibili 2.配套资料 依赖环境 | 尚硅谷 Web 前端之 Webpack5 教程 3.webpack 官方文档 入口起点(entry points) | webpack 中文文档 4.vue cli 官方文档 介绍 | Vue CLI 挖矿:Coding Tree...

VSCode C++ 调试方法
VSCode 调试 C 主要就是 .vscode 中的 launch.json 和 tasks.json 的配置。 launch.json 可以通过 vscode 界面 ——》左侧调试功能按钮——》创建 launch.json ——》C(GDB/LLDB)生成。 其中 launch.json 默认配置如下,主要配置项说明&…...

Java设计模式-命令模式
命令模式 1.命令模式含义 命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化。对请求排队或记录请求日志,以及支持可撤销的操作。 命令模式乍一看,有点懵懵的。即使这个定义看完,也是不明…...

Linux编译宏BUILD_BUG_ON_ZERO
本系列文章主要写我在阅读Linux内核过程中,关注的比较难以理解但又设计巧妙的代码片段(不关注OS的各个模块的设计思想,此部分我准备写在“深入理解Linux Kernel”系列文章中),一来通过内核代码复习一下C语言及汇编语言…...

从Arweave开始:4EVERLAND存储签入挑战开始
嗨,4evers, 今天,我们热烈欢迎您参加 Galxe 上的 4EVERLAND “Arweave 入门”活动。这是一项长期的重头活动,所有参与的用户都有机会获得相应的奖励。 Arweave 是一种革命性的去中心化存储协议,为寻求安全可靠的有价…...

数据结构—链表
链表 前言链表链表的概念及结构链表的分类 无头单向非循环链表的相关实现带头双向循环链表的相关实现顺序表和链表(带头双向循环链表)的区别 前言 顺序表是存在一些固有的缺陷的: 中间/头部的插入删除,时间复杂度为O(N)…...

windows 10/11 修改右键新建菜单
问题:修改右键新建菜单内容 解决方法:使用软件ShellNew Settings 1.打开软件 2.根据需要取消勾选项 3.最终效果...

6.修饰符
文章目录 6.1 在一个静态方法内调用一个非静态成员为什么是非法的?6.2 静态方法和实例方法有何不同 6.1 在一个静态方法内调用一个非静态成员为什么是非法的? 由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量࿰…...

【leetcode难题】2569. 更新数组后处理求和查询【线段树实现01翻转和区间求和模版】
题目截图 题目分析 关键就是记录每次操作2时,nums1中的1的个数这就需要实现线段树进行区间反转以及区间求和 ac code class Solution:def handleQuery(self, nums1: List[int], nums2: List[int], queries: List[List[int]]) -> List[int]:n len(nums1)m le…...

练习时长两年半的入侵检测
计算机安全的三大中心目标是:保密性 (Conf idential ity) 、完整性 (Integrity) 、可用性 (Availability) 。 身份认证与识别、访问控制机制、加密技术、防火墙技术等技术共同特征就是集中在系统的自身加固和防护上,属于静态的安全防御技术,…...

【弹力设计篇】聊聊隔离设计
为什么需要隔离设计 隔离其实就是Bulkheads,隔板。在生活中隔板的应用主要在船舱中进行设计,目的是为了避免因一处漏水导致整个船都沉下去。可以将故障减少在一定的范围内,而不是整个船体。 从架构演变来说的话,大多数系统都是从…...

MFC 透明窗体
如何制作透明窗体 ????? 使用SetLayeredWindowAttributes可以方便的制作透明窗体,此函数在w2k以上才支持,而且如果希望直接使用的话,可能需要下载最新的SDK。不过此函数在w2k的user32.dll里有实…...

C++笔记之vector的resize()和clear()用法
C笔记之vector的resize()和clear()用法 code review! 文章目录 C笔记之vector的resize()和clear()用法1.resize()2.clear() 1.resize() 运行 2.clear() 运行...

Vue2基础九、路由
零、文章目录 Vue2基础九、路由 1、单页应用 (1)单页应用是什么 单页面应用(SPA:Single Page Application): 所有功能在 一个html页面 上实现具体示例: 网易云音乐 https://music.163.com/ (2)单页面应用VS多页面…...

移动零——力扣283
题目描述 双指针 class Solution{ public:void moveZeroes(vector<int>& nums){int n nums.size(), left0, right0;while(right<n){if(nums[right]){swap(nums[right], nums[left]);left;}right;}} };...

Transformer+MIA Future Work
TransformerMIA Future Work 主要的挑战和未来发展分为三个部分,即 1、特征集成和计算成本降低、 2、数据增强和数据集收集、 3、学习方式和模态-对象分布 1、特征集成和计算成本降低 为了同时捕获局部和全局特征来提高模型性能,目前大多数工作只是…...

深度学习入门(二):神经网络整体架构
一、前向传播 作用于每一层的输入,通过逐层计算得到输出结果 二、反向传播 作用于网络输出,通过计算梯度由深到浅更新网络参数 三、整体架构 层次结构:逐层变换数据 神经元:数据量、矩阵大小(代表输入特征的数量…...

rust 配置
rustup 镜像 在 cmd 中输入以下代码,设置环境变量 setx RUSTUP_UPDATE_ROOT https://mirrors.tuna.tsinghua.edu.cn/rustup/rustup setx RUSTUP_DIST_SERVER https://mirrors.tuna.tsinghua.edu.cn/rustupcrates.io 索引镜像 在 C:\Users\用户名\.cargo\config 文…...