赞
踩
我发现docker启动容器时(以redis为例),在已经启动了一个-p 6379:6379的redis1容器后,当我们开启第二个redis2容器时,
右边的端口映射既可以写别的我们想要映射的端口(-p 6380:6380 redis2),也可以继续写6379(-p 6380:6379 redis2)!!!
因为众所周知,一个服务只能占用一个端口,但是这里却能映射相同的docker容器的端口号!(所以我很好奇)
(注:先测试映射6380的redis2,再换成映射6379的redis2,并且redis1一直是开启的状态)
1* 启动两个redis容器的(redis1配置文件端口为6379,redis2是6380)
首先是映射不同的端口创建两个容器,分别映射6379 和 6380 端口。
[root@zch config]# docker run -d --name redis1 -v /usr/local/docker/redis/config/redis1/redis.conf:/etc/redis.conf -v /usr/local/docker/redis/data:/data -p 6379:6379 redis:6.0.12 redis-server /etc/redis.conf
ffeac01946f1d34115734fb1405a68f5a020e6bb1b0f6100c6dbd257630ffe7a
[root@zch config]# docker run -d --name redis2 -v /usr/local/docker/redis/config/redis2/redis.conf:/etc/redis.conf -v /usr/local/docker/redis/data:/data -p 6380:6380 redis:6.0.12 redis-server /etc/redis.conf
ca58fb27e6f92d12afacebafaa854692f99fab9db4ce8fe66af8304cf8e9fffc
[root@zch config]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ca58fb27e6f9 redis:6.0.12 “docker-entrypoint.s…” 13 seconds ago Up 12 seconds 6379/tcp, 0.0.0.0:6380->6380/tcp redis2
ffeac01946f1 redis:6.0.12 “docker-entrypoint.s…” 52 seconds ago Up 51 seconds 0.0.0.0:6379->6379/tcp redis1
然后进入redis1和redis2的客户端,可以看到都是能成功连接上的
(注:在进入redis2的时候一定要以==-p 6380==进入)
[root@zch config]# docker exec -it redis1 redis-cli
127.0.0.1:6379> exit
[root@zch config]# docker exec -it redis2 redis-cli -p 6380
127.0.0.1:6380>
2* 接着我将原来的redis2容器删除后,再重新创建redis2,并把右边的映射端口,也改成和redis1一样的6379
docker run -d --name redis2 -v /usr/local/docker/redis/config/redis2/redis.conf:/etc/redis.conf -v /usr/local/docker/redis/data:/data -p 6380:6379 redis:6.0.12 redis-server /etc/redis.conf
然后再次进入redis2容器,会发现虽然是映射的还是6379,但依然是能够进入到客户端的
[root@zch ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
203a0d3dad1a redis:6.0.12 “docker-entrypoint.s…” 5 hours ago Up 5 minutes 0.0.0.0:6380->6379/tcp redis2
ffeac01946f1 redis:6.0.12 “docker-entrypoint.s…” 15 hours ago Up 3 seconds 0.0.0.0:6379->6379/tcp redis1
[root@zch ~]# docker exec -it redis2 redis-cli -p 6380
127.0.0.1:6380>
但是,注意到docker ps 的时候redis2的PORTS属性只剩下0.0.0.0:6380->6379/tcp了
再回看之前映射6380的redis2的PORTS属性:6379/tcp, 0.0.0.0:6380->6380/tcp
可以看到映射内部6380端口的redis2容器PORTS有两个值,并且没有与内部端口6379映射的本机ip
我们可以看下pull下来的redis镜像的具体信息
[root@zch config]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis 6.0.12 090314e0c44c 4 weeks ago 104MB [root@zch config]# docker inspect 090314e0c44c [ { "Id": "sha256:090314e0c44c58e5faaa379904242657dcb4203e1a6a61413e534e0f40e8bdd5", "RepoTags": [ "redis:6.0.12" ], "RepoDigests": [ "redis@sha256:cc4231ed1a6ae4d0a3e0c85c205ba68d0cbcd60c837caca1334b01661eb8b3bb" ], "Parent": "", "Comment": "", "Created": "2021-03-13T04:04:30.678552814Z", "Container": "c62962de94021537ddd3d2a2cf36c1ee26eec6f374b65c9624fc54675b65beb3", "ContainerConfig": { "Hostname": "c62962de9402", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "6379/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "GOSU_VERSION=1.12", "REDIS_VERSION=6.0.12", "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.12.tar.gz", "REDIS_DOWNLOAD_SHA=f16ad973d19f80f121e53794d5eb48a997e2c6a85b5be41bb3b66750cc17bf6b" ], "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"redis-server\"]" ], "Image": "sha256:09a494871c16ded394e132a87f16e105522b63e88c92018a1dddcf21d8b401f3", "Volumes": { "/data": {} }, "WorkingDir": "/data", "Entrypoint": [ "docker-entrypoint.sh" ], "OnBuild": null, "Labels": {} }, "DockerVersion": "19.03.12", "Author": "", "Config": { "Hostname": "", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "6379/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "GOSU_VERSION=1.12", "REDIS_VERSION=6.0.12", "REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-6.0.12.tar.gz", "REDIS_DOWNLOAD_SHA=f16ad973d19f80f121e53794d5eb48a997e2c6a85b5be41bb3b66750cc17bf6b" ], "Cmd": [ "redis-server" ], "Image": "sha256:09a494871c16ded394e132a87f16e105522b63e88c92018a1dddcf21d8b401f3", "Volumes": { "/data": {} }, "WorkingDir": "/data", "Entrypoint": [ "docker-entrypoint.sh" ], "OnBuild": null, "Labels": null }, "Architecture": "amd64", "Os": "linux", "Size": 104291820, "VirtualSize": 104291820, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/6f0cd9ab5a300e71ce8475861a4bc2b76a2826ec0020e787a43d38a5ff2db2ef/diff:/var/lib/docker/overlay2/d70138999bd376d810f4b4f6d1ada4560923317c74609ac467381fd0fc67d50a/diff:/var/lib/docker/overlay2/12991f82bf1068b3191de47ebf9d581f34bcc3a8a8cbdef0f90f052bf65b53e8/diff:/var/lib/docker/overlay2/85b82010fca6b6fa29cc66a3e3df59c1c934a5340e0dcfd023650c23439b2439/diff:/var/lib/docker/overlay2/0ae0ed3fdcd6cbe7a7c6aa491d837653a84e1a55f774a6604df1035c29012c65/diff", "MergedDir": "/var/lib/docker/overlay2/83b39cef71e2dc3cd1ff367a3496afcbf68c248afe6cb427a348907fb94cefce/merged", "UpperDir": "/var/lib/docker/overlay2/83b39cef71e2dc3cd1ff367a3496afcbf68c248afe6cb427a348907fb94cefce/diff", "WorkDir": "/var/lib/docker/overlay2/83b39cef71e2dc3cd1ff367a3496afcbf68c248afe6cb427a348907fb94cefce/work" }, "Name": "overlay2" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:14a1ca976738392ffa2ae4e54934ba28ab9cb756e924ad9297a4795a4adbfdf6", "sha256:a6b7270e6c20bae1d8c5d009171ce7db2e268c3d32e447a2ec4f33b02b256955", "sha256:cf2aefb51919d2cf15e3311fec4e187f968e06f168ee610d500e81757b53a3f7", "sha256:6e0e8a8a5ad7776289d5929ba624ce58e64600af5995f0208502fc265773a192", "sha256:e3059a3a1a65e206c34ae3e24ae6098ede134e7ad4cbd8a5eae4b5feeeb38589", "sha256:65508d7d88a08e37d76fad31e959cd15facecee0f1b3513ef4592d1186be077e" ] }, "Metadata": { "LastTagTime": "0001-01-01T00:00:00Z" } } ] [root@zch config]#
注意到这个地方
“ExposedPorts”: {
“6379/tcp”: {}
},
也就是说,当我们pull下来镜像的时候,就已经在docker内部有一个默认的端口号了(一般就是平常各种服务默认的端口号),所以当我们通过镜像创建容器的时候,对于同一个镜像,它所创建的不同容器在docker内部的端口都有一个默认的和镜像一致的端口!
===查看与6380内部端口映射(-p 6380:6380)的redis2的元数据时(docker inspect redis2)发现
“Ports”: {
“6379/tcp”: null, //这里的就是docker容器内部默认的端口,只不过我们没有本机地址与它映射,所以为null,也是为何docker ps时有两个值的原因
“6380/tcp”: [
{
“HostIp”: “0.0.0.0”,
“HostPort”: “6380”
}
]
}
===再看与6379内部端口映射(-p 6380:6379)的redis2的元数据时(docker inspect redis2)发现
“Ports”: {
“6379/tcp”: [
{
“HostIp”: “0.0.0.0”,
“HostPort”: “6380”
}
]
}
这里就只有容器默认的内部端口6379和本机的映射了
所以,为何同一个docker内部端口6379能够与不同的本机端口相映射呢
我猜测是跟docker网络有关。。
所以我们查看一下开启前后的ip
(注:此时两个容器都是与内部端口6379映射的)
[root@zch ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
203a0d3dad1a redis:6.0.12 "docker-entrypoint.s…" 6 hours ago Up 49 minutes 0.0.0.0:6380->6379/tcp redis2
ffeac01946f1 redis:6.0.12 "docker-entrypoint.s…" 16 hours ago Up 43 minutes 0.0.0.0:6379->6379/tcp redis1
[root@zch ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:16:3e:30:ac:de brd ff:ff:ff:ff:ff:ff inet 172.24.11.75/18 brd 172.24.63.255 scope global dynamic eth0 valid_lft 307823829sec preferred_lft 307823829sec 3: br-2ebc59f84c42: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:51:6f:6a:ad brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-2ebc59f84c42 valid_lft forever preferred_lft forever 4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:42:98:e1:75 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
[root@zch ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:16:3e:30:ac:de brd ff:ff:ff:ff:ff:ff inet 172.24.11.75/18 brd 172.24.63.255 scope global dynamic eth0 valid_lft 307824120sec preferred_lft 307824120sec 3: br-2ebc59f84c42: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:51:6f:6a:ad brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-2ebc59f84c42 valid_lft forever preferred_lft forever 4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:42:98:e1:75 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 12178: vethb34c46b@if12177: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 5a:35:bb:a2:4e:c1 brd ff:ff:ff:ff:ff:ff link-netnsid 0 12180: vetha7fde8c@if12179: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 72:24:61:31:6a:41 brd ff:ff:ff:ff:ff:ff link-netnsid 1
很明显,最后多了两个ip,也就是说docker为不同的容器分配了不同的ip,所以即便内部端口都是6379,但是由于前面的ip不同,所以自然也就可以共存(我猜的**)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。