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

推荐订阅源

Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
H
Hacker News: Front Page
Stack Overflow Blog
Stack Overflow Blog
B
Blog
I
InfoQ
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
Y
Y Combinator Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
F
Full Disclosure
Hacker News - Newest:
Hacker News - Newest: "LLM"
Recent Announcements
Recent Announcements
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
T
Tailwind CSS Blog
S
Secure Thoughts
P
Privacy International News Feed
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LINUX DO - 最新话题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
C
Cybersecurity and Infrastructure Security Agency CISA
Last Week in AI
Last Week in AI
W
WeLiveSecurity
Google Online Security Blog
Google Online Security Blog
P
Privacy & Cybersecurity Law Blog
D
DataBreaches.Net
Engineering at Meta
Engineering at Meta
Know Your Adversary
Know Your Adversary
P
Palo Alto Networks Blog
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Project Zero
Project Zero
V2EX - 技术
V2EX - 技术
H
Heimdal Security Blog
博客园 - Franky
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
Troy Hunt's Blog
V
Vulnerabilities – Threatpost
H
Help Net Security
Martin Fowler
Martin Fowler
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
G
GRAHAM CLULEY
博客园 - 【当耐特】

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 的流量大小 shell | centos 初始化 loki (二) 部署 loki (一) 简介 prometheus (六) Alertmanager prometheus (五) 记录规则与告警规则 prometheus (四) 黑盒监控 prometheus (三) 服务发现 prometheus (二) 静态配置 prometheus (一) 简介及部署 traefik (四) TraefikService 服务 traefik (三) Middleware 中间件 traefik (二) ingressRoute 路由 traefik (一) 简介、部署和配置 kubernetes | Gateway API 简介及部署 linux | dns 配置文件中 search 和 options ndots 详解 kubernetes | command args 和 dockerfile 中的 ENTRYPOINT CMD docker | dockerfile 最佳实践 docker | dockerfile 指令详解 linux | kill 命令详解以及 linux 中的信号 troubleshooting | elasticsearch 安装插件报错 shell | if 条件判断 docker | 下载外网镜像的几种方式 python | 鬼谷子数学问题 steam挂刀教程 linux | history 命令的格式化输出 shell | 将本地镜像批量推送到 harbor windows | hosts 文件修复 kubernetes | configmap & secret kubernetes | RBAC 鉴权和 NetworkPolicy kubernetes | service & ingress kubernetes | 存储 kubernetes | 滚动升级和自动伸缩 kubernetes | 控制器 kubernetes | 日志 kubernetes | 调度 kubernetes | pod kubernetes | 杂记 linux | set 命令详解 ceph | openeuler 部署 ceph-v16 ceph | ceph-v16 离线安装解决方案 pxe 如何应对复杂的服务器硬件环境 python | 批量修改目录下文件名 《微习惯》 ceph | openeuler (aarch64) 部署 ceph-v16 troubleshooting | glibc 误升级后修复 pxe 安装配置大全 《人间失格》 跑步日常 [置顶] Hello, hugo! shell | 检索某 url 中所有文件的内容 shell | 不同执行方式的区别 shell | 开启 debug 模式 vscode | 常见问题 windows & linux 多网卡时设置默认路由以及添加静态路由 mysql (二) 主从复制原理 GTID 并行复制 mysql (一) 部署 mysql | 杂记 cicd | jenkins 部署 mall-swarm 项目 httpd 源码打包编译成 rpm 包 openssl 源码打包编译成 rpm 包 centos7 | 修改网卡名称 ceph | pool pg_num 配置 docker | 脚本方式批量导出/导入镜像 centos 密码尝试次数过多问题处理 centos7 | 升级内核至 5.10 CVE-1999-0526 ceph | centos7 部署 ceph-v12 python | 修改 pip 源 troubleshooting | 安装 cloud-init 后导致 ssh 连接失败 windows | autohotkey 常用脚本
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

以上