Docker——Docker Compose的使用

Docker Compose概述

  • 之前使用 Docker,需要定义 Dockerfile 文件,然后使用 docker build、docker run 等命令操作容器。然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,那么效率之低,维护量之大可想而知
  • 因此使用 Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具
  • Compose是用于定义和运行多容器Docker应用程序的工具。通过Compose,可以使用YAML文件来配置应用程序的服务。然后使用一个命令,就可以从配置中创建并启动所有服务

使用Compose基本是一个三步过程

  1. 通过编写Dockerfile文件保证我们的项目在任何地方都可以运行
  2. 通过docker-compose.yml文件定义组成应用程序的服务,以便它们在隔离的环境中一起运行
  3. 运行docker compose up,然后Docker compose命令启动并运行整个应用程序。也可以docker-compose up使用docker-compose二进制文件运行。

作用:
批量容器编排

docker-compose.yml 就是这种:

version: "3.9" 
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:
  logvolume01: {}

Compose一些理解

  1. Compose 是Docker官方的开源项目,需要手动安装
  2. 每一个容器就相当于一个服务service,如web、redis、mysql… 将所有服务打包就是一个项目
  3. 项目project就是由一组关联的容器(服务)组成,如一个wordpress,里面包含了web和mysql

Docker Compose的安装

下载安装compose
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose  

% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   423  100   423    0     0    315      0  0:00:01  0:00:01 --:--:--   315
100 16.7M  100 16.7M    0     0  3672k      0  0:00:04  0:00:04 --:--:-- 5250k

授权
chmod +x /usr/local/bin/docker-compose 

查看版本
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

Docker Compose的使用方法

  • 建立一个运行在Docker Compose上的Python Web应用程序。该应用程序使用Flask框架,并在Redis中缓存一个计数器。
  1. 编写程序
mkdir -p /home/compose/python-redis
cd /home/compose/python-redis

写python应用
vim app.py

#! /usr/bin/python3
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)

编写依赖包文件
vim requirements.txt

flask
redis
  1. 编写Dockerfile文件
vim Dockerfile

FROM python:3.7-alpine

WORKDIR /code

ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0

RUN apk add --no-cache gcc musl-dev linux-headers

COPY requirements.txt requirements.txt

RUN pip install -r requirements.txt

EXPOSE 5000

COPY . .
CMD ["flask", "run"]

  1. 定义一个服务在compose里
vim docker-compose.yml

version: "3"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

  1. 通过compose构建和运行应用
目前有四个文件
[root@docker python-redis]# ls
app.py  docker-compose.yml  Dockerfile  requirements.txt

启动compose项目
docker-compose up 

Creating python-redis_web_1   ... done
Creating python-redis_redis_1 ... done

最后构建镜像

[root@docker python-redis]# docker-compose build
redis uses an image, skipping
Building web
Step 1/10 : FROM python:3.7-alpine
 ---> c46f62f378d7
Step 2/10 : WORKDIR /code
 ---> Using cache
 ---> 3d09c3c9e5f7
Step 3/10 : ENV FLASK_APP=app.py
 ---> Using cache
 ---> 5401ce448bf0
Step 4/10 : ENV FLASK_RUN_HOST=0.0.0.0
 ---> Using cache
 ---> cd3cf06ed26e
Step 5/10 : RUN apk add --no-cache gcc musl-dev linux-headers
 ---> Using cache
 ---> 5b887aadaeb6
Step 6/10 : COPY requirements.txt requirements.txt
 ---> Using cache
 ---> 24c8b54c831f
Step 7/10 : RUN pip install -r requirements.txt
 ---> Using cache
 ---> e26516cdef01
Step 8/10 : EXPOSE 5000
 ---> Using cache
 ---> 2ffe08dae8ee
Step 9/10 : COPY . .
 ---> Using cache
 ---> e1299046671d
Step 10/10 : CMD ["flask", "run"]
 ---> Using cache
 ---> ecc8f48e18e5
Successfully built ecc8f48e18e5
Successfully tagged python-redis_web:latest

再次启动会发现
docker-compose up 
项目迅速启动

保证启动之后有两个容器
[root@docker ~]# docker ps
CONTAINER ID   IMAGE              COMMAND                  CREATED         STATUS              PORTS                         
              NAMES
e92f6c104c29   redis:alpine       "docker-entrypoint.s…"   9 minutes ago   Up About a minute   6379/tcp                     
               python-redis_redis_1
ad9ab1f0220d   python-redis_web   "flask run"              9 minutes ago   Up About a minute   0.0.0.0:5000->5000/tcp, :::500
0->5000/tcp   python-redis_web_1

测试

[root@docker ~]# curl localhost:5000
Hello World! I have been seen 1 times.
[root@docker ~]# curl localhost:5000
Hello World! I have been seen 2 times.

在这里插入图片描述

网络规则

我们查看网络,会发现compose会单独创建一个网络
在这里插入图片描述

查看网络详情
docker network inspect python-redis_default

[
    {
        "Name": "python-redis_default",
        "Id": "0e1cc417dc99dc66c337823ed1cbda0b680e7543732444d1120d54a50b72989c",
        "Created": "2021-04-25T03:03:35.019219454-04:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "ad9ab1f0220dda2638747f03852e547a0154514574b65930720ead939fc66048": {
                "Name": "python-redis_web_1",
                "EndpointID": "8c23797f7d6e4ea8464cddc12a0757c119a41381a45d936b8d8c5beeb2978e85",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "e92f6c104c29e79459e0c5eaebbd0d98c674c273cc1354bd4e18704f0c41e2b2": {
                "Name": "python-redis_redis_1",
                "EndpointID": "68c762f33ebf63a77cbde1bc6af15484f1458a43c50d7384a748cbdfe1033a33",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "python-redis",
            "com.docker.compose.version": "1.25.5"
        }
    }
]

里面包含python-redis_redis_1、python-redis_web_1,因为在同一个网络就可以通过容器名直接访问
  • 这里我们看之前python代码
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

这里host='redis' 没有写host=‘localhost’或者127.0.0.1

就是因为docker容器在同一个网络里面可以通过容器名访问

yaml编写规则

官方详解
耐心查看官方的教程,会有很大收获的

  • 编写规则
3层	第一层:版本	第二层:服务	第三层:其他配置

version:  	# 版本
services: 	# 服务
服务1:web
  # 服务配置
  images
  build
  netwokr
  .....

服务2:redis

服务3:redis
  ... 
# 其他配置	 网络/卷、全局规则
volumes:
networks:
configs:

如以下一个样本

version: "3.9"
services:

  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        max_replicas_per_node: 1
        constraints:
          - "node.role==manager"

  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - "5000:80"
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure

  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints:
          - "node.role==manager"

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints:
          - "node.role==manager"

networks:
  frontend:
  backend:

volumes:
  db-data:

depends_on

version: "3.9"
services:
  web:
    build: .
    depends_on:		web依赖于db和redis
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

容器运行顺序就是1.db 2.redis 3.web

deploy

version: "3.9"
services:
  redis:
    image: redis:alpine
    deploy:
      replicas: 6		
      placement:
        max_replicas_per_node: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure

replicas是副本

使用compose 一键部署wordpress博客

mkdir /home/wordpress
cd /home/wordpress

编写yaml
vim docker-compose.yml

version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: 123
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: 123

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: 123
       WORDPRESS_DB_NAME: wordpress
volumes:
    db_data: {}

docker-compose up

在这里插入图片描述
在这里插入图片描述

通过docker-compose使微服务上线

package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Autowired
    StringRedisTemplate redisTemplate;

    @GetMapping("/hello")
    public String hello(){
        Long views = redisTemplate.opsForValue().increment("views");
        return "hello,xiaotian,thank you,views:"+views;

    }
}

application.properties

# 应用名称
spring.application.name=demo
# 应用服务 WEB 访问端口
server.port=8080
spring.redis.host=redis

dockerfile

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java","-jar","/app.jar"]

docker-compose.yml

version: '3.8'
services:
  tianapp:
    build: .
    image: tianapp
    depends_on:
      - redis
    ports:
      - "8080:8080"
  redis:
    image: "library/redis:alpine"

将jar包上传至服务器后启动项目

[root@docker javaapp]# ls
docker-compose.yml  Dockerfile  maomao-0.0.1-SNAPSHOT.jar


测试

[root@docker python-redis]# curl localhost:8080/hello
hello,xiaotian,thank you,views:1
[root@docker python-redis]# curl localhost:8080/hello
hello,xiaotian,thank you,views:2

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值