Docker学习教程(⾮常详细)
转⾃:
⼀、Docker 简介
Docker 两个主要部件:
Docker: 开源的容器虚拟化平台
Docker Hub: ⽤于分享、管理 Docker 容器的 Docker SaaS 平台 --
Docker 使⽤客户端-服务器 (C/S) 架构模式。Docker 客户端会与 Docker 守护进程进⾏通信。Docker 守护进程会处理复杂繁重的任务,例如建⽴、运⾏、发布你的 Docker 容器。Docker 客户端和守护进程可以运⾏在同⼀个系统上,当然你也可以使⽤ Docker 客户端去连接⼀个远程的 Docker 守护进程。Docker 客户端和守护进程之间通过 socket 或者 RESTful API 进⾏通信。
1.1 Docker 守护进程
如上图所⽰,Docker 守护进程运⾏在⼀台主机上。⽤户并不直接和守护进程进⾏交互,⽽是通过 Docker 客户端间接和其通信。
1.2 Docker 客户端
Docker 客户端,实际上是 docker 的⼆进制程序,是主要的⽤户与 Docker 交互⽅式。它接收⽤户指令并且与背后的 Docker 守护进程通信,如此来回往复。
1.3 Docker 内部
要理解 Docker 内部构建,需要理解以下三种部件:
Docker 镜像 - Docker images
Docker 仓库 - Docker registeries
Docker 容器 - Docker containers
Docker 镜像
Docker 镜像是 Docker 容器运⾏时的只读模板,每⼀个镜像由⼀系列的层 (layers) 组成。Docker 使⽤ UnionFS 来将这些层联合到单独的镜像中。UnionFS 允许独⽴⽂件系统中的⽂件和⽂件夹(称之为分⽀)被透明覆盖,形成⼀个单独连贯的⽂件系统。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了⼀个 Docker 镜像,⽐如升级到某个程序到新的版本,⼀个新的层会被创建。因此,不⽤替换整个原先的镜像或者重新建⽴(在使⽤虚拟机的时候你可能会这么做),只是⼀个新 的层被添加或升级了。现在你不⽤重新发布整个镜像,只需要升级,层使得分发 Docker 镜像变得简单和快速。
Docker 仓库⽤来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞⼤的镜像集合供使⽤。这些镜像可以是⾃⼰创建,或者在别⼈的镜像基础上创建。Docker 仓库是Docker 的分发部分。
Docker 容器
Docker 容器和⽂件夹很类似,⼀个Docker容器包含了所有的某个应⽤运⾏所需要的环境。每⼀个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运⾏、开始、停⽌、移动和删除。每⼀个 Docker 容器都是独⽴和安全的应⽤平台,Docker 容器是 Docker 的运⾏部分。
1.4 libcontainer
Docker 从 0.9 版本开始使⽤ libcontainer 替代 lxc,libcontainer 和 Linux 系统的交互图如下:
图⽚来源:
1.5 命名空间「Namespaces」
pid namespace
不同⽤户的进程就是通过 pid namespace 隔离开的,且不同 namespace 中可以有相同 PID。具有以下特征:
每个 namespace 中的 pid 是有⾃⼰的 pid=1 的进程(类似 /sbin/init 进程)
每个 namespace 中的进程只能影响⾃⼰的同⼀个 namespace 或⼦ namespace 中的进程
因为 /proc 包含正在运⾏的进程,因此在 container 中的 pseudo-filesystem 的 /proc ⽬录只能看到⾃⼰ namespace 中的进程因为 namespace 允许嵌套,⽗ namespace 可以影响⼦ namespace 的进程,所以⼦ namespace 的进程可以在⽗ namespace 中看到,但是具有不同的 pid
参考⽂档:
mnt namespace
类似 chroot,将⼀个进程放到⼀个特定的⽬录执⾏。mnt namespace 允许不同 namespace 的进程看到的⽂件结构不同,这样每个namespace 中的进程所看到的⽂件⽬录就被隔离开了。同 chroot 不同,每个 namespace 中的 container 在 /proc/mounts 的信息只包含所在 namespace 的 mount point。
⽹络隔离是通过 net namespace 实现的, 每个 net namespace 有独⽴的 network devices, IP addresses, IP routing tables,
/proc/net ⽬录。这样每个 container 的⽹络就能隔离开来。 docker 默认采⽤ veth 的⽅式将 container 中的虚拟⽹卡同 host 上的⼀个docker bridge 连接在⼀起。
参考⽂档:
uts namespace
UTS ("UNIX Time-sharing System") namespace 允许每个 container 拥有独⽴的 hostname 和 domain name, 使其在⽹络上可以被视作⼀个独⽴的节点⽽⾮ Host 上的⼀个进程。
参考⽂档:
docker进入容器ipc namespace
container 中进程交互还是采⽤ Linux 常见的进程间交互⽅法 (interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然⽽同 VM 不同,container 的进程间交互实际上还是 host 上具有相同 pid namespace 中的进程间交互,因此需要在IPC资源申请时加⼊ namespace 信息 - 每个 IPC 资源有⼀个唯⼀的 32bit ID。
参考⽂档:
user namespace
每个 container 可以有不同的 user 和 group id, 也就是说可以以 container 内部的⽤户在 container 内部执⾏程序⽽⾮ Host 上的⽤户。
有了以上 6 种 namespace 从进程、⽹络、IPC、⽂件系统、UTS 和⽤户⾓度的隔离,⼀个 container 就可以对外展现出⼀个独⽴计算机的能⼒,并且不同 container 从 OS 层⾯实现了隔离。 然⽽不同 namespace 之间资源还是相互竞争的,仍然需要类似 ulimit 来管理每个container 所能使⽤的资源 - cgroup。
Reference
1.6 资源配额「cgroups」
cgroups 实现了对资源的配额和度量。 cgroups 的使⽤⾮常简单,提供类似⽂件的接⼝,在 /cgroup ⽬录下新建⼀个⽂件夹即可新建⼀个 group,在此⽂件夹中新建 task ⽂件,并将 pid 写⼊该⽂件,即可实现对该进程的资源控制。具体的资源配置选项可以在该⽂件夹中新建⼦ subsystem ,{⼦系统前缀}.{资源项} 是典型的配置⽅法, 如 memory.usageinbytes 就定义了该 group 在 subsystem memory
中的⼀个内存限制选项。 另外,cgroups 中的 subsystem 可以随意组合,⼀个 subsystem 可以在不同的 group 中,也可以⼀个group 包含多个 subsystem - 也就是说⼀个 subsystem。
memory
内存相关的限制
cpu
在 cgroup 中,并不能像硬件虚拟化⽅案⼀样能够定义 CPU 能⼒,但是能够定义 CPU 轮转的优先级,因此具有较⾼ CPU 优先级的进程会更可能得到 CPU 运算。 通过将参数写⼊ cpu.shares ,即可定义改 cgroup 的 CPU 优先级 - 这⾥是⼀个相对权重,⽽⾮绝对值
blkio
block IO 相关的统计和限制,byte/operation 统计和限制 (IOPS 等),读写速度限制等,但是这⾥主要统计的都是同步 IO devices
设备权限限制
参考⽂档:
⼆、Docker 安装
docker 的相关安装⽅法这⾥不作介绍,具体安装参考
获取当前 docker 版本
$ sudo docker version
Client version: 1.3.2
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 39fa2fa/1.3.2
OS/Arch (client): linux/amd64
Server version: 1.3.2
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 39fa2fa/1.3.2
三、Docker 基础⽤法
: Docker镜像⾸页,包括官⽅镜像和其它公开镜像
因为国情的原因,国内下载 Docker HUB 官⽅的相关镜像⽐较慢,可以使⽤  镜像,镜像保持和官⽅⼀致,关键是速度块,推荐使⽤。
3.1 Search images
$ sudo docker search ubuntu
3.2 Pull images
$ sudo docker pull ubuntu # 获取 ubuntu 官⽅镜像
$ sudo docker images      # 查看当前镜像列表
3.3 Running an interactive shell
$ sudo docker run -i -t ubuntu:14.04 /bin/bash
docker run - 运⾏⼀个容器
-t - 分配⼀个(伪)tty (link is external)
-i - 交互模式 (so we can interact with it)
ubuntu:14.04 - 使⽤ ubuntu 基础镜像 14.04
/bin/bash - 运⾏命令 bash shell
注: ubuntu 会有多个版本,通过指定 tag 来启动特定的版本 [image]:[tag]
$ docker ps    # 查看当前运⾏的容器
$ docker ps -a #列出当前系统所有的容器
CONTAINER ID        IMAGE              COMMAND            CREATED            STATUS              PORTS              NAMES
6c9129e9df10        ubuntu:14.04        /bin/bash 6 minutes ago      Up 6 minutes                            cranky_babbage
3.4 相关快捷键
退出:Ctrl-Dorexit
detach:Ctrl-P + Ctrl-Q
attach:docker attach CONTAINER-ID
四、Docker 命令帮助
4.1 docker help
docker command
$ sudo docker  # docker 命令帮助
Commands:
attach    Attach to a running container                # 当前 shell 下 attach 连接指定运⾏镜像
build    Build an image from a Dockerfile              # 通过 Dockerfile 定制镜像
commit    Create a new image from a container's changes # 提交当前容器为新的镜像
cp        Copy files/folders from the containers filesystem to the host path
# 从容器中拷贝指定⽂件或者⽬录到宿主机中
create    Create a new container                        # 创建⼀个新的容器,同 run,但不启动容器
diff      Inspect changes on a container's filesystem  # 查看 docker 容器变化
events    Get real time events from the server          # 从 docker 服务获取容器实时事件
exec      Run a command in an existing container        # 在已存在的容器上运⾏命令
export    Stream the contents of a container as a tar archive
# 导出容器的内容流作为⼀个 tar 归档⽂件[对应 import ]
history  Show the history of an image                  # 展⽰⼀个镜像形成历史
images    List images                                  # 列出系统当前镜像
import    Create a new filesystem image from the contents of a tarball
# 从tar包中的内容创建⼀个新的⽂件系统映像[对应 export]
info      Display system-wide information              # 显⽰系统相关信息
inspect  Return low-level information on a container  # 查看容器详细信息
kill      Kill a running container                      # kill 指定 docker 容器
load      Load an image from a tar archive              # 从⼀个 tar 包中加载⼀个镜像[对应 save]
login    Register or Login to the docker registry server
# 注册或者登陆⼀个 docker 源服务器
logout    Log out from a Docker registry server        # 从当前 Docker registry 退出
logs      Fetch the logs of a container                # 输出当前容器⽇志信息
port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
# 查看映射端⼝对应的容器内部源端⼝
pause    Pause all processes within a container        # 暂停容器
ps        List containers                              # 列出容器列表
pull      Pull an image or a repository from the docker registry server
# 从docker镜像源服务器拉取指定镜像或者库镜像
push      Push an image or a repository to the docker registry server
# 推送指定镜像或者库镜像⾄docker源服务器
restart  Restart a running container                  # 重启运⾏的容器
rm        Remove one or more containers                # 移除⼀个或者多个容器
rmi      Remove one or more images
# 移除⼀个或多个镜像[⽆容器使⽤该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]    run      Run a command in a new container
# 创建⼀个新的容器并运⾏⼀个命令
save      Save an image to a tar archive                # 保存⼀个镜像为⼀个 tar 包[对应 load]
search    Search for an image on the Docker Hub        # 在 docker hub 中搜索镜像
start    Start a stopped containers                    # 启动容器
stop      Stop a running containers                    # 停⽌容器
tag      Tag an image into a repository                # 给源中镜像打标签
top      Lookup the running processes of a container  # 查看容器中运⾏的进程信息
unpause  Unpause a paused container                    # 取消暂停容器
version  Show the docker version information          # 查看 docker 版本号
wait      Block until a container stops, then print its exit code
# 截取容器停⽌时的退出状态值
Run 'docker COMMAND --help' for more information on a command.
docker option

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。