使用docker compose編排容器

1、安裝docker compose

二進制包安裝

一、安裝 Docker Compose 從 官方 GitHub Release 處直接下載編譯好的二進制文件便可html

# curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-composepython

[root@bogon ~]# curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   617    0   617    0     0    355      0 --:--:--  0:00:01 --:--:--   355
100 7783k  100 7783k    0     0   471k      0  0:00:16  0:00:16 --:--:-- 1484k
[root@bogon ~]#
[root@bogon ~]# cd /usr/local/bin/
[root@bogon bin]# 
[root@bogon bin]# ls
docker-compose
[root@bogon bin]# ll
total 7784
-rw-r--r--. 1 root root 7970401 Apr  9 06:22 docker-compose
[root@bogon bin]#

二、併爲安裝腳本添加執行權限git

# chmod 755 docker-compose github

[root@bogon bin]# chmod 755 docker-compose 
[root@bogon bin]# 
[root@bogon bin]# ll
total 7784
-rwxr-xr-x. 1 root root 7970401 Apr  9 06:22 docker-compose
[root@bogon bin]#

三、查看安裝是否成功web

# docker-compose -vredis

[root@bogon bin]# docker-compose -v
docker-compose version 1.8.0, build f3628c7

四、對於卸載若是是二進制包方式安裝的,刪除二進制文件便可。docker

# rm -rf /usr/local/bin/docker-composeflask

2、使用docker-compose

一、爲項目建立一個目錄瀏覽器

# mkdir composetest服務器

# cd composetest/

[root@localhost ~]# mkdir composetest
[root@localhost ~]# 
[root@localhost ~]# cd composetest/
[root@localhost composetest]# 

二、建立一個app.py在項目目錄中調用的文件

# vi app.py

[root@localhost composetest]# vi 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)

 

redis是應用程序網絡上redis容器的主機名。咱們使用Redis的默認端口6379

三、建立requirements.txt項目目錄中調用的另外一個文件

# vi requirements.txt

[root@localhost composetest]# vi requirements.txt
flask
redis

 

四、建立dockerfile文件

# vi Dockerfile

[root@localhost composetest]# vi Dockerfile
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

說明:

FROM:從Python 3.4鏡像開始構建映像

ADD:添加當前目錄文件到code

WORKDIR:定義工做目錄code

RUN:在構建的鏡像中運行命令

CMD:將容器的默認命令設置爲python app.py

五、在Compose文件中定義服務

建立docker-compose.yml

# vi docker-compose.yml

[root@localhost composetest]# vi docker-compose.yml
version: '2'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

注意:官網上寫的是version '3',而後運行docker-compose up命令時報錯,而後把3改爲2

[root@localhost composetest]# ls
app.py  docker-compose.yml  Dockerfile  requirements.txt
[root@localhost composetest]# 
[root@localhost composetest]# docker-compose -v
docker-compose version 1.8.0, build f3628c7
[root@localhost composetest]# 
[root@localhost composetest]# docker-compose up
ERROR: Version in "./docker-compose.yml" is unsupported. You might be seeing this error because you're using the wrong Compose file version. Either specify a version of "2" (or "2.0") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.
For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/

此Compose文件定義了兩個服務,web和redis

該web服務使用從Dockerfile當前目錄中構建的鏡像

將容器上的公開端口5000轉發到主機上的端口5000。

咱們使用Flask Web服務器的默認端口5000

六、使用Compose構建並運行您的應用程序

從項目目錄中,經過運行啓動應用程序

# docker-compose up

[root@localhost composetest]# docker-compose up
Creating network "composetest_default" with the default driver
Building web
Step 1/5 : FROM python:3.4-alpine
Trying to pull repository docker.io/library/python ... 
3.4-alpine: Pulling from docker.io/library/python
8e402f1a9c57: Pull complete
cda9ba2397ef: Pull complete
aafecf9bbbfd: Pull complete
bc2e7e266629: Pull complete
e1977129b756: Pull complete
Digest: sha256:c210b660e2ea553a7afa23b41a6ed112f85dbce25cbcb567c75dfe05342a4c4b
Status: Downloaded newer image for docker.io/python:3.4-alpine
 ---> c06adcf62f6e
Step 2/5 : ADD . /code
 ---> d700bcab2d17
Removing intermediate container 3f5775b19826
Step 3/5 : WORKDIR /code
 ---> eefa4e6c6f62
Removing intermediate container 8bc944b6cf72
Step 4/5 : RUN pip install -r requirements.txt
 ---> Running in 7de50b315d7c

DEPRECATION: Python 3.4 support has been deprecated. pip 19.1 will be the last one supporting it. Please upgrade your Python as Python 3.4 won't be maintained after March 2019 (cf PEP 429).
Collecting flask (from -r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB)
Collecting redis (from -r requirements.txt (line 2))
  Downloading https://files.pythonhosted.org/packages/ac/a7/cff10cc5f1180834a3ed564d148fb4329c989cbb1f2e196fc9a10fa07072/redis-3.2.1-py2.py3-none-any.whl (65kB)
Collecting Werkzeug>=0.14 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/18/79/84f02539cc181cdbf5ff5a41b9f52cae870b6f632767e43ba6ac70132e92/Werkzeug-0.15.2-py2.py3-none-any.whl (328kB)
Collecting Jinja2>=2.10 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB)
Collecting click>=5.1 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
Collecting itsdangerous>=0.24 (from flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask->-r requirements.txt (line 1))
  Downloading https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz
Building wheels for collected packages: MarkupSafe
  Building wheel for MarkupSafe (setup.py): started
  Building wheel for MarkupSafe (setup.py): finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/f2/aa/04/0edf07a1b8a5f5f1aed7580fffb69ce8972edc16a505916a77
Successfully built MarkupSafe
Installing collected packages: Werkzeug, MarkupSafe, Jinja2, click, itsdangerous, flask, redis
Successfully installed Jinja2-2.10.1 MarkupSafe-1.1.1 Werkzeug-0.15.2 click-7.0 flask-1.0.2 itsdangerous-1.1.0 redis-3.2.1
 ---> 3be612bb7eee
Removing intermediate container 7de50b315d7c
Step 5/5 : CMD python app.py
 ---> Running in c6bd8cb54574
 ---> 70884628abf7
Removing intermediate container c6bd8cb54574
Successfully built 70884628abf7
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)...
Trying to pull repository docker.io/library/redis ... 
alpine: Pulling from docker.io/library/redis
8e402f1a9c57: Already exists
4c2113a1bbc9: Pull complete
a4b5ad98d179: Pull complete
779a3abe033a: Pull complete
84714e9d5602: Pull complete
8e66c4c614cb: Pull complete
Digest: sha256:a228f66132cd46a53fd818443c42458af5d6a3e1231df25184304b8e732e51c4
Status: Downloaded newer image for docker.io/redis:alpine
Creating composetest_web_1
Creating composetest_redis_1
Attaching to composetest_redis_1, composetest_web_1
redis_1  | 1:C 09 Apr 2019 12:13:05.157 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 09 Apr 2019 12:13:05.158 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 09 Apr 2019 12:13:05.158 # 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 09 Apr 2019 12:13:05.165 * Running mode=standalone, port=6379.
redis_1  | 1:M 09 Apr 2019 12:13:05.165 # 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 09 Apr 2019 12:13:05.165 # Server initialized
redis_1  | 1:M 09 Apr 2019 12:13:05.165 # 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 09 Apr 2019 12:13:05.165 # 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 09 Apr 2019 12:13:05.165 * Ready to accept connections
web_1    |  * Serving Flask app "app" (lazy loading)
web_1    |  * Environment: production
web_1    |    WARNING: Do not use the development server in a production environment.
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: 198-489-453
web_1    | 172.18.0.1 - - [09/Apr/2019 12:24:25] "GET / HTTP/1.1" 200 -
web_1    | 172.18.0.1 - - [09/Apr/2019 12:24:25] "GET /favicon.ico HTTP/1.1" 404 -
web_1    | 172.18.0.1 - - [09/Apr/2019 12:24:31] "GET / HTTP/1.1" 200 -

頁面就停留在這裏了,而後打開瀏覽器輸入地址訪問

http://IP地址:5000/

刷新頁面,數字應該增長。

切換到另外一個終端窗口,而後鍵入

# docker images

查看本地鏡像

[root@localhost ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
composetest_web     latest              70884628abf7        39 minutes ago      84.5 MB
docker.io/python    3.4-alpine          c06adcf62f6e        2 weeks ago         72.9 MB
docker.io/redis     alpine              07103bda7d12        2 weeks ago         51.6 MB

經過docker-compose down 在第二個終端的項目目錄中運行,或者在啓動應用程序的原始終端中按CTRL + C來中止應用程序。

web_1    | 172.18.0.1 - - [09/Apr/2019 14:05:56] "GET / HTTP/1.1" 200 -
^CGracefully stopping... (press Ctrl+C again to force)
Stopping composetest_redis_1 ... done
Stopping composetest_web_1 ... done
[root@localhost composetest]# 

 

七、編輯Compose文件以添加綁定裝載

 編輯docker-compose.yml在項目目錄添加綁定安裝web服務:

# vi docker-compose.yml

version: '2'
services:
  web:
    build: .
    ports:
     - "5000:5000"
    volumes:
     - .:/code
  redis:
    image: "redis:alpine"

 

新volumes密鑰將主機上的項目目錄(當前目錄)/code安裝到容器內部,容許您動態修改代碼,而無需重建鏡像。

八、使用Compose從新構建並運行應用程序

從項目目錄中,鍵入docker-compose up以使用更新的Compose文件構建應用程序,而後運行它。

# docker-compose up

提示我這個項目正在運行,不能再次開啓

[root@localhost composetest]# docker-compose up
Recreating composetest_web_1
Starting composetest_redis_1

ERROR: for web  Cannot start service web: driver failed programming external connectivity on endpoint composetest_web_1 (db4744d1208089127c52e9b1e201bfc0b94a66db86e4d266e356c15e7f24b147):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 5000 -j DNAT --to-destination 172.18.0.3:5000 ! -i br-012aad8c1511: iptables: No chain/target/match by that name.
 (exit status 1))
ERROR: Encountered errors while bringing up the project.

 

而後執行關閉命令

# docker-compose down

[root@localhost composetest]# docker-compose down
Stopping composetest_redis_1 ... done
Removing composetest_web_1 ... done
Removing composetest_redis_1 ... done
Removing 2386004fa63c_composetest_web_1 ... done
Removing network composetest_default
[root@localhost composetest]# 

 

再次開啓

# docker-compose up

[root@localhost composetest]# docker-compose up
Creating network "composetest_default" with the default driver
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule:  (iptables failed: iptables --wait -t nat -I DOCKER -i br-12896ecfa420 -j RETURN: iptables: No chain/target/match by that name.
 (exit status 1))

 

又報錯了,還好這個錯誤很常見,重啓docker服務便可解決

[root@localhost composetest]# systemctl restart docker
[root@localhost composetest]# 
[root@localhost composetest]# docker-compose up
Creating network "composetest_default" with the default driver
Creating composetest_web_1
Creating composetest_redis_1
Attaching to composetest_redis_1, composetest_web_1
redis_1  | 1:C 09 Apr 2019 14:15:11.016 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 09 Apr 2019 14:15:11.016 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 09 Apr 2019 14:15:11.016 # 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 09 Apr 2019 14:15:11.018 * Running mode=standalone, port=6379.
redis_1  | 1:M 09 Apr 2019 14:15:11.018 # 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 09 Apr 2019 14:15:11.018 # Server initialized
redis_1  | 1:M 09 Apr 2019 14:15:11.018 # 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 09 Apr 2019 14:15:11.018 # 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 09 Apr 2019 14:15:11.018 * Ready to accept connections
web_1    |  * Serving Flask app "app" (lazy loading)
web_1    |  * Environment: production
web_1    |    WARNING: Do not use the development server in a production environment.
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: 198-489-453

 再次瀏覽器訪問

九、更新應用程序

因爲應用程序代碼如今使用卷安裝到容器中,所以您能夠更改其代碼並當即查看更改,而無需重建鏡像。

更改問候語app.py並保存。例如,將Hello World!郵件更改Hello from Docker!

# vi app.py 

[root@localhost ~]# cd composetest/
[root@localhost composetest]# 
[root@localhost composetest]# ls
app.py  docker-compose.yml  Dockerfile  requirements.txt
[root@localhost composetest]# 
[root@localhost composetest]# vi 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 from Docker! I have been seen {} times.\n'.format(count)

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

刷新瀏覽器訪問

十、嘗試其餘一些命令

若是要在後臺運行服務,能夠將-d標誌(用於「分離」模式)傳遞給docker-compose up並使用docker-compose ps以查看當前正在運行的內容:

# docker-compose up -d

# docker-compose ps

 

[root@localhost composetest]# docker-compose ps
       Name                      Command               State    Ports 
---------------------------------------------------------------------
composetest_redis_1   docker-entrypoint.sh redis ...   Exit 0         
composetest_web_1     python app.py                    Exit 0         
[root@localhost composetest]# 
[root@localhost composetest]# docker-compose up -d
Starting composetest_web_1
Starting composetest_redis_1
[root@localhost composetest]# 
[root@localhost 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 
[root@localhost composetest]# 

 

docker-compose run命令容許您爲服務運行一次性命令。例如,要查看web服務可用的環境變量 :

# docker-compose run web env

[root@localhost composetest]# docker-compose run web env
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=931311c9a4f2
TERM=xterm
LANG=C.UTF-8
GPG_KEY=97FC712E4C024BBEA48A61ED3A5CA953F73C700D
PYTHON_VERSION=3.4.10
PYTHON_PIP_VERSION=19.0.3
HOME=/root

 

參閱其餘可用命令

# docker-compose --help

[root@localhost composetest]# docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [options] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file (default: docker-compose.yml)
  -p, --project-name NAME     Specify an alternate project name (default: directory name)
  --verbose                   Show more output
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the name specified
                              in the client certificate (for example if your docker host
                              is an IP address)

Commands:
  build              Build or rebuild services
  bundle             Generate a Docker bundle from the Compose file
  config             Validate and view the compose file
  create             Create services
  down               Stop and remove containers, networks, images, and volumes
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pulls service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  unpause            Unpause services
  up                 Create and start containers
  version            Show the Docker-Compose version information

 

中止服務

# docker-compose stop

[root@localhost 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 
[root@localhost composetest]# 
[root@localhost composetest]# docker-compose stop
Stopping composetest_redis_1 ... done
Stopping composetest_web_1 ... done
[root@localhost composetest]# 
[root@localhost composetest]# docker-compose ps
       Name                      Command               State    Ports 
---------------------------------------------------------------------
composetest_redis_1   docker-entrypoint.sh redis ...   Exit 0         
composetest_web_1     python app.py                    Exit 0         
[root@localhost composetest]# 

 

徹底刪除容器

# docker-compose down --volumes

--volumes:刪除Redis容器使用的數據卷

[root@localhost composetest]# docker-compose down --volumes
Removing composetest_web_run_1 ... done
Removing composetest_redis_1 ... done
Removing composetest_web_1 ... done
Removing network composetest_default
[root@localhost composetest]# 
[root@localhost composetest]# docker-compose ps 
Name   Command   State   Ports 
------------------------------
[root@localhost composetest]# 

 

參考博客:

https://www.cnblogs.com/ee900222/p/docker_5.html

官方文檔:

https://docs.docker.com/compose/gettingstarted/

相關文章
相關標籤/搜索