Docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙盒机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和云之间移动。
问题导入:
①作为新时代的全干工程师,当我们编写好一个项目以后,一般都需要准备一个服务器,在上面一般需要安装MySQL,Redis等开发期间常用的中间件。但是这往往非常麻烦,因为我们要考虑到与操作系统的适配问题等因素。Docker应运而生,它可以帮助我们跨平台的快速运行一个应用。
②当我们与客户对接时,我们会给客户专门写一个部署文档:安装Java环境... ,长篇大论一大堆,客户只想要见简单的运行我们交付的程序。Docker应运而生,它可以帮助我们把软件打成软件包,实现快速构建应用目的。
③我们需要将软件发送给客户,可能使用U盘,百度网盘,文件传输助手等... 但是这样以来,当客户软件丢失或者需要软件的其它版本时,我们就需要不断的给客户提供。Docker应运而生,它可以帮助我们快速的分享应用。分享到Docker的应用商店DockerHub
Docker 的核心概念
-
镜像(Image):Docker 镜像是一个轻量级、可执行的独立软件包,它包含运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量和配置文件。简而言之:将做好的项目,及其所需要的外部环境,定格拍照就称之为镜像
-
容器(Container):Docker 容器是由 Docker 镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
-
仓库(Repository):Docker 仓库是集中存放镜像文件的场所。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。
-
定制镜像文件(Dockerfile):将制作镜像(image)的步骤称之为定制镜像文件。它详细的描述了描述了制作镜像的过程。
Docker的主要用途
-
提供一次性的环境:例如,本地测试他人的软件、持续集成时提供单元测试和构建的环境。
-
提供弹性的云服务:Docker容器可以随开随关,适合动态扩容和缩容。
-
组建微服务架构:通过多个容器,一台机器可以运行多个服务,模拟微服务架构。
Docker容器与虚拟机的区别
1. 架构与资源利用
-
虚拟机:虚拟机通过在宿主机上模拟完整的硬件环境来运行操作系统和应用程序。每个虚拟机都包含了一个完整的操作系统实例,这意味着每个虚拟机都需要占用大量的系统资源,如内存、CPU和磁盘空间。
-
Docker容器:Docker容器则不同,它利用操作系统级别的虚拟化技术,与宿主机共享同一个操作系统内核。容器只包含了应用程序及其依赖项,而不包含完整的操作系统。因此,容器比虚拟机更加轻量级,启动速度更快,资源利用率更高。
2. 隔离性
-
虚拟机:虚拟机提供了较强的隔离性,每个虚拟机都有自己独立的操作系统和硬件资源,互不影响。这种隔离性使得虚拟机在安全性和稳定性方面具有优势。
-
Docker容器:虽然Docker容器也提供了一定的隔离性,但其隔离程度相对较低。容器之间以及容器与宿主机之间仍然存在一定的资源共享和交互。因此,在安全性要求较高的场景下,虚拟机可能更加适合。
3. 性能与启动速度
-
虚拟机:由于虚拟机需要模拟完整的硬件环境并运行一个完整的操作系统,因此其启动速度相对较慢,且性能损耗较大。
-
Docker容器:Docker容器由于轻量级和与宿主机共享操作系统内核的特点,其启动速度非常快,且性能损耗较小。这使得容器在需要快速部署和扩展的场景下具有明显优势。
4. 管理与部署
-
虚拟机:虚拟机的管理和部署相对复杂,需要安装和配置完整的操作系统以及相关的应用程序。此外,虚拟机的迁移和扩展也需要较多的手动操作。
-
Docker容器:Docker容器则提供了更加简化和自动化的管理和部署方式。通过Dockerfile和Docker Compose等工具,可以轻松地构建、运行和管理容器化应用程序。此外,容器的迁移和扩展也更加方便和灵活。
5. 应用场景
-
虚拟机:虚拟机更适合用于需要高隔离性和安全性的场景,如运行不同的操作系统、测试和开发环境等。
-
Docker容器:Docker容器则更适合用于微服务架构、持续集成/持续部署(CI/CD)以及快速部署和扩展应用程序等场景。
本次教学是在centos腾讯云服务器上进行操作和实验的,如果有不一样的请前往官网参考使用手册来进行操作和配置
官网地址:Docker: Accelerated Container Application Developmenthttps://www.docker.com/
本篇环境:开启了腾讯云服务器,并且使用可视化工具,远程连接云服务器,在其面板中进行Docker操作与实验。
WindTerm(可视化工具):https://github.com/kingToolbox/WindTerm/releases/download/2.6.0/WindTerm_2.6.1_Windows_Portable_x86_64.ziphttps://github.com/kingToolbox/WindTerm/releases/download/2.6.0/WindTerm_2.6.1_Windows_Portable_x86_64.zip
安装Docker
①卸载旧版本的Docker
# 移除旧版本docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
②配置Docker的下载源,默认是Docker官网地址。这里我们自定义设置为阿里的地址下载源。
# 配置docker yum源。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
③安装Docker引擎,包含Docker引擎的命令行程序,Docker的运行时环境,Docker用来构建镜像的插件工具,以及做批量的插件工具。
# 安装 最新 docker
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
④以root身份来启动Docke容器,直接让Docker在开机甚至关机的时候也保持启动。停机后每次开机也可以直接运行Docker指令。
# 启动& 开机启动docker; enable + start 二合一
systemctl enable docker --now
⑤优化配置项,Docker在下载镜像时,是默认到DockerHub上去下载的。连接国外速度慢,所以推荐连接国内的镜像市场。
# 配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://docker.m.daocloud.io"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
容器管理命令
1.1 查看容器
-
docker ps
:列出当前正在运行的容器。
-
-a
:列出所有容器(包括已停止的)。ALL全部 -
-q
:仅列出容器ID。
-
1.2 创建和启动容器(重点)
-
docker run
:创建并启动一个新的容器。如果启动的镜像不存在的话,那么Docker就会自动帮你下载对应的镜像,然后再进行运行。
-
--name
:为容器指定一个名称。注意自定义名称不能带有中文否则会报错 -
-d
:在后台运行容器。deamon后台 -
-p
:将宿主机的端口映射到容器的端口。解释:每一个容器其实都拥有完整的文件系统,名称空间,CPU进程、内存等这些操作。相当于是一个小型的系统。 -
--network
:将启动的容器加入指定的网络当中,实现容器之间的相互通信。 -
-v
:将宿主机的目录或文件挂载到容器内。或者是卷映射。
思考:以下图为例,请问80可以重复吗?哪88呢?
答:80可以重复设置,88不能重复设置。因为每一台主机上不能出现重复的端口号,但是容器就不一样了它们之间相互隔离,相当于是不同的主机可以设置重复的80端口,供外部端口映射访问。
-
1.3 停止和启动容器
-
docker stop
:停止一个或多个正在运行的容器。 -
docker start
:启动一个或多个已停止的容器。 -
docker restart
:重启一个或多个容器。无论容器是否处于启动中都可以操作成功。
1.4 删除容器
-
docker rm
:删除一个或多个容器。注意:删除一个容器必须先要将其停止
-
-f
:强制删除正在运行的容器。force remove 强制删除
-
1.5 进入容器(重点)
-
docker exec
:在运行的容器中执行命令。
-
-it
:以交互模式进入容器。
-
结果演示:
1.6 查看容器日志
-
docker logs
:查看容器的日志输出。
-
-f
:实时跟踪容器的日志输出。
-
1.7查看容器状态
-
docker stats
:查看容器状态,占用CPU资源大小等...
镜像管理命令
2.1 查看镜像
-
docker images
:列出本地所有的镜像。
-
-a
:列出所有镜像(包括中间层镜像)。 -
-q
:仅列出镜像ID。
-
2.2 拉取镜像
-
docker pull
:从远程仓库拉取镜像。下载镜像
2.3 删除镜像
-
docker rmi
:删除一个或多个本地镜像。注意版本问题。版本不同所代表的镜像也不同
-
-f
:强制删除镜像。force remove强制性删除操作
-
2.4 构建镜像
-
docker build
:根据 Dockerfile 构建镜像。(了解Dockerfile文件怎么来编写,后面有介绍Dockerfile的相关知识)
-
-t
:指定镜像的名称和标签。 -
-f
:指定构建镜像时所使用的文件
-
2.5检索镜像
-
docker search
:搜索镜像,模糊搜索。想要了解镜像更加详细的信息就去DockerHub上搜索
分享命令
3.1 保存和加载镜像
3.2提交镜像
-
docker commit
:将整个容器及其所有变化打包成一个新的镜像
-
-a
:指定文件作者 -
-c
:改变的列表 -
-m
:提交的留言 -
-p
:暂停运行
-
3.3登录DockerHub
-
docker login
:登录DockerHub,在上面分享自己的镜像。
3.4修改镜像名称
-
docker tag
:对已有的镜像进行重新的命名,名称会改变。但是对应的镜像ID是保持不变的
3.5推送镜像
-
docker push
:将自己的镜像推送到DockerHub上,供其他人pull下载并使用
总结:
小问题:还有一个事情要说明一下就是有人在使用Docker run这个命令设置端口映射时,发现如果是其它端口映射到容器的80端口时(例如:88端口)访问对应的ip+port时会出现找不到的情况。这是由于我们购买的云服务器防火墙也就是安全组对其他的端口是不开放的,需要我们在云服务器的安全组中手动配置相应的入站规则。如下所示:
Docker存储
问题引入:容器一启动,就会启动自己的空间,文件系统和进程。容器一销毁,就会销毁所有的文件系统内容。由此看出,修改容器中目录文件不容易。数据还容易丢失。
中间两次访问效果:
①自定义修改后的页面效果
②删除容器重新运行后页面效果
4.1目录挂载
用于将宿主机的文件或目录映射到容器内部。这样可以实现数据共享、持久化存储或者方便调试。
-
-v [主机目录/挂载目录]:[容器目录/被挂载目录]
实验过程:挂载启动相应的容器后,进行访问,没有页面信息(挂载的目录下没有html页面),在挂载的主机目录中对页面信息进行设置后再次访问,可以访问到自定义页面信息。然后移除容器,查看在主机目录中是否还保存有设置的页面信息。以原方式进行启动,再次访问查看页面数据是否被重置。结果为否。在定位到容器部内部,在内部对页面信息进行修改,退出容器后,发现主机文件下页面信息也跟着修改了。
4.2卷映射
问题引入:我们想要使用目录挂载实现在主机目录就可以完成对容器的配置,但是在具体实操的过程中,我们发现即使使用run命令-v挂载了配置文件,容器也无法启动。原因是因为:我们在使用目录挂载时,系统会默认先给我们外部创建一个空文件夹,所以当我们挂载到容器的配置文件下就相当于是容器的配置文件也什么都没有。当然了容器启动要使用默认的配置文件,此时配置文件一片空白,容器当然会启动失败。注意以外部目录为准
-
-v [卷名称]:[配置文件位置]
在使用卷映射时,Docker会自动为卷创建一个存储位置
/var/lib/docker/volumes/<volume-name>
。并且卷内容与容器路径内部的内容保持一致。 -
docker volume ls
列出所有的卷
-
docker volume create [卷名]
自己创建一个卷
-
docker volume inspect [卷名]
查看卷的详情,就是一些有关卷创建时的信息
总结:不论是在目录挂载还是卷映射中,只要容器与主机建立联系后,对公共资源的修改都会导致对方位置的信息改变。
-
目录挂载(bind mount):
-
将宿主机的文件或目录直接映射到容器。
-
数据存储在宿主文件系统中,依赖宿主机的文件结构。
-
适合临时数据共享和调试。
-
缺乏持久性和高级管理功能。
-
-
卷映射(volume mount):
-
使用 Docker 管理的独立存储卷。
-
数据存储在 Docker 的内部卷中,与宿主文件系统隔离。
-
提供数据持久化、备份和恢复等功能。
-
适合需要长期保存和共享的数据。
-
特性 | 目录挂载(Bind Mount) | 卷映射(Volume Mount) |
---|---|---|
数据存储位置 | 宿主机文件系统 | Docker 管理的独立存储卷 |
持久性 | 依赖宿主文件系统的生命周期,缺乏持久性 | 数据独立于容器和宿主机,具有高持久性 |
隔离性 | 容器与宿主机共享同一文件系统,可能导致意外修改 | 数据隔离,安全性更高 |
管理功能 | 简单配置,无高级管理功能 | 支持备份、恢复、扩展等高级管理 |
性能 | 通常较高,直接使用宿主文件系统 | 取决于存储驱动和后端,可能稍逊于绑定挂载 |
适用场景 | 快速数据共享、临时调试 | 长期数据保存、生产环境、协作开发 |
Docker网络
容器网络模型
-
桥接网络(Bridge Networking):这是默认的网络模式。Docker 创建一个虚拟桥接设备 (
docker0
) 在宿主机上,所有连接到这个桥的容器都能通过它互相通信,并且可以与外部网络进行交互。默认是不支持主机稳定域名的方式来进行访问 -
host 网络模式:容器直接使用宿主机的网络接口和IP地址,这意味着容器进程将运行在宿主机的网络命名空间中。这种方式适合需要高性能网络通信的应用场景。
-
container 网络模式:此模式允许容器共享另一个容器的网络栈,即它们共用同一个网络接口、IP地址和端口。这种模式主要用于需要共享网络配置的容器之间。
-
自定义网络(Custom Networks):用户可以根据需求创建自定义的网络,通过
docker network create
命令定义网络驱动和参数,并将容器连接到这个网络中,实现更灵活的网络拓扑结构。其中容器名就是稳定域名,可供其它容器进行访问。
容器间的通信
-
跨容器通信:在桥接网络中,每个容器都会被分配一个唯一的IP地址。它们可以通过这些IP地址或服务名称进行通信。
-
服务发现与负载均衡:通过Docker的
docker service create
命令创建的服务,默认会启用服务发现和负载均衡功能,使客户端能够通过服务名称访问后端容器,并自动实现流量分发。
容器与宿主机间的通信
-
端口映射(Port Mapping):用户可以通过
-P
或--publish
参数将宿主机的指定端口映射到容器内的对应端口,使外部网络能够通过宿主机IP和端口访问到容器中的服务。 -
直接访问(Direct Access):在
host
网络模式下,容器共享宿主机的网络接口,允许其他应用程序或服务直接通过宿主机的IP地址和端口访问到容器内的资源。
-
docker 【container】inspect [容器名]
查看一个容器的细节
-
docker network create
创建自定义网络,启动的容器连接上这个网络之后,容器名就是其稳定的域名
-
docker network ls
列举出所有的网络
Redis集群
架构图:说明一下,这里我们使用的是bitnami的redis镜像,如果使用官方镜像的话需要去配置文件中对redis主从模式进行设置,操作麻烦。这里使用bitnami的镜像可以直接在启动容器的时候通过配置环境变量的方式来进行设置。
Docker Compose
Docker Compose 是一个用于定义和运行多-container Docker 应用程序的工具。通过一个 YAML 文件(通常是 docker-compose.yml
),用户可以配置应用程序的各个服务、网络和卷,然后使用一条命令启动、停止或重建所有这些组件。
基本概念
-
compose文件 (
docker-compose.yml
):定义了要运行的所有容器化的服务。包括每个服务的名称、使用的镜像、端口映射、卷挂载等配置。 -
环境变量:可以使用
.env
文件或通过命令行传递环境变量,便于在不同环境中使用相同的 compose 配置
compose.yml文件写法
理论上来讲,compose.yml文件是有六个顶级元素的,但是在日常使用中我们只用声明前四个是完全够用的。所以一下实例就以声明前四个为例子,如果想要了解后两个元素怎么声明以下附带有官方的参考文档。
参考文档:Compose file reference | Docker DocsFind the latest recommended version of the Docker Compose file format for defining multi-container applications.https://docs.docker.com/compose/compose-file
主要命令
-
docker compose up
:启动所有服务。如果没有正在运行的容器,则会创建新的容器。-
-f
:指定要运行的compose.yml文件,默认运行的是compose.yml文件 -
-d
:后台运行compose.yml文件
-
-
docker compose down
:停止所有服务并删除相关的容器、网络和卷。-
--rmi
:在停止服务的时候,移除所有的镜像 -
-v
:在停止服务时,移除所有的卷
-
-
docker compose build
:构建或重新构建应用程序镜像。 -
docker compose run
:在不启动整个服务的情况下,执行某个命令。
以下为一个Docker Compose 的yml文件实例,这个应用的主要功能是启动一个博客管理程序并连接上数据库,持久化保存博客。可以将以下代码进行复制粘贴保存到你主机的文件系统里面,使用Docker运行。测试一下是否通过。如果成功访问你主机ip+wordpress暴露的port就可以进入博客管理系统了。
name: myblog
services:
mysql:
container_name: mysql
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
- /app/myconf:/etc/mysql/conf.d
restart: always
networks:
- blog
wordpress:
image: wordpress
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: 123456
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress:/var/www/html
restart: always
networks:
- blog
depends_on:
- mysql
volumes:
mysql-data:
wordpress:
networks:
blog:
高级功能
-
Docker Compose File v3:提供了更强大的网络配置和扩展性,支持自定义网络驱动、服务发现等功能。
-
动态配置与扩展:可以根据负载需求动态调整服务数量,实现应用的弹性伸缩。
-
依赖管理:通过定义容器间的启动顺序和服务间依赖,确保应用程序按正确的顺序初始化。
总结
Docker Compose 是一个强大的工具,能够简化多-container 应用程序的配置与管理。通过合理使用 compose 文件、网络、卷以及环境变量等特性,可以有效地部署和维护复杂的应用架构。掌握 Docker Compose 的核心概念和高级功能,将有助于提升开发效率和系统可靠性。
Dockerfile
Dockerfile 是用于定义和构建 Docker 容器镜像的文本文件。通过编写 Dockerfile,开发者可以自动化配置应用程序环境,并指定如何构建、运行和使用容器。
基本结构:
# 指定基础镜像
FROM imageName:tag
# 设置环境变量
ENV key=value
# 安装软件包
RUN apt-get update && apt-get install -y package-name
# 复制文件到镜像中
COPY src/ /dest/
# 暴露端口
EXPOSE portNumber
# 定义容器启动时运行的命令
CMD ["executable", "arg1", "arg2"]
示例
①以下是一个简单的Dockerfile示例,用于构建一个运行Node.js应用的镜像:
# 指定基础镜像
FROM node:14
# 设置工作目录
WORKDIR /app
# 复制package.json和package-lock.json
COPY package*.json ./
# 安装依赖
RUN npm install
# 复制应用代码
COPY . .
# 暴露端口
EXPOSE 3000
# 定义启动命令
CMD ["node", "app.js"]
②构建一个Java的hello world页面镜像
FROM openjdk:17
LABEL author=leifengyang
COPY app.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
镜像分层存储机制
-
镜像结构:
-
每个 Docker 镜像由多个“层”(Layers)组成,每一层都是一个只读的文件系统。
-
最底层是基础操作系统镜像,上面依次叠加用户定义的应用程序和服务。
-
-
联合文件系统:
-
使用如 OverlayFS 或 AUFS 等技术实现分层存储,允许多个只读层和一个可写顶层共存。
-
当容器运行时,所有层合并成统一的视图,确保文件访问的一致性。
-
-
构建过程:
-
根据 Dockerfile 指令逐步创建新层,每一层对应一条指令的结果。
-
利用缓存机制,重复使用的层直接加载,减少构建时间。
-
-
运行时管理:
-
容器运行时为每个容器创建可写的顶层,用于保存个性化修改。
-
隔离性:不同容器的修改不会相互影响,保证独立性和安全性。
-
-
存储效率:
-
多个容器共享相同的底层镜像层,节省磁盘空间和网络传输带宽。
-
只有变化的部分需要额外存储或传输,提高资源利用率。
-
-
性能优化:
-
联合文件系统经过优化,确保即使在多层叠加的情况下,文件访问速度依然高效。
-
现代 Docker 和容器运行时持续改进底层技术,提升整体性能。
-
-
镜像管理:
-
镜像以 tar 格式打包成多个层文件,按顺序下载并叠加,确保快速拉取和构建。
-
支持强制重新构建,通过
--no-cache
标志清除缓存,确保最新的依赖关系。
-
附录-一键安装超多常用中间件
前置命令操作,为了适应openSearch,保证其可以成功运行
#Disable memory paging and swapping performance
sudo swapoff -a
# Edit the sysctl config file
sudo vi /etc/sysctl.conf
# Add a line to define the desired value
# or change the value if the key exists,
# and then save your changes.
vm.max_map_count=262144
# Reload the kernel parameters using sysctl
sudo sysctl -p
# Verify that the change was applied by checking the value
cat /proc/sys/vm/max_map_count
常用中间件compose.yml文件如下:
注意:使用时请修改kafka 的 119.45.147.122 改为你自己的服务器IP。其中所有容器都做了时间同步,这样容器的时间和linux主机的时间就一致了
name: devsoft
services:
redis:
image: bitnami/redis:latest
restart: always
container_name: redis
environment:
- REDIS_PASSWORD=123456
ports:
- '6379:6379'
volumes:
- redis-data:/bitnami/redis/data
- redis-conf:/opt/bitnami/redis/mounted-etc
- /etc/localtime:/etc/localtime:ro
mysql:
image: mysql:8.0.31
restart: always
container_name: mysql
environment:
- MYSQL_ROOT_PASSWORD=123456
ports:
- '3306:3306'
- '33060:33060'
volumes:
- mysql-conf:/etc/mysql/conf.d
- mysql-data:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
rabbit:
image: rabbitmq:3-management
restart: always
container_name: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
- RABBITMQ_DEFAULT_USER=rabbit
- RABBITMQ_DEFAULT_PASS=rabbit
- RABBITMQ_DEFAULT_VHOST=dev
volumes:
- rabbit-data:/var/lib/rabbitmq
- rabbit-app:/etc/rabbitmq
- /etc/localtime:/etc/localtime:ro
opensearch-node1:
image: opensearchproject/opensearch:2.13.0
container_name: opensearch-node1
environment:
- cluster.name=opensearch-cluster # Name the cluster
- node.name=opensearch-node1 # Name the node that will run in this container
- discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligibile to serve as cluster manager
- bootstrap.memory_lock=true # Disable JVM heap memory swapping
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
- "DISABLE_INSTALL_DEMO_CONFIG=true" # Prevents execution of bundled demo script which installs demo certificates and security configurations to OpenSearch
- "DISABLE_SECURITY_PLUGIN=true" # Disables Security plugin
ulimits:
memlock:
soft: -1 # Set memlock to unlimited (no soft or hard limit)
hard: -1
nofile:
soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
hard: 65536
volumes:
- opensearch-data1:/usr/share/opensearch/data # Creates volume called opensearch-data1 and mounts it to the container
- /etc/localtime:/etc/localtime:ro
ports:
- 9200:9200 # REST API
- 9600:9600 # Performance Analyzer
opensearch-node2:
image: opensearchproject/opensearch:2.13.0
container_name: opensearch-node2
environment:
- cluster.name=opensearch-cluster # Name the cluster
- node.name=opensearch-node2 # Name the node that will run in this container
- discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
- cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligibile to serve as cluster manager
- bootstrap.memory_lock=true # Disable JVM heap memory swapping
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
- "DISABLE_INSTALL_DEMO_CONFIG=true" # Prevents execution of bundled demo script which installs demo certificates and security configurations to OpenSearch
- "DISABLE_SECURITY_PLUGIN=true" # Disables Security plugin
ulimits:
memlock:
soft: -1 # Set memlock to unlimited (no soft or hard limit)
hard: -1
nofile:
soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
hard: 65536
volumes:
- /etc/localtime:/etc/localtime:ro
- opensearch-data2:/usr/share/opensearch/data # Creates volume called opensearch-data2 and mounts it to the container
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:2.13.0
container_name: opensearch-dashboards
ports:
- 5601:5601 # Map host port 5601 to container port 5601
expose:
- "5601" # Expose port 5601 for web access to OpenSearch Dashboards
environment:
- 'OPENSEARCH_HOSTS=["http://opensearch-node1:9200","http://opensearch-node2:9200"]'
- "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true" # disables security dashboards plugin in OpenSearch Dashboards
volumes:
- /etc/localtime:/etc/localtime:ro
zookeeper:
image: bitnami/zookeeper:3.9
container_name: zookeeper
restart: always
ports:
- "2181:2181"
volumes:
- "zookeeper_data:/bitnami"
- /etc/localtime:/etc/localtime:ro
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
kafka:
image: 'bitnami/kafka:3.4'
container_name: kafka
restart: always
hostname: kafka
ports:
- '9092:9092'
- '9094:9094'
environment:
- KAFKA_CFG_NODE_ID=0
- KAFKA_CFG_PROCESS_ROLES=controller,broker
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://0.0.0.0:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,EXTERNAL://119.45.147.122:9094
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka:9093
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- ALLOW_PLAINTEXT_LISTENER=yes
- "KAFKA_HEAP_OPTS=-Xmx512m -Xms512m"
volumes:
- kafka-conf:/bitnami/kafka/config
- kafka-data:/bitnami/kafka/data
- /etc/localtime:/etc/localtime:ro
kafka-ui:
container_name: kafka-ui
image: provectuslabs/kafka-ui:latest
restart: always
ports:
- 8080:8080
environment:
DYNAMIC_CONFIG_ENABLED: true
KAFKA_CLUSTERS_0_NAME: kafka-dev
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9092
volumes:
- kafkaui-app:/etc/kafkaui
- /etc/localtime:/etc/localtime:ro
nacos:
image: nacos/nacos-server:v2.3.1
container_name: nacos
ports:
- 8848:8848
- 9848:9848
environment:
- PREFER_HOST_MODE=hostname
- MODE=standalone
- JVM_XMX=512m
- JVM_XMS=512m
- SPRING_DATASOURCE_PLATFORM=mysql
- MYSQL_SERVICE_HOST=nacos-mysql
- MYSQL_SERVICE_DB_NAME=nacos_devtest
- MYSQL_SERVICE_PORT=3306
- MYSQL_SERVICE_USER=nacos
- MYSQL_SERVICE_PASSWORD=nacos
- MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
- NACOS_AUTH_IDENTITY_KEY=2222
- NACOS_AUTH_IDENTITY_VALUE=2xxx
- NACOS_AUTH_TOKEN=SecretKey012345678901234567890123456789012345678901234567890123456789
- NACOS_AUTH_ENABLE=true
volumes:
- /app/nacos/standalone-logs/:/home/nacos/logs
- /etc/localtime:/etc/localtime:ro
depends_on:
nacos-mysql:
condition: service_healthy
nacos-mysql:
container_name: nacos-mysql
build:
context: .
dockerfile_inline: |
FROM mysql:8.0.31
ADD https://raw.githubusercontent.com/alibaba/nacos/2.3.2/distribution/conf/mysql-schema.sql /docker-entrypoint-initdb.d/nacos-mysql.sql
RUN chown -R mysql:mysql /docker-entrypoint-initdb.d/nacos-mysql.sql
EXPOSE 3306
CMD ["mysqld", "--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci"]
image: nacos/mysql:8.0.30
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=nacos_devtest
- MYSQL_USER=nacos
- MYSQL_PASSWORD=nacos
- LANG=C.UTF-8
volumes:
- nacos-mysqldata:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
ports:
- "13306:3306"
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
interval: 5s
timeout: 10s
retries: 10
prometheus:
image: prom/prometheus:v2.52.0
container_name: prometheus
restart: always
ports:
- 9090:9090
volumes:
- prometheus-data:/prometheus
- prometheus-conf:/etc/prometheus
- /etc/localtime:/etc/localtime:ro
grafana:
image: grafana/grafana:10.4.2
container_name: grafana
restart: always
ports:
- 3000:3000
volumes:
- grafana-data:/var/lib/grafana
- /etc/localtime:/etc/localtime:ro
volumes:
redis-data:
redis-conf:
mysql-conf:
mysql-data:
rabbit-data:
rabbit-app:
opensearch-data1:
opensearch-data2:
nacos-mysqldata:
zookeeper_data:
kafka-conf:
kafka-data:
kafkaui-app:
prometheus-data:
prometheus-conf:
grafana-data:
tip:如果重启了服务器,可能有些容器会启动失败。再执行一遍 docker compose up -d即可。所有程序都可运行成功,并且不会丢失数据。请放心使用。
zookeeper可视化工具下载: https://github.com/vran-dev/PrettyZoo/releases/download/v2.1.1/prettyZoo-win.ziphttps://github.com/vran-dev/PrettyZoo/releases/download/v2.1.1/prettyZoo-win.zip redis可视化工具下载: https://github.com/qishibo/AnotherRedisDesktopManager/releases/download/v1.6.4/Another-Redis-Desktop-Manager.1.6.4.exe
https://github.com/qishibo/AnotherRedisDesktopManager/releases/download/v1.6.4/Another-Redis-Desktop-Manager.1.6.4.exe
最后切记开通了云服务器的一定要销毁实例。只有完全销毁服务器这样所有的计费资源
就会被删除
本次服务器我一共使用了5块多钱,账单如下:
具体操作如下:
选择立即销毁和立即释放一直下一步下一步即可完成操作
总结:
最后如果想要进阶请前往学习k8s