(一)Docker的简单介绍
首先,我先说一下什么是Linux容器?
Linux容器不是模拟一个完整的操作系统,而是对进程进行隔离,就像是给正常的进程外面套了一个保护层,对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。它相比虚拟机来说,因为是进程级别的,所以有很多优势:启动快、资源占用少、体积小;
那么Docker和Linux容器是什么关系?
Docker属于Linux容器一种封装,提供简单易用的容器使用接口;它将应用程序与该程序的依赖大宝在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机运行一样;总体来说,Docker的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器,另外,它还可以进行版本管理、复制、分享、修改就像管理普通的代码一样;
(二)Docker的安装及简单应用
1、实验环境:
- 物理机的IP为: 172.25.45.250 (rhel7.3)
- 防火墙关闭
- selinux设置为disabled
2、实验操作:
首先官网下载软件
docker-engine-17.03.1.ce-1.el7.centos.x86_64.rpm
docker-engine-selinux-17.03.1.ce-1.el7.centos.noarch.rpm
1、装包
[root@foundation45 ~]# rpm -ivh docker-engine-17.03.1.ce-1.el7.centos.x86_64.rpm docker-engine-selinux-17.03.1.ce-1.el7.centos.noarch.rpm
Preparing... ################################# [100%]
Updating / installing...
1:docker-engine-selinux-17.03.1.ce-################################# [ 50%]
setsebool: SELinux is disabled.
libsemanage.semanage_direct_install_info: Overriding docker module at lower priority 100 with module at priority 400.
2:docker-engine-17.03.1.ce-1.el7.ce################################# [100%]
2、开启docker服务
[root@foundation45 ~]# systemctl start docker
A:下面我们利用docker做个简单的测试,搭建一个简单的网页游戏;
第一步,下载game2048.tar(2048游戏包);
[root@foundation45 Desktop]# docker load -i game2048.tar
011b303988d2: Loading layer 5.05 MB/5.05 MB
36e9226e74f8: Loading layer 51.46 MB/51.46 MB
192e9fad2abc: Loading layer 3.584 kB/3.584 kB
6d7504772167: Loading layer 4.608 kB/4.608 kB
88fca8ae768a: Loading layer 629.8 kB/629.8 kB
Loaded image: game2048:latest
[root@foundation45 Desktop]# docker run -d --name wkn game2048 ##其中-d 打入后台;--name命名;run相当于create一个命名为wkn的容器,并start;
1df97a36bcabd23f3413fd9c1179bb474b6a8d65c5795b07c246ed5c76924756
[root@foundation45 Desktop]# ip addr ##我们可以看到ip addr查看,多出来一个docker0的网关
9: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
inet 172.17.0.1/16 scope global docker0 ##内部的容器通信
valid_lft forever preferred_lft forever
inet6 fe80::42:cdff:fe89:3a1/64 scope link
valid_lft forever preferred_lft forever
[root@foundation45 images]# docker ps ##查看当前容器的进程
1df97a36bcab game2048 "/bin/sh -c 'sed -..." 11 minutes ago Up 11 minutes 80/tcp, 443/tcp wkn
[root@foundation45 Desktop]# docker inspect wkn ##查看当前wkn容器的信息
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DiskQuota": 0,
"KernelMemory": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": -1,
"OomKillDisable": false,
"PidsLimit": 0,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0
},
"GraphDriver": {
"Name": "overlay",
"Data": {
"LowerDir": "/var/lib/docker/overlay/d8459c263b25cd330c31edee9cb195dbc41d24dce37dcfb7aea52e7fb65f6375/root",
"MergedDir": "/var/lib/docker/overlay/ce8d48858d471a8ca736fd2af4d2fce414690e99b4dfb01cfa67fadf2ca0727a/merged",
"UpperDir": "/var/lib/docker/overlay/ce8d48858d471a8ca736fd2af4d2fce414690e99b4dfb01cfa67fadf2ca0727a/upper",
"WorkDir": "/var/lib/docker/overlay/ce8d48858d471a8ca736fd2af4d2fce414690e99b4dfb01cfa67fadf2ca0727a/work"
}
},
"Mounts": [],
"Config": {
"Hostname": "1df97a36bcab",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"443/tcp": {},
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.11.7"
],
"Cmd": [
"/bin/sh",
"-c",
"sed -i \"s/ContainerID: /ContainerID: \"$(hostname)\"/g\" /usr/share/nginx/html/index.html && nginx -g \"daemon off;\""
],
"ArgsEscaped": true,
"Image": "game2048",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "ce83a0d0d8332462e459bf978909eee1011cf3aa37fae8d4bd6026da0936a832",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"443/tcp": null,
"80/tcp": null
},
"SandboxKey": "/var/run/docker/netns/ce83a0d0d833",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "dd110fa9a7ad307ce272c28eab9f711bc96d7d8b49c4d28835f9cd430e0a4b71",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "d37d53c872d7b70e043628e6ff760f2921b238e7b2ce2e8eb9fa4f27040ca440",
"EndpointID": "dd110fa9a7ad307ce272c28eab9f711bc96d7d8b49c4d28835f9cd430e0a4b71",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",##我们可以看到当前容器的有效IP为172.17.0.2
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02"
}
}
}
}
]
注:对于容器而言,它的IP数是随着容器的数目而递增的;如,如果我先创建了容器vm1,它的IP为172.17.0.2;那么再创建一个容器vm2,它的IP将会为172.17.0.3;依次类推......
浏览器访问172.17.0.2:
一个简单的网页游戏i就搭建好了。
我们来了解一下常用的docker命令:
docker ps -a ##查看当前所有容器的状态(包括没有运行的)
docker ps ##查看当前正再使用的容器状态
docker attach vm1 ##连接容器vm1
docker top vm1 ##查看容器进程
docker inspect vm1 ##查看容器详情
docker stats vm1 ##查看容器资源使用率
docker diff vm1 ##查看容器的修改
docker stop vm1 ##停止容器
docker start vm1 ##启动容器
docker kill vm1 ##强制干掉容器
docker pause/unpause vm1 ##暂停/恢复容器
docker run -d --name vm1 ubuntu ##-d后台运行容器,并返回容器ID;
docker run -it --name vm1 ubuntu bash ##创建容器,并与其进行bash交互;-i 以交互模式运行容器,通常与t一起使用;-t 为容器重新分配一个伪输入终端;
docker rm vm1 ##删除容器
docker export vm1 > vm1.tar ##导出容器
docker import vm1.tar image ##导入容器为镜像 image
docker rmi nginx ##删除镜像
docker images ##查看本地所有镜像
docker inspect ubuntu ##查看容器详情
docker save ubuntu > ubuntu.tar ##导出镜像
docker load -i ubuntu.tar ##导入镜像
docker search ##查询镜像
docker pull ##拉取镜像
docker push ##推送镜像
注:如果要退出bash有2种操作:1)Ctrl + d 退出并停止容器;2)Ctrl + p +q 退出并在后台运行容器; 想要了解更多命令: docker --help
镜像管理:
镜像用来创建容器,是容器的只读模板;
为了之后方便,可以更快速下载镜像,我们可以搭建一个镜像加速器;
首先,大家先注册一个阿里云帐号,(加速器需要和 Daocloud ID 绑定才能正常工作)
登陆后,选择控制台:
点击你的操作系统类型 ,安装操作文档完成设置:
[root@foundation45 Desktop]# mkdir -p /etc/docker
[root@foundation45 Desktop]# cd /etc/docker/
[root@foundation45 docker]# ls
key.json
[root@foundation45 docker]# vim daemon.json
{
"registry-mirrors": ["https://0ntw8ss1.mirror.aliyuncs.com"]
}
[root@foundation45 docker]# systemctl daemon-reload
[root@foundation45 docker]# systemctl restart docker
##完成之后,拉取镜像测试一下(这种方式很耗费流量,但是方便快捷):
[root@foundation45 docker]# docker pull nginx ##拉取镜像成功
Using default tag: latest
latest: Pulling from library/nginx
be8881be8156: Pull complete
32d9726baeef: Pull complete
87e5e6f71297: Pull complete
Digest: sha256:d85914d547a6c92faa39ce7058bd7529baacab7e0cd4255442b04577c4d1f424
Status: Downloaded newer image for nginx:latest
[root@foundation45 docker]# docker images nginx ##可以看到本地有一个nginx镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest c82521676580 3 weeks ago 109 MB
[root@foundation45 docker]# docker run -d --name vm1 nginx ##创建容器vm1.运行并打入后台
cf0b2cf50f56d370fc4dccaa420e6d179464fc38a43c130352d0fceb57e0d310
[root@foundation45 ~]# vim index.html ##编辑默认发布文件
[root@foundation45 ~]# docker cp index.html vm1:/usr/share/nginx/html ##将文件内容拷贝到容器vm1的nginx发布目录下
浏览器查看:
但是这种方式由缺陷:每一次index.html文件更改都要再给vm1发送一次,很麻烦;还有一种方式,将文件index.html直接挂载在vm1的nginx发布目录下,这样即改即生效;
[root@foundation45 web]# docker rm -f vm1
vm1
[root@foundation45 web]# docker run -d --name vm1 -v /tmp/docker/web:/usr/share/nginx/html nginx ##挂载
0b70bea92a3b4a5dab665a49366f815b7b6c856c240ed53476ed144b6a6ff45
[root@foundation45 ~]# mkdir /tmp/docker/web -p
[root@foundation45 ~]# mv index.html /tmp/docker/web
[root@foundation45 web]# vim index.html
浏览器查看:
学习了这么多后,我们还可以有第二种办法
搭建这个2048小游戏平台!!
如果镜像是通过docker pull在官方镜像拉取得到的,想要玩2048小游戏,可以通过以下方式:
- docker pull docker pull registry.cn-hangzhou.aliyuncs.com/what_oo/game2048 (这个是公有地址)
- docker run -d --name vm1 registry.cn-hangzhou.aliyuncs.com/what_oo/game2048
- docker export vm1 > game2048.tar
- mv game2048.tar /var/www/html
- mkdir /var/www/html/game2048
- tar xvf game2048.tar -d /var/www/html/game2048
- docker inspect vm1 ##查询当前的容器IP
- 在物理机的浏览器输入此IP,就可以看见2048小游戏的画面啦!
数据卷的管理
docker run 在创建容器时使用 -v 参数可以挂载一个或多个数据卷到当前运行的容器中, -v 的作用是将宿主机上的目录作为容器的数据卷挂载到容器中,使宿主机和容器之间可以共享一个目录;而且-v 参数可以重复使用,挂载多个数据卷到容器中,冒号前面的是宿主机的目录(本地目录
不存在 docker 会自动创建),冒号后面的是容器中的挂载目录。
(1)挂载数据卷到新创建的容器上:
[root@foundation45 images]# docker load -i rhel7.tar ##导入镜像到本地
e1f5733f050b: Loading layer 147.1 MB/147.1 MB
[root@foundation45 images]# docker run -it --name vm1 -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro -v /etc/yum.repos.d/yum.repo:/etc/yum.repos.d/yum.repo:ro rhel7 bash ##指定容器内目录与宿主机(物理机)目录共享;其中data1是默认读写挂载;data2是只读挂载;打开了一个新的shell
bash-4.2#
测试:
##data1有读写权限
bash-4.2# cd /data1/
bash-4.2# touch file1
bash-4.2# ls
file1
bash-4.2# rm -fr file1
bash-4.2# ls
##data2只有读的权限
bash-4.2# cd /data2
bash-4.2# ls
file1 file2 file3 file4
(2)容器卷的备份:
[root@foundation45 images]# docker load -i ubuntu.tar
[root@foundation45 data2]# docker create --name datavol -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro -v /etc/yum.repos.d/yum.repo:/etc/yum.repos.d/yum.repo:ro
rhel7 bash ##创建数据卷容器datavol,但是未激活;将物理机的/tmp/data1挂载到/data1;
52cba109b4dff101e1bdd45f30e3b9756d2b19d6be90f9606ffbfa93622a8d18
[root@foundation45 data2]# docker ps ##当前并没有运行的容器
CONTAINER ID IMAGE COMMAND CREATED
[root@foundation45 data2]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
52cba109b4df rhel7 "bash" 16 seconds ago Created datavol
[root@foundation45 data2]# docker run --rm -v /tmp/backup:/backup ubuntu tar cf /backup/etc.tar /etc ##备份镜像;
tar: Removing leading `/' from member names
[root@foundation45 data2]# cd /tmp/backup
[root@foundation45 backup]# ls
etc.tar
[root@foundation45 data2]# docker run -it --name vm2 -v /tmp/backup:/backup rhel7 bash
bash-4.2# cd backup/
bash-4.2# ls
etc.tar