DOCKER
http://www.runoob.com/docker/docker-command-manual.html docker命令大全
镜像用来创建容器,是容器的只读模板,默认可以从 docker hub 上下载。docker 的镜像是
增量修改,每次创建新的镜像都会在父镜像上构建一个增量的层,基于 AUFS 技术。镜像默认可以从 docker hub 上下载,这是 docker 官方的公共仓库,为我们免费提供了大量已经容器化的应用镜像
Docker 是一个开源的应用容器引擎,主要利用 linux 内核 namespace 实现沙盒隔离,用
cgroup 实现资源限制。Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。
1,安装docker
真机
yum install -y docker-engine-17.03.1.ce-1.el7.centos.x86_64.rpm docker-engine-selinux-17.03.1.ce-1.el7.centos.noarch.rpm
systemctl start docker
如果安装报错:
采用rhel7.3的yum源
2,docker常用命令
[root@foundation28 rhel7.3]# docker version
[root@foundation28 rhel7.3]# docker info
[root@foundation28 rhel7.3]# docker
build events images login plugin restart secret swarm version
commit exec import logout port rm service system volume
container export info logs ps rmi stack tag wait
cp help inspect network pull run start top
create history kill node push save stats unpause
diff image load pause rename search stop update
3,容器管理
# 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 restart vm1 重启容器
# docker rm vm1 删除容器
# docker export vm1 > vm1.tar 导出容器
# docker import vm1.tar image 导入容器为镜像 image
# docker history nginx 查看nginx的创建历史
# docker cp /etc/passwd vm2:/tmp 复制本地passwd到容器的/tmp
# docker exec vm2 ‘rm -f /tmp/passwd’ 在vm2上执行删除
# docker rmi test 删除镜像
# docker rm vm3 删除容器 -f :通过SIGKILL信号强制删除一个运行中的容器
# docker kill vm3 杀掉一个运行中的容器。
# docker diff vm1 检查容器里文件结构的更改。
# docker port vm1 列出容器的端口映射
# docker container prune删除所有处于停止状态的容器
# docker create --name datavol创建一个新的容器但不启动它
game2048网页游戏
1,获取game2048.tar,导入
[root@foundation28 pub]# docker load -i game2048.tar
2,docker运行game2048
[root@foundation28 pub]# docker run -d --name vm1 game2048
d83f9ef7fc84614ed8aeaec42741ca1c39c34513557ed50ecaa33fbc0ad78f3c
创建一个容器vm1,运行程序game2048
-d 在后台运行,不占用终端
3,docker -a 查看所有进程
[root@foundation28 pub]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d83f9ef7fc84 game2048 "/bin/sh -c 'sed -..." 23 minutes ago Up 23 minutes 80/tcp, 443/tcp vm1
-a 显示所有,默认只显示正在运行的
3,会生成一个docker0网卡
[root@foundation28 pub]# ip addr show
9: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ef:32:31:8e brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:efff:fe32:318e/64 scope link
[root@foundation28 pub]# docker inspect
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
4,浏览器访问
开始游戏!!!
nginx-snat映射
snat端口映射,由于真机的80端口被占用了,我们需要把端口号改为8080,浏览器访问8080,
1,导入.tar包
[root@foundation28 pub]# docker load -i nginx.tar
[root@foundation28 pub]# docker images 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
game2048 latest 19299002fdbe 20 months ago 55.5 MB
nginx latest af4b3d7d5401 2 years ago 190 MB
2,snat映射
[root@foundation28 pub]# docker run -d --name vm2 -p 8080:80 nginx
8080:80 docker的nginx端口:真机的nginx端口
fc8aa12d406afe54cd9ccd5f7144383557933b0327c673500aa957d480ffb65f
3,真机访问8080端口
容器在镜像上做了一个读写层,否则不能写入数据,因为镜像是只读的,删除容器之后,数据销毁释放,如果要保存,需要用docker commit -m “说明文字” container 实例名,下次再用这个创建容器时,数据出现
我们在pull时,分成很多个部分,一个一个的下载。事实也确实如此,这就是镜像的分层,
docker镜像的存储位置/var/lib/docker/,在aufs/layer/下可以看到ubuntu镜像的分层,正是这四层组成了ubuntu镜像。下载时所显示的层标识和在aufs/layer/下看到的不一样,
在docker 1.10之前镜像和分层数据通过一个随机产生的UUID标识,到1.10版本时docker引入了哈希值的方式,而且在1.10之前层ID与aufs/layer/下的目录名是相同的,1.10之后也变得不一样了。镜像是静态的,镜像的每一层都只是可读的,而容器是动态的里面运行着我们指定的应用,容器里面的应用可能会新建一个文件,修改一个目录,这些操作所带来的改变并不会作用到镜像里面,因为镜像只是可读的。所以通过镜像创建容器就是在镜像上加一个可读写的层.
NGINX
1,搜索安装nginx
[root@foundation28 docker]# docker search nginx 默认是官方的源
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 9307 [OK]
2,下载
[root@foundation28 docker]# docker pull nginx
3,建立/etc/docker和daemon.json
[root@foundation28 docker]# ls
daemon.json key.json
[root@foundation28 docker]# cat daemon.json
{
"registry-mirrors": ["https://u0nb22ie.mirror.aliyuncs.com"]
}
注:也可以不写这个,用的源就是官方的,写这个配置文件可以加速,源是阿里云的,注册之后显示
加载daemon,重启docker
4,直接下载的源不用导入,直接启动服务
[root@foundation28 docker]# docker run -d --name vm2 nginx
6e0e5d55305f651a810e38f14fefef72f3864c7e6c501871ee8456b69c33421c
[root@foundation28 docker]# docker start vm2
[root@foundation28 docker]# docker inspect vm2
注意:这里没有进行snat,所以只能在本机访问172.17.0.2
[root@foundation28 ~]# cat index.html
[root@foundation28 ~]# cat index.html
<h1>www.westos.html</h1>
<h1>www.westos.html</h1>
<h1>www.westos.html</h1>
5,创建配置文件
[root@foundation28 ~]# docker cp index.html vm2:/usr/share/nginx/html
注意:默认发布路径可以用docker history查看
5,浏览器访问
6,挂载文件,用cp的方法太麻烦,不适合做频繁修改
[root@foundation28 ~]# mkdir -p /tmp/docker/web
[root@foundation28 ~]# cd /tmp/docker/web/
[root@foundation28 web]# mv ~/index.html .
[root@foundation28 web]# docker run -d --name vm2 -v /tmp/docker/web/:/usr/share/nginx/html/ nginx
f48aac37fcca4c7d1283bd8de817b23049b5ea2944d355121e4175d45e5f2a46
7,保存为.tar,这个tar包可以直接导入,无须下载,保留了修改后的数据
[root@foundation28 web]# docker save nginx > nginx.tar
[root@foundation28 pub]# docker load -i nginx.tar
****************************************************************************
ctrl+pq退出并且在后台运行,如果直接输入exit或者ctrl+d会直接结束进程,不是所有的镜像都可以连接的
ubuntu默认执行了/bin/bash命令
不存在bash
有些需要自己在后面自己添加bash
[root@foundation28 pub]# docker run -it --name vm2 rhel7 bash
-t:在新容器内指定一个伪终端或终端。
-i:允许你对容器内的标准输入 (STDIN) 进行交互。
******************************************************************************
数据卷管理
[root@foundation28 pub]# docker load -i rhel7.tar
e1f5733f050b: Loading layer 147.1 MB/147.1 MB
[root@foundation28 pub]# docker run -it --name vm1 -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro -v /etc/yum.repos.d/redhat.repo:/etc/yum.repos.d/redhat.repo:ro rhel7 bash
-v 参数可以重复使用,挂载多个数据卷到容器中,冒号前面的是宿主机的目录(本地目录不存在 docker 会自动创建),冒号后面的是容器中的挂载目录。
注:docker commit 时卷的数据不会被保存。默认是可读可写,ro表示只读,在真机操作docker中都可以看到,在docker指定目录的权限下操作,真机也可以看到
应用:备份
1,创建一个容器,把本地/tmp/data1挂载到远程的/data1
[root@foundation28 pub]# docker create --name datavol -v /tmp/data1:/data1 -v /tmp/data2:/data2:ro -v /etc/yum.repos.d/redhat.repo:/etc/yum.repos.d/redhat.repo:ro rhel7 bash
4dce607947bf034204f2e004f744965eb537dec92eff0a1db10ef529c7e47e1d
2,运行一个容器,并且挂载数据卷容器
[root@foundation28 data1]# docker run -it --name vm1 --volumes-from datavol rhel7 bash
--rm参数的用法
--rm表示退出时自动删除容器
[root@foundation28 data1]# docker run --rm -v /tmp/backup/:/backup ubuntu tar cf /backup/etc.tar /etc
把容器的/etc打包为/backup/etc.tar,而真机/tmp/backup挂载在容器的/backup下
tar: Removing leading `/' from member names
[root@foundation28 data1]# cd /tmp/backup/
[root@foundation28 backup]# ls
etc.tar
网络管理
容器的四种网络模式:bridge 桥接模式、host 模式、container 模式和 none禁用模式,启动容器时可以使用 --net 参数指定,默认是桥接模式。
以下是 docker 网络初始化的过程:
1,桥接
Bridge 桥接模式的实现步骤主要如下:
(1) Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为
veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将
报文传输给另一方。
(2) Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
(3) Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。
如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到
Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网
络环境的隔离性。
bridge 桥接模式下的 Docker Container 在使用时,并非为开发者包办了一切。最明显的是,
该模式下 Docker Container 不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致
的结果是宿主机以外的世界不能直接和容器进行通信。虽然 NAT 模式经过中间处理实现了
这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器
内部服务的访问者需要使用服务发现获知服务的外部端口等。另外 NAT 模式由于是在三层
网络上的实现手段,故肯定会影响网络的传输效率。
[root@28 docker]# docker start vm1
vm1
root@d204428cbb37:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
15: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
[root@28 docker]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.18dbf22b8e94 no p9p1
docker0 8000.0242afb6d71a no veth5ade6d8
virbr0 8000.000000000000 yes
virbr1 8000.000000000000 yes
[root@28 docker]# docker run -it --name vm3 ubuntu
[root@28 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5a5dd9fde223 ubuntu "/bin/bash" 22 seconds ago Up 19 seconds vm3
d204428cbb37 ubuntu "/bin/bash" 11 minutes ago Up 40 seconds vm1
[root@28 docker]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.18dbf22b8e94 no p9p1
docker0 8000.0242afb6d71a no veth5ade6d8
vethbc12770
virbr0 8000.000000000000 yes
virbr1 8000.000000000000 yes
每启动一个就会多一个接口桥接到docker0上
2,host模式
Host 网络模式:
host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用
宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公
有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。当然,
有这样的方便,肯定会损失部分其他的特性,最明显的是 Docker Container 网络环境隔离性
的弱化,即容器不再拥有隔离、独立的网络栈。另外,使用 host 模式的 Docker Container 虽
然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱
化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资
源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网
络模式容器的端口映射。
[root@28 docker]# docker run -it --name vm3 --net host ubuntu
root@28:/# ip addr # 和真机共享网络资源
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: p9p1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN group default qlen 1000
link/ether 18:db:f2:2b:8e:94 brd ff:ff:ff:ff:ff:ff
4: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 18:db:f2:2b:8e:94 brd ff:ff:ff:ff:ff:ff
inet 172.25.254.28/24 brd 172.25.254.255 scope global br0
valid_lft forever preferred_lft forever
inet 172.25.28.250/24 brd 172.25.28.255 scope global br0
valid_lft forever preferred_lft forever
5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 7e:ae:b8:78:08:34 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
6: virbr1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 32:43:dc:2e:00:7b brd ff:ff:ff:ff:ff:ff
7: wlp0s20f0u2u3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 70:f1:1c:0c:2d:09 brd ff:ff:ff:ff:ff:ff
inet 10.181.12.128/16 brd 10.181.255.255 scope global dynamic wlp0s20f0u2u3
valid_lft 256117sec preferred_lft 256117sec
inet6 fe80::72f1:1cff:fe0c:2d09/64 scope link
valid_lft forever preferred_lft forever
8: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:af:b6:d7:1a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:afff:feb6:d71a/64 scope link
valid_lft forever preferred_lft forever
16: veth5ade6d8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 5a:ec:3b:c5:42:2d brd ff:ff:ff:ff:ff:ff
inet6 fe80::58ec:3bff:fec5:422d/64 scope link
valid_lft forever preferred_lft forever
root@28:/# ping www.baidu.com
PING www.a.shifen.com (220.181.111.188) 56(84) bytes of data.
64 bytes from 220.181.111.188: icmp_seq=1 ttl=53 time=23.6 ms
64 bytes from 220.181.111.188: icmp_seq=2 ttl=53 time=25.0 ms
3,container模式
Container 网络模式:
(1) 查找 other container(即需要被共享网络环境的容器)的网络 namespace;
(2) 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,使用
other container 的 namespace。
Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。
在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输
效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他
容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。但是需要注意的是,
它并没有改善容器与宿主机以外世界通信的情况。
[root@28 docker]# docker run -it --name vm2 ubuntu
[root@28 pub]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.18dbf22b8e94 no p9p1
vnet0
docker0 8000.0242afb6d71a no veth9ccaf30
virbr0 8000.000000000000 yes
virbr1 8000.000000000000 yes
[root@28 docker]# docker run -it --name vm1 --net container:vm2 ubuntu
container模式下vm1和vm2共享网络资源
[root@28 pub]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.18dbf22b8e94 no p9p1
vnet0
docker0 8000.0242afb6d71a no veth9ccaf30
virbr0 8000.000000000000 yes
virbr1 8000.000000000000 yes
4,none模式
None 网络模式:
网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docker Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。在 none 网络模式下分配固定 ip:netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备以及 iptables 规则等都是独立的,就好像进入了另外一个网络一样。
[root@28 docker]# docker run -it --name vm5 --net none ubuntu
root@4db3083aa775:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
[root@28 pub]# docker inspect vm5 | grep Pid
"Pid": 26819,
"PidMode": "",
"PidsLimit": 0,
[root@28 pub]# cd /proc/26819/ns/
[root@28 ns]# ls
ipc mnt net pid uts
[root@28 ns]# ll
total 0
lrwxrwxrwx 1 root root 0 Aug 20 20:41 ipc -> ipc:[4026532957]
lrwxrwxrwx 1 root root 0 Aug 20 20:41 mnt -> mnt:[4026532955]
lrwxrwxrwx 1 root root 0 Aug 20 20:39 net -> net:[4026532960]
lrwxrwxrwx 1 root root 0 Aug 20 20:41 pid -> pid:[4026532958]
lrwxrwxrwx 1 root root 0 Aug 20 20:41 uts -> uts:[4026532956]
[root@28 ~]# mkdir /var/run/netns
[root@28 netns]# ln -s /proc/26819/ns/net /var/run/netns/26819
[root@28 netns]# ls
26819
[root@28 netns]# ip netns list
26819
[root@28 netns]# ip link add name veth0 type veth peer name veth1
[root@28 docker]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.18dbf22b8e94 no p9p1
vnet0
docker0 8000.0242afb6d71a no veth9ccaf30
virbr0 8000.000000000000 yes
virbr1 8000.000000000000 yes
[root@28 docker]# brctl addif docker0 veth0
[root@28 docker]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.18dbf22b8e94 no p9p1
vnet0
docker0 8000.0242afb6d71a no veth0
veth9ccaf30
virbr0 8000.000000000000 yes
virbr1 8000.000000000000 yes
[root@28 docker]# ip link set up veth0
[root@28 docker]# ip link set up veth1
[root@28 docker]# ip link set veth1 netns 26819
[root@28 netns]# ip netns exec 26819 ip link set veth1 name eth0
[root@28 netns]# ip netns exec 26819 ip link set up dev eth0
[root@28 netns]# ip netns exec 26819 ip addr add 172.17.0.100/24 dev eth0
[root@28 netns]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.18dbf22b8e94 no p9p1
vnet0
docker0 8000.0242afb6d71a no veth0
veth9ccaf30
virbr0 8000.000000000000 yes
virbr1 8000.000000000000 yes
root@4db3083aa775:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
24: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether d6:9e:90:6a:0e:f3 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.100/24 scope global eth0 #添加的ip
valid_lft forever preferred_lft forever
inet6 fe80::d49e:90ff:fe6a:ef3/64 scope link
valid_lft forever preferred_lft forever
root@4db3083aa775:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.036 ms
[root@28 netns]# ip netns exec 26819 ip route add default via 172.17.0.1 #网关
root@4db3083aa775:/# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.0.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
root@5710084dc42c:/# ping baidu.com
PING baidu.com (123.125.115.110) 56(84) bytes of data.
64 bytes from 123.125.115.110: icmp_seq=1 ttl=49 time=28.8 ms
64 bytes from 123.125.115.110: icmp_seq=2 ttl=49 time=24.2 ms
docker的互联
1,删除其他所有进程
[root@foundation28 ~]# docker ps -aq
-q :静默模式,只显示容器编号
3d357d9993d2
9beddd11281b
4dce607947bf
f48aac37fcca
[root@foundation28 ~]# docker rm -f `docker ps -aq`
3d357d9993d2
9beddd11281b
4dce607947bf
f48aac37fcca
[root@foundation28 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2,运行nginx服务,做snat
[root@foundation28 ~]# docker run -d --name vm1 -p 8080:80 nginx
c46870c862d74e323e47ae5c8b7b1e598a384e0835485a29228ddc23811d782a
[root@foundation28 ~]# iptables -t nat -nL
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
[root@foundation28 ~]# docker run -it --name vm2 --link vm1:nginx ubuntu
--link 参数可以在不映射端口的前提下为两个容器间建立安全连接, --link 参数可以连接一个
或多个容器到将要创建的容器。--link 参数的格式为 --link name:alias,其中 name 是要链接的容器的名称,alias 是这个连接的别名。
root@087a02be3908:/usr/share# env
root@087a02be3908:/usr/share# ping nginx
PING nginx (172.17.0.2) 56(84) bytes of data.
64 bytes from nginx (172.17.0.2): icmp_seq=1 ttl=64 time=0.147 ms
64 bytes from nginx (172.17.0.2): icmp_seq=2 ttl=64 time=0.111 ms
^C
--- nginx ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.111/0.129/0.147/0.018 ms
构建镜像-httpd
1,编辑测试yum源
[root@foundation28 ~]# docker run -it --name vm1 rhel7 bash
bash-4.2# cd /etc/yum.repos.d/
bash-4.2# vi dvd.repo
[dvd]
name=rhel7.3
baseurl=http://172.25.254.28/rhel7.3
gpgcheck=0
bash-4.2# yum repolist
2,制作镜像所需的Dockerfile,可以用docker history参考其他服务的启动
[root@foundation28 docker]# vim Dockerfile
[root@foundation28 docker]# cat Dockerfile
FROM rhel7 # 指定基础镜像,如果有版本指定rhel:v1,默认是最原始的
ENV HOSTNAME server1 # 设置容器主机名ENV 命令能够对容器内的环境变量进行设置:
MAINTAINER root@localhost # 作者信息
EXPOSE 80 # 暴露容器端口,由于内部服务会启动 Web 服务,我们需要把对应的 80 端口暴露出来,可以提供给容器间互
联使用
COPY dvd.repo /etc/yum.repos.d/dvd.repo # dev.repo是本机的,需要自己写,向镜像中添加文件有两种命令,这个dvd.repo最好写绝对路径
RUN rpmdb --rebuilddb && yum install -y httpd && yum clean all
VOLUME ["/var/www/html"] # 可写可不写,说明一下发布目录
CMD ["/usr/sbin/httpd","-D","FOREGROUND"] # 启动httpd
# 镜像启动命令,默认只能启动一条。
3,建立dvd.repo
[root@foundation28 docker]# vim dvd.repo
[dvd]
name=rhel7.3
baseurl=http://172.25.254.28/rhel7.3
gpgcheck=0
4,清理无效文件
[root@foundation28 docker]# cd web/
[root@foundation28 web]# ls
index.html nginx.tar
[root@foundation28 web]# rm -rf nginx.tar # 构建镜像时会默认读取当前目录下的所有文件,所以注意清理无效文件,否则构建的镜像会很大
5,构建镜像
[root@foundation28 docker]# docker build -t rhel7:v1 .
6,查看镜像
[root@foundation28 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rhel7 v1 084b7e664991 15 seconds ago 169 MB
nginx latest c82521676580 3 weeks ago 109 MB
7,测试
挂载测试
[root@foundation28 web]# docker run -d --name vm3 -v /tmp/docker/web:/var/www/html rhel:v1
[root@foundation28 web]# ls
index.html
Dockerfile 常用指令:
1. 指定容器运行的用户
该用户将作为后续的 RUN 命令执行的用户。这个命令本实验不需要,但在一些需要指定用
户来运行的应用部署时非常关键,比如提供 hadoop 服务的容器通常会使用 hadoop 用户来启动服务。命令使用方式,例如使用 shiyanlou 用户来执行后续命令:
USER shiyanlou
2. 指定后续命令的执行目录
由于我们需要运行的是一个静态网站,将启动后的工作目录切换到/var/www/html 目录:WORKDIR /var/www/html
3. 对外连接端口号
由于内部服务会启动 Web 服务,我们需要把对应的 80 端口暴露出来,可以提供给容器间互
联使用,可以使用 EXPOSE 命令。在镜像操作部分增加下面一句:
EXPOSE 80
4. 设置容器主机名
ENV 命令能够对容器内的环境变量进行设置:
ENV HOSTNAME sevrer1.example.com
5. 向镜像中增加文件
向镜像中添加文件有两种命令:COPY 和 ADD。
COPY 命令可以复制本地文件夹到镜像中:
COPY website /var/www/html
ADD 命令支持添加本地的 tar 压缩包到容器中指定目录,压缩包会被自动解压为目录,也
可以自动下载 URL 并拷贝到镜像,例如:
ADD html.tar /var/www
ADD http://www.westos.org/html.tar /var/www
6. CMD 与 ENTRYPOINT
ENTRYPOINT容器启动后执行的命令,让容器执行表现的像一个可执行程序一样,与
CMD 的区别是不可以被docker run覆盖,会把docker run后面的参数当作传递给ENTRYPOINT指令的参数。Dockerfile 中只能指定一个 ENTRYPOINT,如果指定了很多,
只有最后一个有效。 docker run命令的-entrypoint参数可以把指定的参数继续传递给
ENTRYPOINT。
7. 挂载数据卷
将 apache 访问的日志数据存储到宿主机可以访问的数据卷中:
VOLUME ["/var/log/apche2"]
构建镜像-ssh
1,编辑,创建Dockfile
[root@foundation28 docker]# mkdir ssh
[root@foundation28 docker]# cd ssh/
[root@foundation28 ssh]# ls
[root@foundation28 ssh]# cp ../Dockerfile .
[root@foundation28 ssh]# vim Dockerfile
[root@foundation28 ssh]# cat Dockerfile
FROM rhel7
ENV HOSTNAME server2
MAINTAINER root@localhost
EXPOSE 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y openssh-server openssh-clients && yum clean all
CMD ["/usr/sbin/sshd","-D"]
2,容器内测试
[root@foundation28 ssh]# docker run -it --name vm3 rhel7 bash
bash-4.2# /usr/sbin/sshd
bash: /usr/sbin/sshd: No such file or directory
bash-4.2# vi /etc/yum.repos.d/dvd.repo
[dvd]
name=rhel7.3
baseurl=http://172.25.254.28/rhel7.3
gpgcheck=0
bash-4.2# yum install -y openssh-server openssh-clients
bash-4.2# /usr/sbin/sshd
Could not load host key: /etc/ssh/ssh_host_rsa_key
Could not load host key: /etc/ssh/ssh_host_ecdsa_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
3,测试获取key
ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N
echo root:redhat | chpasswd 设置密码
bash-4.2# /usr/sbin/sshd 成功!!
4,编辑Dockerfile
[root@foundation28 ~]# cd /tmp/docker/
[root@foundation28 docker]# ls
Dockerfile dvd.repo ssh web
[root@foundation28 docker]# vim ssh/Dockerfile
[root@foundation28 docker]# cat ssh/Dockerfile
FROM rhel7
ENV HOSTNAME server2
MAINTAINER root@localhost
EXPOSE 22
COPY dvd.repo /etc/yum.repos.d/dvd.repo
RUN rpmdb --rebuilddb && yum install -y openssh-server openssh-clients && yum clean all && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:redhat | chpasswd
CMD ["/usr/sbin/sshd","-D"]
5,构建镜像
[root@foundation28 ssh]# cp ../dvd.repo .
[root@foundation28 ssh]# docker build -t rhel7:v2 .
6,测试
[root@foundation28 ssh]# docker run -d --name vm4 rhel7:v2
7e993b54ef4bda63348fd279c6f07d55b0129c1fe43a336779ebd3e900870d5d
[root@foundation28 ssh]# netstat -antlp
[root@foundation28 ssh]# docker inspect vm4
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.5",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:05"
[root@foundation28 ssh]# ssh root@172.17.0.5
The authenticity of host '172.17.0.5 (172.17.0.5)' can't be established.
ECDSA key fingerprint is 00:34:af:bb:d2:45:c6:a8:5d:4d:22:39:20:f8:f2:90.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.5' (ECDSA) to the list of known hosts.
root@172.17.0.5's password:
-bash-4.2#
成功!!!