• 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
    
    • 1
    • 2
    • 3
    • 4
    • 5

    安装完毕后,使用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
    • 2
    • 3
    • 4
    • 5
    1. 创建并进入项目目录
    mkdir composetest
    cd composetest
    
    • 1
    • 2
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. 创建requirements.txt,此文件存放项目当中需要拉取的依赖包
    flask
    redis
    
    • 1
    • 2
    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. 在项目目录下创建 Compose 文件,名字为docker-compose.yml,该文件格式为yaml
    version: "3"
    services:
      web:
        build: .
        ports:
          - "8000:5000"
      redis:
        image: "redis:alpine"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里先简单介绍一下 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
    
    • 1
    • 2
    • 3
    • 4

    最后用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
    • 2

    在这里插入图片描述

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

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查看数据卷是否挂载成功 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 其余使用方法。在DockerfileCompose文件当中同样可以使用到数据卷,只是定义的语法上略有不同,在之前文章《Docker 进阶指南(上)- 使用Dockerfile自定义镜像》,以及本篇文章均有相关介绍,这里就不再重复讲解了

    docker的常用命令大总结

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

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

    结束语

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

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

  • 相关阅读:
    计算机毕业设计之java+javaweb的医院门诊挂号系统
    监控系统典型架构
    Python复习笔记5——常用模块
    ROS中tf转换 launch文件 静态坐标转化写法
    SprimgMVC增删改查·
    【JVM基础】方法区
    linux study01
    kaggle_competition1_CIFAR10_Reg
    R语言APRIORI关联规则、K-MEANS均值聚类分析中药专利复方治疗用药规律网络可视化...
    CY3/CY3.5/CY5/CY5.5/CY7/CY7.5标记链霉亲和素 Streptavidin
  • 原文地址:https://blog.csdn.net/u011035397/article/details/126762422