Docker之Docker-Compose

1 Docker Compose 简介

1.1 Docker Compose介绍

•Docker Compose是一个能一次性定义和管理多个Docker容器的工具。Docker Compose是一个单机情况下容器编排的工具,k8s支持多机(上千台服务器管理上万个容器)的容器编排,不光是docker容器,还有其他公司出的容器。

•详细地说:

​ Compose中定义和启动的每一个容器都相当于一个服务(service)

​ Compose中能定义和启动多个服务,且它们之间通常具有协同关系

•管理方式:

​ 使用YAML文件来配置我们应用程序的服务,通过一条命令根据yml去创建,管理这些容器

使用单个命令(docker-compose up),就可以创建并启动配置文件中配置的所有服务。


1.2 Docker Compose 工作原理

1.3 Docker Compose安装

# Docker for Mac与Docker for Windows自带docker-compose
# Linux下需要单独安装:
# 第一步:下载
curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 第二步:让它变成可执行文件
chmod +x /usr/local/bin/docker-compose
# 第三步:终端中使用docker-compose --version查看安装的版本

# 访问github可能网络原因下载失败,可以使用国内镜像
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.12.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

1.4 Docker Compose CLI

利用docker-compose --help查看
对比后会发现:Docker Compose CLI的很多命令的功能和Docker Client CLI是相似的。最主要的区别就是前者能一次性运行管理多个容器,后者只能一次管理一个。

 

2 了解 Docker Compose File

2.1 Docker Compose File版本

Docker Compose File 有多个版本,基本是向后兼容的,但也有极个别配置项高版本中没有。

•在docker-compose.yml一开始就需要利用version关键词标明当前file使用的版本。

2.2 Docker Compose File TOP配置参数概览

Docker Compose File 顶级配置项:

​ •version:指定Docker Compose File版本号

​ •services:定义多个服务并配置启动参数

​ •volumes:声明或创建在多个服务中共同使用的数据卷对象

​ •ports:在多个服务中共同使用的端口映射

​ •networks:定义在多个服务中共同使用的网络对象

​ •configs:声明将在本服务中要使用的一些配置文件

​ •secrets:声明将在本服务中要使用的一些秘钥、密码文件

​ •x-***:自定义配置。主要用于复用相同的配置。

# version:有1,2,3版本,目前都用"3"
# 一个service代表一个container,这个container可以从Docker Hub的image来创建,或者从本地Dockerfile build的image来创建
# service的启动类似docker run,可以指定network和volume

2.3 docker-compose命令

# 启动管理容器
docker-compose up              # 会自动搜索当前路径下的 docker-compose.yml文件
docker-compose -f 指定文件 up
docker-compose up -d           # 后台执行,一般我们看日志输出,不用这个

docker-compose stop   # 停止,不会删除容器和镜像
docker-compose down   # 停止,并删除关联的容器
docker-compose start  # 启动yml文件管理的容器
docker-compose ps     # 查看正在运行的用yml管理的容器
docker-compose images # 查看docker-compose管理的容器的镜像

docker-compose exec yml文件中写的service /bin/bash  # 进入到容器内

2.4 docker-compose案例

services:
  db:
    image: mysql:5.7
    volumes:
      - "db-data:/var/lib/mysql"
    networks:
      - my-bridge
# 等同于
# docker run -di --network my-bridge -v db-data:/var/lib/mysql mysql:5.7

 

3 Docker Compose 部署应用,水平扩展

3.1 使用Docker Compose部署一个wordpress

# 第一步:docker-compose.yml
version: '3'
services:
  wordpress:          # 容器名,不能重名
    image: wordpress  # 基于Docker Hub拉的镜像,如果本地没有,会先pull拉取镜像
    ports:            # 端口映射
      - 8080:80
    depends_on:       # 基于mysql容器
      - mysql
    environment:      # 配置环境变量
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_PASSWORD: root
    networks:         # 配置网路
      - my-bridge

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    volumes:          # 目录映射
      - mysql-data:/var/lib/mysql
    networks:
      - my-bridge

volumes:
  mysql-data:

networks:
  my-bridge:
    driver: bridge
      
      
# 第二步:docker-compose up

3.2 Docker Compose  多应用部署

# 基于flask框架搭建小型web服务项目,框架中要集成redis。Docker Hub上没有这种镜像,需要利用Dockerfile构建镜像。

# 第一步:创建Dockerfile  vim Dockerfile
# 小型服务,没有从git上拉项目,直接在服务搭建,配置Dockerfile  docker-compose.yml app.py
FROM python:3.6
COPY . /app                  # 把当前路径下所有东西拷贝到容器的/app目录
WORKDIR /app                 # 工作目录
RUN pip install flask redis  # 基于python3.6镜像启动容器,安装flask和redis
EXPOSE 5000                  # 暴露5000端口
CMD [ "python", "app.py" ]   # 当前路径下的app.py文件已经拷贝到容器/app路径下,容器启动,app.py文件执行python命令


# 第二步:编写docker-compose.yml
# 利用docker-compose同时启动两个容器:
# 1、web容器,基于python3.6环境,安装了flask和redis,执行app.py代码,启动web服务
# 2、redis容器,启动redis服务
version: "3"

services:

  redis:         # 基于Dcoker Hub上下载的redis镜像启动容器
    image: redis

  web:           # 基于Dcokerflie构建的镜像启动容器
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8080:5000
    environment:
      REDIS_HOST: redis
    
# 第三步:编写app.py
from flask import Flask
from redis import Redis
import os
import socket

app = Flask(__name__)
# 通过环境变量配置, REDIS_HOST='redis'
# docker-compose启动的services之间是连通的,所以web服务通过redis容器名可以连通redis,不需要知道redis的ip地址
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)


@app.route('/')
def hello():
    redis.incr('hits')
    return '你好! 查看 %s 次, hostname 是 %s.\n' % (redis.get('hits'),socket.gethostname())


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=True)
    
# 第四步:启动容器
docker-compose up

3.3 Docker Compose 水平扩展

 把上列中的web服务扩展成三个,利用负载均衡器实现转发

# 启动docker-compose时,指定web容器启动3个,但这样执行有问题,因为yml配置时用了端口映射,8888端口已经被映射了
docker-compose up --scale web=3   

# 删除docker-compose.yml中的port端口映射
# 再启动
docker-compose up --scale web=3
docker-compose start
docker-compose ps  # 可以看到三个web启动了

# 前面加一个负载均衡器HAProxy,相当于Nginx

# app.py 改成监听的端口为80,监听HAProxy,通过HAProxy再转发

# Dockerfile不需要改

# docker-compose.yml
version: "3"

services:
    
  redis:
    image: redis

  web:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      REDIS_HOST: redis

  lb:
    image: dockercloud/haproxy
    links:
      - web
    ports:
      - 8080:80
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock 
    
# 启动一个web
docker-compose up
# 把web扩展为3个
docker-compose up --scale web=3 -d
# 把web缩减为1个
docker-compose up --scale web=1 -d

3.4 Docker Compose 部署一个复杂的应用

# 项目地址:https://pan.baidu.com/s/1lzfaza5kO-jbRLsEFrslIg  提取码: 加群获 830644110
# 第一步,下载项目,解压,cd进入(内部自带项目,Dockerfile,docker-compose.yml)
# docker-compose.yml如下
services:
  voting-app:
    build: ./voting-app/.
    volumes:
     - ./voting-app:/app
    ports:
      - "5000:80"
    links:
      - redis
    networks:
      - front-tier
      - back-tier

  result-app:
    build: ./result-app/.
    volumes:
      - ./result-app:/app
    ports:
      - "5001:80"
    links:
      - db
    networks:
      - front-tier
      - back-tier

  worker:
    build: ./worker
    links:
      - db
      - redis
    networks:
      - back-tier

  redis:
    image: redis
    ports: ["6379"]
    networks:
      - back-tier

  db:
    image: postgres:9.4
    volumes:
      - "db-data:/var/lib/postgresql/data"
    networks:
      - back-tier

volumes:
  db-data:

networks:
  front-tier:
  back-tier:
# 第二步:部署
docker-compose up  # 时间很久

# 补充:9a37
docker-compose build # 如果yml文件中有需要先build的image,会先构建,然后再up,节约时间(并不会节约)

3.5 docker-compose单机环境ELK系统

# 第一步:编写docker-compose.yml(ELK镜像地址:https://www.docker.elastic.co/)

# 第二步:运行
docker-compose up
# 官方提供的
version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.5.2
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster # 集群名称
      - discovery.seed_hosts=es02,es03 # 指定集群
      - cluster.initial_master_nodes=es01,es02,es03 # 设置集群发现
      - bootstrap.memory_lock=true # 存锁,限制es不会无限制使用内存
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m" # jvm内存使用
    ulimits: # 跟上方bootstrap.memory_lock关联
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.5.2
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
    networks:
      - elastic
  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.5.2
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic

volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

 

posted @ 2022-10-20 19:13  不会钓鱼的猫  阅读(425)  评论(0编辑  收藏  举报