1+X 云计算运维与开发(中级)案例实战——docker-compose的部署和基本使用
前言
学而不思则罔,思而不学则殆。
使用一台k8s镜像
IP | 主机名 |
---|---|
192.168.200.132/24 | compose |
思路
了解docker-compose的架构
了解docker-compose的基本运作和哪些文件之间的关系
实操
1.安装 docker-compose
[root@compose ~]# mv docker-compose /usr/local/bin/
[root@compose ~]# chmod +x /usr/local/bin/docker-compose
[root@compose ~]# docker-compose -v
docker-compose version 1.25.0-rc2, build 661ac20e
这里是下载命令:
curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
这里是github的地址: https://github.com/docker/compose
2.创建项目目录
[root@compose ~]# mkdir composetest
[root@compose ~]# cd composetest/
[root@compose composetest]#
3.定义app.py文件
在这个例子中,Redis 就是应用网络中 Redis 容器的主机名。端口使用的 Redis 默认端口 6379
[root@compose composetest]# cat app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits')
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/')
def hello():
count = get_hit_count()
return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
如果自己手打,千万注意格式,不然后面执行启动命令时会报错
4.定义requirements.txt文件
[root@compose composetest]# cat requirements.txt
flask
redis
5.定义Dockerfile
在这一步中,需要编写一个 Dockerfile 来构建一个 Docker 镜像。这个镜像包含 Python应用的所有依赖,也包含 Python 其本身。
[root@compose composetest]# cat Dockerfile
FROM python:3.5-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
本 Dockerfile 主要完成以下工作:
①构建一个基于 Python 3.5 的镜像。
②把当前目录添加到镜像中的/code 路径下。
③把工作路径设置成/code。
④安装 Python 依赖。
⑤设置容器的默认命令为 python app.py。
6.定义服务
在工作路径下创建一个 docker-compose.yml 文件并写入以下内容。
[root@compose composetest]# cat docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
编写时注意格式
这里有参考文章:转载自https://www.jianshu.com/p/cea930923f3d
这个 Compose 文件中定义了两个服务 Web 与 Redis。
Web 服务使用当前目录 Dockerfile 构建出来的镜像,并且将容器上暴露的 5000 端口转发到主机的 5000 端口,
使用 Flask Web 服务器的默认端口 5000。
Redis 服务使用从 Docker Hub 注册表中拉取的公有镜像。
7.运行服务
当我们只输入 “ docker-compose up ” 时:
Creating network "composetest_default" with the default driver
Building web
Step 1/5 : FROM python:3.5-alpine
3.5-alpine: Pulling from library/python
df20fa9351a1: Pull complete
36b3adc4ff6f: Pull complete
0c2f653029e6: Pull complete
62f59dc43a4a: Pull complete
ba334520d4fe: Pull complete
Digest: sha256:179992e913f024340db6347446966f69c153de72ad440b72bf7418c940c8692a
Status: Downloaded newer image for python:3.5-alpine
---> 6d034ccc54a2
Step 2/5 : ADD . /code
---> 5085bc7a68aa
Step 3/5 : WORKDIR /code
---> Running in 0478ce6b4361
Removing intermediate container 0478ce6b4361
---> f8971d25f45f
Step 4/5 : RUN pip install -r requirements.txt
---> Running in 0f0635b689da
DEPRECATION: Python 3.5 reached the end of its life on September 13th, 2020. Please upgrade your Python as Python 3.5 is no longer maintained. pip 21.0 will drop support for Python 3.5 in January 2021. pip 21.0 will remove support for this functionality.
Collecting flask
Downloading Flask-1.1.4-py2.py3-none-any.whl (94 kB)
Collecting redis
Downloading redis-3.5.3-py2.py3-none-any.whl (72 kB)
Collecting click<8.0,>=5.1
Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting Werkzeug<2.0,>=0.15
Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Collecting Jinja2<3.0,>=2.10.1
Downloading Jinja2-2.11.3-py2.py3-none-any.whl (125 kB)
Collecting itsdangerous<2.0,>=0.24
Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting MarkupSafe>=0.23
Downloading MarkupSafe-1.1.1.tar.gz (19 kB)
Building wheels for collected packages: MarkupSafe
Building wheel for MarkupSafe (setup.py): started
Building wheel for MarkupSafe (setup.py): finished with status 'done'
Created wheel for MarkupSafe: filename=MarkupSafe-1.1.1-py3-none-any.whl size=12629 sha256=93eb385bd9000e5e00e0c7ef3fb374e0cc5dc684aede347b3a00cf12d74ae73f
Stored in directory: /root/.cache/pip/wheels/18/c6/76/e7b4c7aeea1fc00134bfddf7ebadb0d91afda4c958b5bd4032
Successfully built MarkupSafe
Installing collected packages: click, Werkzeug, MarkupSafe, Jinja2, itsdangerous, flask, redis
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 flask-1.1.4 itsdangerous-1.1.0 redis-3.5.3
WARNING: You are using pip version 20.2.3; however, version 20.3.4 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
Removing intermediate container 0f0635b689da
---> a579d8cde2a8
Step 5/5 : CMD ["python", "app.py"]
---> Running in 7e667ee465e7
Removing intermediate container 7e667ee465e7
---> d8993f218a34
Successfully built d8993f218a34
Successfully tagged composetest_web:latest
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Pulling redis (redis:alpine)...
alpine: Pulling from library/redis
df9b9388f04a: Pull complete
192e03523482: Pull complete
7151bccd2756: Pull complete
683d62ead94f: Pull complete
b4ca937b9a43: Pull complete
b4bb2d8d1296: Pull complete
Digest: sha256:541e6d75df5dfb08e8859929bab06da265673808a6f2285abe6b7c76c1c98c6e
Status: Downloaded newer image for redis:alpine
Creating composetest_web_1 ... done
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
redis_1 | 1:C 29 Apr 2022 21:12:49.063 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 29 Apr 2022 21:12:49.063 # Redis version=7.0.0, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 29 Apr 2022 21:12:49.063 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis_1 | 1:M 29 Apr 2022 21:12:49.064 * monotonic clock: POSIX clock_gettime
redis_1 | 1:M 29 Apr 2022 21:12:49.065 * Running mode=standalone, port=6379.
redis_1 | 1:M 29 Apr 2022 21:12:49.065 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
redis_1 | 1:M 29 Apr 2022 21:12:49.065 # Server initialized
redis_1 | 1:M 29 Apr 2022 21:12:49.065 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
redis_1 | 1:M 29 Apr 2022 21:12:49.067 * The AOF directory appendonlydir doesn't exist
redis_1 | 1:M 29 Apr 2022 21:12:49.067 * Ready to accept connections
web_1 | * Serving Flask app "app" (lazy loading)
web_1 | * Environment: production
web_1 | WARNING: This is a development server. Do not use it in a production deployment.
web_1 | Use a production WSGI server instead.
web_1 | * Debug mode: on
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
web_1 | * Restarting with stat
web_1 | * Debugger is active!
web_1 | * Debugger PIN: 122-350-284
## 他会光标一直在这里闪,因为这是我们编写以上文件时,开启了debug模式
##当我们使用新窗口或者另一台机子(浏览器也行)去访问这台机子的IP地址:5000时他会有以下回显:
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:05] "GET / HTTP/1.1" 200 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:05] "GET /favicon.ico HTTP/1.1" 404 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:09] "GET / HTTP/1.1" 200 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:09] "GET / HTTP/1.1" 200 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:09] "GET / HTTP/1.1" 200 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:10] "GET / HTTP/1.1" 200 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:10] "GET / HTTP/1.1" 200 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:10] "GET / HTTP/1.1" 200 -
web_1 | 192.168.200.1 - - [29/Apr/2022 21:15:10] "GET / HTTP/1.1" 200 -
##以上是我刷新多次的结果
附上浏览器视图:
我们可以使用ctrl+c终止,但是该容器也会停止,所以我们需要使用 “ docker-compose up -d ” 命令使其在后台一直运行
^CGracefully stopping... (press Ctrl+C again to force)
Stopping composetest_redis_1 ... done
Stopping composetest_web_1 ... done
[root@compose composetest]# docker-compose up -d
Starting composetest_redis_1 ... done
Starting composetest_web_1 ... done
[root@compose composetest]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8c132fed0d2 redis:alpine "docker-entrypoint.s…" 4 minutes ago Up 3 seconds 6379/tcp composetest_redis_1
9e283cc00523 composetest_web "python app.py" 4 minutes ago Up 3 seconds 0.0.0.0:5000->5000/tcp composetest_web_1
[root@compose composetest]#
[root@compose composetest]# curl http://192.168.200.132:5000
Hello World! I have been seen 9 times.
##可以看到容器在后台运行着
8.更新服务文件
在项目路径下编辑 docker-compose.yml 为 Web 服务添加一个绑定挂载。
[root@compose composetest]# docker-compose down
Stopping composetest_redis_1 ... done
Stopping composetest_web_1 ... done
Removing composetest_redis_1 ... done
Removing composetest_web_1 ... done
Removing network composetest_default
[root@compose composetest]# vi docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
redis:
image: "redis:alpine"
[root@compose composetest]# docker-compose up -d
Creating network "composetest_default" with the default driver
Creating composetest_web_1 ... done
Creating composetest_redis_1 ... done
注意格式
新的 volumes 键将当前路径(项目路径)与容器中的/code 路径挂载到一起,允许用户及时修改代码而不用重新构建镜像
试验一下:
更改app.py文件中的回显语句,将第25行内容改为:
return 'Hello Docker! I have been seen {} times.\n'.format(count)
[root@compose composetest]# curl http://192.168.200.132:5000
Hello Docker! I have been seen 1 times.
[root@compose composetest]# curl http://192.168.200.132:5000
Hello Docker! I have been seen 2 times.
##可以看到Hello World变为了Hello Docker
总结
需要掌握Dockerfile的编写和docker-compose.yml的编写