一、docker介绍
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低
主要利用 linux 内核 namespace 实现沙盒隔离,用cgroup 实现资源限制。
namespace:挂载点 主机名和域名 信号量/消息队列/共享内存 进程号 网络设备/网络栈、端口等 用户和组
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。 其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
虚拟化技术依赖物理CPU和内存,是硬件级别的;而docker构建在操作系统上,利用操作系统的containerization技术,所以docker甚至可以在虚拟机上运行。
虚拟化系统一般都是指操作系统镜像,比较复杂,称为“系统”;而docker开源而且轻量,称为“容器”,单个容器适合部署少量应用,比如部署一个redis、一个memcached。
传统的虚拟化技术使用快照来保存状态;而docker在保存状态上不仅更为轻便和低成本,而且引入了类似源代码管理机制,将容器的快照历史版本一一记录,切换成本很低。
传统的虚拟化技术在构建系统的时候较为复杂,需要大量的人力;而docker可以通过Dockfile来构建整个容器,重启和构建速度很快。更重要的是 Dockfile可以手动编写,这样应用程序开发人员可以通过发布Dockfile来指导系统环境和依赖,这样对于持续交付十分有利。
当然KVM对比于容器也有一个比较大的优势就是可以使用不同的操作系统或内核。所以,举例说,你可以使用微软Azure,同时运行Windows Server2012的实例和SUSE Linux企业级服务器的实例。至于Docker,所有容器都必须使用同样的操作系统和内核。
容器的一大特点,与物理机共享内核
docker镜像的特点,为什么要分层?
1、节省空间,同样的镜像只会存一份
2、被保存的镜像是只读的
实验环境
server1 172.25.85.1
二、docker初体验,安装docker并部署一个小游戏
1、安装docker
[root@server1 docker]# ls
container-selinux-2.21-1.el7.noarch.rpm
docker-ce-18.06.1.ce-3.el7.x86_64.rpm
libsemanage-2.5-8.el7.x86_64.rpm
libsemanage-python-2.5-8.el7.x86_64.rpm
pigz-2.3.4-1.el7.x86_64.rpm
policycoreutils-2.5-17.1.el7.x86_64.rpm
policycoreutils-python-2.5-17.1.el7.x86_64.rpm
yum install -y *
[root@server1 ~]# docker version ##查看docker的版本
Client:
Version: 18.06.1-ce
API version: 1.38
Go version: go1.10.3
Git commit: e68fc7a
Built: Tue Aug 21 17:23:03 2018
OS/Arch: linux/amd64
Experimental: false
Server:
Engine:
Version: 18.06.1-ce
API version: 1.38 (minimum version 1.12)
Go version: go1.10.3
Git commit: e68fc7a
Built: Tue Aug 21 17:25:29 2018
OS/Arch: linux/amd64
Experimental: false
2、开启docker
systemctl start docker
3、导入模块
[root@server1 ~]# ls
docker game2048.tar
[root@server1 ~]# docker load -i game2048.tar ##导入模块
011b303988d2: Loading layer 5.05MB/5.05MB
36e9226e74f8: Loading layer 51.46MB/51.46MB
192e9fad2abc: Loading layer 3.584kB/3.584kB
6d7504772167: Loading layer 4.608kB/4.608kB
88fca8ae768a: Loading layer 629.8kB/629.8kB
Loaded image: game2048:latest
[root@server1 ~]# docker images ##查看模块
REPOSITORY TAG IMAGE ID CREATED SIZE
game2048 latest 19299002fdbe 2 years ago 55.5MB
4、开启httpd,运行docker
[root@server1 ~]# systemctl start httpd
[root@server1 ~]# docker run -d --name game -p 8080:80 game2048
e77d29f8c399e4e8803a2138036aa1e1c57a737c3588279ed481464a74b119c3
测试:访问172.35.38.1:8080 ,可以进行游戏
三、docker的一些操作
# docker run -it --name vm1 ubuntu bash ##创建容器
# docker ps -a ###查看容器状态,不加-a表示显示活跃的容器。
# docker attach vm1 ##连接容器。Ctrl+p+q,将当前交互的容器打入后台,使用attach可以连接
# docker top vm1 ##查看容器进程
# docker logs vm1 查看容器指令输出 -f 参数可以实时查看
# docker inspect vm1 查看容器详情
# docker stats vm1 查看容器资源使用率
# docker diff vm1 查看容器修改
# docker run -d --name vm1 ubuntu bash -c "while true; do echo westos; sleep 1; done" 后台运行一个容器
--it i交互 t终端,应用服务无法交互,可以后接bash
--rm 运行完后直接删除
-d 后台运行
# docker stop vm1 停止容器
# docker start vm1 启动容器
# docker kill vm1 强制干掉容器
# docker restart vm1 重启容器
# docker pause/unpause vm1 暂停/恢复容器
# docker rm vm1 删除容器
# docker export vm1 > vm1.tar 导出容器
# docker import vm1.tar image 导入容器为镜像 image
docker load -i vm1.tar 导入镜像
四、docker部署一个nginx
实验之前先关闭源先的容器
docker kill vm1 杀掉一个运行中的容器
docker rm vm1 删除一个或多个容器
docker stop vm1 停止一个运行中的容器
1、导入nginx
[root@server1 ~]# docker load -i nginx.tar
014cf8bfcb2d: Loading layer [==================================================>] 58.46MB/58.46MB
832a3ae4ac84: Loading layer [==================================================>] 53.91MB/53.91MB
e89b70d28795: Loading layer [==================================================>] 3.584kB/3.584kB
Loaded image: nginx:latest
[root@server1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest e548f1a579cf 12 months ago 109MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
2、运行nginx
[root@server1 ~]# docker run -d --name vm1 nginx ##后台运行容器,并返回容器ID
5ff5d13b9a214971bda7d66c9ce9a6e8791d59542db52bc0e4dafa0b3598e57b
3、查看发布地址
[root@server1 ~]# docker inspect 5ff5d13b9a214971bda7d66c9ce9a6e8791d59542db52bc0e4dafa0b3598e57b
[
{
"Id": "5ff5d13b9a214971bda7d66c9ce9a6e8791d59542db52bc0e4dafa0b3598e57b",
"Created": "2019-03-14T11:45:08.027770275Z",
"Path": "nginx",
"Args": [
"-g",
"daemon off;"
。。。。。。。。。
"EndpointID": "186356bb21a2142a60af9211aac8c9e66dd1989d5700ad1883d7f9ade174b342",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
结果:
[root@server1 ~]# curl 172.17.0.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
4、映射端口
在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内部的网络应用和服务的。
运行时做端口映射:将容器的80端口映射到主机的8080端口
[root@server1 ~]# docker stop vm1 ##关闭
vm1
[root@server1 ~]# docker rm vm1 ##删除
vm1
[root@server1 ~]# docker run -d --name vm1 -p 8080:80 nginx ##添加
bb7c8a949128766f93e0adda2e024cd15191f83df2b5d0f117a42297e7d9603d
测试:
[root@server1 ~]# curl 172.17.0.1:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
5、查看指定镜像的创建历史
[root@server1 ~]# docker history nginx
IMAGE CREATED CREATED BY SIZE COMMENT
e548f1a579cf 12 months ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 12 months ago /bin/sh -c #(nop) STOPSIGNAL [SIGTERM] 0B
<missing> 12 months ago /bin/sh -c #(nop) EXPOSE 80/tcp 0B
<missing> 12 months ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22B
<missing> 12 months ago /bin/sh -c set -x && apt-get update && apt… 53.4MB
<missing> 12 months ago /bin/sh -c #(nop) ENV NJS_VERSION=1.13.9.0.… 0B
<missing> 12 months ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.13.9-… 0B
<missing> 13 months ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 13 months ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 13 months ago /bin/sh -c #(nop) ADD file:27ffb1ef53bfa3b9f… 55.3MB
6、在运行docker时,ip会多处一个docker端口
[root@server1 ~]# ip addr
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:b9:85:52:cf brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:b9ff:fe85:52cf/64 scope link
valid_lft forever preferred_lft forever
7、docker exec 在运行的容器中执行命令
[root@server1 ~]# docker exec vm1 ls /usr/share/nginx/html
50x.html
index.html
[root@server1 ~]# docker exec vm1 hostname
bb7c8a949128
8、docker cp 用于容器与主机间的数据拷贝
[root@server1 ~]# cd /tmp/
[root@server1 tmp]# mkdir docker
[root@server1 tmp]# cd docker/
[root@server1 docker]# vim index.html ##编写默认发布目录
[root@server1 docker]# ls
index.html
[root@server1 docker]# docker cp index.html vm1:/usr/share/nginx/html
测试:
[root@server1 docker]# curl 172.17.0.1:8080
<h1>www.shi.org</h1>
9、直接导入默认发布目录
数据卷管理
docker run 在创建容器时使用 -v 参数可以挂载一个或多个数据卷到当前运行的容器中,-v的作用是将宿主机上的目录作为容器的数据卷挂载到容器中,使宿主机和容器之间可以共享一个目录。
挂载数据卷到新创建的容器上:
-v 参数可以重复使用,挂载多个数据卷到容器中,冒号前面的是宿主机的目录(本地目录不存在 ,docker 会自动创建),冒号后面的是容器中的挂载目录
[root@server1 docker]# docker run -d --name vm1 -v /tmp/docker/:/usr/share/nginx/html nginx
83e160c2befd7e91a0f25001aa6a2aebd1852d264a9127e8a5d37d5b6eca1d10
[root@server1 docker]# docker inspect 83e160c2befd7e91a0f25001aa6a2aebd1852d264a9127e8a5d37d5b6eca1d10
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "97e652ccdce160090f32563dbc67eb658967c3465a0e907ce75452cd0d87a469",
"EndpointID": "c705fbdfccdbe230a517052635082b2b6815cf494e4a86d43ce2a941fd6a9b6b",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
测试:
1、访问
[root@server1 docker]# curl 172.17.0.2
<h1>www.shi.org</h1>
2、此时修改index.html里的内容,直接会在容器里生效
[root@server1 docker]# vim /tmp/docker/index.html
[root@server1 docker]# curl 172.17.0.2
<h1>www.wen.org</h1>