mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-12 12:51:08 +00:00
Use a better structure
This commit is contained in:
@@ -1,36 +1,36 @@
|
||||
# Dockerfile 最佳实践
|
||||
## Dockerfile 最佳实践
|
||||
|
||||
本附录是笔者对 Docker 官方文档中 [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) 的理解与翻译。
|
||||
|
||||
## 一般性的指南和建议
|
||||
### 一般性的指南和建议
|
||||
|
||||
### 容器应该是短暂的
|
||||
#### 容器应该是短暂的
|
||||
|
||||
通过 `Dockerfile` 构建的镜像所启动的容器应该尽可能短暂(生命周期短)。「短暂」意味着可以停止和销毁容器,并且创建一个新容器并部署好所需的设置和配置工作量应该是极小的。
|
||||
|
||||
### 使用 `.dockerignore` 文件
|
||||
#### 使用 `.dockerignore` 文件
|
||||
|
||||
使用 `Dockerfile` 构建镜像时最好是将 `Dockerfile` 放置在一个新建的空目录下。然后将构建镜像所需要的文件添加到该目录中。为了提高构建镜像的效率,你可以在目录下新建一个 `.dockerignore` 文件来指定要忽略的文件和目录。`.dockerignore` 文件的排除模式语法和 Git 的 `.gitignore` 文件相似。
|
||||
|
||||
### 使用多阶段构建
|
||||
#### 使用多阶段构建
|
||||
|
||||
在 `Docker 17.05` 以上版本中,你可以使用 [多阶段构建](../04_image/multistage-builds.md) 来减少所构建镜像的大小。
|
||||
|
||||
### 避免安装不必要的包
|
||||
#### 避免安装不必要的包
|
||||
|
||||
为了降低复杂性、减少依赖、减小文件大小、节约构建时间,你应该避免安装任何不必要的包。例如,不要在数据库镜像中包含一个文本编辑器。
|
||||
|
||||
### 一个容器只运行一个进程
|
||||
#### 一个容器只运行一个进程
|
||||
|
||||
应该保证在一个容器中只运行一个进程。将多个应用解耦到不同容器中,保证了容器的横向扩展和复用。例如 web 应用应该包含三个容器:web应用、数据库、缓存。
|
||||
|
||||
如果容器互相依赖,你可以使用 [Docker 自定义网络](../network/README.md) 来把这些容器连接起来。
|
||||
|
||||
### 镜像层数尽可能少
|
||||
#### 镜像层数尽可能少
|
||||
|
||||
你需要在 `Dockerfile` 可读性(也包括长期的可维护性)和减少层数之间做一个平衡。
|
||||
|
||||
### 将多行参数排序
|
||||
#### 将多行参数排序
|
||||
|
||||
将多行参数按字母顺序排序(比如要安装多个包时)。这可以帮助你避免重复包含同一个包,更新包列表时也更容易。也便于 `PRs` 阅读和审查。建议在反斜杠符号 `\` 之前添加一个空格,以增加可读性。
|
||||
|
||||
@@ -45,7 +45,7 @@ RUN apt-get update && apt-get install -y \
|
||||
subversion
|
||||
```
|
||||
|
||||
### 构建缓存
|
||||
#### 构建缓存
|
||||
|
||||
在镜像的构建过程中,Docker 会遍历 `Dockerfile` 文件中的指令,然后按顺序执行。在执行每条指令之前,Docker 都会在缓存中查找是否已经存在可重用的镜像,如果有就使用现存的镜像,不再重复创建。如果你不想在构建过程中使用缓存,你可以在 `docker build` 命令中使用 `--no-cache=true` 选项。
|
||||
|
||||
@@ -58,22 +58,22 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
一旦缓存失效,所有后续的 `Dockerfile` 指令都将产生新的镜像,缓存不会被使用。
|
||||
|
||||
## Dockerfile 指令
|
||||
### Dockerfile 指令
|
||||
|
||||
下面针对 `Dockerfile` 中各种指令的最佳编写方式给出建议。
|
||||
|
||||
### FROM
|
||||
#### FROM
|
||||
|
||||
尽可能使用当前官方仓库作为你构建镜像的基础。推荐使用 [Alpine](https://hub.docker.com/_/alpine/) 镜像,因为它被严格控制并保持最小尺寸(目前小于 5 MB),但它仍然是一个完整的发行版。
|
||||
|
||||
### LABEL
|
||||
#### LABEL
|
||||
|
||||
你可以给镜像添加标签来帮助组织镜像、记录许可信息、辅助自动化构建等。每个标签一行,由 `LABEL` 开头加上一个或多个标签对。下面的示例展示了各种不同的可能格式。`#` 开头的行是注释内容。
|
||||
|
||||
>注意:如果你的字符串中包含空格,必须将字符串放入引号中或者对空格使用转义。如果字符串内容本身就包含引号,必须对引号使用转义。
|
||||
|
||||
```docker
|
||||
# Set one or more individual labels
|
||||
## Set one or more individual labels
|
||||
LABEL com.example.version="0.0.1-beta"
|
||||
|
||||
LABEL vendor="ACME Incorporated"
|
||||
@@ -86,7 +86,7 @@ LABEL com.example.version.is-production=""
|
||||
一个镜像可以包含多个标签,但建议将多个标签放入到一个 `LABEL` 指令中。
|
||||
|
||||
```docker
|
||||
# Set multiple labels at once, using line-continuation characters to break long lines
|
||||
## Set multiple labels at once, using line-continuation characters to break long lines
|
||||
LABEL vendor=ACME\ Incorporated \
|
||||
com.example.is-beta= \
|
||||
com.example.is-production="" \
|
||||
@@ -96,11 +96,11 @@ LABEL vendor=ACME\ Incorporated \
|
||||
|
||||
关于标签可以接受的键值对,参考 [Understanding object labels](https://docs.docker.com/config/labels-custom-metadata/)。关于查询标签信息,参考 [Managing labels on objects](https://docs.docker.com/config/labels-custom-metadata/)。
|
||||
|
||||
### RUN
|
||||
#### RUN
|
||||
|
||||
为了保持 `Dockerfile` 文件的可读性,可理解性,以及可维护性,建议将长的或复杂的 `RUN` 指令用反斜杠 `\` 分割成多行。
|
||||
|
||||
#### apt-get
|
||||
##### apt-get
|
||||
|
||||
`RUN` 指令最常见的用法是安装包用的 `apt-get`。因为 `RUN apt-get` 指令会安装包,所以有几个问题需要注意。
|
||||
|
||||
@@ -170,19 +170,19 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
> 注意:官方的 Debian 和 Ubuntu 镜像会自动运行 apt-get clean,所以不需要显式的调用 apt-get clean。
|
||||
|
||||
### CMD
|
||||
#### CMD
|
||||
|
||||
`CMD` 指令用于执行目标镜像中包含的软件,可以包含参数。`CMD` 大多数情况下都应该以 `CMD ["executable", "param1", "param2"...]` 的形式使用。因此,如果创建镜像的目的是为了部署某个服务(比如 `Apache`),你可能会执行类似于 `CMD ["apache2", "-DFOREGROUND"]` 形式的命令。我们建议任何服务镜像都使用这种形式的命令。
|
||||
|
||||
多数情况下,`CMD` 都需要一个交互式的 `shell` (bash, Python, perl 等),例如 `CMD ["perl", "-de0"]`,或者 `CMD ["PHP", "-a"]`。使用这种形式意味着,当你执行类似 `docker run -it python` 时,你会进入一个准备好的 `shell` 中。`CMD` 应该在极少的情况下才能以 `CMD ["param", "param"]` 的形式与 `ENTRYPOINT` 协同使用,除非你和你的镜像使用者都对 `ENTRYPOINT` 的工作方式十分熟悉。
|
||||
|
||||
### EXPOSE
|
||||
#### EXPOSE
|
||||
|
||||
`EXPOSE` 指令用于指定容器将要监听的端口。因此,你应该为你的应用程序使用常见的端口。例如,提供 `Apache` web 服务的镜像应该使用 `EXPOSE 80`,而提供 `MongoDB` 服务的镜像使用 `EXPOSE 27017`。
|
||||
|
||||
对于外部访问,用户可以在执行 `docker run` 时使用一个标志来指示如何将指定的端口映射到所选择的端口。
|
||||
|
||||
### ENV
|
||||
#### ENV
|
||||
|
||||
为了方便新程序运行,你可以使用 `ENV` 来为容器中安装的程序更新 `PATH` 环境变量。例如使用 `ENV PATH /usr/local/nginx/bin:$PATH` 来确保 `CMD ["nginx"]` 能正确运行。
|
||||
|
||||
@@ -202,7 +202,7 @@ ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
|
||||
|
||||
类似于程序中的常量,这种方法可以让你只需改变 `ENV` 指令来自动的改变容器中的软件版本。
|
||||
|
||||
### ADD 和 COPY
|
||||
#### ADD 和 COPY
|
||||
|
||||
虽然 `ADD` 和 `COPY` 功能类似,但一般优先使用 `COPY`。因为它比 `ADD` 更透明。`COPY` 只支持简单将本地文件拷贝到容器中,而 `ADD` 有一些并不明显的功能(比如本地 tar 提取和远程 URL 支持)。因此,`ADD` 的最佳用例是将本地 tar 文件自动提取到镜像中,例如 `ADD rootfs.tar.xz`。
|
||||
|
||||
@@ -241,7 +241,7 @@ RUN mkdir -p /usr/src/things \
|
||||
|
||||
对于其他不需要 `ADD` 的自动提取功能的文件或目录,你应该使用 `COPY`。
|
||||
|
||||
### ENTRYPOINT
|
||||
#### ENTRYPOINT
|
||||
|
||||
`ENTRYPOINT` 的最佳用处是设置镜像的主命令,允许将镜像当成命令本身来运行(用 `CMD` 提供默认选项)。
|
||||
|
||||
@@ -318,11 +318,11 @@ $ docker run postgres postgres --help
|
||||
$ docker run --rm -it postgres bash
|
||||
```
|
||||
|
||||
### VOLUME
|
||||
#### VOLUME
|
||||
|
||||
`VOLUME` 指令用于暴露任何数据库存储文件,配置文件,或容器创建的文件和目录。强烈建议使用 `VOLUME` 来管理镜像中的可变部分和用户可以改变的部分。
|
||||
|
||||
### USER
|
||||
#### USER
|
||||
|
||||
如果某个服务不需要特权执行,建议使用 `USER` 指令切换到非 root 用户。先在 `Dockerfile` 中使用类似 `RUN groupadd -r postgres && useradd -r -g postgres postgres` 的指令创建用户和用户组。
|
||||
|
||||
@@ -332,10 +332,10 @@ $ docker run --rm -it postgres bash
|
||||
|
||||
最后,为了减少层数和复杂度,避免频繁地使用 `USER` 来回切换用户。
|
||||
|
||||
### WORKDIR
|
||||
#### WORKDIR
|
||||
|
||||
为了清晰性和可靠性,你应该总是在 `WORKDIR` 中使用绝对路径。另外,你应该使用 `WORKDIR` 来替代类似于 `RUN cd ... && do-something` 的指令,后者难以阅读、排错和维护。
|
||||
|
||||
## 官方镜像示例
|
||||
### 官方镜像示例
|
||||
|
||||
这些官方镜像的 Dockerfile 都是参考典范:https://github.com/docker-library/docs
|
||||
@@ -1,6 +1,6 @@
|
||||
# 如何调试 Docker
|
||||
## 如何调试 Docker
|
||||
|
||||
## 开启 Debug 模式
|
||||
### 开启 Debug 模式
|
||||
|
||||
在 dockerd 配置文件 daemon.json(默认位于 /etc/docker/)中添加
|
||||
|
||||
@@ -18,14 +18,14 @@ $ sudo kill -SIGHUP $(pidof dockerd)
|
||||
|
||||
此时 dockerd 会在日志中输入更多信息供分析。
|
||||
|
||||
## 检查内核日志
|
||||
### 检查内核日志
|
||||
|
||||
```bash
|
||||
$ sudo dmesg |grep dockerd
|
||||
$ sudo dmesg |grep runc
|
||||
```
|
||||
|
||||
## Docker 不响应时处理
|
||||
### Docker 不响应时处理
|
||||
|
||||
可以杀死 dockerd 进程查看其堆栈调用情况。
|
||||
|
||||
@@ -33,16 +33,16 @@ $ sudo dmesg |grep runc
|
||||
$ sudo kill -SIGUSR1 $(pidof dockerd)
|
||||
```
|
||||
|
||||
## 重置 Docker 本地数据
|
||||
### 重置 Docker 本地数据
|
||||
|
||||
*注意,本操作会移除所有的 Docker 本地数据,包括镜像和容器等。*
|
||||
|
||||
$ sudo rm -rf /var/lib/docker
|
||||
```
|
||||
|
||||
## 常见故障排查
|
||||
### 常见故障排查
|
||||
|
||||
### 容器启动失败
|
||||
#### 容器启动失败
|
||||
|
||||
如果容器启动后立即退出,可以使用 `docker logs` 查看原因。
|
||||
|
||||
@@ -52,21 +52,21 @@ $ sudo rm -rf /var/lib/docker
|
||||
* 调整容器内存限制 (`--memory`)。
|
||||
* **Exit Code 127**: 命令未找到。可能是 `ENTRYPOINT` 或 `CMD` 指定的命令不存在。
|
||||
|
||||
### 网络连接问题
|
||||
#### 网络连接问题
|
||||
|
||||
#### 容器内部无法联网
|
||||
##### 容器内部无法联网
|
||||
|
||||
1. 检查 Docker DNS 配置 (`/etc/docker/daemon.json`)。
|
||||
2. 检查宿主机防火墙 (iptables/firewalld) 是否拦截了转发。
|
||||
3. 容器内测试: `ping 8.8.8.8` (测试连通性), `nslookup google.com` (测试 DNS)。
|
||||
|
||||
#### 端口映射不通
|
||||
##### 端口映射不通
|
||||
|
||||
1. 检查容器端口是否正确监听: `netstat -tunlp` (宿主机) 或 `docker exec <container> netstat -tunlp`。
|
||||
2. 确认应用监听地址是 `0.0.0.0` 而不是 `127.0.0.1`。
|
||||
* 如果应用监听在 `127.0.0.1`,只有容器内部能访问,映射到宿主机外部也无法被外部请求访问。
|
||||
|
||||
### 镜像拉取失败
|
||||
#### 镜像拉取失败
|
||||
|
||||
* **connection refused**: 检查网络或代理设置。
|
||||
* **image not found**: 检查镜像名称和 Tag 拼写。
|
||||
@@ -1,6 +1,6 @@
|
||||
# 资源链接
|
||||
## 资源链接
|
||||
|
||||
## 官方网站
|
||||
### 官方网站
|
||||
|
||||
* Docker 官方主页:https://www.docker.com
|
||||
* Docker 官方博客:https://www.docker.com/blog/
|
||||
@@ -12,18 +12,18 @@
|
||||
* Docker 常见问题:https://docs.docker.com/engine/faq/
|
||||
* Docker 远端应用 API:https://docs.docker.com/develop/sdk/
|
||||
|
||||
## 实践参考
|
||||
### 实践参考
|
||||
|
||||
* Dockerfile 参考:https://docs.docker.com/engine/reference/builder/
|
||||
* Dockerfile 最佳实践:https://docs.docker.com/build/building/best-practices/
|
||||
|
||||
## 技术交流
|
||||
### 技术交流
|
||||
|
||||
* Docker 邮件列表: https://groups.google.com/forum/#!forum/docker-user
|
||||
* Docker 社区 Slack:https://dockercommunity.slack.com/
|
||||
* Docker Community Discord: https://discord.gg/docker
|
||||
* Docker 的 Twitter 主页:https://twitter.com/docker
|
||||
|
||||
## 其它
|
||||
### 其它
|
||||
|
||||
* Docker 的 StackOverflow 问答主页:https://stackoverflow.com/search?q=docker
|
||||
@@ -1,4 +1,4 @@
|
||||
# 附录
|
||||
# 第十五章 附录
|
||||
|
||||
本章包含了 Docker 相关的参考资料、常见问题解答以及最佳实践指南,旨在为读者提供便捷的查阅工具。
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
* [**常见问题总结 (FAQ)**](faq/README.md):汇总了学习和使用 Docker 过程中的常见问题与错误解决方案。
|
||||
* [**热门镜像介绍**](repo/README.md):详细介绍了 Nginx, MySQL, Redis 等常用官方镜像的使用方法。
|
||||
* [**Docker 命令查询**](command/README.md):速查 Docker 客户端和服务端的常用命令。
|
||||
* [**Dockerfile 最佳实践**](best_practices.md):提供编写高效、安全 Dockerfile 的指导原则。
|
||||
* [**如何调试 Docker**](debug.md):介绍 Docker 调试技巧和工具。
|
||||
* [**资源链接**](resources.md):推荐更多 Docker 相关的学习资源。
|
||||
* [**Dockerfile 最佳实践**](15.1_best_practices.md):提供编写高效、安全 Dockerfile 的指导原则。
|
||||
* [**如何调试 Docker**](15.2_debug.md):介绍 Docker 调试技巧和工具。
|
||||
* [**资源链接**](15.3_resources.md):推荐更多 Docker 相关的学习资源。
|
||||
@@ -1,6 +1,6 @@
|
||||
# Docker 命令查询
|
||||
## Docker 命令查询
|
||||
|
||||
## 基本语法
|
||||
### 基本语法
|
||||
|
||||
Docker 命令有两大类,客户端命令和服务端命令。前者是主要的操作接口,后者用来启动 Docker Daemon。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 客户端命令 - docker
|
||||
## 客户端命令 - docker
|
||||
|
||||
## 客户端命令选项
|
||||
### 客户端命令选项
|
||||
|
||||
* `--config=""`:指定客户端配置文件,默认为 `~/.docker`;
|
||||
* `-D=true|false`:是否使用 debug 模式。默认不开启;
|
||||
@@ -12,7 +12,7 @@
|
||||
* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径;
|
||||
* `--tlsverify=true|false`:启用 TLS 校验,默认为否。
|
||||
|
||||
## 客户端命令
|
||||
### 客户端命令
|
||||
|
||||
可以通过 `docker COMMAND --help` 来查看这些命令的具体用法。
|
||||
|
||||
@@ -62,10 +62,10 @@
|
||||
* `volume`:管理 Docker volume,包括查看、创建、删除等;
|
||||
* `wait`:阻塞直到一个容器终止,然后输出它的退出符。
|
||||
|
||||
## 一张图总结 Docker 的命令
|
||||
### 一张图总结 Docker 的命令
|
||||
|
||||

|
||||
|
||||
## 参考
|
||||
### 参考
|
||||
|
||||
* [官方文档](https://docs.docker.com/engine/reference/commandline/cli/)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 服务端命令(dockerd)
|
||||
## 服务端命令(dockerd)
|
||||
|
||||
## dockerd 命令选项
|
||||
### dockerd 命令选项
|
||||
|
||||
* `--api-cors-header=""`:CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 "*";
|
||||
* `--authorization-plugin=""`:载入认证的插件;
|
||||
@@ -53,6 +53,6 @@
|
||||
* `--userland-proxy=true|false`:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true;
|
||||
* `--userns-remap=default|uid:gid|user:group|user|uid`:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。
|
||||
|
||||
## 参考
|
||||
### 参考
|
||||
|
||||
* [官方文档](https://docs.docker.com/engine/reference/commandline/dockerd/)
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# 附录一:常见问题总结
|
||||
## 附录一:常见问题总结
|
||||
|
||||
## 镜像相关
|
||||
### 镜像相关
|
||||
|
||||
### 如何批量清理临时镜像文件?
|
||||
#### 如何批量清理临时镜像文件?
|
||||
|
||||
答:可以使用 `docker image prune` 命令。
|
||||
|
||||
### 如何查看镜像支持的环境变量?
|
||||
#### 如何查看镜像支持的环境变量?
|
||||
|
||||
答:可以使用 `docker run IMAGE env` 命令。
|
||||
|
||||
### 本地的镜像文件都存放在哪里?
|
||||
#### 本地的镜像文件都存放在哪里?
|
||||
|
||||
答:与 Docker 相关的本地资源默认存放在 `/var/lib/docker/` 目录下,以 `overlay2` 文件系统为例,其中 `containers` 目录存放容器信息,`image` 目录存放镜像信息,`overlay2` 目录下存放具体的镜像层文件。
|
||||
|
||||
### 构建 Docker 镜像应该遵循哪些原则?
|
||||
#### 构建 Docker 镜像应该遵循哪些原则?
|
||||
|
||||
答:整体原则上,尽量保持镜像功能的明确和内容的精简,要点包括
|
||||
|
||||
@@ -25,27 +25,27 @@
|
||||
* 如果安装应用时候需要配置一些特殊的环境变量,在安装后要还原不需要保持的变量值;
|
||||
* 使用 Dockerfile 创建镜像时候要添加 .dockerignore 文件或使用干净的工作目录。
|
||||
|
||||
更多内容请查看 [Dockerfile 最佳实践](../best_practices.md)
|
||||
更多内容请查看 [Dockerfile 最佳实践](../15.1_best_practices.md)
|
||||
|
||||
### 碰到网络问题,无法 pull 镜像,命令行指定 http\_proxy 无效?
|
||||
#### 碰到网络问题,无法 pull 镜像,命令行指定 http\_proxy 无效?
|
||||
|
||||
答:在 Docker 配置文件中添加 `export http_proxy="http://<PROXY_HOST>:<PROXY_PORT>"`,之后重启 Docker 服务即可。
|
||||
|
||||
## 容器相关
|
||||
### 容器相关
|
||||
|
||||
### 容器退出后,通过 docker container ls 命令查看不到,数据会丢失么?
|
||||
#### 容器退出后,通过 docker container ls 命令查看不到,数据会丢失么?
|
||||
|
||||
答:容器退出后会处于终止(exited)状态,此时可以通过 `docker container ls -a` 查看。其中的数据也不会丢失,还可以通过 `docker start` 命令来启动它。只有删除掉容器才会清除所有数据。
|
||||
|
||||
### 如何停止所有正在运行的容器?
|
||||
#### 如何停止所有正在运行的容器?
|
||||
|
||||
答:可以使用 `docker stop $(docker container ls -q)` 命令。
|
||||
|
||||
### 如何批量清理已经停止的容器?
|
||||
#### 如何批量清理已经停止的容器?
|
||||
|
||||
答:可以使用 `docker container prune` 命令。
|
||||
|
||||
### 如何获取某个容器的 PID 信息?
|
||||
#### 如何获取某个容器的 PID 信息?
|
||||
|
||||
答:可以使用
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
docker inspect --format '{{ .State.Pid }}' <CONTAINER ID or NAME>
|
||||
```
|
||||
|
||||
### 如何获取某个容器的 IP 地址?
|
||||
#### 如何获取某个容器的 IP 地址?
|
||||
|
||||
答:可以使用
|
||||
|
||||
@@ -61,7 +61,7 @@ docker inspect --format '{{ .State.Pid }}' <CONTAINER ID or NAME>
|
||||
docker inspect --format '{{ .NetworkSettings.IPAddress }}' <CONTAINER ID or NAME>
|
||||
```
|
||||
|
||||
### 如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变?
|
||||
#### 如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变?
|
||||
|
||||
答:使用以下命令启动容器可以使容器 IP 固定不变
|
||||
|
||||
@@ -71,40 +71,40 @@ $ docker network create -d bridge --subnet 172.25.0.0/16 my-net
|
||||
$ docker run --network=my-net --ip=172.25.3.3 -itd --name=my-container busybox
|
||||
```
|
||||
|
||||
### 如何临时退出一个正在交互的容器的终端,而不终止它?
|
||||
#### 如何临时退出一个正在交互的容器的终端,而不终止它?
|
||||
|
||||
答:按 `Ctrl-p Ctrl-q`。如果按 `Ctrl-c` 往往会让容器内应用进程终止,进而会终止容器。
|
||||
|
||||
### 使用 `docker port` 命令映射容器的端口时,系统报错“Error: No public port '80' published for xxx”?
|
||||
#### 使用 `docker port` 命令映射容器的端口时,系统报错“Error: No public port '80' published for xxx”?
|
||||
|
||||
答:
|
||||
|
||||
* 创建镜像时 `Dockerfile` 要通过 `EXPOSE` 指定正确的开放端口;
|
||||
* 容器启动时指定 `PublishAllPort = true`。
|
||||
|
||||
### 可以在一个容器中同时运行多个应用进程么?
|
||||
#### 可以在一个容器中同时运行多个应用进程么?
|
||||
|
||||
答:一般并不推荐在同一个容器内运行多个应用进程。如果有类似需求,可以通过一些额外的进程管理机制,比如 `supervisord` 来管理所运行的进程。可以参考 https://docs.docker.com/config/containers/multi-service\_container/ 。
|
||||
|
||||
### 如何控制容器占用系统资源(CPU、内存)的份额?
|
||||
#### 如何控制容器占用系统资源(CPU、内存)的份额?
|
||||
|
||||
答:在使用 `docker create` 命令创建容器或使用 `docker run` 创建并启动容器的时候,可以使用 -c|--cpu-shares\[=0] 参数来调整容器使用 CPU 的权重;使用 -m|--memory\[=MEMORY] 参数来调整容器使用内存的大小。
|
||||
|
||||
## 仓库相关
|
||||
### 仓库相关
|
||||
|
||||
### 仓库(Repository)、注册服务器(Registry)、注册索引(Index) 有何关系?
|
||||
#### 仓库(Repository)、注册服务器(Registry)、注册索引(Index) 有何关系?
|
||||
|
||||
首先,仓库是存放一组关联镜像的集合,比如同一个应用的不同版本的镜像。
|
||||
|
||||
注册服务器是存放实际的镜像文件的地方。注册索引则负责维护用户的账号、权限、搜索、标签等的管理。因此,注册服务器利用注册索引来实现认证等管理。
|
||||
|
||||
## 配置相关
|
||||
### 配置相关
|
||||
|
||||
### Docker 的配置文件放在哪里,如何修改配置?
|
||||
#### Docker 的配置文件放在哪里,如何修改配置?
|
||||
|
||||
答:使用 `systemd` 的系统(如 Ubuntu 16.04、Centos 等)的配置文件在 `/etc/docker/daemon.json`。
|
||||
|
||||
### 如何更改 Docker 的默认存储位置?
|
||||
#### 如何更改 Docker 的默认存储位置?
|
||||
|
||||
答:Docker 的默认存储位置是 `/var/lib/docker`,如果希望将 Docker 的本地文件存储到其他分区,可以使用 Linux 软连接的方式来完成,或者在启动 daemon 时通过 `-g` 参数指定,或者修改配置文件 `/etc/docker/daemon.json` 的 "data-root" 项 。可以使用 `docker system info | grep "Root Dir"` 查看当前使用的存储位置。
|
||||
|
||||
@@ -127,7 +127,7 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
|
||||
[root@s26 lib]# service docker start
|
||||
```
|
||||
|
||||
### 使用内存和 swap 限制启动容器时候报警告:"WARNING: Your kernel does not support cgroup swap limit. WARNING: Your kernel does not support swap limit capabilities. Limitation discarded."?
|
||||
#### 使用内存和 swap 限制启动容器时候报警告:"WARNING: Your kernel does not support cgroup swap limit. WARNING: Your kernel does not support swap limit capabilities. Limitation discarded."?
|
||||
|
||||
答:这是因为系统默认没有开启对内存和 swap 使用的统计功能,引入该功能会带来性能的下降。要开启该功能,可以采取如下操作:
|
||||
|
||||
@@ -135,9 +135,9 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
|
||||
* 更新 grub:`$ sudo update-grub`
|
||||
* 重启系统,即可。
|
||||
|
||||
## Docker 与虚拟化
|
||||
### Docker 与虚拟化
|
||||
|
||||
### Docker 与 LXC(Linux Container)有何不同?
|
||||
#### Docker 与 LXC(Linux Container)有何不同?
|
||||
|
||||
答:LXC 利用 Linux 上相关技术实现了容器。Docker 则在如下的几个方面进行了改进:
|
||||
|
||||
@@ -147,7 +147,7 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
|
||||
* 仓库系统:仓库系统大大降低了镜像的分发和管理的成本;
|
||||
* 周边工具:各种现有工具(配置管理、云平台)对 Docker 的支持,以及基于 Docker的 PaaS、CI 等系统,让 Docker 的应用更加方便和多样化。
|
||||
|
||||
### Docker 与 Vagrant 有何不同?
|
||||
#### Docker 与 Vagrant 有何不同?
|
||||
|
||||
答:两者的定位完全不同。
|
||||
|
||||
@@ -156,7 +156,7 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
|
||||
|
||||
简单说:Vagrant 适合用来管理虚拟机,而 Docker 适合用来管理应用环境。
|
||||
|
||||
### 开发环境中 Docker 和 Vagrant 该如何选择?
|
||||
#### 开发环境中 Docker 和 Vagrant 该如何选择?
|
||||
|
||||
答:Docker 不是虚拟机,而是进程隔离,对于资源的消耗很少,但是目前需要 Linux 环境支持。Vagrant 是虚拟机上做的封装,虚拟机本身会消耗资源。
|
||||
|
||||
@@ -164,17 +164,17 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
|
||||
|
||||
如果本地使用的是 macOS 或者 Windows 环境,那就需要开虚拟机,单一开发环境下 Vagrant 更简单;多环境开发下推荐在 Vagrant 里面再使用 Docker 进行环境隔离。
|
||||
|
||||
## 其它
|
||||
### 其它
|
||||
|
||||
### Docker 能在非 Linux 平台(比如 Windows 或 macOS )上运行么?
|
||||
#### Docker 能在非 Linux 平台(比如 Windows 或 macOS )上运行么?
|
||||
|
||||
答:完全可以。安装方法请查看 [安装 Docker](../../install/) 一节
|
||||
|
||||
### 如何将一台宿主主机的 Docker 环境迁移到另外一台宿主主机?
|
||||
#### 如何将一台宿主主机的 Docker 环境迁移到另外一台宿主主机?
|
||||
|
||||
答:停止 Docker 服务。将整个 Docker 存储文件夹复制到另外一台宿主主机,然后调整另外一台宿主主机的配置即可。
|
||||
|
||||
### 如何进入 Docker 容器的网络命名空间?
|
||||
#### 如何进入 Docker 容器的网络命名空间?
|
||||
|
||||
答:Docker 在创建容器后,删除了宿主主机上 `/var/run/netns` 目录中的相关的网络命名空间文件。因此,在宿主主机上是无法看到或访问容器的网络命名空间的。
|
||||
|
||||
@@ -206,7 +206,7 @@ $ sudo ip netns show
|
||||
$ sudo ip netns exec 1234 ifconfig eth0 172.17.0.100/16
|
||||
```
|
||||
|
||||
### 如何获取容器绑定到本地那个 veth 接口上?
|
||||
#### 如何获取容器绑定到本地那个 veth 接口上?
|
||||
|
||||
答:Docker 容器启动后,会通过 veth 接口对连接到本地网桥,veth 接口命名跟容器命名毫无关系,十分难以找到对应关系。
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# 常见错误速查表
|
||||
## 常见错误速查表
|
||||
|
||||
| 错误信息 / 现象 | 可能原因 | 解决方案 |
|
||||
| :--- | :--- | :--- |
|
||||
| `Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?` | Docker 服务未启动 | Linux: `sudo systemctl start docker`<br>Mac/Win: 启动 Docker Desktop |
|
||||
| `permission denied while trying to connect to the Docker daemon socket` | 当前用户不在 `docker` 用户组 | `sudo usermod -aG docker $USER` (需重新登录) |
|
||||
| `manifest for ... not found: manifest unknown` | 镜像 tag 不存在 | 检查 Docker Hub 该镜像是否存在该 tag,或拼写是否正确 |
|
||||
| `connection refused` (pull image) | 网络不通或镜像源无法访问 | 检查网络,配置[镜像加速器](../../install/mirror.md) |
|
||||
| `connection refused` (pull image) | 网络不通或镜像源无法访问 | 检查网络,配置[镜像加速器](../../install/3.9_mirror.md) |
|
||||
| `Bind for 0.0.0.0:8080 failed: port is already allocated` | 端口被占用 | 检查占用端口的进程 (`lsof -i:8080`) 并杀掉,或换个端口映射 (`-p 8081:80`) |
|
||||
| `exec user process caused "exec format error"` | 架构不匹配 (如在 x86 上跑 ARM 镜像) | 使用 `docker buildx` 构建多架构镜像,或拉取对应架构的镜像 |
|
||||
| `standard_init_linux.go:211: exec user process caused "no such file or directory"` | 找不到解释器或依赖库 | 检查 `ENTRYPOINT`/`CMD` 脚本开头的 shebang (`#!/bin/sh` vs `#!/bin/bash`),或确认二进制文件是否依赖缺失 (Alpine 常见缺少 glibc) |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# 热门镜像介绍
|
||||
## 热门镜像介绍
|
||||
|
||||
本章将介绍一些热门镜像的功能,使用方法等。包括 Ubuntu、CentOS、MySQL、MongoDB、Redis、Nginx、Wordpress、Node.js 等。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# [CentOS](https://hub.docker.com/_/centos)
|
||||
## [CentOS](https://hub.docker.com/_/centos)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 发行版,其软件包大多跟 RedHat 系列保持一致。
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/centos`,提供了 CentOS 从 5 ~ 8 各个版本的镜像(仅作为历史归档,不再更新)。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
使用 Rocky Linux 9 替代(**推荐**):
|
||||
|
||||
@@ -27,6 +27,6 @@ $ docker run --name rocky -it rockylinux:9 bash
|
||||
$ docker run --name centos -it centos:7 bash
|
||||
```
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/centos 查看。
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# minio
|
||||
## minio
|
||||
|
||||
**MinIO** 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几 kb 到最大 5T 不等。
|
||||
|
||||
@@ -6,7 +6,7 @@ MinIO 是一个非常轻量的服务,可以很简单的和其他应用的结合
|
||||
|
||||
[官方文档](https://docs.min.io/)
|
||||
|
||||
## 简单使用
|
||||
### 简单使用
|
||||
|
||||
测试、开发环境下不考虑数据存储的情况下可以使用下面的命令快速开启服务。
|
||||
|
||||
@@ -14,11 +14,11 @@ MinIO 是一个非常轻量的服务,可以很简单的和其他应用的结合
|
||||
$ docker run -d -p 9000:9000 -p 9090:9090 minio/minio server /data --console-address ':9090'
|
||||
```
|
||||
|
||||
## 离线部署
|
||||
### 离线部署
|
||||
|
||||
许多生产环境是一般是没有公网资源的,这就需要从有公网资源的服务器上把镜像导出,然后导入到需要运行镜像的内网服务器。
|
||||
|
||||
### 导出镜像
|
||||
#### 导出镜像
|
||||
|
||||
在有公网资源的服务器上下载好`minio/minio`镜像
|
||||
|
||||
@@ -28,7 +28,7 @@ $ docker save -o minio.tar minio/minio:latest
|
||||
|
||||
> 使用docker save 的时候,也可以使用image id 来导出,但是那样导出的时候,就会丢失原来的镜像名称,推荐,还是使用镜像名字+tag来导出镜像
|
||||
|
||||
### 导入镜像
|
||||
#### 导入镜像
|
||||
|
||||
把压缩文件复制到内网服务器上,使用下面的命令导入镜像
|
||||
|
||||
@@ -36,7 +36,7 @@ $ docker save -o minio.tar minio/minio:latest
|
||||
$ docker load minio.tar
|
||||
```
|
||||
|
||||
### 运行 minio
|
||||
#### 运行 minio
|
||||
|
||||
- 把 `/mnt/data` 改成要替换的数据目录
|
||||
- 替换 `MINIO_ROOT_USER` 的值
|
||||
@@ -53,6 +53,6 @@ $ sudo docker run -d -p 9000:9000 -p 9090:9090 --name minio1 \
|
||||
minio/minio server /data --console-address ':9090'
|
||||
```
|
||||
|
||||
### 访问 web 管理页面
|
||||
#### 访问 web 管理页面
|
||||
|
||||
http://x.x.x.x:9090
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# [MongoDB](https://hub.docker.com/_/mongo/)
|
||||
## [MongoDB](https://hub.docker.com/_/mongo/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是开源的 NoSQL 数据库实现。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/mongo/` ,提供了 MongoDB 2.x ~ 4.x 各个版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
默认会在 `27017` 端口启动数据库。
|
||||
|
||||
@@ -39,6 +39,6 @@ $ docker run -it --rm \
|
||||
```
|
||||
```
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/mongo 查看。
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# [MySQL](https://hub.docker.com/_/mysql/)
|
||||
## [MySQL](https://hub.docker.com/_/mysql/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[MySQL](https://en.wikipedia.org/wiki/MySQL) 是开源的关系数据库实现。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/mysql/` ,提供了 MySQL 5.5 ~ 8.x 各个版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
默认会在 `3306` 端口启动数据库。
|
||||
|
||||
@@ -41,6 +41,6 @@ $ docker run -it --rm \
|
||||
```
|
||||
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/mysql 查看
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# [Nginx](https://hub.docker.com/_/nginx/)
|
||||
## [Nginx](https://hub.docker.com/_/nginx/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.19.x 各个版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
下面的命令将作为一个静态页面服务器启动。
|
||||
|
||||
@@ -44,6 +44,6 @@ $ docker run -d \
|
||||
nginx
|
||||
```
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/nginx 查看。
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# [Node.js](https://hub.docker.com/_/node/)
|
||||
## [Node.js](https://hub.docker.com/_/node/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[Node.js](https://en.wikipedia.org/wiki/Node.js) 是基于 JavaScript 的可扩展服务端和网络软件开发平台。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/node/` ,提供了 Node.js 0.10 ~ 14.x 各个版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
在项目中创建一个 Dockerfile。
|
||||
|
||||
```docker
|
||||
FROM node:12
|
||||
# replace this with your application's default port
|
||||
## replace this with your application's default port
|
||||
EXPOSE 8888
|
||||
```
|
||||
|
||||
@@ -35,6 +35,6 @@ $ docker run -it --rm \
|
||||
node your-daemon-or-script.js
|
||||
```
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/node 查看。
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# [PHP](https://hub.docker.com/_/php/)
|
||||
## [PHP](https://hub.docker.com/_/php/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[PHP](https://en.wikipedia.org/wiki/Php)(Hypertext Preprocessor 超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/php/` ,提供了 PHP 5.x ~ 8.x 各个版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
下面的命令将运行一个已有的 PHP 脚本。
|
||||
|
||||
@@ -14,6 +14,6 @@
|
||||
$ docker run -it --rm -v "$PWD":/app -w /app php:alpine php your-script.php
|
||||
```
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/php 查看。
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# [Redis](https://hub.docker.com/_/redis/)
|
||||
## [Redis](https://hub.docker.com/_/redis/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[Redis](https://en.wikipedia.org/wiki/Redis) 是开源的内存 Key-Value 数据库实现。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/redis/` ,提供了 Redis 3.x ~ 6.x 各个版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
默认会在 `6379` 端口启动数据库。
|
||||
|
||||
@@ -46,6 +46,6 @@ $ docker run -it --rm \
|
||||
sh -c 'exec redis-cli -h some-redis'
|
||||
```
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/redis 查看。
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# [Ubuntu](https://hub.docker.com/_/ubuntu/)
|
||||
## [Ubuntu](https://hub.docker.com/_/ubuntu/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 发行版,其自带软件版本往往较新一些。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/ubuntu/` ,提供了 Ubuntu 从 12.04 ~ 20.04 各个版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
默认会启动一个最小化的 Ubuntu 环境。
|
||||
|
||||
@@ -15,6 +15,6 @@ $ docker run --name some-ubuntu -it ubuntu:20.04
|
||||
root@523c70904d54:/#
|
||||
```
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/ubuntu 查看。
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# [WordPress](https://hub.docker.com/_/wordpress/)
|
||||
## [WordPress](https://hub.docker.com/_/wordpress/)
|
||||
|
||||
## 基本信息
|
||||
### 基本信息
|
||||
|
||||
[WordPress](https://en.wikipedia.org/wiki/WordPress) 是开源的 Blog 和内容管理系统框架,它基于 PHP 和 MySQL。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/wordpress/` ,提供了 WordPress 4.x ~ 5.x 版本的镜像。
|
||||
|
||||
## 使用方法
|
||||
### 使用方法
|
||||
|
||||
启动容器需要 MySQL 的支持,默认端口为 `80`。
|
||||
|
||||
@@ -33,6 +33,6 @@ $ docker run --name some-wordpress -d --network my-wordpress-net -e WORDPRESS_DB
|
||||
* `WORDPRESS_DB_NAME`: WordPress 要使用的数据库名
|
||||
|
||||
|
||||
## Dockerfile
|
||||
### Dockerfile
|
||||
|
||||
请到 https://github.com/docker-library/docs/tree/master/wordpress 查看。
|
||||
|
||||
Reference in New Issue
Block a user