惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
Blog — PlanetScale
Blog — PlanetScale
The GitHub Blog
The GitHub Blog
Microsoft Security Blog
Microsoft Security Blog
I
InfoQ
A
About on SuperTechFans
T
The Blog of Author Tim Ferriss
D
DataBreaches.Net
L
LangChain Blog
F
Fortinet All Blogs
C
Check Point Blog
Google DeepMind News
Google DeepMind News
云风的 BLOG
云风的 BLOG
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
H
Help Net Security
J
Java Code Geeks
月光博客
月光博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
IT之家
IT之家
aimingoo的专栏
aimingoo的专栏
小众软件
小众软件
宝玉的分享
宝玉的分享
Jina AI
Jina AI

lvbibir's Blog

shell | 磁盘空间分析脚本 Linux cat 和 tee 命令写入文件 python | 使用 uv 管理你的 python 环境 Claude Code 完整配置指南 windows | mihomo 内核独立部署指南 linux | 磁盘扩容 wsl | 释放长久运行占用的磁盘空间 mysql | 线程上限问题处理 麒麟 7.6 安装谷歌 OTP 认证模块 suse 12sp5 升级 openssh 及 openssl suse 12sp5 部署 mysql 5.7 《谁的青春不迷茫》 docker | centos7 部署 docker vim | 基础配置和使用 windows | rime 输入法 & 雾凇方案 shell | sshpass 批量传输文件及执行命令 wsl | 原生 linux 方式安装 docker nodejs | fnm + pnpm 开发环境配置 wsl | 安装配置 miniconda 虚拟环境 wsl | 自动更新系统代理 wsl | bashrc 环境变量不正确加载的处理方法 wsl | win10 安装 wsl2 troubleshooting | ssh 成功但是 scp 失败 linux | 常用命令总结 docker 部署 piclist shell | 检测网站存活并自动钉钉告警 Zabbix | 监控端口连通性并自动追踪 TCP 路由 windows | 自定义开机快速启动项 windows | miniconda 配置 python 虚拟环境 Zabbix | 监控主机到指定 ip 的流量大小
kubernetes | statefulset 控制器详解
lvbibir · 2023-04-12 · via lvbibir's Blog

1 基础概念

StatefulSet 应用场景:分布式应用、集群

  • 部署有状态应用
  • 解决 Pod 独立生命周期,保持 Pod 启动顺序和唯一性
    • 稳定,唯一的网络标识符,持久存储
    • 有序,优雅的部署和扩展、删除和终止
    • 有序,滚动更新

StatefulSet 控制器的优势

  • 稳定的存储
    • StatefulSet 的存储卷使用 VolumeClaimTemplate 创建,称为卷申请模板,当 StatefulSet 使用 VolumeClaimTemplate 创建一个 PersistentVolume 时,同样也会为每个 Pod 分配并创建一个编号的 PVC。该 PVC 和 PV 不会随着 StatefulSet 的删除而删除
  • 稳定的网络 ID
    • StatefulSet 中的每个 POD 名称固定:<statefulset-name>-<number>
    • 通过 serviceName 字段指定 Headless Service ,可以为每个 POD 分配一个固定的 DNS 解析,重启或者重建 POD 时虽然 ip 有所变动,但 DNS 解析会保持稳定

示例 yaml

apiVersion: v1
kind: Service
metadata:
  name: statefulset-nginx
  labels:
    app: statefulset-nginx
spec:
  selector:
    app: statefulset-nginx
  clusterIP: None
  ports:
  - name: web
    port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-nginx
spec:
  serviceName: "statefulset-nginx"
  replicas: 2
  selector:
    matchLabels:
      app: statefulset-nginx
  template:
    metadata:
      labels:
        app: statefulset-nginx
    spec:
      terminationGracePeriodSeconds: 5
      containers:
      - name: statefulset-nginx
        image: nginx:1.22.1
        imagePullPolicy: IfNotPresent
        ports:
        - name: web
          containerPort: 80
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      storageClassName: "nfs"
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

2 稳定的存储

可以看到与 deployment 不同,statefulset 中的每个 pod 都分配到了独立的 pv,且重启 pod 后存储对应关系不变

[root@k8s-node1 ~]# kubectl get pod,pvc,pv | awk  '{print $1}'
# pod NAME
pod/nfs-client-provisioner-66d6cb77fd-47hsf
pod/statefulset-nginx-0
pod/statefulset-nginx-1
# pvc NAME
persistentvolumeclaim/www-statefulset-nginx-0
persistentvolumeclaim/www-statefulset-nginx-1
# pv NAME
persistentvolume/pvc-17751fde-1b23-4535-98bb-a70342ddd6fe
persistentvolume/pvc-b7519f46-b2af-42e4-b66d-d7459be2e87c
[root@k8s-node1 ~]# ls  /nfs/
default-www-statefulset-nginx-0-pvc-17751fde-1b23-4535-98bb-a70342ddd6fe 
default-www-statefulset-nginx-1-pvc-b7519f46-b2af-42e4-b66d-d7459be2e87c

3 稳定的网络 ID

手动删除 pod 后除了 pod 的 ip 会变动,主机名和 dns 解析都正常

# POD名字固定
[root@k8s-node1 ~]# kubectl get pods -l app=statefulset-nginx
NAME                  READY   STATUS    RESTARTS   AGE
statefulset-nginx-0   1/1     Running   0          5m18s
statefulset-nginx-1   1/1     Running   0          5m17s

# 主机名固定
[root@k8s-node1 ~]# for i in 0 1; do kubectl exec "statefulset-nginx-$i" -- hostname; done
statefulset-nginx-0
statefulset-nginx-1

# DNS解析固定
[root@k8s-node1 ~]# kubectl run -it --rm --restart=Never --image busybox:1.28 dns-test -- nslookup statefulset-nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      statefulset-nginx
Address 1: 10.244.107.230 statefulset-nginx-1.statefulset-nginx.default.svc.cluster.local
Address 2: 10.244.169.157 statefulset-nginx-0.statefulset-nginx.default.svc.cluster.local
pod "dns-test" deleted

4 暴露应用

由于使用的是 Headless Service ,无法使用 NodePort 的方式暴露应用端口,我们可以单独创建 service 来暴露特定 pod 应用

StatefulSet 控制器中的 pod 名称都是固定的: <statefulset-name>-<number> ,可以通过 statefulset.kubernetes.io/pod-name 标签固定 pod

示例如下

apiVersion: v1
kind: Service
metadata:
  name: ss-nginx-0
  labels:
    app: ss-nginx-0
spec:
  selector:
    statefulset.kubernetes.io/pod-name: statefulset-nginx-0
  type: NodePort
  ports:
  - name: web
    port: 80
    targetPort: 80
    nodePort: 30003

验证

[root@k8s-node1 ~]# kubectl get svc ss-nginx-0
NAME         TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
ss-nginx-0   NodePort   10.111.69.1   <none>        80:30003/TCP   3h53m
[root@k8s-node1 ~]# kubectl get ep ss-nginx-0
NAME         ENDPOINTS           AGE
ss-nginx-0   10.244.169.188:80   3h53m

以上