写在前面的话

在之前的操作中,即使是单个容器每次都需要敲很长的命令,当需要多个容器组合着用的时候更加麻烦,此时我们急需找到一种一次配置,随便运行的方法。

这就是这一节重点,单机容器编排工具:docker-compose。

安装使用 docker-compose

官方文档如下:

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

安装 docker-compose,其实就是一个脚本:

# 下载脚本和修改权限
curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 查看结果
docker-compose --version

在 docker-compose 中,最重要的就是 docker-compose.yml 文件。该文件指明了有哪些容器,运行规则是怎样。

在 docker-compose.yml 中,最重要的几个概念:

services:在该项下面的每一项就代表着一个容器。

networks:定义了容器会用到哪些网络。

volumes:定义了容器持久化规则。

另外,docker-compose.yml 文件是有版本概念的,推荐目前最新的 3 版本,否则可能出现不兼容的情况,以下是之前 Wordpress 服务的 docker-compose.yml 文件,先看后写:

老规矩,还是先删除所有的容器和所有的 volume:

docker container rm -f $(docker ps -aq)
docker volume rm $(docker volume ls -q)

然后编辑 docker-compose.yml 文件:

version: '3'

services:

  wordpress-db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: wordpress
    volumes:
      - wordpress-data:/var/lib/mysql
    networks:
      - my-network

  wordpress-web:
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: wordpress-db
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: 123456
      WORDPRESS_DN_NAME: wordpress
    networks:
      - my-network

volumes:
  wordpress-data:

networks:
  my-network:
    driver: bridge

配置文件说明:

关键字 说明
容器名字 指定容器名称,所有的操作都应该隶属于这个名称之下,这里给 MySQL 容器命名为 wordpress-db。
image 指定镜像,如果不是最新版,可以跟上版本号,和 docker 命令运行规则一样。
ports

端口映射,值得注意,在配置中,端口映射,数据卷,网络都是可以存在多个的,所以这些单词都是复数,

如 networks,volumes。其值的写法也和其他项不同,需要在前面加一个 - 符号,因为值是一个字符串。

所以在 : 之后绝对不能有空格,否则会报错。

volumes 持久化操作。
networks 指定使用的网络,相当于 --networks 参数。
environment 环境变量参数,可以多个,换行写
顶级 volumes 单独声明我们上面持久化的卷的名称。
顶级 networks 设置需要的网络,并指定该网络的 driver。如果该网络不存在,在执行的时候会自动创建。

启动容器:

docker-compose -f docker-compose.yml up -d

使用 -f 参数加配置名字配上 up 启动,如果在当前目录,且名字就是 docker-compose.yml 就可以省略 -f 参数,-d 是为了后台启动,如果处于调试阶段,为了方便看日志,可以不加 -d 参数,但是会直接输出日志,ctrl + C 就会让所有容器都退出。

启动结果:

访问测试:

其他常用的命令:

# 查看有哪些容器
docker-compose -f docker-compose.yml ps

# 停止所有容器
docker-compose -f docker-compose.yml stop 

# 启动所有容器
docker-compose -f docker-compose.yml start

# 停止并删除所有容器
docker-compose -f docker-compose.yml down

直接查看容器:

可以发现,容器的名称并不是之前所定义的容器名字,而是由一系列的组合而成,但在连接数据库的时候又不会有问题。

这样的好处可以通过之后的一个实践项目测试一下。

docker-compose 负载均衡实战

这个实战的项目的代码就是之前的 Flask redis 的代码:app.py

from flask import Flask
from redis import Redis
import os
import socket

app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
@app.route('/')
def hello():
    redis.incr('hits')
    return 'Hello Container World! I have been seen %s times and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname())

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

Dockerfile 文件:

FROM python:2.7
LABEL maintainer="Dylan <1214966109@qq.com>"
COPY app.py /app/
RUN pip install flask && pip install redis
WORKDIR /app/
EXPOSE 5000
CMD ["python", "app.py"]

编写 docker-compose.yml 文件:

version: '

services:

  redis-demo:
    image: redis

  flask-demo:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      REDIS_HOST: redis-demo

  load-balance-demo:
    image: dockercloud/haproxy
    links:
      - flask-demo
    ports:
      - 8888:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

这里用到了一个新的镜像 dockercloud/haproxy,用于制作负载均衡,使用 links 直接将 80 端口代理到容器 flask-demo 的端口上,而不是 ports 映射。

ports 映射最终被用于将 haproxy 的 80 端口映射到外部。

简单的示意图:

同时,由于这里并不是公有镜像,而是 Dockerfile 构建的,所有在 dlask-demo 中也告诉大家一种新的构建方式。

这里将 flask-demo 启动多个节点

docker-compose -f docker-compose.yml up --scale flask-demo=3 -d

注意,这里所有的额外参数都需要放在 up 之后命令才能执行~ 

查看启动结果:

可以看到 flask-demo 容器启动 3 个,并实现了负载均衡。访问测试:

小结

docker-compose 在单机部署的时候会用到,而且现在很多开源项目的部署方式其实采用的也是 docker-compose 的方式。

这种方法需要了解。但是在工作中可能更多的是多主机,集群的形式。这个时候 docker-compose 就有些限制了。

至于这样的需求怎么实现,就得依靠之后的容器编排工具 docker swarm 甚至更牛逼的 K8S 了。当然这都是后话,饭得一口一口得吃。

【08】循序渐进学 docker:docker compose的更多相关文章

  1. 小白学Docker之Compose

    承接上篇文章:小白学Docker之基础篇,自学网站来源于https://docs.docker.com/get-started 概念 Compose是一个编排和运行多容器Docker应用的工具,主要是 ...

  2. 【09】循序渐进学 docker:docker swarm

    写在前面的话 至此,docker 的基础知识已经了解的差不多了,接下来就来谈谈对于 docker 容器,我们如何来管理它. docker swarm 在学习 docker swarm 之前,得先知道容 ...

  3. Docker 15 Compose

    参考源 https://www.bilibili.com/video/BV1og4y1q7M4?spm_id_from=333.999.0.0 https://www.bilibili.com/vid ...

  4. Docker之Compose服务编排

    Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Comp ...

  5. (转)Docker之Compose服务编排

    转自:https://www.cnblogs.com/52fhy/p/5991344.html Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过 ...

  6. Docker系列08—搭建使用私有docker registry

    本文收录在容器技术学习系列文章总目录 1.了解Docker Registry 1.1 介绍 registry 用于保存docker 镜像,包括镜像的层次结构和元数据. 启动容器时,docker dae ...

  7. Ubuntu18.04安装docker、docker-compose、

    Ubuntu18.04下Docker CE安装 Docker版本分为两个:Docker Community Edition (CE)和 Docker Enterprise Edition (EE).D ...

  8. Docker使用compose(原Fig)快速编配

    Docker使用compose(原Fig)快速编配 目录 安装 应用 构建以及运行 安装 在Linux上安装Fig: 在OS上安装: 在Linux上安装Fig: sudo bash-c "c ...

  9. Docker学习—Compose

    前言 前面<Docker学习-DockerFile>文中介绍了dockerfile相关的语法,及使用方式:接下来了解docker三剑客之一的 Compose:接下来详细学习. 一.dock ...

随机推荐

  1. Linux 如何杀死僵尸进程

    问题描述: shell > top top - :: up days, :, user, load average: 0.23, 0.81, 1.07 Tasks: total, running ...

  2. zt <Windows Image Acquisition (WIA)> from msdn

    Windows Image Acquisition (WIA)   Windows Image Acquisition (WIA) is the still image acquisition pla ...

  3. 150. Evaluate Reverse Polish Notation (Stack)

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  4. 使用jquery修改表单的提交地址

    基本思路: 通过使用jquery选择器得到对应表单的jquery对象,然后使用attr方法修改对应的action 示例程序一: 默认情况下,该表单会提交到page_one.html 点击button之 ...

  5. iOS 打印结构体

    关于OC直接打印结构体,点(CGRect,CGSize,CGPoint,UIOffset)等数据类型,我们完全可以把其转换为OC对象来进项打印调试,而不必对结构体中的成员变量进行打印.就好比我们可以使 ...

  6. Qt Signal and Slot

    Qt4中的信号槽 Qt4中的信号槽是通过SIGNAL,SLOT两个宏,将参数转换成字符串.Qt编译前,会从源码的头文件中提取由signal和slot声明的信号和槽的函数, 将其组成一张信号和槽对应的字 ...

  7. ServiceStack.Redis泛型存储后getById问题

    关于ServiceStack.Redis实体存储常用的有一下几个方法 StoreAsHash<T>(T entity)  //将对象按照Hash存储 Redis.As<T>() ...

  8. [C++] Type Conversion(类型转换)

    Type Conversion(类型转换) Two kinds of type conversion explict type conversion(显式类型转换) impict type conve ...

  9. XML(子节点序列化反序列对象)读写

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  10. css实现水平伸缩菜单

    ul li a{transition:width 500ms ease;} a:hover{width:*;} 高度向上延伸用height:*;margin-top:-*px;//负值实现向上