
大概过程如下:
先停止现有容器
docker stop container-name
将容器commit成为一个镜像
docker commit container-name new-image-name
用新镜像运行容器
docker run -it -d --name container-name -p p1:p1 -p p2:p2 new-image-name
一般在运行容器时,我们都会通过参数 -p(使用大写的-P参数则会随机选择宿主机的一个端口进行映射)来指定宿主机和容器端口的映射,例如
docker run -it -d --name [container-name] -p8088:80[image-name]
这里是将容器内的80端口映射到宿主机的8088端口
参数说明
-d 表示后台运行容器
-t 为docker分配一个伪终端并绑定到容器的标准输入上
-i 是让容器的标准输入保持打开状态
-p 指定映射端口
在运行容器时指定映射端口运行后,如果想要添加新的端口映射,可以使用以下两种方式:
方式一:将现有的容器打包成镜像,然后在使用新的镜像运行容器时重新指定要映射的端口
大概过程如下:
先停止现有容器
docker stop container-name
将容器commit成为一个镜像
docker commit container-name new-image-name
用新镜像运行容器
docker run -it -d --name container-name -pp1:p1-pp2:p2new-image-name
方式二:修改要端口映射的容器的配置文件
查看容器信息 :
dockerps-a
查看 容器的端口映射 情况,在容器外执行:
docker port 容器ID 或者 docker port 容器名称
查找要修改容器的容器Id
docker inspect f244 |grepId
进到/var/lib/docker/containers 目录下找到与 Id 相同的目录,修改 hostconfig.json 和 config.v2.json文件 :
若该容器还在运行,先停掉
docker stop 容器ID
停掉docker服务
systemctl stop docker
修改hostconfig.json如下,添加端口绑定"9003/tcp": [{"HostIp": "","HostPort": "9003"}],表示绑定端口9003
修改config.v2.json在ExposedPorts中加上要暴露的端口,即9003
改完之后保存启动docker
systemctl start docker
之后可以再次查看添加的端口是否已映射绑定上
附注:
1、将容器打包成镜像命令:
docker commit -a"king西阳"-m"a new image"[容器名称或id] [打包的镜像名称]:[标签]
常用OPTIONS说明:
-a :提交的镜像作者
-c :使用Dockerfile指令来创建镜像
-m :提交时的说明文字
-p :在commit时,将容器暂停
2、查看宿主机端口是否和容器内端口映射成功,在容器外执行
netstat -an |grep宿主机的映射端口
如果有进程存在则表示有映射
利用Net Namespace可以为Docker容器创建隔离的网络环境,容器具有完全独立的网络栈,与宿主机隔离。也可以使Docker容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要。Docker支持 4种网络模式 :
1)host模式,--net=host指定,不支持多主机。
2)container模式,--net = container : name_or_id指定,不支持多主机。
3)none模式,--net=none指定,不支持多主机。
4)bridge模式,--net=bridge指定,默认设置,不支持多主机。
启动容器的时候使用Host模式,那么该容器与宿主机共用一个Network Namespace,因此容器将不会虚拟自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。
采用Host模式的容器,可以直接使用宿主机的IP地址与外界进行通信,无需额外进行NAT转换。由于容器通信时,不再需要通过Linux Bridge等方式转发或者数据包的拆封,性能上有很大优势。当然, Host模式有利也有弊 ,主要包括以下缺点:
1)容器没有隔离、独立的网络栈。容器因与宿主机共用网络栈而争抢网络资源,并且容器崩溃也可能导致宿主机崩溃,这在生产环境中是不允许发生的。
2)容器不再拥有所有的端口资源,因为一些端口已经被宿主机服务、Bridge模式的容器端口绑定等其他服务占用了。
需要补充说明的是,Host模式下的容器仅仅是网络命名空间与主机相同,但容器的文件系统、进程列表等还是和与宿主机隔离的。
Container模式是一种特殊的网络模式。该模式下的容器使用其他容器的网络命名空间,网络隔离性会处于Bridge模式与Host模式之间。当容器与其他容器共享网络命名空间时,这两个容器间不存在网络隔离,但它们与宿主机及其他容器又存在网络隔离。
在Kubernetes体系架构下引入Pod概念,Kubernetes为Pod创建一个基础设施容器, 同一Pod下的其他容器都以Container模式 共享这个基础设施容器的网络命名空间,相互之间以localhost访问,构成一个统一的整体。
与前两种不同,None模式的Docker容器拥有自己的Network Namespace,但并不为Docker容器进行网络配置。该Docker容器没有网卡、IP、路由等信息。需要用户为Docker容器添加网卡、配置IP等。
Bridge模式是Docker默认的网络模式,也是开发者最常使用的网络模式。在这种模式下,Docker为容器创建独立的网络栈,保证容器内的进程使用独立的网络环境,实现容器之间、容器与宿主机之间的网络栈隔离。同时,通过宿主机上的Docker0网桥,容器可以与宿主机乃至外界进行网络通信。
同一宿主机上,容器之间都是连接在Docker0这个网桥上,Docker0作为虚拟交换机使容器间相互通信 。但是, 由于宿主机的IP地址与容器veth pair的IP地址均不在同一个网段 ,故仅仅依靠 veth pair和NameSpace的技术 并不足以使宿主机以外的网络主动发现容器的存在。Docker采用了 端口绑定的方式(通过iptables的NAT) ,将宿主机上的端口流量转发到容器内的端口上,这样一来,外界就可以与容器中的进程进行通信。 iptables的介绍,请点我点我 。
创建容器,并将宿主机的3306端口绑定到容器的3306端口:docker run -tid --name db -p 3306:3306 mysql
在宿主机上,可以通过“iptables -t nat -L -n”,查到一条DNAT规则:DNAT tcp --0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306
Bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,这会造成对宿主机端口管理很复杂。同时,由于容器与外界通信是基于三层上iptables NAT,性能和效率损耗是显而易见的。
NAT将地址空间分段的做法引入了额外的复杂度。比如容器中应用所见的IP并不是对外暴露的IP, 因为网络隔离,容器中的应用实际上只能检测到容器的IP,但是需要对外宣称的则是宿主机的IP,这种信息的不对称将带来诸如破坏自注册机制等问题 。
摘抄自陆平的《基于Kubernetes的容器云平台实战》一书的第10章Kubernetes网络
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)