**全面拥抱容器化 **。
Ubuntu 24 只需安装 Docker 和 k3d,剩下的繁重工作全部交给Kubernetes集群。
📊 整体架构一览
#mermaid-svg-4M6dPl6OfXunVsY6{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4M6dPl6OfXunVsY6 .error-icon{fill:#552222;}#mermaid-svg-4M6dPl6OfXunVsY6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4M6dPl6OfXunVsY6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4M6dPl6OfXunVsY6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4M6dPl6OfXunVsY6 .marker.cross{stroke:#333333;}#mermaid-svg-4M6dPl6OfXunVsY6 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4M6dPl6OfXunVsY6 p{margin:0;}#mermaid-svg-4M6dPl6OfXunVsY6 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-4M6dPl6OfXunVsY6 .cluster-label text{fill:#333;}#mermaid-svg-4M6dPl6OfXunVsY6 .cluster-label span{color:#333;}#mermaid-svg-4M6dPl6OfXunVsY6 .cluster-label span p{background-color:transparent;}#mermaid-svg-4M6dPl6OfXunVsY6 .label text,#mermaid-svg-4M6dPl6OfXunVsY6 span{fill:#333;color:#333;}#mermaid-svg-4M6dPl6OfXunVsY6 .node rect,#mermaid-svg-4M6dPl6OfXunVsY6 .node circle,#mermaid-svg-4M6dPl6OfXunVsY6 .node ellipse,#mermaid-svg-4M6dPl6OfXunVsY6 .node polygon,#mermaid-svg-4M6dPl6OfXunVsY6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4M6dPl6OfXunVsY6 .rough-node .label text,#mermaid-svg-4M6dPl6OfXunVsY6 .node .label text,#mermaid-svg-4M6dPl6OfXunVsY6 .image-shape .label,#mermaid-svg-4M6dPl6OfXunVsY6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-4M6dPl6OfXunVsY6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4M6dPl6OfXunVsY6 .rough-node .label,#mermaid-svg-4M6dPl6OfXunVsY6 .node .label,#mermaid-svg-4M6dPl6OfXunVsY6 .image-shape .label,#mermaid-svg-4M6dPl6OfXunVsY6 .icon-shape .label{text-align:center;}#mermaid-svg-4M6dPl6OfXunVsY6 .node.clickable{cursor:pointer;}#mermaid-svg-4M6dPl6OfXunVsY6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4M6dPl6OfXunVsY6 .arrowheadPath{fill:#333333;}#mermaid-svg-4M6dPl6OfXunVsY6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4M6dPl6OfXunVsY6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4M6dPl6OfXunVsY6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4M6dPl6OfXunVsY6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4M6dPl6OfXunVsY6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4M6dPl6OfXunVsY6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4M6dPl6OfXunVsY6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4M6dPl6OfXunVsY6 .cluster text{fill:#333;}#mermaid-svg-4M6dPl6OfXunVsY6 .cluster span{color:#333;}#mermaid-svg-4M6dPl6OfXunVsY6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4M6dPl6OfXunVsY6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4M6dPl6OfXunVsY6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-4M6dPl6OfXunVsY6 .icon-shape,#mermaid-svg-4M6dPl6OfXunVsY6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4M6dPl6OfXunVsY6 .icon-shape p,#mermaid-svg-4M6dPl6OfXunVsY6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4M6dPl6OfXunVsY6 .icon-shape .label rect,#mermaid-svg-4M6dPl6OfXunVsY6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4M6dPl6OfXunVsY6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4M6dPl6OfXunVsY6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4M6dPl6OfXunVsY6 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
☸️ k3d K8s 集群
🖥️ Ubuntu 24 宿主机
应用平面
中间件
数据平面
kubectl/helm
浏览器访问
读写
缓存
生产/消费
消费/生产
读写
读写
数据流
存储模型/文件
Docker Engine
k3d CLI
kubectl
Helm
LoadBalancer端口映射
MinIO对象存储
Flink Operator + TaskManager
Spark Job(按需运行)
MySQL
Redis
KafkaKRaft 模式
SpringBoot AI 应用
Node.js 前端
👤 开发者
🧱 阶段一:Ubuntu 24 宿主机基础环境准备
这一步是为整个平台打地基,确保你的 Ubuntu 具备运行 K8s 的能力。
1️⃣ 安装必要系统工具
sudo apt update
sudo apt install -y curl wget git vim net-tools
2️⃣ 安装 Docker Engine
Ubuntu 24 默认不带 Docker,需手动安装:
# 卸载旧版本及可能冲突的包(严格按照官方推荐列表)
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt remove -y $pkg
done
# 安装依赖
sudo apt install -y ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /etc/apt/keyrings/docker.gpg
# 添加稳定版仓库(此处文件名改为 docker-ce.list 更规范,与原路径仅名称不同)
echo \\
"deb [arch=$(dpkg –print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \\
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker-ce.list > /dev/null
# 更新并安装
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
启动 Docker 并设置开机自启:
sudo systemctl enable docker –now
sudo usermod -aG docker $USER # 将当前用户加入 docker 组,避免每次 sudo
⚠️ 重要提示:usermod 后,当前 Shell 的组信息不会立即刷新。您需要退出当前终端并重新登录,或者执行以下命令之一来立即生效(推荐前者):
- 方法一(重新登录):exit 后重新 SSH 连接。
- 方法二(临时切换):执行 newgrp docker(会进入新 Shell,键入 exit 可返回原 Shell)。
✅ 验证:重新登录后,执行 docker run hello-world 应看到欢迎信息。
资源分配建议:
- Docker 默认不限制宿主机资源(即容器可占用全部物理资源)。若需限制,可在 /etc/docker/daemon.json 中配置 cgroup 参数,但通常情况下默认即可。
- 硬件最低参考(根据实际负载调整):
- 轻量级测试/开发:2核 CPU、4GB 内存、30GB 空闲磁盘
- 生产或运行多个容器:建议 4核 CPU 起步、16GB 内存起步、50GB+ 空闲磁盘(具体视容器数量和应用类型而定)。
3️⃣ 安装 k3d 与 kubectl
k3d 能在 Docker 中极速创建 K8s 集群,kubectl 是 K8s 的命令行工具。
# 安装 k3d(使用官方脚本,需 sudo 写入 /usr/local/bin)
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | sudo bash
# 安装 kubectl(自动适配 amd64 / arm64 架构)
ARCH=$(dpkg –print-architecture) # 自动获取架构,例如 amd64 或 arm64
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${ARCH}/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
rm -f kubectl # 清理当前目录下载的临时文件
验证:
k3d –version
kubectl version –client
4️⃣ 安装 Helm(K8s 包管理器)
# 官方安装脚本(需 sudo 写入 /usr/local/bin)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | sudo bash
验证:
helm version
💡 友情提示:如果您的 Ubuntu 系统架构恰好是 arm64(例如 Apple Silicon 虚拟机或 AWS Graviton),修正后的 kubectl 安装命令会自动匹配 linux/arm64 版本,无需手动修改。若您想确认当前架构,可运行 dpkg –print-architecture 查看。
k3d 安装缺少 sudo:官方脚本默认将二进制安装到 /usr/local/bin,非 root 用户直接执行会因权限不足而失败,必须加 sudo。
kubectl 下载后未清理:下载的二进制文件会残留在当前目录,建议执行完毕后删除( rm -f kubectl)。
**Helm 安装 /usr/local/bin 需要 root 权限。
⛵ 阶段二:拉起本地 K8s 集群
我们使用 k3d 创建一个轻量级但功能完整的集群,模拟分布式环境。
k3d cluster create ai-bigdata-cluster \\
–servers 1 \\
–agents 2 \\
-p "8080-8090:8080-8090@loadbalancer" \\
-p "30000-30100:30000-30100@loadbalancer"
参数解释:
- –servers 1:1 个 control-plane 节点
- –agents 2:2 个 worker 节点(用于运行工作负载)
- -p:将宿主机端口段映射到 K8s 负载均衡器,便于外部访问
查看集群状态:
kubectl get nodes -o wide
如果看到 3 个节点状态均为 Ready,说明你的 K8s 港口已准备就绪 🎉。
🗄️ 阶段三:数据端 —— 部署大数据组件
在云原生架构下,我们不再手动配置 XML,而是使用 Helm Chart 和 Operator 一键部署。
1️⃣ 部署对象存储(替代 HDFS):MinIO
HDFS 在容器环境中运维复杂,推荐使用 S3 兼容的对象存储(如 MinIO)作为数据湖底座。
helm repo add minio https://charts.min.io/
helm install minio minio/minio \\
–set mode=standalone \\
–set rootUser=admin \\
–set rootPassword=admin123
暴露 Web 控制台(端口 9001):
kubectl port-forward svc/minio 9001:9001
访问 http://localhost:9001,可用 admin/admin123 登录,创建 bucket 用于后续数据存储。
2️⃣ 部署 Flink 集群(使用 Operator)
Flink Kubernetes Operator 能管理 Flink 作业的生命周期。
helm repo add flink-operator https://downloads.apache.org/flink/flink-kubernetes-operator/
helm install flink-operator flink-operator/flink-kubernetes-operator
之后,你可以提交 FlinkDeployment CRD 来启动 JobManager 和 TaskManager(具体 YAML 后续文章详解)。
3️⃣ 部署 Spark 环境(按需运行)
Spark 原生支持 K8s,无需常驻集群,直接提交任务即可:
kubectl run spark-pi –image=apache/spark:latest \\
–restart=Never — spark-submit –class org.apache.spark.examples.SparkPi \\
–master k8s://https://kubernetes.default.svc \\
–deploy-mode cluster ...
🔥 阶段四:应用端 —— 部署中间件与业务服务
应用端组件(MySQL、Redis、Kafka)同样跑在 K8s 中,与大数据平台处于同一内网,通信延迟极低。
📦 一键部署 MySQL、Redis
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install mysql bitnami/mysql –set auth.rootPassword=root123
helm install redis bitnami/redis –set auth.password=redis123
🐘 部署 Kafka(使用 KRaft 模式,无需 ZooKeeper)
KRaft
传统 Kafka 依赖 ZooKeeper 存储元数据,增加了运维复杂度。KRaft(Kafka Raft)是 Apache Kafka 2.8+ 引入的新模式,将元数据管理内置到 Kafka 自身,省去了外部协调组件,部署更简单、性能更高。
部署命令(Bitnami Chart 默认开启 KRaft)
helm install kafka bitnami/kafka \\
–set replicaCount=3 \\
–set persistence.size=10Gi \\
–set zookeeper.enabled=false \\
–set kraft.enabled=true \\
–set kraft.clusterId=$(openssl rand -hex 6) \\
–set listeners.client.protocol=PLAINTEXT \\
–set listeners.controller.protocol=PLAINTEXT \\
–set listeners.interbroker.protocol=PLAINTEXT \\
–set service.type=ClusterIP
说明:
- replicaCount=3:3 个 broker 节点,保证高可用。
- persistence.size=10Gi:每个 broker 分配 10GB 持久化存储。
- zookeeper.enabled=false 和 kraft.enabled=true 明确使用 KRaft。
- clusterId:集群唯一标识,用随机数生成。
- 监听协议都用 PLAINTEXT(本地测试),生产环境请启用 TLS/SCRAM。
验证 Kafka 部署
kubectl get pods -l app.kubernetes.io/name=kafka
所有 Pod 状态应为 Running。
创建 Topic(示例)
我们可以创建一个测试主题 ai-events,分区 3,副本 2:
kubectl exec -it kafka-0 — kafka-topics.sh \\
–create –topic ai-events \\
–partitions 3 –replication-factor 2 \\
–bootstrap-server localhost:9092
查看主题列表:
kubectl exec -it kafka-0 — kafka-topics.sh –list –bootstrap-server localhost:9092
🧠 Kafka 核心速览
| Topic | 消息的逻辑分类,类似数据库的“表” |
| Partition | Topic 物理分片,每个分区有序,提供并行能力 |
| Replica | 分区副本,Leader 负责读写,Follower 同步数据 |
| ISR | In-Sync Replicas,与 Leader 保持同步的副本集合 |
| Producer | 生产者,发送消息到指定 Topic 的分区 |
| Consumer | 消费者,从 Topic 拉取消息,支持消费组(Group) |
| ACK 机制 | acks=0 不等待确认;acks=1 Leader 确认;acks=-1 (all) ISR 全部确认,可靠性最高 |
| KRaft 元数据 | 使用 Raft 协议选举 Controller,管理所有元数据,不再依赖 ZooKeeper |
#mermaid-svg-Mz6afTddxB9ADNmp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Mz6afTddxB9ADNmp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Mz6afTddxB9ADNmp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Mz6afTddxB9ADNmp .error-icon{fill:#552222;}#mermaid-svg-Mz6afTddxB9ADNmp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Mz6afTddxB9ADNmp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Mz6afTddxB9ADNmp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Mz6afTddxB9ADNmp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Mz6afTddxB9ADNmp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Mz6afTddxB9ADNmp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Mz6afTddxB9ADNmp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Mz6afTddxB9ADNmp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Mz6afTddxB9ADNmp .marker.cross{stroke:#333333;}#mermaid-svg-Mz6afTddxB9ADNmp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Mz6afTddxB9ADNmp p{margin:0;}#mermaid-svg-Mz6afTddxB9ADNmp .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Mz6afTddxB9ADNmp .cluster-label text{fill:#333;}#mermaid-svg-Mz6afTddxB9ADNmp .cluster-label span{color:#333;}#mermaid-svg-Mz6afTddxB9ADNmp .cluster-label span p{background-color:transparent;}#mermaid-svg-Mz6afTddxB9ADNmp .label text,#mermaid-svg-Mz6afTddxB9ADNmp span{fill:#333;color:#333;}#mermaid-svg-Mz6afTddxB9ADNmp .node rect,#mermaid-svg-Mz6afTddxB9ADNmp .node circle,#mermaid-svg-Mz6afTddxB9ADNmp .node ellipse,#mermaid-svg-Mz6afTddxB9ADNmp .node polygon,#mermaid-svg-Mz6afTddxB9ADNmp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Mz6afTddxB9ADNmp .rough-node .label text,#mermaid-svg-Mz6afTddxB9ADNmp .node .label text,#mermaid-svg-Mz6afTddxB9ADNmp .image-shape .label,#mermaid-svg-Mz6afTddxB9ADNmp .icon-shape .label{text-anchor:middle;}#mermaid-svg-Mz6afTddxB9ADNmp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Mz6afTddxB9ADNmp .rough-node .label,#mermaid-svg-Mz6afTddxB9ADNmp .node .label,#mermaid-svg-Mz6afTddxB9ADNmp .image-shape .label,#mermaid-svg-Mz6afTddxB9ADNmp .icon-shape .label{text-align:center;}#mermaid-svg-Mz6afTddxB9ADNmp .node.clickable{cursor:pointer;}#mermaid-svg-Mz6afTddxB9ADNmp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Mz6afTddxB9ADNmp .arrowheadPath{fill:#333333;}#mermaid-svg-Mz6afTddxB9ADNmp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Mz6afTddxB9ADNmp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Mz6afTddxB9ADNmp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Mz6afTddxB9ADNmp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Mz6afTddxB9ADNmp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Mz6afTddxB9ADNmp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Mz6afTddxB9ADNmp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Mz6afTddxB9ADNmp .cluster text{fill:#333;}#mermaid-svg-Mz6afTddxB9ADNmp .cluster span{color:#333;}#mermaid-svg-Mz6afTddxB9ADNmp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Mz6afTddxB9ADNmp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Mz6afTddxB9ADNmp rect.text{fill:none;stroke-width:0;}#mermaid-svg-Mz6afTddxB9ADNmp .icon-shape,#mermaid-svg-Mz6afTddxB9ADNmp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Mz6afTddxB9ADNmp .icon-shape p,#mermaid-svg-Mz6afTddxB9ADNmp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Mz6afTddxB9ADNmp .icon-shape .label rect,#mermaid-svg-Mz6afTddxB9ADNmp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Mz6afTddxB9ADNmp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Mz6afTddxB9ADNmp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Mz6afTddxB9ADNmp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Kafka 集群
key hash
轮询
自定义
拉取
拉取
拉取
副本同步
副本同步
Broker 1
Broker 2
Broker 3
Topic: ai-events
Partition 0Leader: B1
Partition 1Leader: B2
Partition 2Leader: B3
生产者
消费者组 group-1
🧩 开发并部署 SpringBoot AI 应用(集成 Kafka)
1. 在 application.yml 中配置 Kafka
spring:
kafka:
bootstrap-servers: kafka:9092 # K8s 内部 Service 名称
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
consumer:
group-id: ai–consumer–group
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring.json.trusted.packages: "*"
2. 编写生产者与消费者
@Service
public class KafkaProducerService {
@Autowired
private KafkaTemplate<String, Object> kafkaTemplate;
public void sendEvent(String topic, Object event) {
kafkaTemplate.send(topic, event);
}
}
@Slf4j
@Component
public class KafkaConsumer {
@KafkaListener(topics = "ai-events", groupId = "ai-consumer-group")
public void listen(MyEvent event) {
log.info("Received event: {}", event);
// 处理业务逻辑…
}
}
3. 打包 Docker 镜像并导入 k3d
# 在项目根目录执行
mvn clean package
docker build -t my-ai-app:latest .
k3d image import my-ai-app:latest -c ai-bigdata-cluster
4. 部署到 K8s(编写 Deployment + Service)
springboot-deploy.yaml 示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my–ai–app
spec:
replicas: 2
selector:
matchLabels:
app: my–ai–app
template:
metadata:
labels:
app: my–ai–app
spec:
containers:
– name: app
image: my–ai–app:latest
ports:
– containerPort: 8080
env:
– name: SPRING_KAFKA_BOOTSTRAP_SERVERS
value: "kafka:9092"
—
apiVersion: v1
kind: Service
metadata:
name: my–ai–app–svc
spec:
type: ClusterIP
selector:
app: my–ai–app
ports:
– port: 8080
targetPort: 8080
kubectl apply -f springboot-deploy.yaml
🌐 开发并部署 Node.js 前端
同样打包 Docker 镜像,导入 k3d,部署为 NodePort 服务,以便浏览器访问:
# 构建镜像
docker build -t my-frontend:latest .
k3d image import my-frontend:latest -c ai-bigdata-cluster
frontend-deploy.yaml(使用 NodePort 暴露 30000 端口):
apiVersion: v1
kind: Service
metadata:
name: frontend–svc
spec:
type: NodePort
selector:
app: frontend
ports:
– port: 80
targetPort: 3000
nodePort: 30000
然后通过 http://localhost:30000 访问你的前端页面。
📋 关键端口与访问方式
| MinIO API | minio:9000 | 无(内部) | 应用通过内网 minio:9000 |
| MinIO Console | minio:9001 | kubectl port-forward 9001 | http://localhost:9001 |
| MySQL | mysql:3306 | 无(内部) | 应用通过 mysql:3306 |
| Redis | redis:6379 | 无(内部) | 应用通过 redis:6379 |
| Kafka Broker | kafka:9092 | 无(内部) | 应用通过 kafka:9092 |
| SpringBoot App | my-ai-app-svc:8080 | 无(内部) | 前端通过内网调用 |
| Node.js 前端 | frontend-svc:80 | 30000 (NodePort) | 浏览器 http://localhost:30000 |
| 额外服务端口 | – | 8080-8090 / 30000-30100 | 可扩展映射更多服务 |
🧹 总结
- 若需停止集群:k3d cluster stop ai-bigdata-cluster
- 若需彻底删除:k3d cluster delete ai-bigdata-cluster
- 生产中请配置持久化存储(PV/PVC)和网络策略,确保数据安全。


