欢迎光临
我们一直在努力

【应用】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

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: aiconsumergroup
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: myaiapp
spec:
replicas: 2
selector:
matchLabels:
app: myaiapp
template:
metadata:
labels:
app: myaiapp
spec:
containers:
name: app
image: myaiapp:latest
ports:
containerPort: 8080
env:
name: SPRING_KAFKA_BOOTSTRAP_SERVERS
value: "kafka:9092"

apiVersion: v1
kind: Service
metadata:
name: myaiappsvc
spec:
type: ClusterIP
selector:
app: myaiapp
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: frontendsvc
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)和网络策略,确保数据安全。
赞(0)
未经允许不得转载:171主机测评 » 【应用】Ubuntu 24 搭建大数据 & AI 应用云原生容器化实践
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址