什么是容器?
一种虚拟化的方案,操作系统级别的虚拟化,只能运行相同或相似内核的操作系统
docker的容器技术依赖于linux内核特性:namespace和cgroups(control group),所以只能运行linux系统
容器技术的优势
磁盘占用空间更少.因为使用虚拟机部署应用不但包含了应用和其依赖的库,还需要包含完整的操作系统,原本可能只需要几十兆的应用,却需要动着几个G的操作系统来支撑,而容器只需要包含应用和依赖的库,资源占用大大减少,另外虚拟机需要模拟硬件的行为,对内存和cpu的损耗也相当的大,所以同样配置的服务器,使用容器技术比使用虚拟机能够提供更多的服务能力,服务更多的用户.
为啥docker的出现,才真正的让容器技术被关注起来呢?
因为容器技术的复杂性,依赖于linux内核的很多特性,不易安装,不易管理,不易实现自动化,而docker就是为了改变这一切而出现,所以让容器技术被关注了
什么是docker?
将应用程序自动部署到容器的开源引擎
go语言编写
docker目标
提供简单轻量的建模方式(启动快,部署方便,充分利用系统资源)
职责的逻辑分离(开发者只需关心容器中的应用程序,运维人员只需关心如何管理容器)(加强开发人员写代码的开发环境与应用程序要部署的生产环境的一致性)
快速高效的开发生命周期(开发测试生产部署都使用相同的环境,避免了额外的调试和部署上的开销)
鼓励使用面向服务的架构(提倡单个容器运行一个应用程序)(开发思想:高内聚,低耦合,单一任务)
https://blog.lab99.org/post/docker-2016-07-14-faq.html
https://docs-cn.docker.octowhale.com/
docker学习经典链接
docker客户端/守护进程 c/s架构 本地,远程都可以访问
docker镜像 (image)
容器的基石 容器基于镜像启动和运行 镜像就好比容器的源代码,保存了启动容器的各种条件
层叠的只读文件系统: 最低端是一个引导文件系统(bootfs),第二层是root文件系统(rootfs)
联合加载(union mount)
docker 容器(container)
通过镜像启动(怎么通过?在镜像上加载可写层)(容器通过镜像创建)
启动和执行阶段
写时复制(copy on write)
我们在docker中运行的程序,是通过可写层进行的
docker 仓库(registry)
公有 私有
查看内核 uname -a
查看存储驱动 ls -l /sys/class/misc/device-mapper
ubuntu中安装docker的方式
安装ubuntu维护的版本
安装docker维护的版本
安装ubuntu维护的版本(具体google,下面的可能老了)
sudo apt-get install docker.io
source /etc/bash_completion.d/docker.io
安装docker维护的版本(推荐)(具体看链接的)(要配置代理,因为被墙)
http://www.runoob.com/docker/ubuntu-docker-install.html
1.查看apt对https的支持
cat /usr/lib/apt/methods/https
如果不存在,运行安装命令
apt-get isntall apt-transport-https
2.添加docker的apt仓库
echo deb https://get.docker.io/ubuntu docker main\ > /etc/apt/sources.list.d/docker.list
//或者使用下面的命令来设置stable存储库:
//sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
3.添加仓库的key(GPG 密钥)
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
4.安装
apt-get install lxc-docker
因为四部比较复杂,docker提供了shell脚本
apt-get install curl
//curl -sSL https://get.docker.com/ubuntu/ | sudo sh
wget https://get.docker.com/ | sh
sudo groupadd docker
sudo gpasswd -a ${USER} docker
sudO service docker restart
或者:
以非root用户可以直接运行docker时,
需要执行 sudo usermod -aG docker runoob 命令,
然后重新登陆,否则会报错
安装docker维护的版本(centos)
http://www.runoob.com/docker/centos-docker-install.html //安装的是18.06.1-ce
https://docs.docker.com/install/linux/docker-ce/centos/#install-from-a-package
要配置代理,因为被墙
https://www.cnblogs.com/jhj117/p/6148771.html
docker升级
卸载系统安装的docker,再次安装就是新的了
阿里云安装docker
https://help.aliyun.com/document_detail/51853.html //安装的是1.13,可能因为源里面的docker比较旧
Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE。
#.可以查看所有仓库中所有docker版本,并选择特定版本安装
yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 17.09.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.09.0.ce-1.el7.centos @docker-ce-stable
docker-ce.x86_64 17.06.2.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.06.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.06.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.03.2.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.03.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.03.0.ce-1.el7.centos docker-ce-stable
如yum install docker-ce-17.09.0.ce
启动容器
docker run {image} [command] [arg...]
启动交互式容器:
docker run -i -t {image} /bin/bash
另一种创建容器,单未实际启动
docker create ...
https://blog.csdn.net/taiyangdao/article/details/72669201
查看建立的容器
docker ps [-a](所有的) [-l](最新的)
docker inspect id/name
//查看详细
自定义容器名
docker run --naem=ee -i -t {image} /bin/bash
重新启动停止的容器
docker start [-i] id/name
删除停止的容器
docker rm id /name
docker rm $(docker ps -aq)
删除所有停止的容器
第一种启动守护式容器
docker run -i -t {image}/bin/bash
然后ctrl+p ctrl+q
附加到运行中的容器(进入正在运行的容器)
docker attach id/name
第二种启动守护式容器
docker run -d {image}[command] [arg...]
//-d只是在后台运行命令,命令执行完还是会退出,所以后面一般加点让命令不能结束的语句 比如循环和在前台运行啥的
如:docker run -d centos nginx -g "daemon off"
查看容器日志
docker logs [-f][-t][-tail]id/name
-f,–follow跟踪
-t 加上时间
-tail 结尾多少条 默认-tail = all
查看运行中的容器内进程
docker top id/name
在运行中的容器内启动新进程
docker exec [-d][-i][-t] id/name [command] [arg...]
停止守护式容器
docker stop id/name
发出结束的信号,等待结束,返回容器id/name
docker kill id/name
直接杀死容器
重启守护式容器
docker restart id/name
设置容器的端口映射
docker run [-P][-p] {image}
-P 容器中所有端口都映射
-p ip:hostport:containerport
步骤
docker run -p 80 --naem web -i -t centos /bin/bash
容器内:
yum install nginx
简单配置nginx
查看端口映射
docker port id/name
查看docker驱动和位置
docker info
列出镜像
docker images [options] [repository]
option: -a,–all
-f,–force
–no-trunc,
-q,–quiet,只显示id
repository仓库(本地) 和 前面 registry仓库(远程源) 是不同的
tag 标签
查看镜像详细信息
docker inspect [-f] repository:tag
-f,–force
修改镜像repository名称和tag名称
docker tag old_repository:old new_repository:new_tag
删除镜像
docker rmi[-f][--no-prune] {id}/{repository:tag}
-f,–force
–no-prune
docker rmi $(docker images -q)
//删除全部镜像
查找镜像
docker hub 网站查找
命令查找docker search[--automated][--no-trunc][-s] {term}
最多返回 25个结果
-s,–start
拉取镜像
docker pull [-a] name:tag
-a,–all
修改镜像源,镜像加速:(安装的时候已经修改)
cd /etc/docker
vim daemon.json
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
//参数配置是docker守护进程运行时使用的,所以用重启
daocloud网站的源也不错
推送镜像
docker push naem:tag
推的的修改的部分,不是整个镜像,不然人家远程服务器就空间gg了
构建镜像
保存对容器的修改,并再次使用
自定义镜像的能力
以软件的形式打包并分发服务及其运行环境
docker commit [options] {container_id/container_name}
repository[:tag]
-a, --author
-m,–messager
-p,–pause
docker build [options] path|url
–force-rm=false
–no-cache=false
–pull=false
-q,–quiet=false
–rm=true
-t,–tag=“name”
//1.创建dockerfile文件
FROM centos:6.7
MAINTAINER Fisher "[email protected]"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
//每一个指令都会在镜像上创建一个新的层(中间层),每一个指令的前缀都必须是大写的。
//RUN 指令告诉docker 在(以该镜像启动的容器中)/(镜像内)执行命令,安装了什么...
//2.使用docker build
client —> daemoe
命令
remote api
restful api风格
STDIN,STDOUT,STDERR
C/S连接方式:
unix:///var/run/doker.sock
tcp://host:port
fd://socketfd
nc -U /var/run/docker.sock //通过socket建立通信
GET /info HTTP/1.1 //通过remote api方式交互
docker守护进程的配置和操作
//启动
systemctl start docker
//停止
systemctl stop docker
//重启
systemctl restart docker
docker的启动选项
docker -d [options]
-d,守护形式运行
[options]:
https://blog.csdn.net/kikajack/article/details/79518579
https://docs.docker.com/engine/reference/commandline/dockerd/
https://docs.docker.com/config/daemon/
find / -name 'docker.service' -print
(就是通过宿主机的ip访问docker守护进程
服务器启动选项配置,提供远程访问
使用upstart的ubuntu下docker的配置
//修改/etc/default/docker
DOCKER_OPTS="--label name=docker_server_1 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock"
//然后用另一台服务器访问
wget/curl ip:2375 info
//因为unix:///var/run/doker.sock
docker info //还是服务器本地的 不然会出错
但是旧版docker在新版ubuntu配置不成功,这是因为
/etc/default/docker文件是为
upstart和
SysVInit准备的(正如文件第一行注释所言),而使用
service命令时并不会读取它,因此我们可以做如下更改:
在/etc/systemd/system/docker.service.d/Using_Environment_File.conf下添加
EnvironmentFile=-/etc/default/docker
ExecStart=/usr/bin/docker daemon $DOCKER_OPTS
centos下docker配置:(lable必须小写)
//修改/etc/sysconfig/docker文件,在最后增加一行DOCKER_OPTS
DOCKER_OPTS="--label name=docker_server_1 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
//DOCKER_OPTS="-H unix://var/run/docker.sock"
//修改/usr/lib/systemd/system/docker.service
//在[Service]的ExexStart=下面增加一行$DOCKER_OPTS
ExecStart=/usr/bin/dockerd-current \
$DOCKER_OPTS
EnvironmentFile=-/etc/sysconfig/docker
注意:也可以直接在ExecStart后面追加-H unix:///var/run/docker.sock -H 0.0.0.0:2375
新版docker不会自动带有/etc/sysconfig/docker文件,要自己建立
https://blog.csdn.net/jeikerxiao/article/details/78133762
方式2:
在启用服务后
systemctl enable docker
可以直接编辑 /etc/systemd/system/multi-user.target.wants/docker.service 文件来进行配置。
vim /etc/systemd/system/multi-user.target.wants/docker.service
在文件中找到 ExecStart= 这一行,并且在其行尾添加上所需的配置。
//适合使用systemd的ubuntu和centos
可能有点乱,那就不理解上面了:不用理啥系统,都适合的https://icbd.github.io/wiki/notes/2018/03/27/docker-config.html (经典)
客户端配置,访问远程
//方式1
docker -H tcp://ip:2375 info
//方式2
export DOCKER_HOST="tcp://ip:2375"
docker info //就是远程的了
export DOCKER_HOST=""
docker info //本地的了
docker在daemon.json下的配置
https://deepzz.com/post/dockerd-and-docker-remote-api.html (经典)
https://icbd.github.io/wiki/notes/2018/03/27/docker-config.html (经典)
//修改daemon配置:/etc/docker/daemon.json,添加如下行:
{"hosts": ["fd://", "tcp://0.0.0.0:2375"]}
如果重启后发现无法启动
docker
服务,检查一下服务日志,看看是不是之前执行过那些加速器网站的脚本,如果有做过类似的事情,检查一下是不是被建立了/etc/docker/daemon.json
以配置加速器,如果是的话,删掉这个文件,然后在重启服务。使用配置文件是件好事,比如修改配置不必重启服务,只需发送
SIGHUP
信号即可。但需要注意,目前在dockerd
中使用配置文件时,无法输出当前生效配置,并且当dockerd
的参数和daemon.json
文件中的配置有所重复时,并不是一个优先级覆盖另一个,而是会直接导致引擎启动失败。很多人发现配了加速器后 Docker 启动不起来了就是这个原因。解决办法很简单,去掉重复项。不过在这些问题解决前,建议使用修改docker.service
这类做法来实现配置,而不是使用配置文件daemon.json
。方便ps -ef | grep dockerd
一眼看到实际配置情况。
//注释
#xxx
//指令
大写XXX 参数
#First Docker file
FROM ubuntu:14.04
MAINTAINER dormancypress "[email protected]"
RUN apt-get update
RUN apt-get install -y nginx
EXPOSE 80
FROM [:] //第一条必须是它 ,指定基础镜像
MAINTAINER //作者信息
RUN //shell模式
以/bin/sh -c command运行
RUN [“executable”,“param1”,“param2”] //exec模式
RUN ["/bin/bash","-c",“echo hello”] //指定其他形式的shell运行
在镜像构建过程中执行,每个run命令都会在当前镜像上层创建一个镜像来运行命令
EXPOSE […]//执行运行该镜像的容器使用的端口,只是告诉,还是要在run中指定-p参数
CMD
CMD [“executable”,“param1”,“param2”] //exec模式
CMD //shell模式
CMD 指令在容器运行时运行的,并且如果run指定了容器运行时要运行的命令,CMD指令的会被覆盖,不会执行.
CMD [“param1”,“param2”] //作为ENTERYPOINT指令的默认参数
ENTERYPOINT
ENTERYPOINT [“executable”,“param1”,“param2”] //exec模式
ENTERYPOINT //shell模式
和CMD很相似,但是不会被run指定了容器运行时要运行的命令覆盖,但可以使用docker run --entrypoint覆盖
ADD
COPY
都是复制文件
ADD
... ADD[" "..." "](适用于文件路径中有空格的情况)
COPY
... COPY[" ”..." ”](适用于文件路径中有空格的情况) src:本地的相对路径
dest:镜像中的绝对路径
ADD vs COPY
ADD包含类似tar的解压功能
如果单纯复制文件,Docker推荐使用COPY
VOLUME ["/data"] 指定数据卷
WORKDIR 执行容器工作目录
如果使用了相对路径,会一直传递下去
WORKDIR/a
WORKDIR b
WORKDIR c
RUN pwd/a/b/c
ENV 指定环境变量
USER user 指定使用什么用户运行
USER user USER user:group USER user:gid USER uid USER uid:gid USER uid:group
默认是root用户
ONBUILD [instruction]
镜像触发器 当一个镜像被其他镜像作为基础镜像时执行 会在构建过程中插入指令
不会在此次构建中执行,在此次构建的镜像作为基础镜像时才会执行
dockerfile构建过程
从基础镜像运行一个容器
执行一条指令,对容器做出修改
执行类似docker commit的操作,提交一个新的镜像层
再基于刚提交的镜像运行一个新容器
执行Docker中的下一条指令,直至所有指令执行完毕
docker build -t="ee_ubuntu" .
build会删除中间层容器,但是没删除中间层镜像,所以可以进行调试,检查错误
构建缓存:构建过程会缓存,再次同样的构建,就会使用缓存
不使用缓存:docker bulid --no-cache
或者在dockerfile文件中使用ENV REFRESH_DATE 2017-08-0x
的修改来标识缓存刷新的时间,其实就是通过修改使构建过程不一样
查看镜像构建的过程docker history
docker容器的网络基础
docker0: flags=4099 mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:90:ac:ee:eb txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0
linux虚拟网桥 是数据链路层
可以设置ip地址
相当于拥有一个隐藏的虚拟网卡
默认分配 ip 172.17.0.1 netmask 255.255.0.0
ip是三层协议的内容,不应该出现在二层协议的设备上,但是虚拟网桥是通用网络设备抽象的一种,只要是网络设备就可以设置ip
网桥管理工具
bridge-utils工具
命令是brctl
brctl show
修改docker0地址
ifconfig docker0 192.168.200.1 netmask 255.255.255.0
自定义虚拟网桥
添加虚拟网桥
brctl addbr br0
ifconfig br0 192.168.100.1 netmask 255.255.255.0
更改docker守护进程的启动配置
DOCKER_OPTS = "-b br0"
#查看网桥状态
brctl show
#卸载网桥上的端口
brctl delif <网桥名> <端口名>
#删除网桥
brctl delbr <网桥名>
#查看是否有网桥网卡名
ifconfig
#关闭此网卡
ifconfig <网桥名> down
ip link set dev docker0 down //关闭docker0网桥
ip addr add 192.168.100.1/24 dev br0 //设置ip地址
ip link set dev br0 up //启动br0网桥
增加网桥可以通过brctl命令,但是为了简便快捷,配置文件也行
在/etc/sysconfig/network-scripts目录下创建ifcfg-br0文件
docker network命令
docker network所有子命令如下:
docker network create [-d]
docker network connect
docker network ls
docker network rm
docker network disconnect
docker network inspect
应用举例
# 创建三个容器 conTainer1,container2,container3
docker run -itd --name=container1 busybox
docker run -itd --name=container2 busybox
# 创建网络mynet
docker network create -d bridge --subnet 172.25.0.0/16 mynet
# 将容器containerr2连接到新建网络mynet
docker network connect mynet container2
# 使用mynet网络来容器container3
docker run --net=mynet --ip=172.25.3.3 -itd --name=container3 busybox
允许所有容器间互联
配置选项 --icc=true //默认
重启容器,ip刷新改变,造成之前以ip访问的失效,为了避免,采用别名(就是域名)的方式:
docker run --link={container_name}:{alias} ...
//--link:添加了很多别名前辍的环境变量,在host文件中添加了映射
拒绝所有容器间互联
DOCKER_OPTS = "--icc=false"
允许特定容器间的连接
//配置选项
DOCKER_OPTS = "--icc=false --iptables=true"
//启动几个已有的容器
//之前通过--link启动的容器才可以和其链接的容器相互访问
iptable -L -n //查看
iptable -L -n -v
iptable -F //清空
(就是通过宿主机ip访问docker容器的应用服务)
docker守护进程配置参数ip_forward
ip_forward=true //默认允许(流量/数据)转发
sysctl net.ipv4.conf.all.forwarding //系统自带命令,查看是否允许数据转发
iptables
与linux内核集成的包过滤防火墙系统
表(table)
链(chain)
规则(accept,reject,drop)
iptables [-t filter] -L -n
端口映射
docker run -p 80 ...
拒绝某个服务器访问某个容器(就是阻止转发这个服务器的流量)
iptables -I DOCKER -s 源地址 -d 目标地址 -p tcp --dport 80 -j DROP
-I 哪条链
-s 源地址
-d 目标地址
-p 协议
--dport 端口
-j 规则(操作)
docker容器的数据卷
由来:docker的理念之一:就是将应用与其运行的环境打包.所以通常容器的生存周期都是和在容器中运行的程序相一致的,而我们对数据的要求是永久的.另一方面docker容器之间也需要有一个共享数据的渠道
这些需求催生了docker数据卷的产生
什么是数据卷(data volume)
数据卷是经过特殊设计的目录,可以绕过联合文件系统(UFS),为一个或多个 容器提供访问。 数据卷设计的目的,在于数据的永久化,它完全独立与容器的生存周期,因此, Docker不会在容器删除时删除其挂载的数据卷,也不会存在类似的垃圾收集机 制,对容器引用的数据卷进行处理。
//添加数据卷
docker run -v 宿主机中路径:容器中路径 ...
//查看是否挂载数据卷和权限
docker inspect id/name
//为数据卷添加访问权限
docker run -v 宿主机中路径:容器中路径:权限 ...
//删除容器并带数据卷一起
docker rm -v id/name
dockerfile文件
中的VOLUME命令
创建的数据卷是不能映射到本地已经存在的目录或文件的
,会自动创建新的,因此不同的容器创建时映射的目录会不同.(这样怎么共享呢?数据卷容器)
docker的数据卷容器(data container)
docker run --volume-from {container_name} ...
(个人理解)
挂载容器做数据卷
其实就是一个中间媒介,将容器作为数据卷,然后存进容器的数据卷中,
然后通过这个容器的数据卷共享数据,
所以这个容器的数据卷最好通过run添加,可以固定本地目录和自定义名字
容器在这之间的作用仅仅是数据卷配置信息的传递
,
就是将数据卷挂载配置传递到挂载了数据卷的新容器中
docker数据卷备份和还原
//备份
docker run --volumes-from {container_name} -v $(pwd):/backup {image} tar -cvf /backup/backup.tar {container data volume}
//还原
docker run --volumes-from {container_name} -v $(pwd):/backup {image} tar -xvf /backup/backup.tar {container data volume}
使用网桥实现跨主机容器连接
启动选项配置
-b 指定使用自定义网桥 `-b=br0`
--fixed-cidr 限制ip地址分配范围 --fixed-cidr='10.211.60.128/26'
网桥配置
1.brctl+ip xxx命令,临时操作,重启失效,具体谷歌
2.配置网桥文件(centos暂时不会)
使用Open vSwitch实现跨主机容器连接
GRE隧道
GRE:通用路由协议封装、
隧道技术(Tunneling)是一种通过使用互联网络的基础设施在网络之间传递数据的方式。使用隧道传递的数据(或负载)可以是不同协议的数据帧或包。隧道协议将其它协议的数据帧或包重新封装然后通过隧道发送。新的帧头提供路由信息,以便通过互联网传递被封装的负载数据。
//安装ovs
yum install openvswitch
systemctl start openvswitch
操作
ovs-vsctl show //显示
ovs-vsctl add-br obr0 //创建ovs网桥
ovs-vsctl add-port obr0 gre0 //添加gre接口
ovs-vsctl set interface gre0 type=gre options:remote_ip=另一台主机ip(192.168.222.169)
brctl addbr br0
ifconfig br0 192.168.1.1 netmask 255.255.255.0
brctl addif br0 obr0 //为br0网桥添加ovs网桥连接
brctl show
//为不同网段添加路由
ip route add 192.168.2.0/24 via 192.168.222.109 dev eth0
使用weave实现跨主机容器连接
//安装weave
生成Docker的yum源文件
tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
说明:这步可以参考官方文档:https://docs.docker.com/engine/installation/linux/centos/
安装Docker
yum install -y docker-engine
注意:这里是docker-engine而不是docker。
较旧版本的Docker称为docker或docker-engine或docker.io
docker-io包是Debian / Ubuntu用于官方docker发布的名称。
主要原因是避免名称与Ubuntu docker system-tray二进制文件冲突。
http://manpages.ubuntu.com/manpages/precise/man1/docker.1.html
Docker现在有企业版(EE)和免费社区版(CE)
在安装Docker Community Edition之前,您需要删除旧的二进制文件。
Centos的/ RHL:
https://docs.docker.com/engine/installation/linux/docker-ce/centos/
$ sudo yum remove docker \
docker-common \
docker-selinux \
docker-engine
Ubuntu的/ Debian的:
https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/
$ sudo apt-get remove docker docker-engine docker.io
自17年开始,docker分为docker-ce(社区版)、docker-ee(企业版),另外docker-io是较早的版本,通常用的都是docker-ce版;
Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE。
猜测旧版docker根据upstart系统和systemd系统使用不同的配置文件
新版docker 在两种风格下的系统都是同样的配置文件