云原生容器编排技术Docker Compose
Posted 鹤冲天Pro
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了云原生容器编排技术Docker Compose相关的知识,希望对你有一定的参考价值。
为什么需要Docker Compose
Docker帮助我们解决服务的打包安装的问题,随着而来的问题就是服务过多的带来如下问题:
- 多次使用Dockerfile Build Image或者DockerHub拉取Image;
- 需要创建多个Container,多次编写启动命令;
- Container互相依赖的如何进行管理和编排;
当我们服务数量增多的时候,上面三个问题就会更加的被放大,如果这三个问题不解决,其实从虚拟机到容器化除了机器减少一些浪费以外,好像没有更多的变化。Docker有没有什么好的方法,可以让我们通过一个配置就搞定容器编排和运行呢?这个时候Docker Compose就站出来了。
Docker Compose可以做到以下几点:
- 提供工具用于定义和运行多个docker容器应用;
- 使用yaml文件来配置应用服务(docker-compse.yml);
- 可以通过一个简单的命令docker-compse up可以按照依赖关系启动所有服务;
- 可以通过一个简单的命令docker-compose down停止所有服务;
- 当一个服务需要的时候,可以很简单地通过–scale进行扩容;
Docker Compose有以下特征:
- 更高的可移植性,Docker Compose仅需一个docker-compse up可以完成按照依赖关系启动所有服务,然后使用docker-compose down轻松将其拆解。帮助我们更轻松地部署复杂的应用程序;
- 单个主机上的多个隔离环境,Compose可以使用项目名称将环境彼此隔离,这带可以在一台计算机上运行同一环境的多个副本,它可以防止不同的项目和服务相互干扰;
Docker Compose介绍
-
Docker Compose是一个工具,用于定义和运行多容器应用程序的工具;
-
Docker Compose通过yml文件定义多容器的docker应用;
-
Docker Compose通过一条命令根据yml文件的定义去创建或管理多容器;
Docker Compose 是用来做Docker 的多容器控制,是一个用来把 Docker 自动化的东西。有了 Docker Compose 你可以把所有繁复的 Docker 操作全都一条命令,自动化的完成。
Docker Compose安装
Docker Compose安装的最新的版本1.29.2,对于Mac和Windows安装好Docker以后,就已经安装好Docker Compose,不需要手动安装,这里的安装方式是基于Linux的Cnetos的,大家也可以参考官方网站去安装,
具体步骤如下:
- 下载 Docker Compose 二进制文件,版本1.29.2是目前最新最稳定的版本,要下载旧版本的大家可以更改版本号,可以参考github的版本号进行选择;
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- 对二进制文件应用可执行权限;
sudo chmod +x /usr/local/bin/docker-compose
- 安装以后通过docker-compose --version命令检查是否安装成功;
Docker Compose版本介绍
Docker Compose版本与引擎的对应关系如下,可以看到中间主要有两个版本2和版本3两种格式,目前大家使用比较多也就是这两种,对于这两个版本的差别给大家介绍一下:
- v3 版本不支持 volume_from 、extends、group_add等属性;
- cpu 和 内存属性的设置移到了 deploy 中;
- v3 版本支持 Docker Swarm,而 v2 版本不支持;
注意:官方目前在 1.20.0 引入了一个新–compatibility标志,帮助开发人员轻松的过渡到v3,目前还有些问题官方还不建议直接使用到生产,建议大家直接上手v3版本。
Docker Compose基本命令介绍
Docker Compose命令基本上和Docker相差不多,主要就是对Docker Compose生命周期控制、日志格式等相关命令,可以通过docker-compose --help进行帮助。
#构建建启动nignx容器
docker-compose up -d nginx
#进入nginx容器中
docker-compose exec nginx bash
#将会停止UP命令启动的容器,并删除容器
docker-compose down
#显示所有容器
docker-compose ps
#重新启动nginx容器
docker-compose restart nginx
#构建镜像
docker-compose build nginx
#不带缓存的构建
docker-compose build --no-cache nginx
#查看nginx的日志
docker-compose logs nginx
#查看nginx的实时日志
docker-compose logs -f nginx
#验证(docker-compose.yml)文件配置,
#当配置正确时,不输出任何内容,当文件配置错误,输出错误信息
docker-compose config -q
#以json的形式输出nginx的docker日志
docker-compose events --json nginx
#暂停nignx容器
docker-compose pause nginx
#恢复ningx容器
docker-compose unpause nginx
#删除容器
docker-compose rm nginx
#停止nignx容器
docker-compose stop nginx
#启动nignx容器
docker-compose start nginx
Docker Compose实战
我们构建一个如下的应用,通过Nginx转发给后端的两个Java应用;
- 新建Spring Boot应用,增加一个HelloController,编写一个hello方法,返回请求的端口和IP;
/**
* hello
*
* @author wangtongzhou
* @since 2021-07-25 09:43
*/
@RestController
public class HelloController
@GetMapping("/hello")
public String hello(HttpServletRequest req) throws UnknownHostException
return "hello";
- 指定Spring Boot的启动入口;
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 指定该Main Class为全局的唯一入口 -->
<mainClass>cn.wheel.getway.WheelGetWay</mainClass>
</configuration>
<executions>
<execution>
<goals>
<!--可以把依赖的包都打包到生成的Jar包中-->
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 打包Spring Boot应用;
mvn package
- 上传文件到Linux服务器/usr/local/docker-compose-demo的目录;
- 在/usr/local/docker-compose-demo的目录编辑Dockerfile;
#指定基础镜像
FROM java:8
LABEL name="docker-compose-demo" version="1.0" author="wtz"
COPY ./getway-1.0-SNAPSHOT.jar ./docker-compose-demo.jar
#启动参数
CMD ["java","-jar","docker-compose-demo.jar"]
- 编辑docker-compose.yml文件;
version: '3.0'
networks:
docker-compose-demo-net:
driver: bridge
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
services:
docker-compose-demo01:
build:
#构建的地址
context: /usr/local/docker-compose-demo
dockerfile: Dockerfile
image: docker-compose-demo
container_name: docker-compose-demo01
#选择网络
networks:
- docker-compose-demo-net
#选择端口
ports:
- 8081:8080/tcp
restart: always
docker-compose-demo02:
build:
#构建的地址
context: /usr/local/docker-compose-demo
dockerfile: Dockerfile
image: docker-compose-demo
container_name: docker-compose-demo02
#选择网络
networks:
- docker-compose-demo-net
#选择端口
ports:
- 8082:8080/tcp
restart: always
nginx:
image: nginx:latest
container_name: nginx-demo
networks:
- docker-compose-demo-net
ports:
- 80:80/tcp
restart: always
volumes:
- /usr/local/docker-compose-demo/nginx.conf:/etc/nginx/nginx.conf:rw
volumes:
docker-compose-demo-volume:
- 编写nginx.conf,实现负载均衡到每个应用,这里通过容器名称访问,因此不需要管每个容器的ip是多少,这个也是自定义网络的好处;
user nginx;
worker_processes 1;
events
worker_connections 1024;
http
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server
listen 80;
location /
proxy_pass http://docker-compose-demo;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
upstream docker-compose-demo
server docker-compose-demo01:8080;
server docker-compose-demo02:8080;
include /etc/nginx/conf.d/*.conf;
server
listen 80;
location /
proxy_pass http://docker-compose-demo;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
upstream docker-compose-demo
server docker-compose-demo01:8080;
server docker-compose-demo02:8080;
include /etc/nginx/conf.d/*.conf;
-
查看/usr/local/docker-compose-demo目录,有以下确保有以下四个文件;
-
检查docker-compose.yml的语法是否正确,如果不发生报错,说明语法没有发生错误;
docker-compose config -
启动docker-compose.yml定义的服务;
docker-compose up
- 验证服务是否正确;
#查看宿主机ip
ip add
#访问对应的服务
curl http://172.21.122.231/hello
Docker Compose Yml文件介绍
version
指定使用的版本;
Services
每个Service代表一个Container,与Docker一样,Container可以是从DockerHub中拉取到的镜像,也可以是本地Dockerfile Build的镜像。
image
标明image的ID,这个image ID可以是本地也可以是远程的,如果本地不存在,Docker Compose会尝试pull下来;
image: ubuntu
build
该参数指定Dockerfile文件的路径,Docker Compose会通过Dockerfile构建并生成镜像,然后使用该镜像;
build:
#构建的地址
context: /usr/local/docker-compose-demo
dockerfile: Dockerfile
ports
暴露端口,指定宿主机到容器的端口映射,或者只指定容器的端口,则表示映射到主机上的随机端口,一般采用主机:容器的形式来映射端口;
#暴露端口
ports:
- 8081:8080/tcp
expose
暴露端口,但不需要建立与宿主机的映射,只是会向链接的服务提供;
environment
加入环境变量,可以使用数组或者字典,只有一个key的环境变量可以在运行compose的机器上找到对应的值;
env_file
从一个文件中引入环境变量,该文件可以是一个单独的值或者一个列表,如果同时定义了environment,则environment中的环境变量会重写这些值;
depends_on
定义当前服务启动时,依赖的服务,当前服务会在依赖的服务启动后启动;
depends_on:
- docker-compose-demo02
- docker-compose-demo01
deploy
该配置项在version 3里才引入,用于指定服务部署和运行时相关的参数;
replicas
指定副本数;
version: '3.4'
services:
worker:
image: nginx:latest
deploy:
replicas: 6
restart_policy
指定重启策略;
version: "3.4"
services:
redis:
image: redis:latest
deploy:
restart_policy:
condition: on-failure #重启条件:on-failure, none, any
delay: 5s # 等待多长时间尝试重启
max_attempts: 3 #尝试的次数
window: 120s # 在决定重启是否成功之前等待多长时间
update_config
定义更新服务的方式,常用于滚动更新;
version: '3.4'
services:
vote:
image: docker-compose-demo
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2 # 一次更新2个容器
delay: 10s # 开始下一组更新之前,等待的时间
failure_action:pause # 如果更新失败,执行的动作:continue, rollback, pause,默认为pause
max_failure_ratio: 20 # 在更新过程中容忍的失败率
order: stop-first # 更新时的操作顺序,停止优先(stop-first,先停止旧容器,再启动新容器)还是开始优先(start-first,先启动新容器,再停止旧容器),默认为停止优先,从version 3.4才引入该配置项
resources
限制服务资源;
version: '3.4'
services:
redis:
image: redis:alpine
deploy:
resources:
#限制CPU的使用率为50%内存50M
limits:
cpus: '0.50'
memory: 50M
#始终保持25%的使用率内存20M
reservations:
cpus: '0.25'
memory: 20M
healthcheck
执行健康检查;
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 用于健康检查的指令
interval: 1m30s # 间隔时间
timeout: 10s # 超时时间
retries: 3 # 重试次数
start_period: 40s # 启动多久后开始检查
restart
重启策略;
#默认的重启策略,在任何情况下都不会重启容器
restart: "no"
#容器总是重新启动
restart: always
#退出代码指示失败错误,则该策略会重新启动容器
restart: on-failure
#重新启动容器,除非容器停止
restart: unless-stopped
networks
网络类型,可指定容器运行的网络类型;
#指定对应的网络
networks:
- docker-compose-demo-net
networks:
docker-compose-demo-net:
driver: bridge
ipam:
config:
- subnet: 192.168.1.0/24
gateway: 192.168.1.1
ipv4_address, ipv6_address
加入网络时,为此服务指定容器的静态 IP 地址;
version: "3.9"
services:
app:
image: nginx:alpine
networks:
app_net:
ipv4_address: 172.16.238.10
ipv6_address: 2001:3984:3989::10
networks:
app_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
- subnet: "2001:3984:3989::/64"
Networks
网络决定了服务之间以及服务和外界之间如何去通信,在执行docker-compose up的时候,docker会默认创建一个默认网络,创建的服务也会默认的使用这个默认网络。服务和服务之间,可以使用服务的名字进行通信,也可以自己创建网络,并将服务加入到这个网络之中,这样服务之间可以相互通信,而外界不能够与这个网络中的服务通信,可以保持隔离性。
Volumes
挂载主机路径或命名卷,指定为服务的子选项。可以将主机路径挂载为单个服务定义的一部分,无需在顶级volume中定义。如果想在多个服务中重用一个卷,则在顶级volumes key 中定义一个命名卷,将命名卷与服务一起使用。
总结
Docker Compose 的整体使用步骤还是比较简单的,三个步骤为:
- 使用 Dockerfile 文件定义应用程序的环境;
- 使用 docker-compose.yml 文件定义构成应用程序的服务,这样它们可以在隔离环境中一起运行;
- 最后,执行 docker-compose up 命令来创建并启动所有服务。
虽然 docker-compose.yml 文件详解和Compose 常用命令这两大块的内容比较多,但是如果要快速入门使用 Compose,其实只需要了解其中部分内容即可。后期大家可在项目生产环境中根据自身情况再进一步深入学习即可。
[云原生专题-14]:容器 - 批量定义构建运行多个微服务- docker编排工具Compose
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/122726338
目录
第6章 使用 Compose 命令构建和运行docker应用
前言:
在实际系统中,每个docker提供的微服务功能范围较小,因此一个系统中乎拥有大量的实现微服务功能的docker,因此,需要一种机制能够批量的启动这些微服务,提升效率。
Docker Compose就是能够完成这样目标的工具, 如下图所示
第1章 Docker-Compose 简介
docker Compose是一个批量定义、构建、运行多个微服务- dockek编排工具,在复杂docker部署中得到广泛的应用。
通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
如果你还不了解 YML 文件配置,可以先阅读 YAML 入门教程。
Compose 使用的四个步骤:
-
安装Docker Compose工具
-
使用 Dockerfile 单个定义微服务应用程序的环境。
-
使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
-
最后,执行 docker-compose up 命令来启动并运行整个应用程序。
第2章 Docker-Compose 的安装
Linux 上我们可以从 Github 上下载它的二进制包来使用,最新发行的版本地址:Releases · docker/compose · GitHub。
也就是说Docker-Compose并不是docker自身携带的功能,而是一个独立的工具。
#运行以下命令以下载 Docker Compose 的当前稳定版本:
# 工具安装
$ sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
#将可执行权限应用于二进制文件:
$ sudo chmod +x /usr/local/bin/docker-compose
#创建软链:
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 安装后检测
$ docker-compose --version
cker-compose version 1.24.1, build 4667896b
第3章 构建一个新的微服务应用程序
3.1 构建前准备
(1)创建一个测试目录:
$ mkdir composetest $ cd composetest
(2)在测试目录中创建一个名为 app.py 的文件,并复制粘贴以下内容:
composetest/app.py 文件代码
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)
在此示例中,
- 该应用程序依赖外部两个实体:redis和Flask
- redis 是外部应用程序网络上的 redis 容器(也是一个容器)的主机名,该主机使用的端口为 6379。通过redis可以访问外部的redis 容器中的存储和查找服务。
(3)在 composetest 目录中创建另一个名为 requirements.txt 的文件,内容如下:
flask
redis
第4章 把微服务应用程序构建成一个docker镜像
4.1 创建 Dockerfile 文件
在 composetest 目录中,创建一个名为 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
COPY . .
CMD ["flask", "run"]
Dockerfile 内容解释:
-
FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。
-
WORKDIR /code: 将工作目录设置为 /code。
-
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0设置 flask 命令使用的环境变量。
-
RUN apk add --no-cache gcc musl-dev linux-headers: 安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
-
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt复制 requirements.txt 并安装 Python 依赖项。
-
COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
-
CMD ["flask", "run"]: 容器提供默认的执行命令为:flask run。
这样就定义好了一个微服务容器。
4.2 单独构建docker镜像(仅用于测试)
[root@i-kfhwt9y5 ~]# docker build -t python-app:v1 .
[root@i-kfhwt9y5 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 432e8ef5a9b9 25 minutes ago 41.8MB
ubuntu latest d13c942271d6 2 weeks ago 72.8MB
python 3.7-alpine a1034fd13493 8 weeks ago 41.8MB
第5章 创建 docker-compose.yml
在测试目录中创建一个名为 docker-compose.yml 的文件,然后粘贴以下内容:
# yaml 配置
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
该 Compose 文件定义了两个服务:web 和 redis。
- web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像(build: .)。然后,它将容器和主机绑定到暴露的端口 5000(port "5000:5000")。此示例服务使用 Flask Web 服务器的默认端口 5000 。
- redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像
通过docker-compose,可以构建多个相关联的docker镜像。
第6章 使用 Compose 命令构建和运行docker应用
在测试目录中,执行以下命令来启动应用程序:
docker-compose up
如果你想在后台执行该服务可以加上 -d 参数:
docker-compose up -d
第7章 查看构建的docker镜像
(1)静态镜像
[root@i-kfhwt9y5 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 432e8ef5a9b9 36 minutes ago 41.8MB
ubuntu latest d13c942271d6 2 weeks ago 72.8MB
redis alpine 3900abf41552 8 weeks ago 32.4MB
python 3.7-alpine a1034fd13493 8 weeks ago 41.8MB
(2)自动下载redis镜像
(3)自动下载python镜像
(4)自动构建了一个app镜像
(5)自动运行docker镜像
(2)动态docker
docker ps
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/122726338
以上是关于云原生容器编排技术Docker Compose的主要内容,如果未能解决你的问题,请参考以下文章
[云原生专题-14]:容器 - 批量定义构建运行多个微服务- docker编排工具Compose
云原生时代必须具备的核心技能之Docker高级篇(DockerCompose-容器编排)