实现多 Pod 数据隔离方案
目标:在 Kubernetes 集群中部署多个独立 Pod,每个 Pod 对应一个 Service,通过固定 NodePort 实现用户访问隔离。其中每个pod中有多个服务,每个服务都需要对外暴露端口
方案核心要点
StatefulSet 设计
- 使用 StatefulSet 确保每个 Pod 有稳定的网络标识和持久化存储
- 每个 Pod 拥有唯一名称(如
yibin-0、yibin-1) - 通过
POD_NAME环境变量注入容器内部
网络隔离实现
- Headless Service 用于 Pod DNS 发现
- 每个 Pod 配套独立 NodePort Service
- NodePort 计算方式:基础端口 + Pod 序号(如基础端口 31080,则
yibin-0使用 31080,yibin-1使用 31081)
生成脚本
#!/bin/bash
# --- 配置参数 ---
REPLICAS=3
NAMESPACE="simone"
# 格式: "容器端口:NodePort起始端口"
declare -A PORT_MAPPING=(
["8080"]="31080" # code-server
["8888"]="31888" # Jupyter
["22"]="31022" # SSH
["4226"]="31226" # sim-agent
)
# --- 开始生成 YAML ---
# 1. 生成 Headless Service (用于 Pod 发现)
cat <<EOF
apiVersion: v1
kind: Service
metadata:
name: yibin-headless-service
namespace: ${NAMESPACE}
spec:
clusterIP: None
selector:
app: yibin-pod
---
EOF
# 2. 生成 StatefulSet
cat <<EOF
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: yibin
namespace: ${NAMESPACE}
spec:
replicas: ${REPLICAS}
serviceName: "yibin-headless-service"
selector:
matchLabels:
app: yibin-pod
template:
metadata:
labels:
app: yibin-pod
spec:
# --- 关键部分在这里 ---
# nodeSelector:
# node-type: yibin-pool
containers:
- name: yibin
image: yibin:20251127
imagePullPolicy: IfNotPresent
command: ["/init.sh"]
ports:
EOF
# 为 StatefulSet 添加所有容器端口
for container_port in "${!PORT_MAPPING[@]}"; do
echo " - containerPort: ${container_port}"
done
cat <<EOF
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: JUPYTER_EMBEDDED_WEB_URL
value: "http://192.168.1.83:8000"
restartPolicy: Always
---
EOF
# 3. 循环为每个 Pod 生成 NodePort Service
for ((i=0; i<REPLICAS; i++)); do
POD_NAME="yibin-${i}"
cat <<EOF
apiVersion: v1
kind: Service
metadata:
name: yibin-nodeport-service-${i}
namespace: ${NAMESPACE}
spec:
type: NodePort
selector:
app: yibin-pod
statefulset.kubernetes.io/pod-name: ${POD_NAME}
ports:
EOF
# 遍历端口映射,为每个容器端口生成一个 NodePort
for container_port in "${!PORT_MAPPING[@]}"; do
base_nodeport=${PORT_MAPPING[$container_port]}
# 计算每个 Pod 的唯一 NodePort
nodeport=$((base_nodeport + i))
# 根据容器端口设置合适的名称
case $container_port in
22)
port_name="ssh"
;;
8080)
port_name="http"
;;
8888)
port_name="jupyter"
;;
4226)
port_name="sim-agent"
;;
*)
port_name="port-${container_port}"
;;
esac
cat <<EOF
- name: ${port_name}
protocol: TCP
port: ${container_port}
targetPort: ${container_port}
nodePort: ${nodeport}
EOF
done
echo "---"
done
echo "# 生成完毕!请将此输出保存到文件并应用。"
部署验证步骤
- 生成配置文件
bash
chmod +x generate-yaml.sh
./generate-yaml.sh > deployment.yaml
- 应用配置
bash
kubectl apply -f deployment.yaml
- 验证服务状态
bash
kubectl get pods -n simone
kubectl get svc -n simone | grep NodePort
访问模式示例
| Pod名称 | 服务端口类型 | 外部访问地址示例 |
|---|---|---|
| yibin-0 | Jupyter | 节点IP:31080 |
| yibin-0 | SSH | 节点IP:31888 |
| yibin-0 | HTTP | 节点IP:31022 |
| yibin-0 | agent | 节点IP:31226 |
| yibin-1 | Jupyter | 节点IP:31081 |
| yibin-1 | SSH | 节点IP:31889 |
| yibin-1 | HTTP | 节点IP:31023 |
| yibin-1 | agent | 节点IP:31227 |
注意事项
-
NodePort 范围需符合 Kubernetes 集群配置(默认 30000-32767)
获取某个pod状态
查看某个pod: yibin-1状态 Running 为成功
kubectl get pod -n simone yibin-1
重启某个pod删除 yibin-1
kubectl delete service yibin-nodeport-service-1 -n simone
kubectl delete pod yibin-1 -n simone重建对外映射
kubectl apply -f yibin-full.yaml
删除所有pod推荐用这个
kubectl delete -f yibin-full.yaml
这个也可以
kubectl delete statefulset yibin -n simone
启动所有pod启动
kubectl apply -f yibin-full.yaml
查看所有pod状态 Running 为成功
kubectl get pod -n simone -l app=yibin-pod
如果有问题,重启代理
kubectl apply -f yibin-full.yaml