【应用】Ubuntu 24 搭建大数据 & AI 应用云原生容器化实践

**全面拥抱容器化 **。

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
Kafka

KRaft 模式
SpringBoot AI 应用
Node.js 前端
👤 开发者


🧱 阶段一:Ubuntu 24 宿主机基础环境准备

这一步是为整个平台打地基,确保你的 Ubuntu 具备运行 K8s 的能力。

1️⃣ 安装必要系统工具
bash 复制代码
sudo apt update
sudo apt install -y curl wget git vim net-tools
2️⃣ 安装 Docker Engine

Ubuntu 24 默认不带 Docker,需手动安装:

bash 复制代码
# 卸载旧版本及可能冲突的包(严格按照官方推荐列表)
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 并设置开机自启:

bash 复制代码
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 的命令行工具。

bash 复制代码
# 安装 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   # 清理当前目录下载的临时文件

验证:

bash 复制代码
k3d --version
kubectl version --client

4️⃣ 安装 Helm(K8s 包管理器)
bash 复制代码
# 官方安装脚本(需 sudo 写入 /usr/local/bin)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | sudo bash

验证:

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 创建一个轻量级但功能完整的集群,模拟分布式环境。

bash 复制代码
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 负载均衡器,便于外部访问

查看集群状态:

bash 复制代码
kubectl get nodes -o wide

如果看到 3 个节点状态均为 Ready,说明你的 K8s 港口已准备就绪 🎉。


🗄️ 阶段三:数据端 ------ 部署大数据组件

在云原生架构下,我们不再手动配置 XML,而是使用 Helm ChartOperator 一键部署。

1️⃣ 部署对象存储(替代 HDFS):MinIO

HDFS 在容器环境中运维复杂,推荐使用 S3 兼容的对象存储(如 MinIO)作为数据湖底座。

bash 复制代码
helm repo add minio https://charts.min.io/
helm install minio minio/minio \
  --set mode=standalone \
  --set rootUser=admin \
  --set rootPassword=admin123

暴露 Web 控制台(端口 9001):

bash 复制代码
kubectl port-forward svc/minio 9001:9001

访问 http://localhost:9001,可用 admin/admin123 登录,创建 bucket 用于后续数据存储。

Flink Kubernetes Operator 能管理 Flink 作业的生命周期。

bash 复制代码
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,无需常驻集群,直接提交任务即可:

bash 复制代码
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

bash 复制代码
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)
bash 复制代码
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=falsekraft.enabled=true 明确使用 KRaft。
  • clusterId:集群唯一标识,用随机数生成。
  • 监听协议都用 PLAINTEXT(本地测试),生产环境请启用 TLS/SCRAM。
验证 Kafka 部署
bash 复制代码
kubectl get pods -l app.kubernetes.io/name=kafka

所有 Pod 状态应为 Running

创建 Topic(示例)

我们可以创建一个测试主题 ai-events,分区 3,副本 2:

bash 复制代码
kubectl exec -it kafka-0 -- kafka-topics.sh \
  --create --topic ai-events \
  --partitions 3 --replication-factor 2 \
  --bootstrap-server localhost:9092

查看主题列表:

bash 复制代码
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 0

Leader: B1
Partition 1

Leader: B2
Partition 2

Leader: B3
生产者
消费者组 group-1


🧩 开发并部署 SpringBoot AI 应用(集成 Kafka)

1. 在 application.yml 中配置 Kafka
yaml 复制代码
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. 编写生产者与消费者
java 复制代码
@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
bash 复制代码
# 在项目根目录执行
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 示例:

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
bash 复制代码
kubectl apply -f springboot-deploy.yaml

🌐 开发并部署 Node.js 前端

同样打包 Docker 镜像,导入 k3d,部署为 NodePort 服务,以便浏览器访问:

bash 复制代码
# 构建镜像
docker build -t my-frontend:latest .
k3d image import my-frontend:latest -c ai-bigdata-cluster

frontend-deploy.yaml(使用 NodePort 暴露 30000 端口):

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: frontend-svc
spec:
  type: NodePort
  selector:
    app: frontend
  ports:
    - port: 80
      targetPort: 3000
      nodePort: 30000

然后通过 http://localhost:30000 访问你的前端页面。


📋 关键端口与访问方式

组件 K8s Service 宿主机映射端口 访问方式
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)和网络策略,确保数据安全。
相关推荐
TAN-90°-1 小时前
Deep Learning for Computer Vision——Recurrent Neural Networks
数据结构·人工智能·rnn·深度学习·神经网络·机器学习·计算机视觉
starzy19901 小时前
SparkStreaming 之 DStream 底层结构剖析
大数据·spark
天行健,君子而铎1 小时前
2026年中国API安全产品综合排名:选型指南与市场趋势解析
大数据·数据库·安全
ZGi.ai1 小时前
ZGI 父子分块:连接检索片段与完整上下文
人工智能·算法·知识库·企业ai·zgi·父子分块
未来之窗软件服务1 小时前
Web 技能的自主测试系统开好处发架构思维-东方仙盟
大数据·前端·架构·仙盟创梦ide·东方仙盟
yyywxk1 小时前
ICCV 2025 目标检测(object detection)方向上接收论文总结
人工智能·目标检测·计算机视觉
IT毕设实战小研1 小时前
基于大数据的二手车数据分析与预测
java·大数据·后端·爬虫·python·算法·课程设计
欧特克_Glodon1 小时前
OpenCV计算机视觉开发入门与实践<十七>:点运算与灰度变换概述
c++·人工智能·opencv·计算机视觉