当前位置 博文首页 > RtxTitanV的博客:Docker Compose快速入门

    RtxTitanV的博客:Docker Compose快速入门

    作者:[db:作者] 时间:2021-07-07 10:15

    Docker Compose是Docker官方推出的一种容器编排服务,可以快速在集群中部署分布式应用。本文主要参考官方的快速入门示例来总结一下Docker Compose的简单使用。示例的场景是构建一个运行在Docker Compose上的简单Python Web应用程序。该应用程序使用Flask框架,在Redis中维护一个计数器,并将统计的结果返回。至于Docker Compose的安装,可以参考Docker Compose在Linux上的安装。

    一、Docker Compose简介

    Docker Compose是Docker官方开源项目,实现了对Docker容器集群的快速编排。Compose定位是定义和运行多个Docker容器的应用程序。通过Compose,可以使用YAML文件来配置应用服务。然后通过一个命令,就可以从配置中创建并启动所有服务。Compose可以应用于开发、测试、CI工作流和生产等所有环境。

    Compose中有两个重要的概念:

    • 服务(service):一个应用的容器集合,一个服务可以横向扩展为多个容器实例。
    • 项目(project):由一组关联的应用容器组成的一个完整业务单元,一个YAML文件定义的就是一个项目。

    Compose的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。而一个项目可以由多个服务关联而成。

    Compose的使用基本分为三个步骤:

    1. 使用Dockerfile定义应用环境以便可以在任何地方再现它。
    2. docker-compose.yml中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。
    3. 通过docker-compose up命令启动并运行整个应用程序。

    二、环境信息

    本文所使用的环境如下:

    • 操作系统:CentOS Linux release 8.1.1911
    • Docker:19.03.11
    • Docker Compose:1.26.0

    三、创建Web应用

    创建项目目录:

    mkdir composetest
    cd composetest
    

    在项目目录中创建一个名为app.py的文件,内容如下:

    import time
    
    import redis
    from flask import Flask
    
    app = Flask(__name__)
    # redis容器的主机名为redis,端口使用默认的6379端口
    cache = redis.Redis(host='redis', port=6379)
    
    
    # 如果redis服务不可用,此重试循环使我们可以多次尝试请求
    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)
    

    在项目目录中创建另一个名为requirements.txt的文件,内容如下:

    flask
    redis
    

    四、创建Dockerfile

    在项目目录中创建一个名为Dockerfile的文件,内容如下:

    # 指定基础镜像为python:3.7-alpine
    FROM python:3.7-alpine
    # 指定工作目录为/code
    WORKDIR /code
    # 指定环境变量FLASK_APP的值为app.py
    ENV FLASK_APP app.py
    # 指定环境变量FLASK_RUN_HOST的值为0.0.0.0
    ENV FLASK_RUN_HOST 0.0.0.0
    # 安装gcc,以便诸如MarkupSafe和SQLAlchemy之类的Python包可以编译加速
    RUN apk add --no-cache gcc musl-dev linux-headers
    # 复制requirements.txt到容器文件系统的requirements.txt
    COPY requirements.txt requirements.txt
    # 安装Python依赖项
    RUN pip install -r requirements.txt
    # 将项目的当前目录复制到镜像工作目录
    COPY . .
    # 指定容器启动时的默认命令
    CMD ["flask", "run"]
    

    五、使用Compose文件定义服务

    在项目目录中创建一个名为docker-compose.yml的文件,内容如下:

    # 指定docker-compose的版本
    version: '3'
    # 定义项目里所有的服务信息
    services:
      # 服务名
      web:
        # 指定Dockerfile文件的路径,这里指定的docker-compose.yml所在路径
        build: .
        # 指定端口映射,这里将宿主机的5000端口映射到容器的5000端口
        ports:
          - "5000:5000"
      redis:
        # 指定Docker镜像
        image: "redis:alpine"
    

    该Compose文件定义了两个服务:webredis

    • web:该服务使用当前目录中的Dockerfile文件构建了镜像,将宿主机的5000端口映射到容器的5000端口。
    • redis:该服务容器使用Docker Hub拉取的官方镜像创建。

    六、构建并运行应用

    在项目目录中执行以下命令启动应用:

    docker-compose up
    

    如果出现下图错误:
    Compose配置文件格式错误
    错误原因是docker-compose.yml文件中的缩进部分使用了Tab而非两个空格,改成两个空格即可。YAML格式要求得比较严格,所以要特别注意。然后再次启动。本地没有基础镜像会自动拉取:
    本地没有基础镜像会自动拉取
    如果出现下图错误:
    网络错误图1
    先试一下是不是alpine官方源连接不上的问题,尝试换国内源,可以试试阿里云,在Dockerfile的安装gcc的指令之前添加以下指令:

    RUN echo "https://mirrors.aliyun.com/alpine/v3.12/main/" >> /etc/apk/repositories
    RUN echo "https://mirrors.aliyun.com/alpine/v3.12/community/" >> /etc/apk/repositories
    

    如果还是出错,如下图:
    网络错误图2
    更换为国内源还是连接不上可能是容器内访问外部网络出现问题,执行以下命令创建容器并ping一下外网:

    docker run -it python:3.7-alpine ping www.baidu.com
    docker run -it python:3.7-alpine ping 114.114.114.114
    

    果然ping不通百度,容器内访问外部网络出现问题:
    ping不通百度
    容器要想访问外部网络,需要本地系统的转发支持。所以解决办法是打开IP转发。首先打开/etc/sysctl.conf文件(或者/usr/lib/sysctl.d/00-system.conf文件,这个文件没试过):

    vim /etc/sysctl.conf
    

    添加以下内容:

    net.ipv4.ip_forward=1
    

    重启network服务,CentOS8使用以下命令(CentOS7使用systemctl restart network):

    nmcli c reload
    

    查看是否修改成功:

    sysctl net.ipv4.ip_forward
    

    如果返回“net.ipv4.ip_forward = 1”则表示成功了。然后重启Docker:

    systemctl restart docker
    

    再次ping百度发现能ping通:
    再次ping百度能ping通
    如果还不行可以重启主机系统再试。再次启动:
    启动图1
    启动图2
    启动图3
    从启动日志可知Docker Compose完成了镜像的构建和容器的创建运行。切换到另一个终端,输入docker image ls查看本地镜像:
    查看本地镜像
    输入docker ps查看运行中的容器:
    查看运行中的容器
    访问http://MACHINE_VM_IP:5000,其中MACHINE_VM_IP为Docker主机ip,然后不断刷新,结果如下:
    访问web应用
    每刷新一次页面,计数就增加了1,说明Docker Compose运行应用成功。在原始终端中按CTRL + C来停止应用,或在另一个终端进入项目目录执行以下命令停止应用:

    docker-compose down
    

    停止删除服务容器

    七、修改Compose文件以添加目录挂载

    修改docker-compose.yml文件,内容如下:

    # 指定docker-compose的版本
    version: '3'
    # 定义项目里所有的服务信息
    services:
      # 服务名
      web:
        # 指定Dockerfile文件的路径,这里指定的docker-compose.yml所在路径
        build: .
        # 指定端口映射,这里将宿主机的5000端口映射到容器的5000端口
        ports:
          - "5000:5000"
        # 将宿主机项目目录(当前目录)下的/code目录挂载到容器,这样修改代码后不必重新构建镜像
        volumes:
          - .:/code
        # 设置FLASK_ENV环境变量,该变量指示flask run在开发模式下运行并在更改时重新加载代码,该模式仅应在开发中使用
        environment:
          FLASK_ENV: development
      redis:
        # 指定Docker镜像
        image: "redis:alpine"
    

    然后使用更新的Compose文件构建应用并运行:
    使用更新的Compose文件构建应用并运行
    在浏览器中访问应用,刷新计数正常增加。然后修改app.py文件中的输出内容,修改如下:

        return 'Hello Docker Compose! I have been seen {} times.\n'.format(count)
    

    然后在浏览器中刷新访问页面,发现返回的内容已变更,并且计数仍在增加,如下图:
    再次访问web应用

    八、Docker Compose基本操作

    查看Docker Compose基本命令和用法:

    docker-compose --help
    

    查看结果如下:
    帮助图1
    帮助图2
    查看Docker Compose版本信息:

    docker-compose version
    

    创建并运行服务:

    # 交互式启动
    docker-compose up
    # 后台启动
    docker-compose up -d
    # 指定Compose配置文件启动,默认为docker-compose.yml
    docker-compose up -f mycompose.yaml
    

    查看项目中目前的所有容器:

    docker-compose ps
    

    查看结果如下:
    查看当前正在运行的服务
    列出Compose文件中包含的镜像:

    docker-compose images
    

    查看结果如下:
    Compose文件中包含的镜像
    停止运行中的服务容器,这里停止web服务:

    docker-compose stop web
    

    停止web服务容器
    启动已存在的服务容器,这里启动web服务:

    docker-compose start web
    

    启动web服务容器
    重启项目中的服务容器,这里重启web服务:

    docker-compose restart web
    

    重启web服务容器
    暂停服务容器,这里暂停web服务:

    docker-compose pause web
    

    暂停web服务容器
    恢复处于暂停状态的服务,恢复暂停的web服务:

    docker-compose unpause web
    

    恢复web服务容器
    进入指定服务容器,这里进入web服务容器并ping百度:

    docker-compose exec web ping www.baidu.com
    

    进入web服务容器并ping百度
    查看服务容器的输出日志,这里查看的web服务:

    docker-compose logs web
    

    查看结果如下:
    查看web服务容器日志
    查看某个服务容器端口所映射的公共端口,这里指定web服务容器:

    docker-compose port web 5000
    

    查看结果如下:
    查看web服务容器端口映射的公共端口
    查看各个服务容器内运行的进程:

    docker-compose top
    

    查看结果如下:
    查看各个服务容器内运行的进程
    在指定服务上执行一个命令,这里在web服务查看环境变量:

    docker-compose run web env
    

    查看结果如下:
    在web服务查看环境变量
    通过发送SIGKILL信号来强制停止服务容器,这里发送SIGINT信号来强制停止服务容器:

    docker-compose kill -s SIGINT
    

    发送SIGINT信号强制停止服务容器
    验证Compose配置文件格式是否正确,正确会输出文件内容,错误则显示原因:

    docker-compose config
    

    验证结果如下:
    验证Compose配置文件格式是否正确
    删除所有停止状态的服务容器:

    docker-compose rm
    

    删除所有停止状态的服务容器
    构建或重新构建项目中的容器:

    docker-compose build
    

    构建或重新构建项目中的容器
    删除所有服务容器,同时删除网络和挂载目录的数据:

    docker-compose down --volumes
    

    删除所有服务容器,同时删除网络和挂载目录的数据
    置指定服务运行的容器个数,例如:

    docker-compose scale web=2 worker=3
    

    不推荐使用该命令,更推荐使用up命令的--scale选项来指定服务运行的容器个数。

    拉取服务依赖的镜像,该服务依赖的镜像需要在Compose配置文件中指定,例如:

    docker-compose pull db
    

    该命令需在Compose配置文件目录中执行,Compose配置文件中指定db服务依赖镜像,例如:

    services:
      db:
        image: postgres
    

    推送服务依赖的镜像到镜像仓库,例如:

    docker-compose push localhost:5000/yourimage
    docker-compose push youruser/yourimage
    

    Compose配置文件中指定服务依赖镜像,例如:

    services:
      service1:
        build: .
        image: localhost:5000/yourimage  # 推送至本地仓库
    
      service2:
        build: .
        image: youruser/yourimage  # 推送至你的DockerHub仓库
    
    cs
    下一篇:没有了