一、Docker Compose核心概念
1.1、一文件原则(docker-compose.yml)
Docker Compose的核心理念是使用一个YAML格式的Compose文件来定义容器化应用的结构和配置信息。这个Compose文件可以包含多个服务以及它们相关的配置项,例如镜像、环境变量、网络设置等。通过这个一文件原则,我们可以将应用的整体结构和配置信息集中地进行管理和维护。
1.2、服务(service)
服务的定义
服务(service)是Compose文件中的一个关键概念,它代表了一个个容器化的应用。每个服务可以包括一个或多个容器,共同完成特定的功能。比如,一个Web应用可能包含一个Web服务器容器和一个数据库容器。
服务的配置
在Compose文件中,我们可以为每个服务指定以下配置项:
镜像(image):用于指定服务所使用的Docker镜像。
环境变量(environment):用于设置服务容器的环境变量。
端口映射(ports):用于将容器内的端口映射到主机上。
依赖关系(depends_on):用于指定服务之间的依赖关系,确保它们按照正确的顺序启动。
服务的启动和管理 通过执行docker-compose up命令,我们可以启动Compose文件中定义的所有服务。
Docker Compose会自动创建和管理相关的容器。同时,我们还可以使用其他命令来管理服务,如docker-compose stop停止服务、docker-compose restart重启服务等。
1.3、工程(project)
工程的定义
工程(project)是Docker Compose中的另一个核心概念,它代表了一个Compose文件所定义的完整应用。一个工程可以包含多个服务,通过Compose文件统一管理和部署。
多工程支持
Docker Compose不仅支持单一工程,还可以同时管理多个工程。通过指定不同的Compose文件,我们可以轻松地定义和管理多个应用。
多环境支持
在实际开发和部署中,我们通常会有不同的环境(如开发、测试、生产环境)需要支持。Docker Compose通过使用不同的Compose文件,可以方便地适配不同的环境配置。
二、Docker Compose使用步骤
使用Docker Compose编排微服务的步骤
1、编写Compose文件:使用YAML语法编写一个Compose文件,定义每个微服务及其相关配置,如镜像、端口映射和环境变量等。
2、定义服务之间的依赖关系:使用depends_on关键字定义每个服务之间的依赖关系,以确保它们按正确的顺序启动。
3、运行Compose文件:使用docker-compose命令运行Compose文件,Docker Compose将会自动创建和管理所需的容器,并启动微服务。
4、监控和扩展:使用Docker Compose可以轻松监控和扩展微服务。通过添加新的服务实例或增加容器数量,可以根据应用程序的需求进行快速扩展。
三、Docker Compose编排微服务
3.1、实战-改造升级微服务project(常规部署微服务项目)
第一版(无mysql、redis数据库,无swagger-ui、无业务类):
改造升级:
1、建库建表
##建库CREATE DATABASE demo1;##建表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='用户表'
2、启动mysql,redis,这里使用docker部署
docker run -d -p 3306:3306 --name mysql-5.7 -e MYSQL_ROOT_PASSWORD=123456 -v /mysql/data:/var/lib/mysql mysql:5.7docker run -d -p 6379:6379 --privileged=true --name my-redis -v /apps/redis/redis.conf:/etc/redis/redis.conf -v /apps/redis/data:/data -d redis:7.0.9 redis-server /etc/redis/redis.conf
3、微服务project修改
swagger测试:http://http://localhost:你的微服务端口/swagger-ui.html
4、打包
源码及jar下载地址:https://download.csdn.net/download/qq_41840843/88332778
5、上传jar至/root/my-projects,并编写Dockerfile
vi Dockerfile,文件内容:
# 基础镜像使用javaFROM java:8# 作者MAINTAINER zyl# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmpVOLUME /tmp# 将jar包添加到容器中并更名为zzyy_docker.jarADD demo2-0.0.1-SNAPSHOT.jar zyl_docker.jar# 运行jar包RUN bash -c 'touch /zyl_docker.jar'ENTRYPOINT ["java","-jar","/zyl_docker.jar"]#暴露6001端口作为微服务EXPOSE 6001
6、构建镜像
docker build -t zyl_docker:1.0 .[root@zyl-server my-projects]# docker build -t zyl_docker:1.0 .DEPRECATED: The legacy builder is deprecated and will be removed in a future release. BuildKit is currently disabled; enable it by removing the DOCKER_BUILDKIT=0 environment-variable.Sending build context to Docker daemon 54.53MB Step 1/7 : FROM java:8 ---> d23bdf5b1b1b Step 2/7 : MAINTAINER zyl ---> Running in 0b94bf865db4 Removing intermediate container 0b94bf865db4 ---> 7047fae445bc Step 3/7 : VOLUME /tmp ---> Running in 0c1f38b522a5 Removing intermediate container 0c1f38b522a5 ---> 4a2014520455 Step 4/7 : ADD demo2-0.0.1-SNAPSHOT.jar zyl_docker.jar ---> 32de0000fc4c Step 5/7 : RUN bash -c 'touch /zyl_docker.jar' ---> Running in ec844531707c Removing intermediate container ec844531707c ---> 15c50c6da487 Step 6/7 : ENTRYPOINT ["java","-jar","/zyl_docker.jar"] ---> Running in 1c76fb58c562 Removing intermediate container 1c76fb58c562 ---> d3f63fdf430e Step 7/7 : EXPOSE 6001 ---> Running in e9ef4587e5ba Removing intermediate container e9ef4587e5ba ---> 6a1e2c0365fd Successfully built 6a1e2c0365fd Successfully tagged zyl_docker:1.0[root@zyl-server my-projects]#
7、列出本地主机上的Docker镜像
[root@zyl-server my-projects]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZE zyl_docker 1.0 6a1e2c0365fd 18 seconds ago 752MB my-spring-boot-app latest 0e110c7ac812 12 days ago 490MB mytomcat latest 7b01ac741538 13 days ago 838MB
8、运行 zyl_docker 镜像
报错:
[root@zyl-server my-projects]# docker run -d -p 6001:6001 6a1e2c0365fd 24f5aff8de0a4ebd2446e4f325dfff908e506e6280eb7b5ecd0ca1578cdc3833 docker: Error response from daemon: driver failed programming external connectivity on endpoint musing_ardinghelli (9d7e940750a0890604a234d2c1b3c7cc2dca2004a66184aee3120e2f9b7ce5ab): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 6001 -j DNAT --to-destination 172.17.0.4:6001 ! -i docker0: iptables: No chain/target/match by that name. (exit status 1)).
解决:
在我们启动了Docker后,我们再对防火墙firewalld进行操作,就会发生上述报错。
systemctl restart docker #重启docker服务即可。
再次运行:
[root@zyl-server my-projects]# docker run -d -p 6379:6379 --privileged=true --name my-redis -v /apps/redis/redis.conf:/etc/redis/redis.conf -v /apps/redis/data:/data -d redis:7.0.9 redis-server /etc/redis/redis.conf79a615e1c6f7fdc06a03a75969e00c49dc932c3f384ca4a7441b006107ae09da[root@zyl-server my-projects]# docker run -d -p 3306:3306 --name mysql-5.7 -e MYSQL_ROOT_PASSWORD=123456 -v /mysql/data:/var/lib/mysql mysql:5.7 00412323842df42e7cab5da36c419d872b94f5a7b145c73886693fb1a2fe2f5e[root@zyl-server my-projects]# docker run -d -p 6001:6001 6a1e2c0365fd6c6c33d4cf0800c9977750d00bb3a5614269136803a93c74d8710d74488495ee[root@zyl-server my-projects]#
swagger测试:
不用Docker Compose,需要按顺序启动:
1、单独的mysql容器
2、实例单独的redis容器实例
3、微服务project
上面不用Docker Compose情况,有哪些问题?
1、先后顺序要求固定,先mysql+redis才能微服务访问成功,需要确保mysql容器和redis容器在启动微服务之前已经处于运行状态。
2、多个run命令…,需要手动运行适当的docker run命令来启动每个容器。
3、容器间的启停或宕机,有可能导致IP地址对应的容器实例变化,映射出错要么生产IP写死(可以但是不推荐),要么通过服务调用,增加了管理和可伸缩性方面的复杂性。
3.2、实战-改造升级微服务project(使用Docker Compose编排微服务)
1、第二次修改微服务工程project
修改数据库IP地址为服务名:
## spring.datasource.url=jdbc:mysql://192.168.234.10:3306/demo1?useUnicode=true&characterEncoding=utf-8&useSSL=falsespring.datasource.url=jdbc:mysql://mysql:3306/demo1?useUnicode=true&characterEncoding=utf-8&useSSL=false## spring.redis.host=192.168.234.10spring.redis.host=redis
2、重新打包项目,替换旧版demo2-0.0.1-SNAPSHOT.jar
1、删除旧版demo2-0.0.1-SNAPSHOT.jar[root@zyl-server my-projects]# rm -rf demo2-0.0.1-SNAPSHOT.jar[root@zyl-server my-projects]#2、重新打包上传demo2-0.0.1-SNAPSHOT.jar
3、在/root/my-projects下,编写docker-compose.yml文件
文件内容:
version: "3"services: microService: image: zyl_docker:1.0 container_name: demo2 ports: - "6001:6001" volumes: - /app/microService:/data networks: - zyl_network depends_on: - redis - mysql redis: image: redis:7.0.9 ports: - "6379:6379" volumes: - /app/redis/redis.conf:/etc/redis/redis.conf - /app/redis/data:/data networks: - zyl_network command: redis-server /etc/redis/redis.conf mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: '123456' MYSQL_ALLOW_EMPTY_PASSWORD: 'no' MYSQL_DATABASE: 'demo1' MYSQL_USER: 'zyl' MYSQL_PASSWORD: '123456' 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: - zyl_network command: --default-authentication-plugin=mysql_native_password #解决外部无法访问networks: zyl_network:
文件解读:
这个配置文件。定义了三个服务:microService、redis和mysql,并在zyl_network网络上进行通信。
1、microService服务使用自定义的zyl_docker:1.0镜像,容器名称为demo2,将主机的6001端口映射到容器的6001端口。将/app/demo2目录挂载到容器的/data目录。
2、redis服务使用redis:7.0.9镜像,将主机的6379端口映射到容器的6379端口。
还将/app/redis/redis.conf挂载到容器的/etc/redis/redis.conf,并将/app/redis/data挂载到容器的/data目录。
通过redis-server /etc/redis/redis.conf命令启动。
3、mysql服务使用mysql:5.7镜像,并设置了一些环境变量来配置MySQL实例。
将主机的3306端口映射到容器的3306端口。
将/app/mysql/db挂载到容器的/var/lib/mysql,并将/app/mysql/conf/my.cnf挂载到容器的/etc/my.cnf。
还有/app/mysql/init目录挂载到容器的/docker-entrypoint-initdb.d目录,以便在初始化数据库时运行脚本。
4、使用--default-authentication-plugin=mysql_native_password命令解决外部无法访问的问题。
5、最后,该配置文件定义了一个名为zyl_network的网络,用于连接这三个服务。
4、构建镜像
先删除之前运行的mysql容器、redis容器、微服务镜像和容器实例。
---这里是测试环境,非测试环境慎用该批量操作!!!!
[root@zyl-server my-projects]# docker stop $(docker ps -aq)863016411ded b5293f455952 0068f033e4e8[root@zyl-server my-projects]# docker rm $(docker ps -aq)[root@zyl-server my-projects]# docker rmi zyl_docker:1.0
重新构建镜像:
docker build -t zyl_docker:1.0 .1
5、验证和显示Docker Compose配置文件的有效性
docker-compose config -q命令用于验证和显示Docker Compose配置文件的有效性,并以安静模式输出配置文件。它会检查配置文件的语法错误和格式问题,并验证所使用的镜像是否可用。
如果配置文件有效且正确,该命令不会产生任何输出。如果存在错误或问题,它将显示相关的错误消息。
[root@zyl-server my-projects]# docker-compose config -q[root@zyl-server my-projects]#
6、执行 docker-compose up 或者 执行 docker-compose up -d
使用docker-compose up命令启动这三个服务,这将在终端窗口中显示服务的日志输出。如果不希望在终端中查看日志输出,并且希望以后台模式启动服务,则可以使用docker-compose up -d命令。
这将以守护进程模式启动服务,并在后台运行。如果使用后台模式,则可以使用docker-compose logs命令来查看服务的日志输出。
1、当前没有正在运行的容器[root@zyl-server my-projects]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES[root@zyl-server my-projects]#2、执行docker-compose up -d[root@zyl-server my-projects]# docker-compose up -d[+] Running 4/4 ✔ Network my-projects_zyl_network Created 0.0s ✔ Container my-projects-mysql-1 Started 0.4s ✔ Container my-projects-redis-1 Started 0.4s ✔ Container demo2 Started 0.6s[root@zyl-server my-projects]#
7、验证服务
1、列出Docker中的网络列表[root@zyl-server my-projects]# docker network lsNETWORK ID NAME DRIVER SCOPE 5a594d4c92e7 bridge bridge local fe8aa9233f89 host host local 80480229149d my-projects_zyl_network bridge local da1bb471897e mynetwork bridge local 7ae86ca33507 none null local e1aea82ce159 redis-network bridge local[root@zyl-server my-projects]#
2、再次列出正在运行的容器(mysql、redis、zyl_docker已启动运行)[root@zyl-server my-projects]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d10f1034b7a7 zyl_docker:1.0 "java -jar /zyl_dock…" 4 seconds ago Up 3 seconds 0.0.0.0:6001->6001/tcp, :::6001->6001/tcp demo2 5a174e725026 redis:7.0.9 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp my-projects-redis-1009428bcad42 mysql:5.7 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp my-projects-mysql-1[root@zyl-server my-projects]#
3、进入mysql容器,新建库、建表 docker exec -it 009428bcad42 /bin/bash[root@zyl-server my-projects]# docker exec -it 009428bcad42 /bin/bashroot@009428bcad42:/# mysql -u root -pEnter password:Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 2Server version: 5.7.36 MySQL Community Server (GPL)Copyright (c) 2000, 2021, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> show databases -> ;+--------------------+| Database |+--------------------+| information_schema || demo1 || mysql || performance_schema || sys |+--------------------+5 rows in set (0.00 sec)mysql> use demo1 Database changed mysql> show tables;Empty set (0.00 sec)mysql>##建表: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=utf8mb4 COMMENT='用户表';##当前t_user为空表mysql> select * from t_user;Empty set (0.00 sec)mysql>
8、swagger测试:http://http://ip:你的微服务端口/swagger-ui.html
mysql数据库验证:
mysql> select * from t_user;+----+----------+----------+-----+---------+---------------------+---------------------+| id | username | password | sex | deleted | update_time | create_time |+----+----------+----------+-----+---------+---------------------+---------------------+| 1 | zyl1 | 18746a | 0 | 0 | 2023-09-12 16:26:14 | 2023-09-12 16:26:14 || 2 | zyl2 | 434f8c | 0 | 0 | 2023-09-12 16:26:14 | 2023-09-12 16:26:14 || 3 | zyl3 | c8ce19 | 0 | 0 | 2023-09-12 16:26:14 | 2023-09-12 16:26:14 |+----+----------+----------+-----+---------+---------------------+---------------------+3 rows in set (0.00 sec)mysql>
测试成功!!!
3.3、总结-Docker Compose的优点
在现代应用程序开发中,微服务架构已经成为一种非常流行的架构模式。然而,微服务的管理和部署通常会面临一些挑战,例如网络通信和协调。为了解决这些问题,Docker Compose作为一个强大的工具应运而生,它能够帮助开发者轻松地编排和管理微服务。
1、简化部署:Docker Compose允许您使用简单的YAML文件定义应用程序的组成部分,并将它们统一地部署为容器。不再需要手动操作每个容器,大大简化了部署过程。
2、管理复杂网络:微服务通常由多个容器组成,它们需要相互通信。Docker Compose可以自动创建和管理容器之间的网络,使得服务之间的通信变得更加便捷。
3、扩展性:Docker Compose允许您根据需要轻松地扩展微服务。通过添加新的服务实例或增加容器数量,可以快速响应应用程序的需求变化。
4、避免依赖冲突:不同的微服务可能依赖于不同版本的软件或库。Docker Compose可以确保每个服务都在自己的容器中运行,避免了依赖冲突的问题。
5、简化本地开发环境:使用Docker Compose可以轻松创建本地开发环境,不再需要为每个服务手动安装和配置依赖项。
Docker Compose为我们提供了一个简单且强大的工具,用于编排和管理微服务。它简化了部署过程,提高了扩展性,并避免了依赖冲突的问题。通过使用Docker Compose,我们可以更加轻松地构建、部署和管理基于微服务架构的应用程序。
四、Docker 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/bashdocker-compose ps # 展示当前docker-compose编排过的运行的所有容器 docker-compose top # 展示当前docker-compose编排过的容器进程docker-compose logs yml里面的服务id # 查看容器输出日志 dokcer-compose config # 检查配置dokcer-compose config -q # 检查配置,有问题才有输出 docker-compose restart # 重启服务 docker-compose start # 启动服务 docker-compose stop # 停止服务