1.创建一个Nginx 容器,先不映射端口
[root@localhost ~]# docker run --name my_nginx -d nginx
7be3673a4c0f8f7ffe79a7b11ab86c4327dacaf734ed574e88e28c1db2243716
[root@localhost ~]# docker ps -a #可以看到容器启用了80端口,但是在宿主机上没有进行映射
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7be3673a4c0f nginx "nginx -g 'daemon ..." seconds ago Up seconds /tcp my_nginx
2.获取该容器的网络信息
[root@localhost ~]# docker exec -it my_nginx  /bin/bash   #可以看到Nginx容器非常简洁,很多shell命令都没有,无法查看一些我们想要的信息
root@7be3673a4c0f:/# ip a
bash: ip: command not found
root@7be3673a4c0f:/# ifconfig
bash: ifconfig: command not found root@localhost ~]# docker network inspect bridge #我们可以通过inspect查看一下网络信息
"Containers": {
"7be3673a4c0f8f7ffe79a7b11ab86c4327dacaf734ed574e88e28c1db2243716": {
"Name": "my_nginx",
"EndpointID": "6fa4eedf32d4a9d75b591d102613944d49a3cd40d2e41ea6c386685584fd09a7",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16", #容器的IP地址
"IPv6Address": ""
}
},
3.通过宿主机访问一下容器IP地址及端口
[root@localhost ~]# ping 172.17.0.2     #可以ping通
PING 172.17.0.2 (172.17.0.2) () bytes of data.
bytes from 172.17.0.2: icmp_seq= ttl= time=0.073 ms [root@localhost ~]# telnet 172.17.0.2 #Telnet 80端口正常
Trying 172.17.0.2...
Connected to 172.17.0.2.
Escape character is '^]'. [root@localhost ~]# curl -I 172.17.0.2 #访问Nginx容器80端口正常
HTTP/1.1 OK

小结:默认创建的容器如果有服务端口那么从宿主机可以访问,外部无法访问

4.创建一个容器,通过-p参数启动端口映射
[root@localhost ~]# docker rm -f my_nginx
[root@localhost ~]# docker run --name my_nginx -d -p : nginx #注意-p参数的格式
f1166a72ab910b425cf32b91ababde2a5b6a4fda6db08852bf7a99d925d4985f
[root@localhost ~]# docker ps -a #这里的规则映射了 0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过 -p IP:host_port:container_port 或 -p IP::port 来指定允许访问容器的主机上的 IP、接口等,以制定更严格的规则
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f1166a72ab91 nginx "nginx -g 'daemon ..." seconds ago Up seconds 0.0.0.0:->/tcp my_nginx

如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 /etc/docker/daemon.json 中添加如下内容:

{
"ip": "0.0.0.0"
}

通过宿主机IP地址访问(注意端口)

[root@localhost ~]# ifconfig eth0|awk 'NR==2{print $2}'
172.16.150.135

5.创建一个容器,通过-P参数启动端口映射
[root@localhost ~]# docker rm -f my_nginx
my_nginx
[root@localhost ~]# docker run --name my_nginx -d -P nginx #-P直接使用,不需要指定端口
8f9df2a803766862d08709b77054d35e890ca72c0ea17770dac8b3815278d35b
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f9df2a80376 nginx "nginx -g 'daemon ..." seconds ago Up seconds 0.0.0.0:->/tcp my_nginx

外部访问(注意端口)

6.-P及-p参数的用法及区别

官方文档文档:

   -P, --publish-all=true|false
Publish all exposed ports to random ports on the host interfaces. The default is false. When set to true publish all exposed ports to the host interfaces. The default is false. If the operator uses -P (or -p) then Docker will make the
exposed port accessible on the host and the ports will be available to any client that can reach the host. When using -P, Docker will bind any exposed
port to a random port on the host within an ephemeral port range defined by /proc/sys/net/ipv4/ip_local_port_range. To find the mapping between the host
ports and the exposed ports, use docker port. -p, --publish=[]
Publish a container's port, or range of ports, to the host. Format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort Both hostPort and containerPort can be specified as a
range of ports. When specifying ranges for both, the number of container ports in the range must match the number of host ports in the range. (e.g.,
docker run -p -:- --name thisWorks -t busybox but not docker run -p -:- --name RangeContainerPortsBiggerThanRangeHost‐
Ports -t busybox) With ip: docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage Use docker port to see the actual mapping:
docker port CONTAINER $CONTAINERPORT

-P:

在宿主机上通过随机端口映射容器内启用端口,随机的端口范围通过/proc/sys/net/ipv4/ip_local_port_range配置获取
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_local_port_range

-p:

可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。
端口映射支持的格式有:
  ip:hostport:containerport #指定ip、指定主机port、指定容器port
  ip::containerport #指定ip、未指定主机port、指定容器port
  hostport:container #未指定ip port、指定主机port、指定容器port
多次使用-p标记可以绑定多个端口,例 -p 00:80 -p 8088:8080
可以指定范围,例 -p 1234-1236:1222-1224

不管用那种办法,其实也是在本地的 iptable 的 nat 表中添加相应的规则:

使用 -p 80:80 时:

[root@localhost ~]#  iptables -t nat -vnL|grep :
MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:
DNAT tcp -- !docker0 * 0.0.0.0/ 0.0.0.0/ tcp dpt: to:172.17.0.2:

使用 -P 时:

[root@localhost ~]#  iptables -t nat -vnL|grep :
MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:
DNAT tcp -- !docker0 * 0.0.0.0/ 0.0.0.0/ tcp dpt: to:172.17.0.2:

docker容器的端口映射的更多相关文章

  1. 如何修改运行中的docker容器的端口映射和挂载目录

    在docker run创建并运行容器的时候,可以通过-p指定端口映射规则.但是,我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改.当docker start运行容器后并没有提供一个-p选项或设 ...

  2. 教你如何修改运行中的docker容器的端口映射

    在docker run创建并运行容器的时候,可以通过-p指定端口映射规则.但是,我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改.当docker start运行容器后并没有提供一个-p选项或设 ...

  3. [转帖]教你如何修改运行中的docker容器的端口映射

    教你如何修改运行中的docker容器的端口映射   在docker run创建并运行容器的时候,可以通过-p指定端口映射规则.但是,我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改.当dock ...

  4. 如何修改运行中的docker容器的端口映射

    在docker run创建并运行容器的时候,可以通过-p指定端口映射规则.但是,我们经常会遇到刚开始忘记设置端口映射或者设置错了需要修改.当docker start运行容器后并没有提供一个-p选项或设 ...

  5. Docker容器内部端口映射到外部宿主机端口的方法小结

    转自:https://www.cnblogs.com/kevingrace/p/9453987.html Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务.容器启动之后,容器中可以 ...

  6. 修改docker容器的端口映射

    大家都知道docker run可以指定端口映射,但是容器一旦生成,就没有一个命令可以直接修改.通常间接的办法是,保存镜像,再创建一个新的容器,在创建时指定新的端口映射. 有没有办法不保存镜像而直接修改 ...

  7. 修改已经创建的docker容器的端口映射

    原始链接:https://stackoverflow.com/questions/19335444/how-do-i-assign-a-port-mapping-to-an-existing-dock ...

  8. Docker容器内部端口映射到外部宿主机端口 - 运维笔记

    Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务.容器启动之后,容器中可以运行一些网络应用,通过-p或-P参数来指定端口映射. 注意:宿主机的一个端口只能映射到容器内部的某一个端口 ...

  9. 解决docker容器开启端口映射后,会自动在防火墙上打开端口的问题

    在docker中运行第三方服务时,通常需要绑定服务端口到本地主机.但使用 -p 参数进行的端口映射,会自动在iptables中建立规则,绕过firewalld,这对于端口级的黑白名单控制管理是很不利的 ...

随机推荐

  1. MySQL中的group_concat函数的使用

    本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . MySQL中group_concat函数 完整的语法如下: grou ...

  2. C# get files and write the files full name in txt

    static void GetAllFiles() { string path = "filepath"; var allFiles = Directory.GetFiles(pa ...

  3. vue-基本动画

    不使用动画 <div id="app"> <input type="button" value="toggle" @cli ...

  4. charAt()检测回文

    package seday01; /** * char charAt(int index) 返回指定位置对应的字符 * @author xingsir */public class CharAtDem ...

  5. webservice调用天气服务

    常见服务:http://www.webxml.com.cn/zh_cn/support.aspx 可能用到缺少的ArrayOfString.java文件 package com.test.wes.we ...

  6. ProtoBuf格式详解

    - 数据结构 通过前面的例子,可以看到PB的数据结构就是每项数据独立编码,包含一个表示数据类型 - Varint Varint是一种对数字进行编码的方法,将数字编码成不定长的二进制数据,数值越小,编码 ...

  7. 3. 海思Hi3519A MPP从入门到精通(三 视频输入)

    视频输入(VI)模块实现的功能:通过 MIPI Rx(含 MIPI 接口.LVDS 接口和 HISPI 接 口),SLVS-EC,BT.1120,BT.656,BT.601,DC 等接口接收视频数据. ...

  8. Linux 设备树详解【转】

    转自:http://www.pianshen.com/article/428276673/;jsessionid=D90FC6B215155680E0B89A6D060892D4 本文基于天嵌E9V3 ...

  9. 【转】Redis常见面试题

    介绍:Redis 是一个开源的使用 ANSI C 语言编写.遵守 BSD 协议.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API的非关系型数据库. 传统数据 ...

  10. 剑指Offer-5.用两个栈实现队列(C++/Java)

    题目: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 分析: 栈的特点是先进后出,队列的特点则是先进先出. 题目要求我们用两个栈来实现一个队列,栈和队列都有入栈 ...