目录
1. 概览
1.1 基本概念
虚拟化:
进程隔离:
容器(container):操作系统级的虚拟化技术。
镜像(image):容器的模板。
仓库(repository):集中存放镜像文件的站点。
注册服务器(registry):存放仓库的服务器,可以存放多个仓库。
1.2 docker命令总结
2. 使用镜像
2.1 查看
镜像文件包含层(layers)文件和配置(config)文件,两者都存放在mainfest文件。
#overview
docker images
#layers
docker history <image>
#config
docker inspect <image>
2.2 搜索和拉取
Pull命令下载manifest及其中存放的文件。如果层存在,则不会再次从仓库下载。
#search
docker search <keyword>
#default1: tag=latest;
#default2: image_name=registry/app_name, while registry=docker.io
docker pull <image_name>:<tag>
# tag
#docker tag <source_image> <target_image>
LayerId:层文件的sha256sum值。
Digest:manifest文件的sha256sum值。
2.3 删除
# remove images by tag or ID
# rm by ID, all tags of ID would be removed, then remove the image
docker rmi <image>
#
docker image prune
2.4 构建
# 1. 基于已有容器创建
docker commit <container> <new_image>
# 2. 基于本地模板导入
docker import <file> <new_image>
# 3. 基于 Dockerfile 和 context 创建;
## context 是指定位置(PATH, URL)的文件集;它们会被递归传递到 daemon,可以用 .dockerignore 文件去除 context 中需要传递到 daemon 的文件
## daemon 依次且独立地运行 Dockerfile 中的每条指令
docker build -f </path/dockerfile> -t <repo/image> .
2.5 保存和加载
docker save -o <out.tar> <image>
docker load -i <out.tar>
2.6 上传
# image_name=registry/app_name
docker push <image_name>:<tag>
3. 操作容器
利用以下命令:1)管理容器的生命周期。2)提高容器的高可用性和安全性。
docker container help
3.1 查看
# 查看容器
docker ps
# 查看容器输出(-details, -since, -until, -t, -tail)
docker logs <container>
# 查看容器的具体信息
docker container inspect <container>
# 查看容器内进程
docker top <container>
# 查看统计信息
docker stats <container>
# 查看容器内文件系统变更
docker container diff <container>
# 查看端口映射
docker container port <container>
3.2 创建
# 1. 创建+启动,在后台运行的操作包括:
## 镜像检查或获取;
## 创建并启动容器;
## 在只读镜像层外挂载可写层;
## 从宿主机配置的网桥接口桥接一个虚拟接口到容器中;从网桥地址池分配一个IP给容器;
## 执行用户指定的应用;
## 执行后自动终止容器
docker run <image>
# 2.1 创建
docker creat <image>
# 2.2 启动
docker start <image>
表4.1 create命令选项(运行,环境配置,资源,安全)
Options | Describe |
---|---|
-d, --detach=true|fasle | 在后台运行容器(守护态,daemonized) |
entrypoint=“” | 入口命令 |
expose=[] | 指定容器暴露的端口 |
-i, --interactive=true|false | 保持标准输入打开 |
–rm=true|false | 容器退出后是否删除 |
-t | 分配一个伪终端 |
-v, --volume | 将主机上的文件卷挂载到容器 |
-w | 默认的工作目录 |
-e | 指定容器内的环境变量 |
–ip=“” | 指定容器的IPv4地址 |
–blkio-weight | 容器读写块设备的I/O性能权重 |
–cpu-shares | 允许容器使用CPU资源的相对权重 |
–device-read-bps | 挂载设备的读吞吐率限制 |
-m, --memory | 限制容器使用的内存 |
… | … |
3.3 进入容器
docker exec
相当于进入容器并开启一个新的终端,因而进入一般需要指定COMMAND命令,退出可以直接键入exit
而不会影响容器运行。
docker attach
进入运行容器并不会开启新的进程,退出时直接键入exit
会导致容器停止运行。如果想要退出而保持容器继续运行,可以使用Ctrl+P+Q
组合。(摘录于博主:@星丶空LTL)
# -i, -t, -d, -u, -e, --privilege, --detach-keys
docker exec -it <containerID> <COMMAND>
#
docker attach <containerID>
3.4 停止和删除
# 暂停和恢复
docker pause <container>
docker unpause <container>
# 终止:SIGTERM--(default:10s)--SIGKILL
docker stop <container>
# SIGKILL
docker kill <container>
# 先终止,再启动容器
docker restart <container>
# 删除终止或退出状态的容器;-f 强制删除运行状态的容器
docker rm <container>
# 清除处于停止状态的容器
docker container prune
3.5 导入和导出
# 导出容器
docker export -o file <container>
# 导入容器快照,先比 load <image>, 丢弃元数据和历史记录
docker import file <container>
3.6 复制
# 容器和主机间的文件复制
docker cp <container:src_path> <dest_path>
# 更新资源限额配置(表4.1资源限制相关选项)
docker update <container>
4. 访问仓库
- 4.1 公有
常见的公共仓库:Docker hub,DaoClound
# 注册和登录
docker login
# 搜索;下载;上传
docker search <image>
docker pull <image>
docker push <image>
- 4.2 私有
# 使用registry镜像创建仓库
## v:存放镜像文件的目录
docker run -v /var/lib/registry -d -p 5000:5000 registry:2
# 管理仓库(上传)
docker tag <image:tag> <ip:port/image_new:tag_new>
docker push <ip:port/image_new:tag_new>
Q:如何关闭docker对仓库的安全检查?
A:(1)在 docker daemon 启动参数中添加 DOCKER_OPTS="insecure-registry <ip:port>"
;(2)重启docker服务 sudo service docker restart
5. 数据管理
5.1 数据卷
数据卷(Data Volumes)是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器。
# 创建数据卷
docker volumn create -d local rys #/var/lib/docker/volumes/rys
# 绑定数据卷:创建容器时将主机本地路径挂载到容器内作为数据卷
docker run -d -P -name web \
--mount type=bind,source=/wa,destination=/opt/wa test/wa python app.py
docker run -d -P --name web \
-v /wa:/opt/wa test/wa python app.py
5.2 数据卷容器
数据卷容器(Data Volume Containers)是专门提供数据卷给其它容器挂载的容器。
# 创建数据卷容器
docker run -it -v /dvc --name dvc ubuntu
# 挂载数据卷容器中的数据卷
docker run -it --volumes-from dvc --name db1 ubuntu
#docker run -it --volumes-from dvc --name db2 ubuntu
#docker run -it --volumes-from db1 --name db3 ubuntu
6. 容器访问
6.1 端口映射
docker run -d -P test/wa python app.py #-P,-p 指定端口映射
docker port <container> <port> #查看当前映射的端口配置
6.2 互联
互联(linking):在源容器和接收容器之间创建一个虚拟通道,避免映射端口到宿主机上。
docker run -rm -P --name web test/wa python app.py #容器命名
docker run -d --name db test/postgres
docker run -rm -P --name web --link db:db_alias test/wa python app.py
附录1. docker的安装和配置
系统:Ubuntu Bionic 18.04 (LTS)
###############################################
# Method1: Install using the repository (官方推荐)
###############################################
# 1.1 set up the repository
## update
sudo apt-get update
## install packages that allow apt to use a repository over HTTPS
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
## add docker’s official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
## verify
sudo apt-key fingerprint 0EBFCD88
## (aliyun GPG key)
## curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | apt-key add -
##set up the stable repository
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 1.2 install docker engine
## install
sudo apt-get install docker-ce docker-ce-cli containerd.io
## verify
sudo docker run hello-world
###############################################
# config
###############################################
# authority
#sudo groupadd docker
sudo usermod -aG docker $(whoami)
# source ...
###############################################
# debug
###############################################
#sudo docker run hello-world
## docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
## https://stackoverflow.com/questions/60935907/docker-cannot-connect-to-the-docker-daemon-at-unix-var-run-docker-sock-is-t
安装过程中已默认启动了docker服务。此外,如何手动启动docker服务?一种方法是通过 dockerd
命令;另一种是通过操作系统的服务管理工具(如Ubuntu系统的 service
, CentOS系统的 systemctl
)。
附录2:编写Dockerfile
Dockerfile
是一个包含了用于构建镜像命令的文本文档。格式如下:
# Comment
INSTRUCTION arguments
指令分为四部分:基础镜像信息;维护者信息;镜像操作指令和容器启动时的执行命令。下面展示了一个简单的示例。
# directive=value ## 解析器:影响dockerfile处理方式,不会包含在镜像里。
# comment ## 注释行,在dockerfile指令执行前会被移除
# escape= \ or ` ## 转义字符
FROM busybox ## 基础镜像
ENV FOO=/bar ## 声明环境变量,使用 $var_name 引用变量
WORKDIR $FOO ##
ADD test.txt tt/ ## 添加 test.txt 到 /bar/tt
RUN /bin/bash -c 'echo ${foo}' ## 执行命令
RUN ["sh", "-c", "echo $HOME"] ## 执行命令
CMD echo "This is a test." | wc - ## 在构建时不执行任何命令
EXPOSE 80/tcp # 暴露 tcp 80 端口
1. FROM
FROM <image>[(:<tag>)|(@<digest>)] [AS <name>] # 指令需从 FROM 开始
2. ARG
指令ARG
用于定义变量,变量通过docker built
命令中的--build-arg <var_name>=<var_value>
参数进行传递。ARG
变量从定义行开始生效,到构建结束时失效。
ARG <name>[=<default value>]
唯一能在 FROM 前的指令,但在 FROM 之前的 ARG 不在构建内,如果要在构建内引用其值,需要重新声明。
# e.g 1
ARG tag=latest
FROM busybox:$tag
ARG tag
RUN echo $tag > image_version
# e.g 2: 所有 From 支持第一个 From 前 ARG 声明的值。
ARG tag=latest
FROM base:$tag
CMD /code/run-app
FROM extras:$tag
CMD /code/run-extras
3. ENV
使用docker inspect
查看。使用docker run --env <key>=<value>
覆盖。指令ENV
为镜像设置持久环境变量(容器中也有效),如果环境变量只在构建中使用,不需要保存在最终镜像,可以为一条命令设置一个值(e.g.1)或使用ARG
(e.g.2)。
ENV <key>=<value> ...
# e.g 1
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...
# e.g 2
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y ...
4. RUN
指令RUN
会在现有镜像最新一层执行命令并提交结果。RUN
有以下两种格式:
#shell form
RUN <command>
# exec form, not invoke a command shell
RUN ["executable", "param1", "param2"]
5.1 CMD
CMD
可以为容器指定默认的可执行性文件(或由ENTRYPOINT
指令指定)。Dockerfile
中只有最后一个CMD
指令有效。CMD
有以下三种格式:
# exec form, preferred
CMD ["executable","param1","param2"]
# as default parameters to ENTRYPOINT
CMD ["param1","param2"]
# shell form
CMD command param1 param2
5.2 ENTRYPOINT
ENTRYPOINT
可以将容器作为可执行文件运行。使用docker run --entrypoint
命令覆盖ENTRYPOINT
。Dockerfile
中只有最后一个ENTRYPOINT
指令有效。ENTRYPOINT
有以下两种格式:
#exec form
ENTRYPOINT ["executable", "param1", "param2"]
#shell form
ENTRYPOINT command param1 param2
命令docker run <image>
的参数会传递给ENTRYPOINT
,并覆盖CMD
指定的内容。另外由于 shell form 是 /bin/sh -c 的子命令,无法传递信号,所以可执行文件无法响应docker stop
命令。
6. ADD
指令ADD
从<src>复制文件、目录等,添加到镜像文件系统的<dest>路径下。<src>可包含符合Go filepath.Match
的通配符。<dest>为绝对路径或相对于WORKDIR
的路径。
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
7. COPY
指令COPY
从<src>复制文件、目录等,添加到容器文件系统的<dest>路径下。<src>可包含符合Go filepath.Match
的通配符。<dest>为绝对路径或相对于WORKDIR
的路径。
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
8. VOLUME
指令VOLUME
用指定的名称创建一个挂载点,并将其标记为来自宿主机或其它容器的外部挂载卷。主机目录(挂载点)只有在容器创建或运行时才能指定,而不能直接在Dockerfile
中直接挂载。
VOLUME ["/data"]
9. WORKDIR
指令WORKDIR
为其后的指令(RUN
, CMD
, ENTRYPOINT
, COPY
, ADD
)设置工作目录。
WORKDIR /path/to/workdir
10. LABEL
LABEL
指令用于向镜像添加元数据。Labels可以从父镜像继承。可以用docker image inspect --format='' <image>
查看镜像标签。
LABEL <key>=<value> <key>=<value> \
...
11. EXPOSE
EXPOSE
用于告知docker,容器在运行时监听的网络端口,指令本身不发布端口,而是在运行时由docker run [-p port|-P]
命令发布覆盖。
EXPOSE <port> [<port>/<protocol>...]
12. USER
USER
用来设置用户名(UID)和用户组(GID)。
USER <user>[:<group>]
USER <UID>[:<GID>]
表3.1 配置指令总结
指令 | 说明 |
---|---|
ARG | 定义创建过程中使用的变量 |
FROM | 指定所创建镜像的基础镜像 |
LABEL | 为生成的镜像添加元数据标签 |
EXPOSE | 声明镜像内服务监听的端口 |
ENV | 指定环境变量 |
ENTRYPOINT | 指定镜像默认的入口命令 |
VOLUME | 创建一个数据卷挂载点 |
USER | 制定容器运行时的用户名或UID |
WORKDIR | 配置工作目录 |
ONBUILD | 创建子镜像时指定自动执行的操作指令 |
STOPSIGNAL | 指定退出的信号值 |
HEALTHCHECK | 配置所启动容器如何进行健康检查 |
SHELL | 指定默认shell类型 |
表3.2 操作指令总结
指令 | 说明 |
---|---|
RUN | 运行指定命令 |
CMD | 启动容器时默认执行的命令 |
ADD | 添加内容到镜像 |
COPY | 复制内容到容器 |
Dockerfile reference
Best practices for writing Dockerfiles
参考
Docker的Pull Digest和Image ID
Docker 教程
Docker1 架构原理及简单使用
Docker整体架构图