目录
一、docker的架构
二、docker的组件
1.docker
2. dockerd
3. docker-init
4. docker-proxy
三、docker容器的生命周期
四、docker的核心概念
五、docker的常用命令
•镜像命令
•容器命令
一、docker的架构
docker 镜像(Images)
docker 镜像是用于创建 Docker 容器的模板。
docker 容器(Container)
容器是独立运行的一个或一组应用,是镜像运行时的实体。
docker 客户端(Client)
Docker 客户端通过命令行或者其他工具使用 Docker SDK
docker 主机(Host)
一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。
docker Registry
docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。
docker daemon
用于监听并处理docker client发送的api请求并且管理docker镜像(images), 容器(container)以及文件结构。同时也用于跟其它docker daemon进行交互
二、docker的组件
1.docker
docker 是 docker 客户端的一个完整实现,它是一个二进制文件,对用户可见的操作形式为 docker 命令,通过 docker 命令可以完成所有的 docker 客户端与服务端的通信。docker 客户端与服务端的交互过程是:docker 组件向服务端发送请求后,服务端根据请求执行具体的动作并将结果返回给 docker,docker 解析服务端的返回结果,并将结果通过命令行标准输出展示给用户。
2. dockerd
dockerd 是 docker 服务端的后台常驻进程,用来接收客户端发送的请求,执行具体的处理任务,处理完成后将结果返回给客户端。docker 客户端可以通过多种方式向 dockerd 发送请求,我们常用的 docker 客户端与 dockerd 的交互方式有三种:
(1)通过 UNIX 套接字与服务端通信:配置格式为unix://socket_path,默认 dockerd 生成的 socket 文件路径为 /var/run/docker.sock,该文件只有 root 用户或者 docker 用户组的用户才可以访问,这就是为什么 docker 刚安装完成后只有 root 用户才能使用 docker 命令的原因。
(2)通过 TCP 与服务端通信:配置格式为tcp://host:port,通过这种方式可以实现客户端远程连接服务端,但是在方便的同时也带有安全隐患,因此在生产环境中如果你要使用 TCP 的方式与 docker 服务端通信,推荐使用 TLS 认证,可以通过设置 Docker 的 TLS 相关参数,来保证数据传输的安全。
(3)通过文件描述符的方式与服务端通信:配置格式为:fd://socketfd,这种格式一般用于 systemd 管理的系统中。docker 客户端和服务端的通信形式必须保持一致,否则将无法通信。UNIX 套接字是 docker 默认的通信方式,如果想要通过远程的方式访问 dockerd,可以在 dockerd 启动的时候添加 -H 参数指定监听的 HOST 和 PORT。
3. docker-init
在 Linux 系统中,1 号进程是 init 进程,是所有进程的父进程。主机上的进程出现问题时,init 进程可以回收这些问题进程。同样的,在容器内部,当业务进程没有回收子进程的能力时,在执行 docker run 启动容器时可以添加 --init 参数,此时 docker 会使用 docker-init 作为1号进程,管理容器内子进程,例如回收僵尸进程等。
#启动一个busybox 容器 但没有添加 --init 参数
[root@model ~]# docker run -it busybox sh
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 sh
7 root 0:00 ps aux
# 1号进程是sh 进程
#启动一个busybox 容器 添加 --init 参数
[root@model ~]# docker run -it --init busybox sh
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 /sbin/docker-init -- sh
7 root 0:00 sh
8 root 0:00 ps aux
#1 号进程变为 /sbin/docker-init
4. docker-proxy
docker-proxy 主要是用来做端口映射的。当我们使用 docker run 命令启动容器时,如果使用了 -p 参数,docker-proxy 组件就会把容器内相应的端口映射到主机上来,底层是依赖于 iptables 实现的
# 启动一个 nginx 容器并把容器的 80 端口映射到主机的 8080 端口
docker run --name=nginx -d -p 8080:80 nginx
# 查看一下启动的容器 IP
docker inspect --format '{{ .NetworkSettings.IPAddress }}' nginx
# 启动的 nginx 容器 IP 为 172.17.0.2
# 查看一下主机上是否有 docker-proxy 进程
sudo ps aux |grep docker-proxy
# docker 创建了一个 docker-proxy 进程,并且通过参数把容器 IP 和端口传递给 docker-proxy 进程,然后 docker-proxy 通过 iptables 实现了 nat 转发
# 查看一下主机上 iptables nat 表的规则
sudo iptables -L -nv -t nat
# 访问主机的 8080 端口时,iptables 会把流量转发到 172.17.0.2 的 80 端口
#curl 命令访问一下 nginx 容器
#curl http://localhost:8080
总结一下:docker 是官方实现的标准客户端,dockerd 是 docker 服务端的入口,负责接收客户端发送的指令并返回相应结果,而 docker-init 在业务主进程没有进程回收功能时则十分有用,docker-proxy 组件则是实现 docker 网络访问的重要组件
三、docker容器的生命周期
①created:已经被创建 (使用 docker ps -a 命令可以列出)但是还没有被启动 (使用 docker ps 命令无法列出)
②running:运行中
③paused:容器的进程被暂停了
④unpaused:容器进程取消暂停状态
⑤restart:容器的进程正在重启过程中
⑥exited:上图中的 stopped 状态,表示容器之前运行过但是现在处于停止状态(要区别于 created 状态,它是指一个新创出的尚未运行过的容器)。可以通过 start 命令使其重新进入 running 状态
⑦destroyed:容器被删除了,再也不存在了
四、docker的核心概念
Docker中有三个核心概念:镜像、容器和仓库。因此,准确把握这三大概念对于掌握Docker技术尤为重要。
1、镜像(Image)
Docker镜像(Image),用来启动容器的模板,镜像一般是存在镜像仓库中的,就相当于是一个root文件系统。比如官方镜像ubuntu:16.04就包含了完整的一套Ubuntu16.04最小系统的root文件系统。
2、容器(Container)
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等
3、仓库(Repository)
用来保存镜像的仓库。当我们构建好自己的镜像之后,需要存放在仓库中,当我们需要启动一个镜像时,可以在仓库中下载下来。
docker 的镜像概念类似虚拟机的镜像。是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。docker利用容器来运行应用:docker容器是由docker镜像创建的运行实例。docker容器类似虚拟机,可以执行包含启动,停止,删除等。每个容器间是相互隔离的。容器中会运行特定的运用,包含特定应用的代码及所需的依赖文件。可以把容器看作一个简易版的linux环境(包含root用户权限,进程空间,用户空间和网络空间等)和运行在其中的应用程序。
在docker的生命周期中,最核心的两个部分,一个是镜像 Images,一个是容器 Containers。
镜像运行起来就是容器。
容器服务运行的过程中,基于原始镜像做了改变,比如安装了程序,添加了文件,也可以提交回去 (commit)成为镜像
docker仓库:如果使用了git和github就很容易理解docker的仓库概念。docker仓库概念和git类似。docker仓库是用来包含镜像的位置,docker提供了一个注册服务器(register)来保存多个仓库,每个仓库又可以包含多个具备不同tag的镜像,docker运作中使用的默认仓库是docker hub公共仓库。仓库支持的操作类似git,当用户创建了自己的镜像之后就可以使用push命令将它上传到共有或者私有的仓库。这样下次再另外一台机器上使用这个镜像的时候只需要从仓库里面pull下来就可以了。