我们会遇到一个问题:当我们的docker容器启动一个端口为8080,提供Nginx服务。他的IP为127的本地IP,如何才能通过外部网络正常访问呢?
docker给出的解决方案是:使用-p参数,将Nginx容器的80端口映射到宿主机的8080,然后通过宿主机的8080端口对外提供服务。这就好比是在宿主机上启动了一个8080端口提供Nginx服务是一个意思。
我们来实验一下。
首先我们宿主机的IP为:192.168.209.130,默认8080为关闭状态
1,我们需要先登录阿里云的账号,下载一个官方提供的Nginx容器
docker login --username=一梦浮生1987 registry.cn-hangzhou.aliyuncs.com
[root@localhost data01]# docker login --username=一梦浮生1987 registry.cn-hangzhou.aliyuncs.com
Password:
Login Succeeded
[root@localhost data01]# docker pull nginx
Using default tag: latest
Trying to pull repository docker.io/library/nginx ...
latest: Pulling from docker.io/library/nginx
69692152171a: Pull complete
30afc0b18f67: Pull complete
596b1d696923: Pull complete
febe5bd23e98: Pull complete
8283eee92e2f: Pull complete
351ad75a6cfa: Pull complete
Digest: sha256:6d75c99af15565a301e48297fa2d121e15d80ad526f8369c526324f0f7ccb750
Status: Downloaded newer image for docker.io/nginx:latest
给下载的镜像改个名字方便使用
[root@localhost data01]# docker tag docker.io/nginx:latest nginx:v1
[root@localhost data01]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
c
nginx v1 d1a364dc548d 2 days ago 133 MB
2,使用这个Nginx镜像,创建一个Nginx容器。
docker run -itd --name Nginx1 -v /data01:/data01 nginx:v1 /bin/bash
[root@localhost data01]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b087a6082a72 nginx:v1 "/docker-entrypoin..." 11 seconds ago Up 10 seconds 80/tcp Nginx1
进入容器看下
docker exec -it Nginx1 /bin/bash
接下来我们找到Nginx的安装目录
root@b087a6082a72:~# find / -name nginx
/etc/default/nginx
/etc/init.d/nginx
/etc/logrotate.d/nginx
/etc/nginx #主文件目录
/usr/lib/nginx #
/usr/sbin/nginx #启动命令
/usr/share/doc/nginx
/usr/share/nginx
/var/cache/nginx
/var/log/nginx #日志目录
然后我们会发现ps、netstat、vi等等命令都不能用。
找到nginx.conf,发现他调用了
include /etc/nginx/conf.d/*.conf;
cat /etc/nginx/conf.d/default.conf
发现他指定了端口为80,可我们也不能改端口啊,怎么查看Nginx启动状态呢?试了试,还好有个curl工具
root@b087a6082a72:~# curl 127.0.0.1:80
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
发现无法连接,说明Nginx没有启动,让我们直接启动nginx
root@b087a6082a72:~# nginx
再看:
这次有了。
但问题也出来了,我们只能在docker容器里面看nginx进程,怎么对外部提供服务呢?
docker提供了-p参数,我们使用这个参数新建一个容器为nginx2,将宿主机的8080和容器的80端口映射,看是否能在本地打开
[root@localhost ~]# docker run -itd -p 8080:80 --name Nginx2 -v /data01:/data01 nginx:v1 /bin/bash
c6c7ecb6b515f56db942d8ca8aeaa008e299b1dc54aa984322b06c968548c91d
[root@localhost ~]#
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c6c7ecb6b515 nginx:v1 "/docker-entrypoin..." 4 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp Nginx2
查看宿主机,发现宿主机的8080端口开放了
[root@localhost ~]# netstat -ano | grep 8080
tcp6 0 0 :::8080 :::* LISTEN off (0.00/0/0)
我们试试用192.168.209.130:8080访问
成了!实验证明,端口映射起作用了。
实验虽然成功了,但是nginx容器使用起来却不是那么完美,首先我们无法在容器内更改nginx的配置文件,也就无法对nginx进行配置,不过没关系,我们在启动容器的时候,指定了一个共享目录为/data01,我们可以将nginx的配置文件写好后,放在/data01里面,直接替换这个nginx.conf即可。
同样,也可以使用nginx -C 配置文件的绝对路径来自己定义nginx启动所需要的文件。
当然,我们也可以把以上文件编排好之后,使用dockerfile来重新启动一个容器提供服务。
需要注意:
docker端口映射有-P和-p之分
如果使用-P随机映射的话,启动容器后,使用
docker ps -a即可查看映射关系。docker port 也可以查看。
[root@localhost ~]# docker port Nginx2
80/tcp -> 0.0.0.0:8080