本文主要是对 Docker 的以下内容进行详细介绍:
1、Docker简介
2、Docker安装
3、Docker镜像管理
4、Docker容器管理
5、Docker仓库管理
6、Docker数据管理
7、Docker网络管理
一、Dokcer简介
Docker 是一个开源项目, 诞生于2013年初, 最初是 dotCloud 公司后改名为 Docker lnc内部的一个业余项目。 它基于Google 公司推出的 Go 语言实现。项目后来加入了 Linux 基金会, 遵从了 Apache 2.0 协议, 项目代码在 GitHub 上进行维护。
Docker 唯一的官方的安装方法是 Ubuntu,Redhat 已经在其 RHEL 6.5 中集中支持DockerGoogle也在其 PaaS 产品中广泛应用。不过还要注意 Docker 的局限性其只能运行在64位系统上。
1、Docker与虚拟机对比
1)架构对比
2)性能对比
特性 | Docker | 虚拟机 |
启动速度 | 秒级 | 分钟级 |
磁盘使用 | 一般为MB | 一般为GB |
性能 | 接近原声 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般十几个 |
隔离性 | 安全隔离 | 完全隔离 |
2、Docker核心概念
1)镜像
是一个只读的模板,类似于安装系统用到的那个iso文件,我们通过镜像来完成各种应用的部署。
2)容器
镜像类似于操作系统,而容器类似于虚拟机本身。它可以被启动、开始、停止、删除等操作,每个容器都是相互隔离的。
3)仓库
存放镜像的一个场所,仓库分为公开仓库和私有仓库。
最大的公开仓库是Docker hub(hub.docker.com),国内公开仓库http://dockerpool.com/
二、Docker安装
在 CentOS6 上安装,6.5之前的版本需要升级到6.7,直接 yum update 升级即可。
[root@centos ~]# cat /etc/issue
CentOS release 6.7 (Final) |
[root@centos ~]# uname -a
Linux centos 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux |
1、安装
[root@centos ~]# yum install -y epel-release
[root@centos ~]# yum install -y docker-io
说明:若为CentOS7,直接 yum install -y docker 即可。
2、启动
[root@centos ~]# /etc/init.d/docker start
说明:若为CentOS7,启动命令为 systemctl start docker.service
3、查看进程
[root@centos ~]# ps aux|grep docker
root 22283 3.7 1.2 287820 12172 pts/0 Sl 04:36 0:00 /usr/bin/docker -d root 22409 0.0 0.0 103316 900 pts/0 S+ 04:36 0:00 grep docker |
三、Docker镜像管理
1、镜像基本操作
1)从docker仓库搜索docker镜像
[root@centos ~]# docker search centos //后面是关键词
2)从docker.com获取centos镜像
[root@centos ~]# docker pull centos
3)查看本地都有哪些镜像
[root@centos ~]# docker p_w_picpaths
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos latest bb3d629a7cbc 2 weeks ago 196.6 MB |
4)用下载到的镜像开启容器
[root@centos ~]# docker run -i -t centos /bin/bash //生成一个容器并会进入该容器
说明:-i让容器的标准输入打开,-t分配一个伪终端,要把-i -t 放到镜像名字前面;exit 退出容器。
[root@3863e1a43445 /]# cat /etc/redhat-release //查看系统版本与母机不相同
CentOS Linux release 7.2.1511 (Core) |
[root@3863e1a43445 /]# uname -a //docker是基于内核的虚拟化所以内核与母机相同
Linux 3863e1a43445 2.6.32-573.18.1.el6.x86_64 #1 SMP Tue Feb 9 22:46:17 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux |
5)查看正在运行的容器
[root@centos ~]# docker ps //-a 查看所有容器,包括已经退出的
6)为centos镜像设置标签
[root@centos ~]# docker tag centos mylinux //设置标签为mylinux
说明:再使用 docker p_w_picpaths 查看会多出来一行,该行的 p_w_picpath id 和 centos 的一样。
[root@centos ~]# docker p_w_picpaths
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos latest bb3d629a7cbc 2 weeks ago 196.6 MB mylinux latest bb3d629a7cbc 2 weeks ago 196.6 MB |
7)删除指定镜像
[root@centos ~]# docker rmi mylinux:latest
Untagged: mylinux:latest |
说明:其中后面的参数可以是tag,如果是tag时,实际上是删除该tag,只要该镜像还有其他tag,就不会删除该镜像。当后面的参数为镜像ID时,则会彻底删除整个镜像,连同所有标签一同删除。
2、基于已有镜像的容器创建镜像
之前我们用下载到的镜像开启了一个容器,下面我们对这个容器进行一些更改,比如安装一些软件net-tollswget,然后基于这个容器再创建新的镜像。
[root@centos ~]# docker ps -a //先获取ID
[root@centos ~]# docker start 3863e1a43445 //开启容器后面为ID可简写为386
[root@centos ~]# docker exec -i -t 3863e1a43445 /bin/bash //进入容器
[root@3863e1a43445 /]# yum install -y net-tools wget //安装软件
[root@centos ~]# docker commit -m "centos_net_wget" -a "Msiyuetian" 3863e1a43445 centos_net
说明:创建新的镜像,这个命令有点像 svn 的提交,-m 加一些改动信息,-a 指定作者相关信息3863e1a43445 这一串为容器 id,再后面为新镜像的名字。
[root@centos ~]# docker p_w_picpaths //查看本地的镜像多了一个centos_net
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos_net latest eb2c1259bc74 9 minutes ago 267.9 MB centos latest bb3d629a7cbc 2 weeks ago 196.6 MB |
3、基于本地模板导入创建镜像
1)获取模块直接在网上下载一个模块
[root@centos ~]# wget http://download.openvz.org/template/precreated/centos-6-x86-minimal.tar.gz
2)导入镜像
[root@centos ~]# cat centos-6-x86-minimal.tar.gz | docker import - centos-6-x86_64
[root@centos ~]# docker p_w_picpaths //查看导入的镜像
3)导出镜像把现有镜像导出为一个文件
[root@centos ~]# docker save -o my-centos.tar eb2c1259bc74
说明:把现有 ID 为 eb2c1259bc74 的 centos_net 镜像导出到当前目录下
4)恢复镜像方便迁移或备份
[root@centos ~]# docker rmi eb2c1259bc74 //先删除该镜像
[root@centos ~]# docker load -i my-centos.tar //恢复该镜像ID未变
[root@centos ~]# docker tag eb2c1259bc74 my-centos_net:msiyuetian //打上标签
5)传到dockerhub官网
[root@centos ~]# docker push p_w_picpath_name //前提是先要注册一个用户
四、Docker容器管理
[root@centos ~]# docker p_w_picpaths
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos-6-x86_64 latest ada69856edeb 3 days ago 324 MB my-centos_net msiyuetian eb2c1259bc74 4 days ago 267.9 MB centos latest bb3d629a7cbc 3 weeks ago 196.6 MB |
1、创建容器
1)创建一个容器但该容器并没有启动
[root@centos ~]# docker create -it centos
说明:原镜像创建容器可以不用 /bin/bash
[root@centos ~]# docker create -it centos-6-x86_64 /bin/bash
说明:下载的模板镜像需 /bin/bash
[root@centos ~]# docker create -it my-centos_net:msiyuetian
说明:恢复的镜像继承了之前容器的cmd,故不用 /bin/bash,但该TAG与默认TAG(latest)不同需说明
[root@centos ~]# docker start container_id //启动容器有start 就有stop和restart
2)创建一个容器并启动容器
[root@centos ~]# docker run -i -t centos bash //进入了一个虚拟终端里面
说明:run命令相当于先create再start,我们可以运使用命令exit或者ctrl+d 退出该bash,当退出后这个容器也会停止。
3)创建一个容器启动容器并后台运行
[root@centos ~]# docker run -d //实例如下
[root@centos ~]# docker run -d centos bash -c "while :; do echo "123"; sleep 1; done "
[root@centos ~]# docker run --name web -itd centos bash
说明:--name 给容器自定义名字
[root@centos ~]# docker run --rm -it centos bash -c "sleep 30"
说明:--rm 可以让容器退出后直接删除,在这里命令执行完容器就会退出,不能和-d一起使用。
2、进入一个后台运行的容器
[root@centos ~]# docker attach container_id
说明:进入一个后台运行的容器,attach命令不算好用,比如我们想要退出终端就得exit了,这样容器也就退出了,还有一种方法:
[root@centos ~]# docker exec -i -t container_id bash
说明:可以临时打开一个虚拟终端,并且exit后容器依然运行着。
3、获取容器运行历史信息
[root@centos ~]# docker logs container_id
4、删除容器
[root@centos ~]# docker rm container_id
说明:可以把该container删除,如果是运行的容器可以加-f。
5、导出导入容器
1)导出
[root@centos ~]# docker export container_id > file.tar // 导出容器可以迁移到其他机器上
2)导入
[root@centos ~]# cat file.tar |docker import - test //生成test的镜像
说明:利用导出的容器文件生成新的镜像,然后我们可以用这个镜像创建容器
五、Docker仓库管理
1、搭建私有仓库
首先下载registry 镜像,registry是docker官方提供的一个镜像,可以用它创建本地的docker私有仓库。
[root@centos ~]# docker pull registry //下载registry 镜像
[root@centos ~]# docker run -d -p 5000:5000 registry //以registry镜像启动容器监听5000端口
说明:因为容器和宿主机是隔离的,他们网络不相干,所以做个端口的映射宿主端口:容器端口。
[root@centos ~]# docker ps
注意:因为我们做了映射,所以本机5000端口也是通的,并且可以访问。测试如下:
[root@centos ~]# yum install -y telnet
[root@centos ~]# telnet 127.0.0.1 5000
[root@centos ~]# curl 127.0.0.1:5000 //也可以访问它
2、把镜像上传到私有仓库
[root@centos ~]# docker pull busybox //下载一个小镜像1.1M便于测试
[root@centos ~]# docker tag busybox 192.168.0.109:5000/busybox //标记一下tag
注意:必须要带有私有仓库即宿主机的 ip:port
接着上传带有 ip:port 的镜像到私有仓库
[root@centos ~]# docker push 192.168.0.109:5000/busybox //报如下错误
Error response from daemon: invalid registry endpoint https://192.168.0.109:5000/v0/: unable to ping registry endpoint https://192.168.0.109:5000/v0/ v2 ping attempt failed with error: Get https://192.168.0.109:5000/v2/: EOF v1 ping attempt failed with error: Get https://192.168.0.109:5000/v1/_ping: EOF. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add `--insecure-registry 192.168.0.109:5000` to the daemon's arguments. In the case of HTTPS, if you have access to the registry's CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/192.168.0.109:5000/ca.crt |
说明:这是因为Docker从1.3.X之后与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。为了解决这个问题需要在启动docker server时,增加启动参数为默认使用http访问。解决该问题的方法为:
[root@centos ~]# vim /etc/init.d/docker
把 $exec -d $other_args 改为 $exec -d --insecure-registry 192.168.0.109:5000 $other_args |
[root@centos ~]# service docker restart //重启docker服务
[root@centos ~]# docker start b91a9860dd9e //再启动registry容器docker ps -a 查看 id
重新上传镜像到私有仓库
[root@centos ~]# docker push 192.168.0.109:5000/busybox
The push refers to a repository [192.168.0.109:5000/busybox] (len: 1) Sending p_w_picpath list Pushing repository 192.168.0.109:5000/busybox (1 tags) 56ed16bd6310: Image successfully pushed bc744c4ab376: Image successfully pushed Pushing tag for rev [bc744c4ab376] on {http://192.168.0.109:5000/v1/repositories/busybox/tags/latest} |
查看私有仓库里面的所有镜像
[root@centos ~]# curl http://192.168.0.109:5000/v1/search
{"num_results": 1, "query": "", "results": [{"description": "", "name": "library/busybox"}]} |
六、Docker数据管理
1、挂载本地的目录到容器里
容器创建时,默认是挂载本地的 /etc/hosts 目录到容器中,存取数据都在该目录下进行。如下查看:
[root@centos ~]# docker start 3863e1a43445 //开启一个之前创建的centos容器
[root@centos ~]# docker exec -it 3863e1a43445 bash //进入该容器
[root@3863e1a43445 /]# df -h
下面我们在创建容器的时候自定义挂载目录 /dockerdata/,后续容器存取数据都在该目录下进行。
[root@centos ~]# mkdir /dockerdata
[root@centos ~]# echo "msiyuetian.blog.51cto.com" > /dockerdata/1.txt //测试文件
[root@centos ~]# docker run -itd -v /dockerdata/:/data centos bash
07f4d62dc8ec45c2d85d6e7155f2d1596d190fca3eb8be4209923c1175852810 |
说明:-v 用来指定挂载目录: 前面的/dockerdata/为本地目录: 后面的/data/为容器里的目录
[root@centos ~]# docker exec -it 07f4d62dc8ec bash //进入该容器
[root@07f4d62dc8ec /]# df -h
容器/data/目录下的文件和宿主机/dockerdata/目录下文件相同
我们在容器/data/目录下新建一个文件同样在宿主机/dockerdata/目录下可查看到该文件
2、挂载数据卷
其实我们挂载目录的时候,可以指定容器name,如果不指定就随机定义了。比如上面我们没有指定它,就生成了一个名字为 prickly_jang这个名字,可以使用命令 docker ps 看最右侧 NAMES 列。同时我们也可以创建新的容器时,共同使用之前容器的数据卷,操作如下:
1)新建容器自定义容器名和数据卷
[root@centos ~]# docker run -itd --name testname --volumes-from prickly_jang centos bash
1aa408830e6bd86a42ae9d9787555c272a22f6610f00549a92f464ac49ca01db |
说明:--volumes-from 定义的数据卷来源容器名,--name 定义新建容器的名字,这样我们使用centos 镜像创建了新的容器 testname,并且使用了 prickly_jang 容器的数据卷。
2)查看自定义名字
3)查看数据卷是否同步
在 testname 容器 /data/ 目录下新建一个文件 3.txt
在 prickly_jang 容器 /data/ 目录下查看是否有 3.txt 文件
在宿主机 /dockerdata/ 目录下查看是否有 3.txt 文件
3、定义数据卷容器
有时候我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。
1)建立数据卷容器
[root@centos ~]# docker run -itd -v /data/ --name web centos bash
3f8c7445a77ff42d62999f7728aeb1a344eebe3abbf6cd657b3f3b48d58df686 |
注意:这里 -v 定义的/data/是容器的/data/目录,与本地宿主机的/data/目录无关。
2)让其他容器挂载该数据卷
[root@centos ~]# docker run -itd --name web1 --volumes-from web centos bash
aba4ccf51ae25f9da2b89462ad6a837f60ef9dc762069583fa2ad73a73d33048 |
4、数据卷的备份与恢复
1)备份
思路:首先我们需要使用 web 容器的数据卷新开一个容器 web2,这样就实现了 web2 容器挂载了 web 容器分享的数据卷 /data/ 目录,同时我们还需要把本地宿主机的 /dockerdata_backup/ 目录挂载映射到 web2 容器的 /backup 下,这样在 web2 容器中 /backup 目录里面新建的文件,我们就可以直接在本地宿主机的 /dockerdata_backup/ 目录中看到了,然后再把 /data/ 目录下面的文件打包成 data.tar 文件放到 /backup 目录下面。这样就实现了对 web 容器下 /data/ 目录进行备份。操作如下:
[root@centos ~]# mkdir /dockerdata_backup
[root@centos ~]# docker run -itd --name web2 --volumes-from web -v /dockerdata_backup/:/backup centos bash
7265ac13a2e2a10744ff3eecf9b8c53b3185f89a482ee1c2da95fccc7d0e171e |
[root@centos ~]# docker exec -it web2 bash
[root@7265ac13a2e2 /]# tar cvf /backup/data.tar /data/
2)恢复
思路:先新建一个数据卷容器 web3,再建一个新的容器 web4,并挂载容器 web3 的数据卷,然后再把tar包解包。
新建数据卷容器web3
[root@centos ~]# docker run -itd -v /data/ --name web3 centos bash
9317b5f32c7ac55cbb2ed5c219762a64f8202f3074fc505dc6d490d5d2535243 |
挂载数据卷到新建容器web4
[root@centos ~]# docker run -itd --name web4 --volumes-from web3 -v /dockerdata_backup/:/backup centos bash
4191222a33265c5358b1a77022e72d352fd25d0ca8142af73772a4d503fcddb3 |
[root@centos ~]# docker exec -it web4 bash
[root@4191222a3326 /]# tar xvf /backup/data.tar -C .
七、Docker网络管理
1、四种网络模式
1)host模式
使用 docker run 时,用 --net=host 指定 docker 使用的网络,实际上和宿主机一样,在容器内看到的网卡ip是宿主机上的ip
[root@centos ~]# docker run -it --rm --net=host my-centos_net:msiyuetian bash
2)container模式
使用 --net=container:container_id/container_name 多个容器使用共同的网络看到的ip是一样的
3)none模式
使用--net=none,指定这种模式下不会配置任何网络
4)bridge模式
使用 --net=bridge 指定默认模式不用指定默认就是这种网络模式。这种模式会为每个容器分配一个独
立的 Network Namespace。类似于 vmware 的 nat 网络模式。同一个宿主机上的所有容器会在同一个网段下相互之间是可以通信的。
2、外部网络访问容器
1)首先使用 centos 镜像新建一个容器,然后在该容器中 yum 安装 httpd 服务并启动,再把该容器导成一个新的镜像(centos-httpd):
[root@centos ~]# docker ps -a //先获取ID
[root@centos ~]# docker start a8d764bc4f9e //开启容器
[root@centos ~]# docker exec -it a8d764bc4f9e bash //进入容器
[root@centos /]# yum install -y httpd //安装软件
[root@centos /]# exit
[root@centos ~]# docker commit -m "centos_httpd" -a "Msiyuetian" a8d764bc4f9e centos_httpd:msiyuetian
2)然后再使用新镜像创建新容器并指定端口映射:
[root@centos ~]# docker run -itd -p 5123:80 centos_httpd:msiyuetian bash
de11aa626b547438155fd901308c7eab91e640af93f2aee81dfb74d2481d1cf0 |
说明:因为只有在容器启动的时候才会映射成功,-p 可以指定端口映射本例中将容器的 80 端口映射为本地的 5123 端口。
3)进入新容器
[root@centos ~]# docker exec -it de11aa626b54 bash
[root@de11aa626b54 /]# httpd -k start //centos7启动httpd的命令,可用netstat命令查看
[root@de11aa626b54 /]# vi /var/www/html/test.html //新建测试文件
http://msiyuetian.blog.51cto.com |
4)测试映射效果
[root@de11aa626b54 /]# curl localhost/test.html //容器内解析测试文件
http://msiyuetian.blog.51cto.com
[root@de11aa626b54 /]# exit
[root@centos ~]# curl 192.168.0.112:5123/test.html //本地解析测试文件
http://msiyuetian.blog.51cto.com
3、容器互联
其实在同一个宿主机下的容器是可以通过IP地址相互访问的,所以容器互联这个没什么太大的作用,只不过实现互联后我们可以通过容器名字来通信。下面实例是web与mysql互联:
1)做一个mysql镜像
[root@centos ~]# docker run -itd centos-6-x86_64 bash
51b6748fb50de05691aad52a7d8084eada303bdffeaaebb5a7d53c69de18867c |
[root@centos ~]# docker exec -it 51b6748fb50d bash
[root@51b6748fb50d /]# yum install -y mysql-server
[root@51b6748fb50d /]# exit
[root@centos ~]# docker commit -m "centos_mysqld" -a "Msiyuetian" 51b6748fb50d centos_mysql
2)新建一个容器命名为db
[root@centos ~]# docker run -itd -p 13306:3306 --name db mysql bash
[root@centos ~]# docker exec -it db bash
root@40ceb16da189:/# /etc/init.d/mysql start
3)在新建一个web容器并和db互联
[root@centos ~]# docker run -itd -p 18080:80 --name web --link db:db centos_httpd:msiyuetian bash
[root@centos ~]# docker exec -it web bash
root@7893f7a639dd:/# cat /etc/hosts //最后一行可看到
172.17.0.3 db 40ceb16da189 db |
4、配置桥接网络
为了使本地网络中的机器和 Docker 容器更方便的通信,我们经常会有将 Docker 容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将 Docker 容器和宿主机的网卡桥接起来再给 Docker 容器配上 IP 就可以了。
1)centos6按照下面的方法操作:
[root@centos ~]# cd /etc/sysconfig/network-scripts/
[root@centos ~]# cp ifcfg-eth0 ifcfg-br0
[root@network-scripts]# vim ifcfg-eth0 //添加标红处,删除网络设置
DEVICE=eth0 HWADDR=00:0C:29:96:5E:F4 TYPE=Ethernet UUID=94a84b5d-74d2-4c11-8df7-b524f456e5c1 ONBOOT=yes NM_CONTROLLED=yes BRIDGE=br0 BOOTPROTO=none |
[root@network-scripts]# vim ifcfg-br0 //修改标红处,其余按照 eth0 的网络设置保持不变
DEVICE=br0 TYPE=Bridge ONBOOT=yes NM_CONTROLLED=yes BOOTPROTO=static IPADDR=192.168.0.112 NETMASK=255.255.255.0 GATEWAY=192.168.0.1 DNS1=192.168.0.1 DNS2=8.8.8.8 |
[root@network-scripts]# service network restart
安装pipwork:
[root@centos ~]# yum install -y git
[root@centos ~]# git clone https://github.com/jpetazzo/pipework
[root@centos ~]# cp ~/pipework/pipework /usr/local/bin/
开启一个容器:
[root@centos ~]# docker run -itd --net=none --name msiyuetian centos /bin/bash
[root@centos ~]# rpm -Uvh https://repos.fedorapeople.org/openstack/EOL/openstack-grizzly/epel-6/iproute-2.6.32-130.el6ost.netns.2.x86_64.rpm
说明:升级 iproute,若不安装,执行pipework命令会报错Object "netns" is unknown, try "ip help"
[root@centos ~]# pipework br0 msiyuetian 192.168.0.102/24 //给容器设置IP
[root@centos ~]# docker exec -it msiyuetian /bin/bash
进去后ifconfig查看就可以看到新添加的ip
2)centos7按照下面的方法操作:
安装pipwork
#git clone https://github.com/jpetazzo/pipework
#cp ~/pipework/pipework /usr/local/bin/
开启一个容器
#docker run -itd --net=none --name msiyuetian centos /bin/bash
#pipework br0 msiyuetian 192.168.0.102/24@192.168.0.112 #102为容器的ip@后面的ip为宿主机ip
#brctl addif br0 eth0 #eth0为宿主机网卡这一步为把br0和eth0桥接起来
#ip addr add 192.168.0.112/24 br0 #把112的ip绑定在br0上
#docker exec -it msiyuetian /bin/bash #进去后ifconfig查看就可以看到新添加的ip