多容器部署应用实战
一、端口映射
容器中部署的应用,如果端口没有暴露出来,外界是无法访问的:
1、创建nginx容器
[root@localhost ~]# docker run -d --name web-nginx nginx 3da548e8625ea371091922e7460c80e26a0650d50a51dc8f2f95bd4c945e2dea [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3da548e8625e nginx "nginx -g 'daemon of…" 9 seconds ago Up 5 seconds 80/tcp web-nginx
2、访问nginx服务
在访问这个nginx容器的服务时,我们需要知道这个容器的ip,但是nginx这个容器很简单里面查看ip的很多命令都没有,此时我们知道它是连接bridge网络,我们可以通过这来得知其ip地址:
[root@localhost ~]# docker network inspect bridge [ { "Name": "bridge", "Id": "4d8bf95cdadf4cb2d50cffdb9edb2416060e684d198a62d68f5908201a03f5bf", "Created": "2020-02-01T10:34:47.076499589+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "3da548e8625ea371091922e7460c80e26a0650d50a51dc8f2f95bd4c945e2dea": { "Name": "web-nginx", "EndpointID": "2c0f8a5efb5dc62c28a405bb52ef121ffa3e39ffcfae9a354e0217f897f2b8d2", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
可以看到Containers这一项中web-nginx的ip是172.17.0.2,我们在本机(容器的宿主机)是可以访问到的:
[root@localhost ~]# curl 172.17.0.2:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
但是显然外网是无法访问到的,此时我们需要端口的映射,保证外网是可以访问到。
3、端口映射
[root@localhost ~]# docker run -d --name web-nginx -p 80:80 nginx 3b2966afb7406c2abce6da67d9bc16e35d92c03870829ae5be58bb36f359f765 #通过-p参数指定端口映射 -p 容器服务端口:宿主机端口
此时,可以访问宿主机的80端口:
[root@localhost ~]# ifconfig ... ... ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.109 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::84a4:73f5:46d2:79d3 prefixlen 64 scopeid 0x20<link> ether 00:0c:29:f4:16:7e txqueuelen 1000 (Ethernet) RX packets 2427 bytes 189210 (184.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 628 bytes 64717 (63.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
4、总结
通过容器的端口映射将容器地址的80端口映射到虚拟机的地址80端口上,外部网络访问虚拟机地址的80端口即可。
二、多容器部署应用
1、创建app.py和Dcokerfile文件
[root@localhost ~]# cd flask-web/ [root@localhost flask-web]# ls [root@localhost flask-web]# touch app.py [root@localhost flask-web]# touch Dockerfile
- app.py文件
from flask import Flask from redis import Redis import os import socket app = Flask(__name__) redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379) #REDIS_HOST环境变量 @app.route('/') def hello(): redis.incr('hits') return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname()) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True)
- Dockerfile文件
FROM python:2.7 LABEL maintaner="shenjianping@gmail.com" COPY . /app/ WORKDIR /app/ RUN pip install flask redis EXPOSE 5000 CMD [ "python", "app.py" ]
2、Dockerfile文件build成镜像
[vagrant@localhost ~]$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
shenjiangping0307/flask-web latest e424dd15f9a2 About a m
3、运行redis容器
可以看到这个应用中使用到了redis,所以需要先部署redis容器,然后应用的容器进行连接即可:
- 拉取redis镜像
[root@localhost vagrant]# docker pull daocloud.io/daocloud/dao-redis latest: Pulling from library/redis f5d23c7fed46: Pull complete a4a5c04dafc1: Pull complete 605bafc84bc9: Pull complete f07a4e35cd96: Pull complete 17944e5e3eb7: Pull complete 6f875a8605e0: Pull complete Digest: sha256:9815a0d456dbbef05a5fd5efe4406db003d32a2f91de40f01b62457562e1d7f6 Status: Downloaded newer image for daocloud.io/library/redis:latest daocloud.io/library/redis:latest
docker pull daocloud.io/library/redis:latest #其它类似这样
- 启动redis容器
[root@localhost flask-web]# docker run -d --name redis daocloud.io/daocloud/dao-redis
431dc11f9c9c5240a7179efd97273ac557e55ffaa646d8e37fba1ecba193aa64 [root@localhost flask-web]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 431dc11f9c9c daocloud.io/library/redis "docker-entrypoint.s…" 21 seconds ago Up 20 seconds 6379/tcp redis
4、启动app应用
[root@localhost flask-web]# docker run -d --link redis --name web-flask -e REDIS_HOST=redis shenjianping0307/flask-web 3a32fbba037ad165064bc2aebc71c9dced269755005d5393f7e14f0b1d853c1b #-d后台启动 #-p端口映射 #--link 连接redis容器 #-e设置环境变量
可以进入到这个容器内部查看其环境变量:
[root@localhost flask-web]# docker exec -it web-flask /bin/sh # env REDIS_PORT=tcp://172.17.0.2:6379 PYTHONIOENCODING=UTF-8 REDIS_PORT_6379_TCP_ADDR=172.17.0.2 HOSTNAME=3a32fbba037a REDIS_NAME=/web-flask/redis PYTHON_PIP_VERSION=20.0.2 REDIS_PORT_6379_TCP_PORT=6379 HOME=/root REDIS_PORT_6379_TCP_PROTO=tcp REDIS_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-5.0.5.tar.gz GPG_KEY=C01E1CAD5EA2C4F0B8E3571504C367C218ADD4FF REDIS_ENV_REDIS_VERSION=5.0.5 REDIS_PORT_6379_TCP=tcp://172.17.0.2:6379 PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/42ad3426cb1ef05863521d7988d5f7fec0c99560/get-pip.py TERM=xterm PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin REDIS_ENV_REDIS_DOWNLOAD_SHA=2139009799d21d8ff94fc40b7f36ac46699b9e1254086299f8d3b223ca54a375 LANG=C.UTF-8 PYTHON_VERSION=2.7.17
另外,可以进入到app应用的容器查看redis是否连接成功:
[root@localhost flask-web]# docker exec -it web-flask /bin/sh # ping redis PING redis (172.17.0.2) 56(84) bytes of data. 64 bytes from redis (172.17.0.2): icmp_seq=1 ttl=64 time=0.136 ms 64 bytes from redis (172.17.0.2): icmp_seq=2 ttl=64 time=0.051 ms 64 bytes from redis (172.17.0.2): icmp_seq=3 ttl=64 time=0.052 ms
5、访问app应用
此时我们在app容器内部可以访问:
[root@localhost vagrant]# docker exec -it web-flask /bin/sh # curl 127.0.0.1:5000
但是在容器外部却是访问拒绝:
[root@localhost vagrant]# curl 127.0.0.1:5000 curl: (7) Failed connect to 127.0.0.1:5000; Connection refused
这是因为我们没有把端口暴露出来,通过-p命令来进行暴露:
[root@localhost vagrant]# docker run -d -p 5000:5000 --link redis --name web-flask -e REDIS_HOST=redis shenjianping0307/flask-web
这样就可以外部进行访问容器了。
作者:iveBoy
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。