Winse Blog

走走停停, 熙熙攘攘, 忙忙碌碌, 不知何畏.

Docker Compose入门

使用Docker也一段时间了,一开始直接使用命令行 docker run 来启动的,后面使用 k8s 来管理,对于多机环境来说还是挺方便的。但是如果仅仅是单机上面跑docker容器,安装一套 k8s 的话也挺尴尬的。

docker提供了compose编排的功能,通过配置文件的方式来启动、管理(多)容器的运行。有点启动脚本的意思,当然也包含一些管理的元素,对容器LifeCycle的管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@k8s composetest]# docker version
Client:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.6.4
 Git commit:   78d1802
 Built:        Tue Jan 10 20:20:01 2017
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.6
 API version:  1.24
 Go version:   go1.6.4
 Git commit:   78d1802
 Built:        Tue Jan 10 20:20:01 2017
 OS/Arch:      linux/amd64
 
[root@k8s composetest]# docker-compose version
docker-compose version 1.16.1, build 6d1ac21
docker-py version: 2.5.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t  3 May 2016

docker的版本需要和compose配置的版本适配: https://github.com/docker/compose/releases ,docker-1.12的话,compose version不能高于 2.1。Compose file version 2

先安装官网的helloworld来运行一个例子:

安装:

1
2
3
4
5
6
7
8
9
10
11
12
# 浏览器下载docker-compose
https://github.com/docker/compose/releases/download/1.16.1/docker-compose-Linux-x86_64

[root@k8s opt]# cd /usr/local/bin/
[root@k8s bin]# rz
rz waiting to receive.
Starting zmodem transfer.  Press Ctrl+C to cancel.
Transferring docker-compose-Linux-x86_64 (1)...
  100%    8648 KB    4324 KB/sec    00:00:02       0 Errors  

[root@k8s bin]# mv docker-compose-Linux-x86_64 docker-compose
[root@k8s bin]# chmod +x docker-compose 

Hello World:

官网是一个访问量统计的例子,通过python网站结合redis来实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[root@k8s composetest]# ll
total 16
-rw-r--r--. 1 root root 303 Sep 17 08:09 app.py
-rw-r--r--. 1 root root 112 Sep 17 08:39 docker-compose.yml
-rw-r--r--. 1 root root 114 Sep 17 08:42 Dockerfile
-rw-r--r--. 1 root root  13 Sep 17 08:09 requirements.txt

[root@k8s composetest]# cat app.py 
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
  count = redis.incr('hits')
  return 'Hello World! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
  app.run(host="0.0.0.0", debug=True)

[root@k8s composetest]# cat requirements.txt 
flask
redis

[root@k8s composetest]# cat Dockerfile 
FROM python:3.4-alpine

ADD . /code
WORKDIR /code

RUN pip install -r requirements.txt

CMD ["python", "app.py"]

[root@k8s composetest]# cat docker-compose.yml 
version: '2.1'
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

依赖的镜像可以提前下载好,可以不修改docker配置的情况下来下载,参考docker-download-mirror.sh

写好配置后,运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
[root@k8s composetest]# docker-compose up --build
Building web
Step 1 : FROM python:3.4-alpine
 ---> 27a0e572c13a
Step 2 : ADD . /code
 ---> 84082044fb5e
Removing intermediate container 7c4675b618da
Step 3 : WORKDIR /code
 ---> Running in a014af85b748
 ---> 2ada42bd756c
Removing intermediate container a014af85b748
Step 4 : RUN pip install -r requirements.txt
 ---> Running in 4be6f8f5c8b8
Collecting flask (from -r requirements.txt (line 1))
  Downloading Flask-0.12.2-py2.py3-none-any.whl (83kB)
Collecting redis (from -r requirements.txt (line 2))
  Downloading redis-2.10.6-py2.py3-none-any.whl (64kB)
Collecting Jinja2>=2.4 (from flask->-r requirements.txt (line 1))
  Downloading Jinja2-2.9.6-py2.py3-none-any.whl (340kB)
Collecting click>=2.0 (from flask->-r requirements.txt (line 1))
  Downloading click-6.7-py2.py3-none-any.whl (71kB)
Collecting itsdangerous>=0.21 (from flask->-r requirements.txt (line 1))
  Downloading itsdangerous-0.24.tar.gz (46kB)
Collecting Werkzeug>=0.7 (from flask->-r requirements.txt (line 1))
  Downloading Werkzeug-0.12.2-py2.py3-none-any.whl (312kB)
Collecting MarkupSafe>=0.23 (from Jinja2>=2.4->flask->-r requirements.txt (line 1))
  Downloading MarkupSafe-1.0.tar.gz
Building wheels for collected packages: itsdangerous, MarkupSafe
  Running setup.py bdist_wheel for itsdangerous: started
  Running setup.py bdist_wheel for itsdangerous: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/fc/a8/66/24d655233c757e178d45dea2de22a04c6d92766abfb741129a
  Running setup.py bdist_wheel for MarkupSafe: started
  Running setup.py bdist_wheel for MarkupSafe: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/88/a7/30/e39a54a87bcbe25308fa3ca64e8ddc75d9b3e5afa21ee32d57
Successfully built itsdangerous MarkupSafe
Installing collected packages: MarkupSafe, Jinja2, click, itsdangerous, Werkzeug, flask, redis
Successfully installed Jinja2-2.9.6 MarkupSafe-1.0 Werkzeug-0.12.2 click-6.7 flask-0.12.2 itsdangerous-0.24 redis-2.10.6
 ---> ee3e476d4fad
Removing intermediate container 4be6f8f5c8b8
Step 5 : CMD python app.py
 ---> Running in f2f9eefe782e
 ---> 08e3065107b2
Removing intermediate container f2f9eefe782e
Successfully built 08e3065107b2
Recreating composetest_web_1 ... 
Recreating composetest_web_1
Starting composetest_redis_1 ... 
Recreating composetest_web_1 ... done
Attaching to composetest_redis_1, composetest_web_1
redis_1  | 1:C 17 Sep 00:43:45.012 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 17 Sep 00:43:45.013 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 17 Sep 00:43:45.013 # 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 17 Sep 00:43:45.020 * Running mode=standalone, port=6379.
redis_1  | 1:M 17 Sep 00:43:45.020 # 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 17 Sep 00:43:45.020 # Server initialized
redis_1  | 1:M 17 Sep 00:43:45.020 # 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 17 Sep 00:43:45.020 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
redis_1  | 1:M 17 Sep 00:43:45.020 * DB loaded from disk: 0.000 seconds
redis_1  | 1:M 17 Sep 00:43:45.020 * Ready to accept connections
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: 175-303-648

查看容器状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@k8s opt]# curl http://0.0.0.0:5000/
Hello World! I have been seen 1 times.
[root@k8s opt]# curl http://0.0.0.0:5000/
Hello World! I have been seen 2 times.

[root@k8s composetest]# docker-compose ps 
       Name                      Command               State           Ports         
-------------------------------------------------------------------------------------
composetest_redis_1   docker-entrypoint.sh redis ...   Up      6379/tcp              
composetest_web_1     python app.py                    Up      0.0.0.0:5000->5000/tcp

##
docker-compose rm -f # Remove stopped containers
docker-compose down  # Stop and remove containers, networks, images, and volumes

其他

后台运行:

1
2
$ docker-compose up -d
$ docker-compose ps

在指定容器内执行命令:有点类似 docker exec/kubectl exec

1
$ docker-compose run web env

单独编译运行 仅更改过内容的容器:

1
2
$ docker-compose build web
$ docker-compose up --no-deps -d web

配置复用/覆写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# A
webapp:
  build: .
  ports:
    - "8000:8000"
  volumes:
    - "/data"
   
# EA   
web:
  extends:
    file: common-services.yml
    service: webapp
    

学习

–END

Comments