目录
前言
配置集群,不使用docker-compose也同样能配置,使用docker-compose来配置集群的原因最主要的就是简便和方便管理。不建议使用docker的命令去配置集群,直接使用docker-compose即可。
docker-compose用来做什么?
Docker Compose 是用于管理和编排多个 Docker 容器的工具。它允许通过一个简单的配置文件(通常是 YAML 格式)定义应用程序的多个服务、网络、卷和其他资源,然后使用 Docker Compose 命令来启动、停止和管理这些容器。
主要功能:
-
定义多个服务: 使用 Docker Compose,可以定义一个应用程序的多个服务,每个服务对应一个容器或多个容器,也可以指定服务所需的镜像、环境变量、端口映射、卷挂载等配置。
-
编排容器启动顺序: 可以使用 Docker Compose 来定义容器的启动顺序和依赖关系。这样,可以确保在启动应用程序时,各个服务的容器按照正确的顺序启动,并能够正确地互相通信。
-
统一管理容器: Docker Compose 提供了一种集中管理多个容器的方式。可以使用 Docker Compose 命令一次性启动、停止、重启和删除整个应用程序堆栈,管理和操作多个容器变得更加简单和高效。
-
创建和管理网络: Docker Compose 可以定义和管理应用程序的网络。可以创建自定义网络,用于容器之间的通信,或者将容器连接到现有的网络。
-
共享卷和数据: Docker Compose 可以定义卷挂载,从而使容器可以共享数据或访问共享的持久化存储。这使得容器之间可以共享文件和数据,并保留持久性。
-
简化部署和开发环境: Docker Compose 提供了一种简化部署和开发环境的方式。通过将应用程序的各个组件定义在一个文件中,可以轻松地在不同的环境中复制和部署应用程序,确保一致性和可重复性。
docker-compose文件规范及常用元素
官网文档链接:概览 |Docker 文档
docker-compose.yaml文件有严格的缩进和空格要求,一个 docker-compose 文件通常由以下几个部分组成:
-
版本(Version): Docker Compose 文件的顶级元素是
version
,用于指定所使用的 Docker Compose 文件版本。它定义了使用的语法和支持的功能。 -
服务(Services):
services
部分定义了应用程序的各个服务或容器。每个服务都有一个唯一的名称,并包含该服务的配置信息,如所使用的镜像、环境变量、端口映射、卷挂载等。 -
网络(Networks):
networks
部分定义了应用程序的网络配置。可以创建自定义网络,并指定容器连接到哪个网络上,以实现容器之间的通信。 -
卷(Volumes):
volumes
部分定义了应用程序的卷挂载配置。可以指定容器与宿主机之间的文件或目录的映射,实现数据的持久化和共享。 -
环境变量(Environment Variables): 在服务的配置中,可以使用
environment
或env_file
字段指定环境变量。这些环境变量将传递给容器内运行的应用程序。 -
端口映射(Port Mapping): 在服务的配置中,可以使用
ports
字段指定容器端口与宿主机端口之间的映射关系。这使得可以从宿主机访问容器内运行的服务。 -
卷挂载(Volume Mounting): 在服务的配置中,可以使用
volumes
字段指定容器内的路径与宿主机路径之间的映射关系。这允许容器与宿主机之间共享文件和数据。
一、版本和名称顶级元素
1、版本顶级元素 version
用于指定 Docker Compose 文件的版本。该版本指定了使用的 Docker Compose 文件语法和支持的功能。
要指定版本,在 Docker Compose 文件的顶级元素中添加 version
字段。
version: "3.8"
services:
my-service:
image: my-image
# 其他配置项...
version: "3.8"
指定了 Docker Compose 文件的版本为 "3.8"。这意味着该文件将使用 Docker Compose 3.8 版本的语法和功能。
2、名称顶级元素 name
用于指定 Docker Compose 项目的名称。该名称可以在多个方面使用,例如网络、卷和容器的命名,不过一上级元素为默认名称,如下代码所示,my-service即为该服务名称。
要指定项目名称,在 Docker Compose 文件的顶级元素中添加 name
字段
version: "3.8"
services:
my-service:
image: my-image
# 其他配置项...
name: my-project
指定容器名称,指定容器名时有一个专门的container_name元素可以使用
version: "3.8"
services:
my-service:
image: my-image
container_name: my-container
# 其他配置项...
指定网络名称,my-network即为该网路的名称
version: "3.8"
services:
my-service:
networks:
- my-network
networks:
my-network:
# 网络配置...
其他的服务、卷等元素中的name元素基本如上所示
二、服务顶级元素
服务顶级元素中有非常多的元素可以使用,在此只介绍部分常用的元素。
-
image: 指定服务所使用的容器镜像。可以是公共的 Docker Hub 镜像,也可以是私有的镜像。
version: "3.8" services: my-service: # 使用公共镜像 image: mysql:latest # :可使用特定的版本 # 其他配置项... ------------------------------------------------------------------------------------ version: "3.8" services: my-service: build: # 使用本地构建镜像,这部分请自行探索,本文不做解释 context: ./my-app dockerfile: Dockerfile # 其他配置项...
-
volumes: 定义卷挂载配置,用于将容器内的路径与宿主机路径进行映射,实现数据的持久化和共享。
基本卷挂载:指定宿主机路径和容器内路径之间的映射关系。例如,将宿主机的/path/on/host
目录映射到容器内的/path/on/container
目录:version: "3.8" services: my-service: volumes: - /path/on/host:/path/on/container # 其他配置项...
使用命名卷:可以在
volumes
顶级元素部分定义命名卷,然后在服务的配置中引用该命名卷。例如:version: "3.8" services: my-service: volumes: - my-volume:/path/on/container # 其他配置项... volumes: my-volume: # 卷配置...
使用卷挂载有多种模式,rw(读写,默认)、ro(只读)、bind(锚定)、tmpfs(临时文件系统)
version: "3.8" services: my-service: volumes: - /path/on/host:/path/on/container:rw # 其他配置项... version: "3.8" services: my-service: volumes: - /path/on/host:/path/on/container:ro # 其他配置项... version: "3.8" services: my-service: volumes: - type: bind source: /path/on/host target: /path/on/container # 其他配置项... version: "3.8" services: my-service: volumes: - type: tmpfs target: /path/on/container # 其他配置项...
-
ports: 定义端口映射配置,将容器内的端口映射到宿主机的端口上,从而可以通过宿主机访问容器内运行的服务。
基本端口映射:指定将容器内的端口映射到宿主机的端口。例如,将容器内的 8080 端口映射到宿主机的 80 端口:version: "3.8" services: my-service: ports: - 80:8080 # 其他配置项...
指定特定IP:可以指定要将容器端口映射到的特定 IP 地址。例如,将容器内的 8080 端口映射到宿主机的 80 端口,并绑定到特定的 IP 地址:
version: "3.8" services: my-service: ports: - 192.168.0.100:80:8080 # 其他配置项...
不指定时使用动态分配的宿主机端口:
version: "3.8" services: my-service: ports: - 8080 # 其他配置项...
-
environment: 定义环境变量,传递给容器内运行的应用程序。可以使用键值对的形式指定多个环境变量。
这部分,没有特定的子元素,具体的需要查看各个容器的文档,通常在docker-hub的官网中搜索都能查看到,或者在git-hub中也能找到。
需要注意的地方是,environment中的元素可以使用列表和字典两种方式来指定,其他形式无效,注意检查格式。version: "3.8" services: my-service: environment: - DB_HOST=localhost #字典 - DB_PORT=5432 - DB_USER=myuser - DB_PASSWORD=mypassword # 其他配置项... version: "3.8" services: my-service: environment: #列表 DB_HOST: localhost DB_PORT: 5432 DB_USER: myuser DB_PASSWORD: mypassword # 其他配置项...
-
networks: 定义服务所连接的网络,可以是预定义的自定义网络,也可以是默认的网络。
默认网络:如果未指定网络配置,Docker Compose 会自动创建一个默认网络,允许在同一docker-compose.yml
文件中定义的服务之间进行通信。例如:version: "3.8" services: service1: # 服务配置... service2: # 服务配置...
自定义网络:显式地定义一个自定义网络,并将服务连接到该网络。例如:
version: "3.8" services: service1: networks: - my-network # 服务配置... service2: networks: - my-network # 服务配置... networks: my-network: # 网络配置...
外部网络:连接到现有的外部网络,例如在本docker-compose文件之外创建的网络。例如:
version: "3.8" services: service1: networks: - my-external-network # 服务配置... networks: my-external-network: external: true
-
depends_on: 定义服务之间的依赖关系,确保在启动时按正确的顺序启动服务。不过其也并不能保证在所有情况下完全控制服务的启动顺序。它只能确保所依赖的服务在启动时会先行启动,但并不能保证服务完全可用或准备就绪。
version: "3.8" services: db: # 数据库服务配置... app: depends_on: - db # 应用程序服务配置...
app
服务依赖于db
服务。当使用docker-compose up
启动服务时,db
服务会先于app
服务启动。 -
restart: 定义容器在退出时的重启策略。可以设置为"no"、"always"、"on-failure" 或 "unless-stopped"。
无重启策略(默认):如果未指定restart
元素,则容器将不会自动重启。version: "3.8" services: my-service: # 服务配置...
重启策略:可以使用
restart
元素指定容器的重启策略。常见的重启策略包括:
no:不重启容器。即使容器退出或发生错误,也不会自动重启。
always:总是重启容器。无论容器是如何退出或发生错误,都会自动重启。
on-failure:只在容器非正常退出时(退出状态码非零)才重启容器。
unless-stopped:除非手动停止容器,否则始终重启容器。即使容器在正常情况下退出,也会自动重启。version: "3.8" services: my-service: restart: always/no/on-failure/unless-stopped # 服务配置...
-
container_name: 用于指定容器的名称。
默认情况下,Docker Compose 会根据服务的名称和项目名称来生成容器的名称。然而,使用container_name
元素可以覆盖默认生成的容器名称,并为容器指定一个自定义的名称。version: "3.8" services: my-service: image: my-image container_name: my-container # 其他配置项...
my-service
服务使用my-image
镜像,并将容器名称设置为my-container
。 -
hostname: 用于指定容器的主机名,为容器设置自定义的主机名。
version: "3.8" services: my-service: image: my-image hostname: my-host # 其他配置项...
my-service
服务使用my-image
镜像,并将容器的主机名设置为my-host
。
注:建议通常container_name和hostname都要设置并且设置为同一个,这能避免很多麻烦。hostname和container_name的作用不同,hostname通常是和ip绑定的,类比DNS服务。 -
links: 已弃用,和depends_on作用类似,现一般使用depends_on
-
working_dir: 用于指定容器的工作目录(Working Directory),工作目录是容器中执行命令和操作时的默认目录,也可以理解为进入容器后无任何操作的当前路径。
version: "3.8" services: my-service: image: my-image working_dir: /app # 其他配置项...
三、网络顶级元素
- networks:用于定义多个网络,每个网络由一个名称和一个可选的配置对象组成。
version: "3.8" networks: network1: # 网络1的配置 network2: # 网络2的配置 services: # 服务配置...
以上定义了两个网络,分别为
network1
和network2
。 -
name:每个网络都需要一个名称,以便在服务配置中引用它。名称应该是唯一的。
version: "3.8" networks: my-network: # 网络配置 services: my-service: networks: - my-network # 服务配置...
以上定义了一个名为
my-network
的网络,并在my-service
服务的网络配置中引用了它。 -
driver:定义了网络的类型。默认情况下,Docker Compose 使用
bridge
模式。常见的几种模式有
-
bridge
(默认):这是 Docker 默认的网络驱动程序。它创建一个本地网络,允许容器通过网络进行通信。这是最常用的网络驱动程序。 -
host
:使用宿主机的网络命名空间,容器与宿主机共享网络栈。容器的网络与宿主机的网络完全一致,网络性能较高。 -
overlay
:用于创建跨多个 Docker 主机的网络。它允许在多个 Docker 主机上的容器之间进行通信,并提供了跨主机的网络连接。
四、卷顶级元素
- volumes:这是一个列表,用于定义多个卷。每个卷由一个名称和一个可选的配置对象组成。
version: "3.8" volumes: volume1: # 卷1的配置 volume2: # 卷2的配置 services: # 服务配置...
docker-compose样例文件展示
文件只做参考,不保证完全的准确性
version: '3'
networks:
kafka-storm-net:
services:
zookeeper1:
image: zookeeper:3.7.1
container_name: zookeeper1
hostname: zookeeper1
ports:
- 8101:2181
- 8102:2888
- 8103:3888
- 8108:8080
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zookeeper1:2888:3888;2181 server.2=zookeeper2:2888:3888;2181 server.3=zookeeper3:2888:3888;2181
networks:
- kafka-storm-net
zookeeper2:
image: zookeeper:3.7.1
container_name: zookeeper2
hostname: zookeeper2
ports:
- 8201:2181
- 8202:2888
- 8203:3888
- 8208:8080
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zookeeper1:2888:3888;2181 server.2=zookeeper2:2888:3888;2181 server.3=zookeeper3:2888:3888;2181
networks:
- kafka-storm-net
zookeeper3:
image: zookeeper:3.7.1
container_name: zookeeper3
hostname: zookeeper3
ports:
- 8301:2181
- 8302:2888
- 8303:3888
- 8308:8080
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zookeeper1:2888:3888;2181 server.2=zookeeper2:2888:3888;2181 server.3=zookeeper3:2888:3888;2181
networks:
- kafka-storm-net
kafka1:
image: bitnami/kafka:latest
hostname: kafka1
container_name: kafka1
ports:
- 19092:9092
environment:
KAFKA_ENABLE_KRAFT: yes
KAFKA_CFG_NODE_ID: 1
KAFKA_CFG_PROCESS_ROLES: controller,broker
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: OUTSIDE:PLAINTEXT,CONTROLLER:PLAINTEXT,INSIDE:PLAINTEXT
KAFKA_CFG_ADVERTISED_LISTENERS: OUTSIDE://:9092,INSIDE://:9091
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_CFG_LISTENERS: CONTROLLER://:9093,OUTSIDE://0.0.0.0:9092,INSIDE://:9091
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
ALLOW_PLAINTEXT_LISTENER: 'yes'
KAFKA_KRAFT_CLUSTER_ID: iZWRiSqjZAlYwlKEqHFQWI
volumes:
- ./kafka-data/kafka1:/bitnami/kafka:rw
networks:
- kafka-storm-net
kafka2:
image: bitnami/kafka:latest
hostname: kafka2
container_name: kafka2
ports:
- 29092:9092
environment:
KAFKA_ENABLE_KRAFT: yes
KAFKA_CFG_NODE_ID: 2
KAFKA_CFG_PROCESS_ROLES: controller,broker
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: OUTSIDE:PLAINTEXT,CONTROLLER:PLAINTEXT,INSIDE:PLAINTEXT
KAFKA_CFG_ADVERTISED_LISTENERS: OUTSIDE://:9092,INSIDE://:9091
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_CFG_LISTENERS: CONTROLLER://:9093,OUTSIDE://0.0.0.0:9092,INSIDE://:9091
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
ALLOW_PLAINTEXT_LISTENER: 'yes'
KAFKA_KRAFT_CLUSTER_ID: iZWRiSqjZAlYwlKEqHFQWI
volumes:
- ./kafka-data/kafka2:/bitnami/kafka:rw
networks:
- kafka-storm-net
kafka3:
image: bitnami/kafka:latest
hostname: kafka3
container_name: kafka3
ports:
- 39092:9092
environment:
KAFKA_ENABLE_KRAFT: yes
KAFKA_CFG_NODE_ID: 3
KAFKA_CFG_PROCESS_ROLES: controller,broker
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: OUTSIDE:PLAINTEXT,CONTROLLER:PLAINTEXT,INSIDE:PLAINTEXT
KAFKA_CFG_ADVERTISED_LISTENERS: OUTSIDE://:9092,INSIDE://:9091
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
KAFKA_CFG_LISTENERS: CONTROLLER://:9093,OUTSIDE://0.0.0.0:9092,INSIDE://:9091
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
ALLOW_PLAINTEXT_LISTENER: 'yes'
KAFKA_KRAFT_CLUSTER_ID: iZWRiSqjZAlYwlKEqHFQWI
volumes:
- ./kafka-data/kafka3:/bitnami/kafka:rw
networks:
- kafka-storm-net
kafka-ui:
image: provectuslabs/kafka-ui:master
container_name: kafka-ui
ports:
- "9080:8080"
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=hsh_kafka_cluster
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS= kafka1:9092 ,kafka2:9092,kafka3:9092
- DYNAMIC_CONFIG_ENABLED= 'true'
- AUTH_TYPE=LOGIN_FORM
- SPRING_SECURITY_USER_NAME=hsh
- SPRING_SECURITY_USER_PASSWORD=241817
depends_on:
- kafka1
- kafka2
- kafka3
volumes:
- ./kafka-ui/config.yml:/etc/kafkaui/dynamic_config.yaml
networks:
- kafka-storm-net
storm-nimbus:
image: storm:2.5.0
container_name: storm-nimbus
hostname: storm-nimbus
command: storm nimbus
ports:
- 6627:6627
depends_on:
- zookeeper1
- zookeeper2
- zookeeper3
environment:
- STORM_ZOOKEEPER_SERVERS=zookeeper1,zookeeper2,zookeeper3
volumes:
- ./storm-conf/storm.yaml:/conf/storm.yaml
networks:
- kafka-storm-net
storm-supervisor1:
image: storm:2.5.0
container_name: storm-supervisor1
hostname: storm-supervisor1
command: storm supervisor
depends_on:
- storm-nimbus
volumes:
- ./storm-conf/storm.yaml:/conf/storm.yaml
networks:
- kafka-storm-net
storm-supervisor2:
image: storm:2.5.0
container_name: storm-supervisor2
hostname: storm-supervisor2
command: storm supervisor
depends_on:
- storm-nimbus
volumes:
- ./storm-conf/storm.yaml:/conf/storm.yaml
networks:
- kafka-storm-net
storm-supervisor3:
image: storm:2.5.0
container_name: storm-supervisor3
hostname: storm-supervisor3
command: storm supervisor
depends_on:
- storm-nimbus
volumes:
- ./storm-conf/storm.yaml:/conf/storm.yaml
networks:
- kafka-storm-net
storm-ui:
image: storm:2.5.0
container_name: storm-ui
hostname: storm-ui
command: storm ui
ports:
- "8080:8080"
depends_on:
- storm-nimbus
volumes:
- ./storm-conf/storm.yaml:/conf/storm.yaml
networks:
- kafka-storm-net
运行docker-compose文件
在docker-compose.yaml文件的当前目录下,右键点击在终端中打开
输入命令:docker-compose up,即会自动拉取docker-compose文件中的相关镜像并开启容器运行,待其全部完毕,就可以在docker的可视化界面中看到已经开启的集群。
注:
1、docker-compose的文件,只有在文件名为docker-compose时才可以使用docker-compose up命令,如果名字为自定义时,需要指定文件名才行,命令为 docker-compose -f my-compose.yml up。
2、docker-compose文件名后缀使用 .yml 或 .yaml都可。