从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • 计算机历史

  • 数字电路

  • 计算机组成原理

  • 汇编语言

  • C语言

  • 数据结构

  • 操作系统

  • Linux

    • 文本处理三剑客

    • 尚硅谷Docker实战教程

      • 教程简介
      • Docker简介
      • Docker安装
      • Docker常用命令
      • 镜像的分层概念
      • 发布镜像
      • Docker私有库
      • 容器数据卷
      • Docker常用软件安装
      • MySQL主从复制
      • 分布式存储之哈希取余算法
      • 3主3从Redis集群搭建与扩缩容
      • Dockerfile
      • 虚悬镜像
      • Docker微服务实战
      • Docker网络
      • Docker-compose容器编排
        • 为什么要用compose
        • 安装
        • Compose核心概念
        • Compose使用的三个步骤
        • Compose常用命令
        • compose实战
        • 使用Compose
      • Portainer
      • Docker重量级监控
      • 完结
      • Docker
    • Linux安全

    • Linux文章集合
  • 计算机网络

  • Git

  • 数据库

  • 计算机小知识

  • 编译原理

  • 名人堂

  • 计算机基础
  • Linux
  • 尚硅谷Docker实战教程
2023-09-18
目录

Docker-compose容器编排

# 170.Docker-compose容器编排

参考Docker微服务实战

Docker-Compose 是 Docker 公司推出的一个开源工具软件,可以管理多个 Docker 容器组成一个应用。用户需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器(或者说能实现对Docker容器集群的快速管理,编排)   ‍

‍

# 为什么要用compose

Docker建议我们每一个容器中只运行一个服务,因为Docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来。但是这样我们又面临了一个问题:

如果需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样麻烦。所以Docker官方给我们提供了Docker-compose多服务部署的工具

例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库MySQL容器,Redis服务器,注册中心eureka,甚至还包括负载均衡容器等等..

Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。

‍

和Spring类似,在Spring之前,我们得自己管理各个类之间的关系

  1. 有时候一个类的创建,需要其他类的支持,此时就涉及到对象的启动顺序和加载条件
  2. 当类越来越多,就涉及到各种模式,除了用new之外,还可以用工厂模式,装饰器模式等来创建对象

其实Spring也是一个容器,可以用配置文件来管理各个组件的关系

‍

# 安装

官网文档:Docker Compose overview (opens new window)

根据文档,安装Compose的方式有:

  1. 安装Docker Desktop
  2. 安装Compose plugin
  3. 单独安装Compose(不推荐)

在我们安装Docker的时候,已经安装了Compose plugin,也就是方式2,因此不用再次安装。

随着Docker版本的更新,安装方法可能会有不同,具体以官网为准。

此外,旧版本的docker-compose命令中,是带有短线的,例如docker-compose up;新版的没有,直接就是docker compose up

‍

指令格式:docker compose [OPTIONS] COMMAND​。例如查看版本:

$ docker compose version
Docker Compose version v2.20.2
1
2

更多用法参考:​docker run --help​

‍

‍

‍

‍

# Compose核心概念

一文件:docker-compose.yml

两要素:

  • 服务(service): 一个个应用容器实例,比如订单微服务、库存微服务、MySQL容器、Nginx容器或Redis容器
  • 工程(project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

‍

‍

# Compose使用的三个步骤

  • 编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
  • 使用 docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。
  • 最后,执行docker-compose up命令,来启动并运行整个应用程序,完成一键部署上线

‍

‍

# Compose常用命令

docker compose -h :查看帮助

docker compose up:启动所有docker-compose服务

docker compose up -d :启动所有docker-compose服务并后台运行

docker compose down:停止并删除容器、网络、卷、镜像。

docker compose exec yml里面的服务id :进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash

docker compose ps :展示当前docker-compose编排过的运行的所有容器

docker compose top:展示当前docker-compose编排过的容器进程

docker compose logs yml里面的服务id : 查看容器输出日志

docker compose config :检查配置

docker compose config -q :检查配置,有问题才有输出

docker compose restart :重启服务

docker compose start :启动服务

docker compose stop :停止服务

‍

‍

# compose实战

接下来就是实战了,我们改造下之前用的Java工程(参考Docker微服务实战),并使用compose的方式来管理,一键上线

现在我们的需求:引入Redis作为缓存,MySQL作为数据库。然后写一个user类,先从Redis中查询有误命中缓存,没有则从数据库中查。

‍

# 建库建表

这里使用的是本地的MySQL(读者也可以自行用Docker新建MySQL,或用云数据库等):

CREATE DATABASE db2021;

use db20201;

CREATE TABLE `t_user` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `username` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
 `password` varchar(50) NOT NULL DEFAULT '' COMMENT '密码',
 `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别 0=女 1=男 ',
 `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
 `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表'
1
2
3
4
5
6
7
8
9
10
11
12
13
14

‍

‍

# 业务代码

接下来就是写bean类、mappe,接口等。在课件中,老师已经贴出了代码;也可以拷贝一份我的GitHub或Gitee项目代码(分支demo2),或用代码生成工具(在课程中,老师使用的是Maven的插件mybatis-generator)。

说明:

  1. 关于Java方面的知识,这里不是重点,就不逐个说明了。在项目的readme.md文档中有说明

  2. 微服务不是单独指某个语言,而是一种设计思想,其他编程语言也可以用微服务

  3. 拷贝项目后需要修改的地方:MySQL连接信息,Redis连接信息

  4. 本项目主要参考老师的源码 + B站评论区-我自己1213812138 (opens new window) 的源码

    ​​

    docker微服务第二个实例 今天刚做的 里面zip和jar包都有 一起学习
    链接:https://pan.baidu.com/s/1f2aMCKGToDp6DwPLKMJUXw (opens new window)
    提取码:cbwn

‍

‍

最好先本地启动测试一下,没问题再打包。测试的时候可以用本机的MySQL和Redis。启动后先用postman发送get请求,然后查找用户1:

​

‍

‍

访问Swagger:

​​

‍

用mvn package​打包,上传到/mydocker目录下,并重命名为docker_boot-0.0.1-SNAPSHOT.jar

‍

# 编写Dockerfile

‍

在/mydocke编写Dockerfile:

# 基础镜像使用java
FROM java:8

# 作者
MAINTAINER zzyy


# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp

# 将jar包添加到容器中并更名为zzyy_docker.jar
ADD docker_boot-0.0.1-SNAPSHOT.jar zzyy_docker.jar

# 运行jar包
RUN bash -c 'touch /zzyy_docker.jar'
ENTRYPOINT ["java","-jar","/zzyy_docker.jar"]


#暴露6001端口作为微服务
EXPOSE 6001
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

‍

构建镜像:

docker build -t zzyy_docker:1.6 .
1

‍

‍

# 不用Compose的情况下

这里先演示下,不使用compose的情况下,有什么问题出现。按照如下顺序启动容器:

  1. 单独的MySQL容器实例(先停止本机的MySQL,然后新建一个实例,并新建库和表)
  2. 单独的Redis实例
  3. 微服务工程

‍

先停止本机的MySQL实例systemctl stop mysqld​,新建MySQL容器(这里用的是MySQL8):

docker run -p 3306:3306 --name mysql57 --privileged=true -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -v /zzyyuse/mysql/logs:/logs -v /zzyyuse/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
1

‍

‍

进入mysql容器实例并新建库db2021+新建表t_user

docker exec -it mysql57 /bin/bash

mysql -uroot -p

CREATE DATABASE db2021;

use db20201;

CREATE TABLE `t_user` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `username` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
 `password` varchar(50) NOT NULL DEFAULT '' COMMENT '密码',
 `sex` tinyint(4) NOT NULL DEFAULT '0' COMMENT '性别 0=女 1=男 ',
 `deleted` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
 `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

‍

‍

新建Redis实例

docker run -p 6379:6379 --name redis608 --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf
1

‍

‍

启动微服务:

docker run -d -p 6001:6001 zzyy_docker:1.6
1

‍

接下来可以用postman发送POST请求:http://192.168.2.242:6001/user/add​

然后访问http://192.168.2.242:6001/user/find/1​,可以看到是正常运行的

​​

‍

此外Swagger也正常运行,这里就不贴图了

‍

上面成功了,有哪些问题?

  1. 先后顺序要求固定,先 MySQL + Redis 才能微服务访问成功
  2. 每次启停都要运行多个run命令..
  3. 容器间的启停或宕机,有可能导致IP地址对应的容器实例变化,映射出错, 要么生产IP写死(不推荐),要么通过服务调用

‍

‍

‍

# 使用Compose

编写.mydocker/docker-compose.yml文件,内容如下:

version: "3"

services:
  microService:
    image: zzyy_docker:1.6
    container_name: ms01
    ports:
      - "6001:6001"
    volumes:
      - /app/microService:/data
    networks: 
      - atguigu_net 
    depends_on: 
      - redis
      - mysql

  redis:
    image: redis:6.0.8
    ports:
      - "6379:6379"
    volumes:
      - /app/redis/redis.conf:/etc/redis/redis.conf
      - /app/redis/data:/data
    networks: 
      - atguigu_net
    command: redis-server /etc/redis/redis.conf

  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
      MYSQL_DATABASE: 'db2021'
      MYSQL_USER: 'zzyy'
      MYSQL_PASSWORD: 'zzyy123'
    ports:
      - "3306:3306"
    volumes:
      - /app/mysql/db:/var/lib/mysql
      - /app/mysql/conf/my.cnf:/etc/my.cnf
      - /app/mysql/init:/docker-entrypoint-initdb.d
    networks:
      - atguigu_net
    command: --default-authentication-plugin=mysql_native_password #解决外部无法访问

networks: 
   atguigu_net: 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

‍

内容解读:

  • version: "3",是当前Docker compose的版本,目前是3

  • services: 固定写法,里面的内容是各个容器实例的配置

    • microService:微服务,我们自定义的服务,然后container_name,ports,networks,volumes,都是Docker的选项。depends_on则定义了容器的启停顺序。
    • redis:没用定义容器名字,然后配置了容器卷和网络
    • mysql:同理,配置了端口,容器卷以及网络,密码等。
  • networks:会自动创建网络,网络名字为atguigu_net

‍

‍

接下来我们修改下微服务项目的配置文件,使其通过服务名来访问 MySQL 和 Redis:

......
# spring.datasource.url=jdbc:mysql://192.168.2.242:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.url=jdbc:mysql://mysql:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
.....


# ======================== redis =====================
spring.redis.database=0
# spring.redis.host=192.168.2.242
spring.redis.host=redis

......
1
2
3
4
5
6
7
8
9
10
11
12

‍

然后重新打包,上传到Linux里并重命名,删除之前的镜像,然后重新构建镜像:

docker rmi 镜像ID
docker build -t zzyy_docker:1.6 .
1
2

‍

将之前的Redis和MySQL实例也删掉:

 docker rm -f  mysql57 redis608
1

‍

‍

之前讲过compose常用命令,接下来就是用的时候了。在一键启动之前,先检查下配置文件有没问题:

docker compose config -q
1

如果没有任何输出,说明是正常的。

‍

现在我们来一键启动,在/mydocker目录下执行:

docker compose up -d
1

‍

输出:

[+] Running 4/4
 ✔ Network mydocker_atguigu_net  Created        0.2s 
 ✔ Container mydocker-mysql-1    Started        2.8s 
 ✔ Container mydocker-redis-1    Started        2.8s 
 ✔ Container ms01                Started        3.7d
1
2
3
4
5

‍

‍

并且网络也自动创建好了:

$ docker network ls
NETWORK ID     NAME                   DRIVER    SCOPE
f1c9ebe5d961   bridge                 bridge    local
553d2c47bcaa   host                   host      local
fd3878f8116a   mydocker_atguigu_net   bridge    local
1ddfe19eb462   none                   null      local
daf309d234de   zzyy_network           bridge    local
1
2
3
4
5
6
7

‍

‍

根据compose的规则,会在网络名字加个目录名作为前缀。同理,如果不指定容器名,则容器名也会加个前缀(例如mydocker-mysql-1,mydocker-redis-1)

‍

‍

接下来我们去MySQL容器中新建库和表,然后测试下微服务是否正常运行即可

‍

‍

接下来我们测试下一键关停:

docker compose stop
1

‍

输出:

 docker compose stop
[+] Stopping 3/3
 ✔ Container ms01              Stopped     0.8s 
 ✔ Container mydocker-redis-1  Stopped     0.4s 
 ✔ Container mydocker-mysql-1  Stopped     4.1s 
1
2
3
4
5

‍

可以看到正常关闭了,至此测试完毕

‍

‍

(完)

在GitHub上编辑此页 (opens new window)
上次更新: 2023/9/18 12:28:56
Docker网络
Portainer

← Docker网络 Portainer→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式