5.2 容器镜像制作
环境变量优先级
docker run -e > Dockerfile 里定义的 ENV > ~/.bashrc > /etc/.bashrc
容器运行时执行指令
CMD 和 ENTRYPOINT 这两个指令配置容器的运行命令。Dockerfile 里是 CMD 和 ENTRYPOINT;Docker Compose files 则是使用小写,command 和 entrypoint。
CMD/command 指令:是当 Docker 镜像被启动后 Docker 容器将会默认执行的命令。一个 Dockerfile 仅仅最后一个 CMD 起作用。
ENTRYPOINT:用于设定容器启动时第一个运行的命令及其参数。运行镜像的时候,可以通过
--entrypoint
来覆盖默认的ENTRYPOINT
命令。任何使用docker run <image>
命令传入的参数都会附加在entrypoint
指令之后,并且用此命令传入的参数会覆盖在 Dockerfile 中使用CMD
指令设定的值。比如docker run <image> bash
命令会将bash
命令附加在entrypoint
指令设定的值的后面。RUN 指令:是创建 Docker 镜像(image)的步骤,RUN 指令对 Docker 容器( container)造成的改变是会被反映到创建的 Docker 镜像上的。一个 Dockerfile 中可以有许多个 RUN 命令。另外 docker run 命令可用于启动一个容器。
CMD
和 ENTRYPOINT
都定义了容器运行时的执行命令。如下是它们的一些使用规则:
CMD
和ENTRYPOINT
在 Dockerfiles 中应该至少应该有一个被定义。- 当构建可执行容器时,应该定义
ENTRYPOINT
指令。 CMD
要么用于给ENTRYPOINT
提供默认参数,要么用于在容器中执行一个特定命令。CMD
可以通过容器启动命令docker run
的参数来替换它。
# 法 1 shell 语法:命令作为字符串执行,并且会执行变量替换。
ENTRYPOINT command param1 param2
CMD command param1 param2
# 法 2 exce 语法:命令和其参数以 JSON 数组的格式书写,更加安全
CMD [“executable”, “param1”, “param2”…]
单容器 Dockerfile
Dockerfile reference | Docker Documentation
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
镜像构建方式
- docker build 方式,使用 Dockerfile 指令来创建一个新的镜像。
- docker commit 方式,从已经创建的容器中更新镜像,并且提交这个镜像。
通常我们都是使用第一种方式来构建容器,二者的区别就像批处理和单步执行一样。
1. 更新镜像 docker commit
# 容器有修改后,重新执行 commit 命令,会覆盖上一次标签。
docker commit -m='xxx' -a=[author] [contain_id] [dst_image:tag]
2. Dockerfile
容器配置文件 Dockerfile
常用指令有:FROM RUN CMD ENV EXPOSE ADD COPY VOLUME ENTRYPOINT USER WORKDIR ONBUILD
DockerFile 分为四部分组成:基础镜像、维护者信息、镜像操作指令和容器启动时执行指令。例如:
# 第一行必须指令基于的基础镜像 From
From ubutu
# 维护者信息 MAINTAINER
MAINTAINER docker_user docker_user@mail.com
# ENV 设置环境变量,可以被之后的命令使用
ENV BASE_DIR "/opt/redis"
# 镜像的操作指令 RUN~使用&&或\执行多行命令
apt/sourcelist.list
RUN apt-get update && apt-get install -y ngnix
RUN echo "\ndaemon off;">>/etc/ngnix/nignix.conf
# EXPOSE 打开端口并映射到 docker 主机的外部端口上
EXPOSE 6379
# ADD/COPY 将文件移入镜像,ADD 会将 TAR 文件解压,
ADD redis.tgz /rdis
COPY redis.conf $BASE_DIR
# VOLUEM 挂载卷并映射到外部位置
VOLUME $BASE_DIR/data
# 容器启动时执行指令 CMD 或 ENTRYPOINT 执行镜像中 main 命令
# 下面示例:ENTRYPOINT 启动 redis-server,然后 CMD 启动了 nginx
ENTRYPOINT ['redis-server']
CMD /usr/sbin/ngnix
docker build
命令读取指定路径下(包括子目录)所有的 Dockefile,并且把目录下所有内容发送到服务端,由服务端创建镜像。另外可以通过创建.dockerignore 文件(每一行添加一个匹配模式)让 docker 忽略指定目录或者文件。
% docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile
Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
-o, --output stringArray Output destination (format: type=local,dest=path)
--platform string Set platform if server is multi-platform capable
--progress string Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--secret stringArray Secret file to expose to the build (only if BuildKit enabled): id=mysecret,src=/local/secret
--ssh stringArray SSH agent socket or keys to expose to the build (only if BuildKit enabled) (format:
default|<id>[=<socket>|<key>[,<key>]])
-t, --tag list 创建标签。Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
例如:Dockerfile 路径为 /tmp/docker_build/,生成镜像的标签为 build_repo/my_images, -f 可指定 Dockerfile 件名,默认名称就是 Dockerfile
$ docker build -t build_repo/my_images /tmp/docker_build/
# 多平台支持:目前支持 linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le,
# linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
$ docker build --platform linux/amd64 -t build_repo/my_images [dockfile_path]
多容器 docker-compose
Compose file | Docker Documentation
docker-compose 简化了容器的管理与配置,避开了运行多个容器中容易出错的手工步骤。
$ docker-compose.exe --help
Define and run multi-container applications with Docker.
Usage:
docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
docker-compose -h|--help
Options:
-f, --file FILE Specify an alternate compose file
(default: docker-compose.yml)
-p, --project-name NAME Specify an alternate project name
(default: directory name)
--verbose Show more output
--log-level LEVE* Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
--no-ansi Do not print ANSI control characters
-v, --version Print version and exit
-H, --host HOST Daemon socket to connect to
--tls Use TLS; implied by --tlsverify
--tlscacert CA_PATH Trust certs signed only by this CA
--tlscert CLIENT_CERT_PATH Path to TLS certificate file
--tlskey TLS_KEY_PATH Path to TLS key file
--tlsverify Use TLS and verify the remote
--skip-hostname-check Don't check the daemon's hostname against the
name specified in the client certificate
--project-directory PATH Specify an alternate working directory
(default: the path of the Compose file)
--compatibility If set, Compose will attempt to convert deploy
keys in v3 files to their non-Swarm equivalent
Commands:
build Build or rebuild services
bundle Generate a Docker bundle from the Compose file
config Validate and view the Compose file
create Create services
down Stop and remove containers, networks, images, and volumes
events Receive real time events from containers
exec Execute a command in a running container
help Get help on a command
images List images
kill Kill containers
logs View output from containers
pause Pause services
port Print the public port for a port binding
ps List containers
pull Pull service images
push Push service images
restart Restart services
rm Remove stopped containers
run Run a one-off command
scale Set number of containers for a service
start Start services
stop Stop services
top Display the running processes
unpause Unpause services
up Create and start containers
version Show the Docker-Compose version information
配置文件 :docker-compose.yml 或者 xxx.yml
yml 文件规范 (以下是四大顶级关键词)
version: 代表了 Compose 文件格式的版本号。为了应用于 Stack,需要 3.0 或者更高的版本。
services: 定义了组成当前应用的服务都有哪些。
networks: 列出了必需的网络。
secrets: 定义了应用用到的密钥。
示例:容器服务 web,依赖于 redis
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports: #映射端口:宿主:容器
- "5000:5000"
volumes: #挂载卷
- .:/code
- logvolume01:/var/log
links: # 或者用 depends_on
- redis
redis:
image: redis # 镜像
restart: always # 容器是否重启
environment: # 环境变量
REDIS_HOST: redisx
REDIS_PORT: 6379
volumes:
logvolume01: {}
后台启动: -d
$ docker-compose up -d
# 停止
$ docker-compose down
docker stack
表格 Docker Stack 和 Docker Compose 区别
docker stack | docker-compose | |
---|---|---|
镜像 | 会忽略了“构建”指令,无法使用 stack 命令构建新镜像,它是需要镜像是预先已经构建好的。 | 更适合于开发场景 |
工具 | 包含在 Docker 引擎中。你不需要安装额外的包来使用它,docker stacks 只是 swarm mode 的一部分。 | 需要安装单独工具。在内部,它使用 Docker API 规范来操作容器。 |
yml 版本 | 版本 3 以上 | 支持版本 2 和 3 |
备注:同服务名称的配置项,yml 文件后面的会覆盖前面的。
docker stack 把 docker compose 的所有工作都做完了,因此 docker stack 将占主导地位。同时,对于大多数用户来说,切换到使用 docker stack 既不困难,也不需要太多的开销。如果您是 Docker 新手,或正在选择用于新项目的技术,请使用 docker stack。
表格 Docker Stack 常用命令
命令 | 描述 |
---|---|
docker stack deploy | 部署新的堆栈 或 更新现有堆栈 |
docker stack ls | 列出现有堆栈 |
docker stack ps | 列出堆栈中的任务 |
docker stack rm | 删除一个或多个堆栈 |
docker stack services | 列出堆栈中的服务 |
$ docker stack
Usage: docker stack [OPTIONS] COMMAND
Manage Docker stacks
Options:
--orchestrator string Orchestrator to use (swarm|kubernetes|all)
Commands:
deploy Deploy a new stack or update an existing stack
ls List stacks
ps List the tasks in the stack
rm Remove one or more stacks
services List the services in the stack
Run 'docker stack COMMAND --help' for more information on a command.
$ docker stack deploy --help
Usage: docker stack deploy [OPTIONS] STACK
Deploy a new stack or update an existing stack
Aliases:
deploy, up
Options:
-c, --compose-file strings Path to a Compose file, or "-" to read from stdin
--orchestrator string rchestrator to use (swarm|kubernetes|all) 容器编排方式
--prune Prune services that are no longer referenced
--resolve-image string Query the registry to resolve image digest and supported platforms ("always"|"changed"|"never") (default "always")
--with-registry-auth Send registry authentication details to Swarm agents, default false
说明:实际上 docker stack COMMAND STACK_NAME ,STACK_NAME 为栈名称,要有 STACK_NAME 才能执行。
进阶
- 只重启 stack 单个服务
# 若报错 image could not be accessed on a registry to record its digest
# 则加上参数 --with-registry-auth
# 法 1:stack depoly 命令部署更新,只更新标记需要更新的服务?
$ docker stack deploy STACK_NAME --with-registry-auth
# 法 2:指定 service id 强制更新某个 service, 这个命令只能用于 swarm 管理节点
# 示例中 service_id 是 3xrdy2c7pfm3
$ docker stack services STACK_NAME
# 重启服务,重启服务并更新某个服务的镜像
$ docker service update --force 3xrdy2c7pfm3
$ docker service update --image image_name service_name
- 查看服务问题
# 服务有启动:查看某个服务的日志, -f 日志持续查看
$ docker service logs -f SERVICE_NAME
# 查看容器报错信息
$ docker ps --no-trunc
# 若容器失败,查看对应失败容器的日志. docker ps -a 可以查看所有历史启动容器
$ docker logs -f <container_id>
# 查看 stack 的启动状态, --no-trunc 查看服务详细报错 如 yml 加载错误的信息
$ docker stack ps <stack-name> --no-trunc
docker stack 集群部署
docker stack 默认使用 swarm 模式部署。部署细节 详见下文章节。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论