1 制作一个简单镜像
# 先启动一个容器,增加一些文件,然后基于此做成一个镜像
[root@docker ~]# docker run --name b1 -it busybox
/ # mkdir /data/html -p
/ # vi /data/html/index.html
/ # cat /data/html/index.html
<h1>Busybox httpd server.</h1>
新建终端窗口操作
[root@docker ~]# docker commit -p b1
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 50290c5e9b46 5 seconds ago 1.15MB
redis 4-alpine 05097a3a0549 4 weeks ago 30MB
busybox latest 59788edf1f3e 4 weeks ago 1.15MB
nginx 1.14-alpine 14d4a58e0d2e 7 weeks ago 17.4MB
quay.io/coreos/flannel v0.10.0-amd64 f0fad859c909 9 months ago 44.6MB
给新创建的镜像打标签
[root@docker ~]# docker tag 50290c5e9b46 rsqlh/httpd:v1.0.0
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
rsqlh/httpd v1.0.0 50290c5e9b46 59 seconds ago 1.15MB
redis 4-alpine 05097a3a0549 4 weeks ago 30MB
busybox latest 59788edf1f3e 4 weeks ago 1.15MB
nginx 1.14-alpine 14d4a58e0d2e 7 weeks ago 17.4MB
quay.io/coreos/flannel v0.10.0-amd64 f0fad859c909 9 months ago 44.6MB [root@docker ~]# docker tag rsqlh/httpd:v1.0.0 rsqlh/httpd:latest
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
rsqlh/httpd latest 50290c5e9b46 3 minutes ago 1.15MB
rsqlh/httpd v1.0.0 50290c5e9b46 3 minutes ago 1.15MB
redis 4-alpine 05097a3a0549 4 weeks ago 30MB
busybox latest 59788edf1f3e 4 weeks ago 1.15MB
nginx 1.14-alpine 14d4a58e0d2e 7 weeks ago 17.4MB
quay.io/coreos/flannel v0.10.0-amd64 f0fad859c909 9 months ago 44.6MB
此时最新的那个镜像相当于链接文件,如果删除不会影响到源文件
[root@docker ~]# docker image rm rsqlh/httpd:latest
Untagged: rsqlh/httpd:latest
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
rsq/busybox_httpd latest 50290c5e9b46 3 minutes ago 1.15MB
rsqlh/httpd v1.0.0 50290c5e9b46 3 minutes ago 1.15MB
redis 4-alpine 05097a3a0549 4 weeks ago 30MB
busybox latest 59788edf1f3e 4 weeks ago 1.15MB
nginx 1.14-alpine 14d4a58e0d2e 7 weeks ago 17.4MB
quay.io/coreos/flannel v0.10.0-amd64 f0fad859c909 9 months ago 44.6MB
启动我们之前创建的新镜像,看是否有我们最开始创建的index.html文件
[root@docker ~]# docker run --name t1 -it rsqlh/httpd:v1.0.0
/ # ls /
bin data dev etc home proc root sys tmp usr var
/ # cat /data/html/index.html
<h1>Busybox httpd server.</h1>
在做镜像的时候更改默认启动命令,把httpd启动命令作为默认启动命令测试
[root@docker ~]# docker commit -a "RSQ <cactirsq@163.com>" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p b1 rsqlh/httpd:v1.0.1
[root@docker ~]# docker run --name t2 rsqlh/httpd:v1.0.1
换个终端查看
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
51464876dbea rsqlh/httpd:v1.0.1 "/bin/httpd -f -h /d…" 2 minutes ago Up 2 minutes t2
[root@docker ~]# docker inspect t2 | grep IPAddress
[root@docker ~]# curl 172.17.0.2
<h1>Busybox httpd server.</h1>
推送到docker hub
[root@docker ~]# docker login -u rsqlh # 先登陆到服务器上
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@docker ~]# docker push rsqlh/httpd
Tips:若删除镜像失败,可有以下操作,原因是因为有依赖
[root@docker ~]# docker rmi rsq/busybox_httpd:v1.0.0
Error response from daemon: conflict: unable to remove repository reference "rsq/busybox_httpd:v1.0.0" (must force) - container c7bc06d55b36 is using its referenced image 10231b71c4ab
[root@docker ~]# docker rm c7bc06d55b36
c7bc06d55b36
[root@docker ~]# docker rmi rsq/busybox_httpd:v1.0.0
若要换成阿里云的hub,则先登出,然后登陆阿里云的账号
[root@docker ~]# docker login --username=rsqlh registry.cn-shenzhen.aliyuncs.com
镜像的导入和导出
[root@docker ~]# docker save -o myimages.gz rsqlh/httpd:v1.0.1 rsqlh/httpd:v1.0.0
[root@docker ~]# ll -h myimages.gz
-rw-------. 1 root root 1.4M Nov 4 22:16 myimages.gz
[root@docker ~]# scp myimages.gz root@10.0.0.10:/root/
在另外一台设备上加载此镜像
[root@docker ~]# docker load -i myimages.gz
但是这种方式,若是本地没有镜像,还是会从仓库pull下来镜像,所以事先还需要下载好镜像
2 Docker网络
2.1 暴露端口,相当于DNAT
(1)将指定的容器端口映射至宿主机所有地址的一个动态端口,这个端口会随机生成
-p <containerPort>
(2)将容器端口<containerPort>映射至指定的宿主机端口<hostPort>
-p <hostPort>:<containerPort>
(3)将指定的容器端口<containerPort>映射至宿主机指定<ip>的动态端口
-p <ip>::<containerPort>
(4)将指定的容器端口<containerPort>映射至宿主机指定<ip>的指定端口<hostPort>
-p <ip>:<hostPort>:<containerPort>
“动态端口”指随机端口,具体的映射结果可以使用docker port命令查看
运行busybox,使得可以修改主机名,更改网络模式
docker run --name b1 -it --network bridge -h b1.rsql.com --rm busybox:latest
自定义dns
docker run --name b1 -it --network bridge -h b1.rsql.com --dns 114.114.114.114 --rm 4.114 --rm busybox:latest
在外部添加dns解析
[root@docker ~]# docker run --name b1 -it --network bridge -h b1.rsql.com --dns-search ilinux.io --add-host www.rsq.com:1.1.1.1 --rm busybox:latest
/ # cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
1.1.1.1 www.rsq.com
172.17.0.4 b1.rsql.com b1
终端1开启http服务
[root@docker ~]# docker run --name t2 -it --network bridge --rm -p 80 rsqlh/httpd:v1.0.1
终端2查看进程转换端口
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7b0c262f2bb4 rsqlh/httpd:v1.0.1 "/bin/httpd -f -h /d…" 24 seconds ago Up 23 seconds 0.0.0.0:32770->80/tcp t2
[root@docker ~]# docker port t2
80/tcp -> 0.0.0.0:32770
[root@docker ~]# curl 172.17.0.2
<h1>Busybox httpd server.</h1>
外部测试
固定IP地址,-p x.x.x.x::80 两个冒号中间指定宿主机端口,空的话默认动态自动分配
[root@docker ~]# docker run --name t2 --network bridge --rm -p 10.0.0.101::80 rsqlh/httpd:v1.0.1
[root@docker ~]# docker port t2
80/tcp -> 10.0.0.101:32769
[root@docker ~]# docker run --name t2 --network bridge --rm -p 80:80 rsqlh/httpd:v1.0.1
[root@docker ~]# docker port t2
80/tcp -> 0.0.0.0:80
指定宿主机IP有指定宿主机端口
[root@docker ~]# docker run --name t2 --network bridge --rm -p 10.0.0.101:8080:80 rsqlh/httpd:v1.0.1
[root@docker ~]# docker port t2
80/tcp -> 10.0.0.101:8080
2.2 联盟式容器
- 联盟式容器是指使用某个已存在的容器的网络接口的容器,接口被联盟内的个容器共享使用,因此,联盟式容器彼此之间完全无隔离。
- 联盟式容器彼此间虽然共享同一个网络名称空间(
UTS
、NETWORK
、IPC
),但其它名称空间如User
、Mount
、PID
还是隔离的。 - 联盟式容器彼此间存在端口冲突的可能性,因此,通常只会在多个容器上的程序需要程序
loopback
接口互相通信、或对某已存在的容器的网络属性进行监控时才使用此种模式的网络模型。
创建两个容器b1和b2
[root@docker ~]# docker run --name b1 -it --rm busybox
/ # hostname -i
172.17.0.2
[root@docker ~]# docker run --name b2 -it --rm busybox
/ # hostname -i
172.17.0.3
共用网络,可用ifconfig查看到两个容器的网卡IP一样
[root@docker ~]# docker run --name b2 --network container:b1 -it --rm busybox
/ # hostname -i
172.17.0.2
测试文件系统是分离的,b1上创建一文件
/ # touch /tmp/test
/ # ls /tmp/test
/tmp/test
b2上查看,可以发现非网络namespace是不共享的
/ # ls /tmp
/ #
测试共用网络系统,在b1上启动httpd,在b2上访问自己
/ # echo "This is a test file." > /tmp/index.html
/ # httpd -h /tmp/
/ # netstat -lntup
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::80 :::* LISTEN 12/httpd
/ #
b2访问,可以发现会共享网络
/ # wget -O - -q 127.0.0.1
This is a test file.
自定义docker0桥的网络属性信息:
# 核心选项为`bip`,即bridge ip之意,用于指定`docker0`桥自身的IP地址;其它选项可通过此地址计算得出。
vim /etc/docker/daemon.json
{
"bip": "172.25.0.1/24",
"fixed-cidr": "10.20.0.0/16",
"fixed-cidr-v6": "2001:db8::/64",
"mtu": 1500,
"default-gateway": "10.20.1.1",
"default-gateway-v6": "2001:db8:abcd::89",
"dns": ["10.20.1.2","10.20.1.3"]
}
docker守护进程的C/S,其默认仅监听Unix Socket格式的地址,/var/run/docker.sock;如果使用TCP套接字则添加如下信息
[root@docker ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://3po4uu60.mirror.aliyuncs.com","https://registry.docker-cn.com"]
"bip": "172.25.0.1/24",
"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
}
也可向docker直接传递"-H|–host"选项执行远程连接命令
[root@docker ~]# docker -H 10.0.0.101:2375 ps
手动创建docker网卡
[root@docker-node2 ~]# docker network create -d bridge --subnet "172.25.0.0/16" --gateway "172.25.0.1" mybr0
1972a1e1e51d47a5bff155cbb67a91fc11b229fb9c06e5682ee1617781cefdc2
[root@docker-node2 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
a38e08270902 bridge bridge local
8a64c907bbdc host host local
1972a1e1e51d mybr0 bridge local
645fe58f5d5d none null local
[root@docker-node2 ~]# ifconfig
br-1972a1e1e51d: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.25.0.1 netmask 255.255.0.0 broadcast 172.25.255.255
ether 02:42:0d:a0:07:56 txqueuelen 0 (Ethernet)
RX packets 1031 bytes 95743 (93.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 621 bytes 62157 (60.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
修改网卡名字为docker1,此时会报错,先关掉此网卡
[root@docker-node2 ~]# ip link set dev br-1972a1e1e51d name docker1
RTNETLINK answers: Device or resource busy
[root@docker-node2 ~]# ip link set dev br-1972a1e1e51d down
[root@docker-node2 ~]# ip link set dev br-1972a1e1e51d name docker1
[root@docker-node2 ~]# ip link set dev docker1 up
[root@docker-node2 ~]# ifconfig docker1
docker1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.25.0.1 netmask 255.255.0.0 broadcast 172.25.255.255
inet6 fe80::42:dff:fea0:756 prefixlen 64 scopeid 0x20<link>
ether 02:42:0d:a0:07:56 txqueuelen 0 (Ethernet)
RX packets 6 bytes 392 (392.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 24 bytes 1856 (1.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
在创建容器的时候可以直接加入此网卡即可
[root@docker-node2 ~]# docker run --name t1 -it --net mybr0 busybox:latest
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:19:00:02
inet addr:172.25.0.2 Bcast:172.25.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1016 (1016.0 B) TX bytes:0 (0.0 B)
再创建一个容器,这个容器选择默认的bridge,此时看二则能否通信,先关闭防火墙
[root@docker-node2 ~]# systemctl stop firewalld.service
[root@docker-node2 ~]# systemctl disable firewalld.service
[root@docker-node2 ~]# docker run --name t2 -it --net bridge busybox:latest
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1016 (1016.0 B) TX bytes:0 (0.0 B)
/ # ping 172.25.0.2
PING 172.25.0.2 (172.25.0.2): 56 data bytes
64 bytes from 172.25.0.2: seq=0 ttl=63 time=0.104 ms
64 bytes from 172.25.0.2: seq=1 ttl=63 time=0.145 ms
64 bytes from 172.25.0.2: seq=2 ttl=63 time=0.088 ms
^C
--- 172.25.0.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.088/0.112/0.145 ms