Docker-compose:管理多个容器

news2024/12/24 20:36:02

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 也是一个容器,可以用配置文件来管理各个组件的关系

安装

官网文档:docs.docker.com/compose

根据文档,安装 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

更多用法参考:​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 :进入容器实例内部中的 /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='用户表'

业务代码

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

说明:

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

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

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

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

    docker 微服务第二个实例 今天刚做的 里面 zip 和 jar 包都有 一起学习
    链接:https://pan.baidu.com/s/1f2aMCKGToDp6DwPLKMJUXw
    提取码: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

构建镜像:

docker build -t zzyy_docker:1.6 .

不用 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

进入 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='用户表'

新建 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

启动微服务:

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

接下来可以用 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: 

内容解读:

  • 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

......

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

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

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

 docker rm -f  mysql57 redis608

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

docker compose config -q

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

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

docker compose up -d

输出:

[+] 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

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

$ 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

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

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

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

docker compose stop

输出:

 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 

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

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2139939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

七、垃圾收集器ParNewCMS与底层三色标记算法详解

文章目录 垃圾收集算法分代收集理论标记-复制算法标记-清除算法标记-整理算法 垃圾收集器1.1 Serial收集器(-XX:UseSerialGC -XX:UseSerialOldGC)1.2 Parallel Scavenge收集器(-XX:UseParallelGC(年轻代),-XX:UseParallelOldGC(老年代))1.3 ParNew收集器(-XX:UseParNewGC)1.4 C…

POSIX信号量以及利用POSIX信号量实现基于循环队列的高效生产者消费者模型

🍑个人主页:Jupiter. 🚀 所属专栏:Linux从入门到进阶 欢迎大家点赞收藏评论😊 目录 🍁POSIX信号量 🍁信号量的相关接口介绍*初始化信号量**销毁信号量**等待信号量**发布信号量* 🍁&…

YOLOv9 简介

YOLO v9 是目前表现最佳的目标检测器之一,被视为现有 YOLO 变体(如 YOLO v5、YOLOX 和 YOLO v8)的改进版本。 YOLOv9 在实时目标检测领域取得了重大进展,引入了诸如可编程梯度信息(PGI)和通用高效层聚合网…

后端开发刷题 | 打家劫舍

描述 你是一个经验丰富的小偷,准备偷沿街的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家,就不能再偷第二家;如果偷了第二家&#xff0…

Dina靶机详解

靶机下载 https://www.vulnhub.com/entry/dina-101,200/ 靶机配置 默认是桥接模式,切换为NAT模式后重启靶机 主机发现 arp-scan -l 端口扫描 nmap -sV -A -T4 192.168.229.157 发现80端口开启,访问 访问网站 目录扫描 python dirsearch.py -u http…

1.2 交换技术

欢迎大家订阅【计算机网络】学习专栏,开启你的计算机网络学习之旅! 文章目录 前言一、电路交换1. 定义与原理2. 工作过程3. 优点与局限 二、分组交换1. 定义与原理2. 工作过程3. 优点与局限 三、报文交换1. 定义与原理2. 工作过程3. 优点与局限 四、比较…

改进RRT*的路径规划算法

一、RRT算法 RRT 算法是一种基于随机采样的快速搜索算法。该算法的主要思想是通过随机采样来创建一个快速探索的树,从而生长出一条从起点到终点的路径。如图为随机树的生长过程。 初始化。首先,初始化起始点和目标点位置,并将起点作为根节点…

printf()函数的全面介绍及用法——简单易懂

printf()函数介绍 目录 printf()函数介绍 一:头文件 二:格式控制字符串 1.格式字符。 2.转义字符。 3.普通字符。 三:格式字符输出示例 1. %c-----------输出字符 2. %s-----------输…

Linux中断实操-概念

1、裸机中的中断处理方法: (1)使能中断、初始化相应寄存器 (2)注册中断服务函数,向irqTable数组的指定标号处写入中断服务函数 (3)中断发生后进入IRQ中断服务函数,执行对…

【0~1】实现一个精简版的Tomcat服务器

真正的勇气,是在知道生活的真相之后,依然热爱生活。 《To Kill a Mockingbird》 01 Tomcat 介绍 Tomcat 是一个开源的 Java 应用服务器,主要用来运行基于 Servlet 和 JSP 技术的 Web 应用。Tomcat 实现了 Servlet 规范和 JSP 规范&#xff0…

一次RPC调用过程是怎么样的?

注册中心 RPC(Remote Procedure Call)翻译成中文就是 {远程过程调用}。RPC 框架起到的作用就是为了实现,调用远程方法时,能够做到和调用本地方法一样,让开发人员更专注于业务开发,不用去考虑网络编程等细节…

【开源免费】基于SpringBoot+Vue.JS企业客户管理系统(JAVA毕业设计)

本文项目编号 T 036 ,文末自助获取源码 \color{red}{T036,文末自助获取源码} T036,文末自助获取源码 目录 一、系统介绍1.1 管理员角色1.2 普通员工角色1.3 系统特点 二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内…

苹果手机备份照片怎么删除

在数字时代,备份照片是保护我们珍贵记忆不受意外丢失影响的一种重要方式。苹果手机用户通常利用iCloud或iTunes来备份他们的照片,确保数据的安全。然而,随着时间的推移,这些备份可能会积累大量不再需要的照片,占用宝贵…

鸿蒙开发之ArkTS 基础二

ArkTS常用的基础数据类型 1.字符串 关键字是string 2.数字 关键字是number 3.布尔 关键字是boolean 语法格式是:let 变量名:变量类型 变量值 其中let是关键表示变量,可以修改,可以改变一只对应的是const 修饰,常量不能修改,…

Python画笔案例-050 绘制天空之眼

1、绘制天空之眼 通过 python 的turtle 库绘制 天空之眼,如下图: 2、实现代码 绘制 天空之眼,以下为实现代码: """天空之眼.py """ import math import turtledef draw_square(length,level):if l…

idea同时装了两个版本,每次打开低版本都需要重新激活破解

问题描述: idea同时装了两个版本,每次打开低版本都需要重新激活破解。低版本是2021.1,高版本是2023.1 解决方案: 找到idea的配置路径,比如我的是:C:\Users\Administrator\AppData\Roaming\JetBrains 2021…

【我要成为配环境高手】Nodejs安装与配置

文章目录 1.nodejs安装2.配置npm的全局安装路径3.切换npm的淘宝镜像4.安装vue-cli 1.nodejs安装 从官网下载安装LTS版本的nodejs nodejs会自动安装环境变量,因此安装完成后直接在cmd中查看node版本 node -v2.配置npm的全局安装路径 以管理员身份运行cmd&#xff…

office 2021安装教程

软件介绍 Microsoft Office是微软公司开发的一套基于 Windows 操作系统的办公软件套装。常用组件有 Word、Excel、Powerpoint等。该软件最初出现于九十年代早期,最初是一个推广名称,指一些以前曾单独发售的软件的合集。当时主要的推广重点是购买合集比单…

matlab边缘点提取函数

1、边缘提取 matlab自带点云边缘提取函数,用于搜索点云边界,其核心是alpha shapes算法。alpha shapes提取边缘点,主要是依据滚动圆绕点云进行旋转,实现边缘检测,原理如下图所示。具体原理及效果,可以参考之前我写的博客:基于alpha shapes的边缘点提取(matlab)-CSDN博客…

实习项目|苍穹外卖|day10

Spring Task cron 表达式 入门案例 订单状态定时处理 通知用户支付!通知商家完成订单! Scheduled(cron "0 0/1 * * * ? ")public void processTimeoutOrder(){log.info("定时处理超时订单: {}", LocalDateTime.now());//答案是…