跳至主要內容

十五、Docker 端口映射

安图新大约 5 分钟云原生Docker

Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源

Docker 可以让开发者打包它们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化

Docker 使用完全使用沙箱机制,两个容器之间不会有任何接口 (这个有点像 iPhone 的 app ) ,更重要的是容器性能开销极低

学习前提

在继续阅读之前,我们希望你对 Linux 有一些基本的了解,包括

1、 会使用Linux常用的命令;
2、 知道大部分的Linux常识,比如终端serviceip用户等;
3、 熟练使用Ubuntu或者Centos或者MacOS种的一种昂;

如果你对这些知识还是一知半解,可以访问我们的 Linux 基础教程 先进行一些简单的了解

Docker的应用场景

1、 Web应用的自动化打包和发布;
2、 自动化测试和持续集成、发布;
3、 在服务型环境中部署和调整数据库或其他的后台应用;
4、 从头编译或者扩展现有的OpenShift或CloudFoundry平台来搭建自己的PaaS环境;

Docker 的优点

1、 简化程序;

Docker 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,便可以实现虚拟化
Docker 改变了虚拟化的方式,使开发者可以直接将自己的成果放入 Docker 中进行管理
方便快捷已经是 Docker 的最大优势,过去需要用数天乃至数周的 任务,在Docker容器的处理下,只需要数秒就能完成

2、 解决运维配置噩梦;

在没有 Docker 之前,每一台机器,每一个要用到的依赖,几乎都要重新配置一遍
比如新增一台 MySQL 数据库,就要从头开始配置所有环境
有了 Docker 之后,只需要从仓库里把之前的 MySQL 镜像拉出来,直接使用

3、 节省开支;

使用 Docker ,可以在一台电脑上部署多个服务,多个应用,从而充分榨干每一滴性能
同时,又不用担心多个应用之间出现相互访问的情况

相关链接

Docker 官网: http://www.docker.comopen in new window

Github Docker 源码: https://github.com/docker/dockeropen in new window

前面章节中,当我们从一个镜像创建一个容器时,都会看到一个 -p 参数,这个 -p 参数就是用来实现端口映射的

网络应用程序都要开放端口供其它程序使用,Docker 容器中运行的网络应用程序也一样

如果要访问一个容器中的网络服务,方法之一就是先将容器中网络应用程序的端口映射到母机的一个端口上,这样,其它应用程序通过访问母机的端口来访问容器中的服务

网络端口映射

docker run 命令创建容器时添加端口映射的方法有两种: -P ( 大写的 P ) 和 -p (小写的 p )

这两种方法的区别是:

1、 **-P:**是容器内部端口随机映射到主机的高端口;
2、 **-p:**是容器内部端口绑定到指定的主机端口;

使用 -P ( 大写的 P ) 参数

例如下面的命令使用 -P 参数随机绑定本机端口

[root@www.hotmindshare.com ~]# docker run -d -P jcdemo/flaskapp
f6a0e149983a29294abd76c141f44e8da59bcbaf1d283be63fca803a486f9582
[root@www.hotmindshare.com ~]# docker run -d -P jcdemo/flaskapp
23f628a826340f24921233a1a48d3b3d4eedd23c9a5ee05abdf8f5e21fcf9c03

然后使用 docker ps -a 命令可以看到 PORTS 栏的本地端口,具有一定的随机性

[root@www.hotmindshare.com ~]# docker ps -a
CONTAINER ID  IMAGE               PORTS                  
23f628a82634  jcdemo/flaskapp     0.0.0.0:32769->5000/tcp
f6a0e149983a  jcdemo/flaskapp     0.0.0.0:32768->5000/tcp

使用 -p ( 小写的 p ) 参数指定端口映射

如果要指定映射到某个端口,则可以使用 -p [port]:[port] 参数

但这种方式需要我们实现知道容器内的网络服务的端口号

例如下面的应用程序使用 -p 标识来指定容器端口绑定到主机端口

[root@www.hotmindshare.com ~]# docker run -d -p 5555:5000 jcdemo/flaskapp
74795df6fcb856cdaf84d8222b27960774ba0b0f8d5ce40e8f12c26ac9c35a3a

使用docker ps 命令得到如下结果

[root@www.hotmindshare.com ~]# docker ps -a
CONTAINER ID   IMAGE               PORTS 
74795df6fcb8   jcdemo/flaskapp     0.0.0.0:5555->5000/tcp
23f628a82634   jcdemo/flaskapp     0.0.0.0:32769->5000/tcp
f6a0e149983a   jcdemo/flaskapp     0.0.0.0:32768->5000/tcp

如果指定的端口已经存在,容器仍然会被创建但出于停止状态,而且报错

[root@www.hotmindshare.com ~]# docker run -d -p 5000:5000 jcdemo/flaskapp
ac8dade70e675beecd02e18fb8af2c064b1700a38a58c6179f68fdcb2fefba9b
docker: Error response from daemon: driver failed programming external connectivity on endpoint hopeful_bassi (6cf77c7df2e9caaa2f4819cbbe82f2004fb75d2a221a1e90fbadb492dd32b9b5): Error starting userland proxy: Bind for 0.0.0.0:5000 failed: port is already allocated.

因为5000 端口已经被使用了,所以报错了,绑定端口错误

另外,我们可以指定容器绑定的网络地址,比如绑定 127.0.0.1

[root@www.hotmindshare.com ~]# docker run -d -p 127.0.0.1:5554:5000 jcdemo/flaskapp
a43d61d10e12802b4f108481cfb4f5008f11d2531d1e4715bd6f9a5dd39e17c1

使用docker ps -a 输出结果如下

[root@www.hotmindshare.com ~]# docker ps -a
CONTAINER ID   IMAGE               PORTS 
a43d61d10e12   jcdemo/flaskapp     127.0.0.1:5554->5000/tcp
74795df6fcb8   jcdemo/flaskapp     0.0.0.0:5555->5000/tcp
23f628a82634   jcdemo/flaskapp     0.0.0.0:32769->5000/tcp
f6a0e149983a   jcdemo/flaskapp     0.0.0.0:32768->5000/tcp

绑定 UDP 端口

默认情况下 -p-P 绑定的都是 tcp 协议端口

如果要绑定 udp 协议端口,只能使用 -p 参数,且在最后添加 /udp 字符串

例如下面的命令绑定了一个 udp 端口

[root@www.hotmindshare.com ~]# docker run -d -p 127.0.0.1:5553:5000/udp jcdemo/flaskapp
6aa30aa070a6e77f0d3f8653df69c654edf6e8bb68cea475aefbc68f6f7f9572

然后使用 docker ps -a 可以看到输出如下

[root@www.hotmindshare.com ~]# docker ps -a
CONTAINER ID   IMAGE               PORTS 
6aa30aa070a6   jcdemo/flaskapp     127.0.0.1:5553->5000/udp
a43d61d10e12   jcdemo/flaskapp     127.0.0.1:5554->5000/tcp
74795df6fcb8   jcdemo/flaskapp     0.0.0.0:5555->5000/tcp
23f628a82634   jcdemo/flaskapp     0.0.0.0:32769->5000/tcp
f6a0e149983a   jcdemo/flaskapp     0.0.0.0:32768->5000/tcp

docker port 命令查看端口绑定情况

可以使用 docker port 命令查看某个容器的端口绑定情况

docker port <CONTAINER_id> [PRIVATE_PORT[/PROTO]]

例如我们使用 docker port a43d61d10e12 查看容器 a43d61d10e12 的端口绑定情况如下

[root@www.hotmindshare.com ~]# docker port a43d61d10e12
5000/tcp -> 127.0.0.1:5554

绑定多个端口

多次使用 -p 参数可以映射多个端口

[root@www.hotmindshare.com ~]# docker run -d -p 5552:5000  -p 5551:5001 jcdemo/flaskapp
fa116ae4f5c19d82d9d4f40560c3219c85540a21d88f7fa999b60382ab57524a

使用docker ps 输出结果如下

[root@www.hotmindshare.com ~]# docker ps -a
CONTAINER ID   IMAGE               PORTS 
fa116ae4f5c1   jcdemo/flaskapp     0.0.0.0:5552->5000/tcp, 0.0.0.0:5551->5001/tcp
6aa30aa070a6   jcdemo/flaskapp     127.0.0.1:5553->5000/udp
a43d61d10e12   jcdemo/flaskapp     127.0.0.1:5554->5000/tcp
74795df6fcb8   jcdemo/flaskapp     0.0.0.0:5555->5000/tcp
23f628a82634   jcdemo/flaskapp     0.0.0.0:32769->5000/tcp
f6a0e149983a   jcdemo/flaskapp     0.0.0.0:32768->5000/tcp

上次编辑于:
贡献者: Andy