Docker学习笔记
➡️了解 Docker
Docker
最初是dotCloud
公司创始人Solomon Hykes
在法国期间发起的一个公司内部项目,它是基于dotCloud
公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在GitHub
上进行维护。Docker
项目后来还加入了Linux基金会
,并成立推动 开放容器联盟(OCI)。
Docker
自开源后受到广泛的关注和讨论,至今其GitHub
项目 已经超过 5 万 2 千个星标和一万多个fork
。甚至由于Docker
项目的火爆,在 2013 年底,dotCloud
公司决定改名为Docker
。Docker
最初是在Ubuntu 12.04
上开发实现的;Red Hat
则从RHEL 6.5
开始对Docker
进行支持;PaaS
产品中广泛应用Docker
。Docker
使用Go
语言 进行开发实现,基于Linux
内核的cgroup
,namespace
,以及AUFS
类的Union FS
等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于LXC
,从0.7
版本以后开始去除LXC
,转而使用自行开发的libcontainer
,从1.11
开始,则进一步演进为使用runC
和containerd
。
➡️Docker 生命周期
Docker 包括三个基本概念
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
容器是由镜像实例化而来的,可以理解成容器是镜像的基础备份,当Docker实例化一个容器时,相当于把这个镜像备份一份,然后在这个备份的基础上启动,开始各种操作。
我们可以把镜像想象成类,把容器想象成类经过实例化后的对象。
➡️Docker 镜像
Docker
的镜像概念类似于虚拟机里的镜像,是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了Mysql或用户需要的其它应用程序。Docker
的镜像实际上由一层一层的文件系统组成,这种层级的文件系统被称为UnionFS。镜像可以基于Dockerfile
构建,Dockerfile
是一个描述文件,里面包含若干条命令,每条命令都会对基础文件系统创建新的层次结构。Docker
提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
注:镜像是只读的,可以理解为静态文件。
镜像是一堆只读层(read-only layer)
的统一视角,那些只读层
重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker
内部的实现细节,并且能够在主机(运行Docker
的机器)的文件系统上访问到。统一文件系统(union file system)
技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
注:Docker
在linux上共享内核,无需虚拟化,完全支持native功能。Docker
在windows上,启用Hyper-V
或者虚拟化技术
,通过虚拟机来实现,不共享windows内核。Docker
在macOS上,同样用虚拟化技术xhyve
或者virtualbox
来实现,不共享macOS内核。
所以,在macOS和Windows下是无法直接访问到镜像的文件的。
➡️Docker 容器
Docker
利用容器来运行应用。容器(container)
和镜像(image)
的几乎一样,区别就是容器
的最上面一层是可读写的
注:相对于镜像来说容器是动态的,容器在启动的时候创建一层可写层作为最上层。
容器的定义并没有提及容器是否在运行。
➡️Running Container Definition
一个运行态容器(running container)
被定义为一个可读写的统一文件系统加上隔离的进程空间和包含其中的进程。
一个容器中的进程对着个容器里的文件进行增加,删除,修改操作都将作用于容器中最上面的那一层可读写层。
➡️Image Layer Definition
镜像层(image layer)
表示一层中的各种零零星星的数据,它并不仅仅包含文件系统的改变,还能包含了其他重要信息。
元数据(metadata)
就是关于这个层的额外信息,它不仅能够让Docker
获取运行和构建时的信息,还包括父层的层次信息。需要注意,只读层和读写层都包含元数据。
除此之外,每一层都包括了一个指向父层的指针。如果一个层没有这个指针,说明它处于最底层。
➡️Docker 仓库
如果你使用过git和github就很容易理解Docker的仓库概念。Docker 仓库的概念跟Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。
Docker 仓库是用来包含镜像的位置,Docker提供一个注册服务器(Register)来保存多个仓库,每个仓库又可以包含多个具备不同tag的镜像。Docker运行中使用的默认仓库是 Docker Hub 公共仓库。
仓库支持的操作类似git,当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。
➡️全局理解(Tying It All Together)
1 | docker create <image-id> |
docker create
命令为指定的镜像(image)
创建了一个可读可写层,构成了一个新的容器。注意,这个容器并没有运行。
1 | docker start <container-id> |
Docker start
命令为容器文件系统创建了一个进程隔离空间。注意,每一个容器只能够有一个进程隔离空间。
1 | docker run <image-id> |
docker start
和docker run
命令的区别。
从图片可以看出,docker run
命令先是利用镜像创建了一个容器,然后运行这个容器。这个命令非常的方便,并且隐藏了两个命令的细节,但从另一方面来看,这容易让用户产生误解。
注:docker run
相当于docker create
和docker start
两个命令的组合。
1 | docker ps |
docker ps
命令会列出所有运行中的容器。这隐藏了非运行态容器的存在。
1 | docker ps –a |
docker ps –a
命令会列出所有的容器,不管是运行的,还是停止的。
1 | docker images |
docker images
命令会列出了所有顶层(top-level)镜像
。实际上,在这里我们没有办法区分一个镜像和一个只读层,所以我们提出了top-level镜像
。只有创建容器时使用的镜像或者是直接pull下来的镜像能被称为顶层(top-level)镜像
,并且每一个顶层镜像下面都隐藏了多个镜像层。
1 | docker images –a |
docker images –a
命令列出了所有的镜像,也可以说是列出了所有的可读层。如果你想要查看某一个image-id
下的所有层,可以使用docker history
来查看。
1 | docker stop <container-id> |
docker stop
命令会向运行中的容器发送一个SIGTERM
的信号,然后停止所有的进程。
1 | docker kill <container-id> |
docker kill
命令向所有运行在容器中的进程发送了一个不友好的SIGKILL
信号。
1 | docker pause <container-id> |
docker stop
和docker kill
命令会发送UNIX的信号给运行中的进程,docker pause
命令则不一样,它利用了cgroups
的特性将运行中的进程空间暂停。但是这种方式的不足之处在于发送一个SIGTSTP
信号对于进程来说不够简单易懂,以至于不能够让所有进程暂停。
1 | docker rm <container-id> |
docker rm
命令会移除构成容器的可读写层。注意,这个命令只能对非运行态容器执行。
1 | docker rmi <image-id> |
docker rmi
命令会移除构成镜像的一个只读层。你只能够使用docker rmi
来移除最顶层(top level layer)
(也可以说是镜像),你也可以使用-f
参数来强制删除中间的只读层。
1 | docker commit <container-id> |
docker commit
命令将容器的可读写层转换为一个只读层,这样就把一个容器转换成了不可变的镜像。
1 | docker build |
docker build
命令会反复的执行多个命令。
build
命令根据Dockerfile
文件中的FROM
指令获取到镜像,然后重复地
run(create和start)
- 修改
- commit
在循环中的每一步都会生成一个新的层,因此许多新的层会被创建。
1 | docker exec <running-container-id> |
docker exec
命令会在运行中的容器执行一个新进程
1 | docker inspect <container-id> or <image-id> |
docker inspect
命令会提取出容器或者镜像最顶层的元数据。
1 | docker save <image-id> |
docker save
命令会创建一个镜像的压缩文件,这个文件能够在另外一个主机的Docker
上使用。和export
命令不同,这个命令为每一个层都保存了它们的元数据。这个命令只能对镜像生效。
1 | docker export <container-id> |
docker export
命令创建一个tar文件,并且移除了元数据和不必要的层,将多个层整合成了一个层,只保存了当前统一视角看到的内容。
注:expoxt
后的容器再import
到Docker
中,通过docker images –tree
命令只能看到一个镜像;而save
后的镜像则不同,它能够看到这个镜像的历史镜像。
1 | docker history <image-id> |
docker history
命令递归地输出指定镜像的历史镜像。
➡️Docker 命令
参考链接➡️Docker run
1 | docker run [OPTIONS] IMAGE [COMMAND] [ARG...] |
OPTIONS说明:
- -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;
- -d: 后台运行容器,并返回容器ID;
- -i: 以交互模式运行容器,通常与 -t 同时使用;
- -P: 随机端口映射,容器内部端口随机映射到主机的高端口
- -p: 指定端口映射,格式为:主机(宿主)端口:容器端口
- -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
- –name=“nginx-lb”: 为容器指定一个名称;
- –dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
- –dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
- -h “mars”: 指定容器的hostname;
- -e username=“ritchie”: 设置环境变量;
- –env-file=[]: 从指定文件读入环境变量;
- –cpuset=“0-2” or --cpuset=“0,1,2”: 绑定容器到指定CPU运行;
- -m :设置容器使用内存最大值;
- –net=“bridge”: 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
- –link=[]: 添加链接到另一个容器;
- –expose=[]: 开放一个端口或一组端口;
- –volume , -v: 绑定一个卷
实例:
1 | 使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。 |
➡️Docker start/stop/restart 命令
docker start
:启动一个或多个已经被停止的容器docker stop
:停止一个运行中的容器docker restart
:重启容器
1 | docker start [OPTIONS] CONTAINER [CONTAINER...] |
实例:
1 | 启动已被停止的容器myrunoob |
➡️Docker attach 命令
docker attach
:连接到正在运行中的容器。
1 | docker attach [OPTIONS] CONTAINER |
要attach上去的容器必须正在运行,可以同时连接上同一个container来共享屏幕(与screen命令的attach类似)。
官方文档中说attach后可以通过CTRL-C来detach,但实际上经过我的测试,如果container当前在运行bash,CTRL-C自然是当前行的输入,没有退出;如果container当前正在前台运行进程,如输出nginx的access.log日志,CTRL-C不仅会导致退出容器,而且还stop了。这不是我们想要的,detach的意思按理应该是脱离容器终端,但容器依然运行。好在attach是可以带上–sig-proxy=false来确保CTRL-D或CTRL-C不会关闭容器。
➡️Docker create 命令
创建一个新的容器
1 | docker create [OPTIONS] IMAGE [COMMAND] [ARG...] |
➡️Options
Name,shorthand | Default | Description |
---|---|---|
–add-host | Add a custom host-to-IP mapping (host:ip) | |
–attach , -a | Attach to STDIN, STDOUT or STDERR | |
–blkio-weight | Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0) | |
–blkio-weight-device | Block IO weight (relative device weight) | |
–cap-add | Add Linux capabilities | |
–cap-drop | Drop Linux capabilities | |
–cgroup-parent | Optional parent cgroup for the container | |
–cidfile | Write the container ID to the file | |
–cpu-count | CPU count (Windows only) | |
–cpu-percent | CPU percent (Windows only) | |
–cpu-period | Limit CPU CFS (Completely Fair Scheduler) period | |
–cpu-quota | Limit CPU CFS (Completely Fair Scheduler) quota | |
–cpu-rt-period | API 1.25+ Limit CPU real-time period in microseconds | |
–cpu-rt-runtime | API 1.25+ Limit CPU real-time runtime in microseconds | |
–cpu-shares , -c | CPU shares (relative weight) | |
–cpus | API 1.25+ Number of CPUs | |
–cpuset-cpus | CPUs in which to allow execution (0-3, 0,1) | |
–cpuset-mems | MEMs in which to allow execution (0-3, 0,1) | |
–device | Add a host device to the container | |
–device-cgroup-rule | Add a rule to the cgroup allowed devices list | |
–device-read-bps | Limit read rate (bytes per second) from a device | |
–device-read-iops | Limit read rate (IO per second) from a device | |
–device-write-bps | Limit write rate (bytes per second) to a device | |
–device-write-iops | Limit write rate (IO per second) to a device | |
–disable-content-trust | true | Skip image verification |
–dns | Set custom DNS servers | |
–dns-opt | Set DNS options | |
–dns-option | Set DNS options | |
–dns-search | Set custom DNS search domains | |
–domainname | Container NIS domain name | |
–entrypoint | Overwrite the default ENTRYPOINT of the image | |
–env , -e | Set environment variables | |
–env-file | Read in a file of environment variables | |
–expose | Expose a port or a range of ports | |
–gpus | API 1.40+ GPU devices to add to the container (‘all’ to pass all GPUs) | |
–group-add | Add additional groups to join | |
–health-cmd | Command to run to check health | |
–health-interval | Time between running the check (ms丨s丨m丨h) (default 0s) | |
–health-retries | Consecutive failures needed to report unhealthy | |
–health-start-period | API 1.29+ Start period for the container to initialize before starting health-retries countdown (ms丨s&丨m丨h) (default 0s) | |
–health-timeout | Maximum time to allow one check to run (ms丨s丨m丨h) (default 0s) | |
–help | Print usage | |
–hostname , -h | Container host name | |
–init | API 1.25+ Run an init inside the container that forwards signals and reaps processes | |
–interactive , -i | Keep STDIN open even if not attached | |
–io-maxbandwidth | Maximum IO bandwidth limit for the system drive (Windows only) | |
–io-maxiops | Maximum IOps limit for the system drive (Windows only) | |
–ip | IPv4 address (e.g., 172.30.100.104) | |
–ip6 | IPv6 address (e.g., 2001:db8::33) | |
–ipc | IPC mode to use | |
–isolation | Container isolation technology | |
–kernel-memory | Kernel memory limit | |
–label , -l | Set meta data on a container | |
–label-file | Read in a line delimited file of labels | |
–link | Add link to another container | |
–link-local-ip | Container IPv4/IPv6 link-local addresses | |
–log-driver | Logging driver for the container | |
–log-opt | Log driver options | |
–mac-address | Container MAC address (e.g., 92:d0:c6:0a:29:33) | |
–memory , -m | Memory limit | |
–memory-reservation | Memory soft limit | |
–memory-swap | Swap limit equal to memory plus swap: ‘-1’ to enable unlimited swap | |
–memory-swappiness | -1 | Tune container memory swappiness (0 to 100) |
–mount | Attach a filesystem mount to the container | |
–name | Assign a name to the container | |
–net | Connect a container to a network | |
–net-alias | Add network-scoped alias for the container | |
–network | Connect a container to a network | |
–network-alias | Add network-scoped alias for the container | |
–no-healthcheck | Disable any container-specified HEALTHCHECK | |
–oom-kill-disable | Disable OOM Killer | |
–oom-score-adj | Tune host’s OOM preferences (-1000 to 1000) | |
–pid | PID namespace to use | |
–pids-limit | Tune container pids limit (set -1 for unlimited) | |
–platform | experimental (daemon)API 1.32+ Set platform if server is multi-platform capable | |
–privileged | Give extended privileges to this container | |
–publish , -p | Publish a container’s port(s) to the host | |
–publish-all , -P | Publish all exposed ports to random ports | |
–read-only | Mount the container’s root filesystem as read only | |
–restart | no | Restart policy to apply when a container exits |
–rm | Automatically remove the container when it exits | |
–runtime | Runtime to use for this container | |
–security-opt | Security Options | |
–shm-size | Size of /dev/shm | |
–stop-signal | SIGTERM | Signal to stop a container |
–stop-timeout | API 1.25+ Timeout (in seconds) to stop a container | |
–storage-opt | Storage driver options for the container | |
–sysctl | Sysctl options | |
–tmpfs | Mount a tmpfs directory | |
–tty , -t | Allocate a pseudo-TTY | |
–ulimit | Ulimit options | |
–user , -u | Username or UID (format: <name丨uid>[:<group丨gid>]) | |
–userns | User namespace to use | |
–uts | UTS namespace to use | |
–volume , -v | Bind mount a volume | |
–volume-driver | Optional volume driver for the container | |
–volumes-from | Mount volumes from the specified container(s) | |
–workdir , -w | Working directory inside the container |