Docker 进阶指南(下)- 使用Docker Compose编排多个容器

前言

大家好,我是洋子。在文章《Docker 进阶指南(上)- 使用Dockerfile自定义镜像》介绍了使用DockerFile文件自定义Docker镜像方法,编写好DockerFile文件后,执行docker build命令,即可生成一个镜像,我们再使用docker run命令,即可运行该镜像所生成的容器

但我们使用DockerFile自定义的都是单个镜像,然后手动执行docker run运行单个容器,在实际工作当中,我们需要同时使用到多个容器(如Mysql容器,Nginx容器等),去部署完整的Web服务,那要是想同时部署多个Docker 容器该怎么办呢

这时候需要用到Docker-Compose容器编排工具即可解决这个问题

Docker-Compose 使用方法

Compose 是用于定义和运行多容器 Docker 应用程序的工具

在Docker官网上,提供了使用Docker-Compose的详细例子,https://docs.docker.com/compose/gettingstarted/,下面根据这个例子来操作一遍,部署Python Web开发项目

  1. 安装下载。在已经安装好Docker环境后(Docker的安装方法,可以查看文章Docker快速入门指南),执行以下命令安装Docker-Compose
# 官方下载源,安装慢
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker- compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 其他下载源,安装快
sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

安装完毕后,使用docker-compose version验证安装结果,出现以下信息代表安装成功

[root@yangzi ~]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019
  1. 创建并进入项目目录
mkdir composetest
cd composetest
  1. 在项目目录下,创建程序入口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)
  1. 创建requirements.txt,此文件存放项目当中需要拉取的依赖包
flask
redis
  1. 创建Dockerfile文件,用于定义Python环境的镜像
# syntax=docker/dockerfile:1
# 基础镜像基于Python3.7
FROM python:3.7-alpine
# 设置工作目录为`/code`
WORKDIR /code
# 设置两个环境变量,启动Flask项目时会读取
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
# 安装gcc等其他依赖
RUN apk add --no-cache gcc musl-dev linux-headers
# 拷贝requirements.txt到工作目录,并且安装python依赖
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
# 容器暴露端口5000
EXPOSE 5000
# 把当前项目目录里的内容,拷贝到容器里的工作目录/code
COPY . .
# 容器启动时,执行命令flask run
CMD ["flask", "run"]
  1. 在项目目录下创建 Compose 文件,名字为docker-compose.yml,该文件格式为yaml
version: "3"
services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"

这里先简单介绍一下 Compose 文件的格式含义

  • version表示指明Compose文件版本,可以是2.x或者3.x
  • services表示定义了两个服务,用于容器创建,第一个服务名为web,这里使用build关键字,后面还有一个.表示当前目录,它的含义和命令docker build一样,即编译当前目录下的Dockerfile文件创建镜像,同时映射端口8000对应于容器里面的5000端口
  • 第二个服务名为redis,直接使用了官方镜像redis:alpine
  • Compose 文件当中更多字段含义,可以查看官方文档
    https://docs.docker.com/compose/compose-file/
  1. 执行命令docker-compose up -d就可以同时创建两个容器(docker ps 命令可以查看创建的容器),-d参数表示后台执行
[root@yangzi composetest]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS         PORTS                                       NAMES
a84114348ef8   composetest_web   "flask run"              24 minutes ago   Up 9 minutes   0.0.0.0:8000->5000/tcp, :::8000->5000/tcp   composetest_web_1
255dea45b4d6   redis:alpine      "docker-entrypoint.s…"   24 minutes ago   Up 9 minutes   6379/tcp                                    composetest_redis_1

最后用curl http://127.0.0.1:8000命令,验证一下服务的运行情况,也可以用hostname -i 查看到本机的ip,用本地ip:8000端口,在浏览器访问查看效果

[root@zhouyueyang composetest]# curl http://127.0.0.1:8000
Hello World! I have been seen 1 times.

在这里插入图片描述

  1. 如果我们的项目代码,要进行多次修改,按照目前Compose文件的定义,我们需要重新创建容器,可以继续优化一下Compose文件,进行持久化绑定,如我们使用到volumes字段,将本地当前的目录绑定到容器里面的/code目录,在本地目录下修改代码后会实时同步,就不再需要重新创建容器了
version: "3"
services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
    environment:
      FLASK_DEBUG: True
  redis:
    image: "redis:alpine"

Docker 容器数据卷

我们现在已经知道Docker将应用和运行的环境打包形成容器运行,所以容器内产生的数据,都在容器内保存,如果我使用了MySQL容器,不小心把容器删了,所有数据就没有了,这不就直接删库跑路了

那如何将容器内的数据同步到本地,进行持久化存储呢?使用数据卷技术即可解决这个问题

在docker中,卷的本质是文件或者目录,存在一个或者多个容器中,由docker挂载到容器,不属于联合文件系统;对数据卷的修改会立马生效,对数据卷的更新不会影响镜像

数据卷用于容器的持久化,以及容器间的继承和数据共享

容器卷有哪些特点

  • 数据卷可在容器之间共享或重用数据

  • 数据卷中的更改不会包含在镜像的更新中

  • 卷中的更改可以直接生效

  • 数据卷的生命周期一直持续到没有容器使用它为止

如何使用数据卷

  1. 方法一,通过命令行添加,以运行centos容器为例子
#前提条件,先拉取centos7镜像
docker pull centos:7

# 命令
docker run -it -v 宿主机绝对路径目录:容器内目录 镜像名
# 测试
[root@yangzi ~]# docker run -it -v /home/test:/home centos /bin/bash

查看数据卷是否挂载成功 docker inspect 容器id,可以看到这里Source就是挂载的宿主机本地的目录在这里插入图片描述
接下来我们在centos容器/home目录进行新建文件,在本地宿主机上/home/test目录就可以出现,同理,在本地卷目录/home/test下更新文件,centos容器里面相应目录下,也会进行内容更新

下面的操作就是在宿主机挂载的卷目录下新建了xxx.java文件,自动同步到容器里面

[root@yangzi test]# touch xxx.java
[root@yangzi test]# ls
xxx.java
[root@yangzi test]# docker attach 531a8f70f60c
[root@531a8f70f60c /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@531a8f70f60c /]# cd /home
[root@531a8f70f60c home]# ls
xxx.java
  1. 其余使用方法。在DockerfileCompose文件当中同样可以使用到数据卷,只是定义的语法上略有不同,在之前文章《Docker 进阶指南(上)- 使用Dockerfile自定义镜像》,以及本篇文章均有相关介绍,这里就不再重复讲解了

docker的常用命令大总结

  • 操作容器的常用命令有 docker psdocker rundocker execdocker stop
  • 操作镜像的常用命令有 docker imagesdocker rmidocker tagdocker build
  • 操作镜像仓库的常用命令有 docker pulldocker push

如果前面的内容都已经学完了,看这张图就比较容易了,Docker命令都是基于Registry镜像仓库和Images镜像,Container容器这三个角色展开,其中的大部分命令我们都使用过了
在这里插入图片描述

结束语

到这里,Docker的系列的三篇文章就完结了,后面即将开启学习新的容器技术k8s,毕竟这才是目前容器技术的主角

如果你觉得本篇文章对你有帮助,麻烦点一下【赞】和【在看】,你的支持就是我前进的动力

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bug 挖掘机

支持洋子

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值