k8s
  • Initial page
  • 序言
  • 前言
    • 发展历史
    • CNCF - 云原生计算基金会简介
    • Kubernetes与云原生应用的概念
  • 概念与原理
    • 基本概念总结
    • 开放接口
      • CRI - Container Runtime Interface
      • CNI - Container Network Interface
      • CSI - Container Storage Interface
    • 核心概念与原理
      • Kubernetes简介
      • Kubernetes架构与原理
      • 核心组件
      • 设计理念
      • 核心组件原理
        • etcd概念与原理
          • Etcd基于RAFT的一致性
          • Etcd v2 与 v3存储
        • kube-apiserver
        • kube-scheduler
        • kube-Controller Manager
        • Kubelet
        • kubectl常用命令
      • kubectl
      • kube-proxy
      • IPVS负载均衡
      • kube-dns
      • Federation-集群联邦
      • kubeadm
    • 资源对象与基本概念解析
    • 资源对象
      • Pod
        • Pod概述
        • Pod解析
        • Pod 的生命周期
        • 探针
        • Init 容器
        • Pause容器
        • Pod 安全策略
        • Pod hook
        • Pod Preset
        • pod其他设置
        • Pod中断与PDB
    • Kubernetes中的网络
      • 图解Kubernetes网络(一)
      • 图解Kubernetes网络(二)
      • 图解Kubernetes网络(三)
      • calico
      • flannel
    • 转发K8S后端服务的四种方式
    • 集群资源对象
      • Node
      • Namespace
      • Label
      • Annotation
      • Taint和Toleration(污点和容忍
      • 垃圾收集
      • Autoscaling
      • Horizontal Pod Autoscaling
        • Metrics-Server
        • Heapster
      • ReplicationController和ReplicaSet
    • 控制器资源对象
      • CronJob
      • Job
      • DaemonSet
      • Deployment
      • StatefulSet
    • 服务发现-资源对象
      • DNS原理讲解
      • Ingress 选型
      • Service
      • Ingress
    • 存储对象
      • ConfigMap
      • Volume
      • Persistent Volume(持久化卷)
      • StorageClass
      • 本地持久化存储
      • Secret
    • 策略对象
      • Resource Quota
      • SecurityContext
    • 身份对象
      • 认证
      • Service Account
      • RBAC——基于角色的访问控制
      • 准入控制
      • Network Policy
    • 资源调度
      • QoS(服务质量等级)
  • 插件扩展
    • Kubernetes的CI/CD
    • Dashboard
    • CoreDNS
    • 监控
      • 概述
      • 第1章 采集
        • Probes
        • Docker Stats
        • cAdvisor
        • Heapster
          • HPA
        • metrics-server
        • custom metrics自定义指标
        • kube-state-metrics
        • node-exporter
        • Prometheus
          • go 自定义metric
          • 本地存储
          • Prometheus概述
          • Prometheus基本架构
          • Prometheus部署方案
          • Prometheus的配置与服务发现
          • PromQL查询解析
          • Prometheus数据可视化
          • Prometheus存储机制
        • Sysdig
        • Untitled
      • 自定义监控
      • Custom-Metrics及Prometheus监控系统
      • grafana各种类型监控-实用
    • 日志
    • 存储
      • Kubernetes Ceph 工作原理详解
    • Metrics
    • GPU
    • Cluster AutoScaler
    • CI/CD
      • 基于DOCKER的CI工具—DRONE
      • DRONE安装指南
      • 如何使用DRONE
      • Drone
      • Jenkins
        • jenkins 集成 keycloak 认证
    • 50个免费的Kubernetes工具盘点
      • Kube集群部署工具
      • 监控工具
      • 测试工具
      • 安全工具
      • 实用的CLI工具
      • 开发工具
      • 无服务器/函数工具
      • 原生服务发现
      • 原生可视化与控制
    • Untitled
  • 领域应用
    • Istio
      • Helm安装
      • 安装并试用Istio service mesh
      • 示例应用部署
      • Bookinfo 应用-
      • 配置请求的路由规则
      • 故障注入
      • 流量转移
      • Istio流量管理实现机制深度解析
      • istio:监控能力介绍
      • Istio 04:Istio性能及扩展性介绍
      • Untitled
  • 实践
    • 大规模集群
    • 高可用
  • k8s运维排查
    • 常用命令
    • Kubernetes之YAML文件
      • yaml文件例子--pod
      • yaml文件例子--rc
    • Kubernetes运维
      • 集群管理
      • 集群与应用监控
      • 日志收集与管理
      • 常见问题定位
      • 权限管理RBAC
    • 排错概览
    • 集群排错
      • kubernetes集群管理常用命令一
    • Pod 排错
    • 网络排错
      • 容器内抓包定位网络问题
    • PV 排错
    • Windows 排错
    • 云平台排错
    • 集群安装脚本
    • 排错工具
    • 常见问题
      • k8s故障解决干货文档链接
      • 记一次Docker/Kubernetes上无法解释的连接超时原因探寻之旅
      • service没有负载均衡
      • kubernetes集群etcd空间配额2G的坑优化
    • K8S--100问
      • 解决 Docker 日志文件太大的问题
      • Kubernetes集群里容器之间的通讯方式
      • k8s 优化
      • lxcfs 在容器内显示容器的 CPU、内存状态
      • kubectl 创建 Pod流程
      • k8s网络-iptables
      • k8s底层网络原理
      • 网络排查
      • kubectl top 和 cadvisor metric ,docker state不一致的问题
      • 容器挂载数据卷的几种情况
      • 容器的终止流程
      • Kubernetes 中如何保证优雅地停止 Pod
      • K8S的apiVersion
      • 如何在Pod中执行宿主机上的命令
      • 创建 Pod 流程
      • k8s主要组件说明
      • 节点网络规划
      • Deployment管理方式
      • pod的分配方式
  • 深入浅出k8s
    • 说明
    • k8s发布策略介绍
    • oom kill原理讲解
    • Kubernetes 的架构设计与实现原理
  • 附录
    • CKA认证
    • 生态圈
    • 资讯快报
      • 2018态势回顾与2019年前景展望
      • Untitled
    • 学习资源
    • 参考文档
    • Kubernetes版本更新日志
      • Kubernetes 1.14 更新日志
      • Kubernetes 1.13 更新日志
      • Kubernetes1.12更新日志
      • Kubernetes1.10更新日志
      • Kubernetes1.11更新日志
  • 思维导图
    • k8s
    • DEVOPS
  • DEVOPS
    • 开源仓库-nexus
      • 一,nexus的安装
      • 二,使用nexus3配置docker私有仓库
      • 三,使用nexus3配置maven私有仓库
      • 四,nexus-3.14.0升级到3.15.2
      • 五,nexus3搭建golang私服
    • vpn
      • openvpn
    • Tcpdump 示例教程
    • Ipsec VPN-centos7使用strangwang搭建vpn
    • yum安装redis及常用指令
    • 数据库
      • mysql表操作
      • mysql 库常用操作及备份还原
      • MySQL 优化实施方案
    • NSQ
      • nsq问题解答
      • 选型
      • docker-compose部署 简单nsq 集群
    • 部署Redis集群
    • zookeeper安装及使用
    • Etcd
      • Untitled
      • Etcd配置
  • k8s系统完整部署
    • CentOS7.5 使用二进制程序部署Kubernetes1.12.2
    • 二进制的方式部署 K8S-1.16 高可用集群
    • CoreOS部署Kubernetes集群
    • EFK
      • 日志-kafka
      • logstash的部署、整合ELK+Filebeat
      • 应用日志收集
      • ES搭建
      • es集群部署
      • ElasticSearch技术原理
      • Elasticsearch操作
      • kibana
      • kibana简单使用
      • 非K8S主机部署Filebat
    • 镜像仓库-Harbor
    • Harbor 2.6.2安装
    • cURL 命令获取本机外网 IP
    • Shell 解析 JSON
    • 制作 gitbook 文档镜像,运行在 K8S 上
    • Kubernetes 之 MySQL 持久存储和故障转移
    • 如何删除etcd上的旧数据
    • Git 实战教程
  • 生活
    • 信合.阳光城
Powered by GitBook
On this page
  • StatefulSet
  • 使用 StatefulSet
  • 限制
  • 组件
  • Pod 身份
  • 稳定的网络 ID
  • 部署和 Scale 保证
  • 更新 StatefulSet
  • Partitions
  • Pod 管理策略
  • Parallel 示例
  1. 概念与原理
  2. 控制器资源对象

StatefulSet

PreviousDeploymentNext服务发现-资源对象

Last updated 6 years ago

StatefulSet

StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序。

使用案例参考:,其中包含zookeeper和kakfa的statefulset设置和使用说明。

StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现

  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现

  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现

  • 有序收缩,有序删除(即从N-1到0)

从上面的应用场景可以发现,StatefulSet由以下几个部分组成:

  • 用于定义网络标志(DNS domain)的Headless Service

  • 用于创建PersistentVolumes的volumeClaimTemplates

  • 定义具体应用的StatefulSet

StatefulSet中每个Pod的DNS格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local,其中

  • serviceName为Headless Service的名字

  • 0..N-1为Pod所在的序号,从0开始到N-1

  • statefulSetName为StatefulSet的名字

  • namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace

  • .cluster.local为Cluster Domain

使用 StatefulSet

StatefulSet 适用于有以下某个或多个需求的应用:

  • 稳定,唯一的网络标志。

  • 稳定,持久化存储。

  • 有序,优雅地部署和 scale。

  • 有序,优雅地删除和终止。

  • 有序,自动的滚动升级。

限制

  • StatefulSet 是 beta 资源,Kubernetes 1.5 以前版本不支持。

  • 对于所有的 alpha/beta 的资源,您都可以通过在 apiserver 中设置 --runtime-config 选项来禁用。

  • 给定 Pod 的存储必须由 PersistentVolume Provisioner 根据请求的 storage class 进行配置,或由管理员预先配置。

  • 删除或 scale StatefulSet 将不会删除与 StatefulSet 相关联的 volume。 这样做是为了确保数据安全性,这通常比自动清除所有相关 StatefulSet 资源更有价值。

组件

下面的示例中描述了 StatefulSet 中的组件。

  • 一个名为 nginx 的 headless service,用于控制网络域。

  • 一个名为 web 的 StatefulSet,它的 Spec 中指定在有 3 个运行 nginx 容器的 Pod。

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: gcr.io/google_containers/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
      annotations:
        volume.beta.kubernetes.io/storage-class: anything
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
$ kubectl create -f web.yaml
service "nginx" created
statefulset "web" created
​
# 查看创建的 headless service 和 statefulset
$ kubectl get service nginx
NAME      CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx     None         <none>        80/TCP    1m
$ kubectl get statefulset web
NAME      DESIRED   CURRENT   AGE
web       2         2         2m
​
# 根据 volumeClaimTemplates 自动创建 PVC(在 GCE 中会自动创建 kubernetes.io/gce-pd 类型的 volume)
$ kubectl get pvc
NAME        STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE
www-web-0   Bound     pvc-d064a004-d8d4-11e6-b521-42010a800002   1Gi        RWO           16s
www-web-1   Bound     pvc-d06a3946-d8d4-11e6-b521-42010a800002   1Gi        RWO           16s
​
# 查看创建的 Pod,他们都是有序的
$ kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
web-0     1/1       Running   0          5m
web-1     1/1       Running   0          4m
​
# 使用 nslookup 查看这些 Pod 的 DNS
$ kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
/ # nslookup web-0.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
​
Name:      web-0.nginx
Address 1: 10.244.2.10
/ # nslookup web-1.nginx
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
​
Name:      web-1.nginx
Address 1: 10.244.3.12
/ # nslookup web-0.nginx.default.svc.cluster.local
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
​
Name:      web-0.nginx.default.svc.cluster.local
Address 1: 10.244.2.10

还可以进行其他的操作

# 扩容
$ kubectl scale statefulset web --replicas=5
​
# 缩容
$ kubectl patch statefulset web -p '{"spec":{"replicas":3}}'
​
# 镜像更新(目前还不支持直接更新 image,需要 patch 来间接实现)
$ kubectl patch statefulset web --type='json' -p='[{"op":"replace","path":"/spec/template/spec/containers/0/image","value":"gcr.io/google_containers/nginx-slim:0.7"}]'
​
# 删除 StatefulSet 和 Headless Service
$ kubectl delete statefulset web
$ kubectl delete service nginx
​
# StatefulSet 删除后 PVC 还会保留着,数据不再使用的话也需要删除
$ kubectl delete pvc www-web-0 www-web-1

Pod 身份

StatefulSet Pod 具有唯一的身份,包括序数,稳定的网络身份和稳定的存储。 身份绑定到 Pod 上,不管它(重新)调度到哪个节点上。

序数

对于一个有 N 个副本的 StatefulSet,每个副本都会被指定一个整数序数,在 [0,N)之间,且唯一。

稳定的网络 ID

StatefulSet 中的每个 Pod 从 StatefulSet 的名称和 Pod 的序数派生其主机名。构造的主机名的模式是$(statefulset名称)-$(序数)。 上面的例子将创建三个名为web-0,web-1,web-2的 Pod。

在创建每个Pod时,它将获取一个匹配的 DNS 子域,采用以下形式:$(pod 名称).$(管理服务域),其中管理服务由 StatefulSet 上的 serviceName 字段定义。

以下是 Cluster Domain,服务名称,StatefulSet 名称以及如何影响 StatefulSet 的 Pod 的 DNS 名称的一些示例。

Cluster Domain

Service (ns/name)

StatefulSet (ns/name)

StatefulSet Domain

Pod DNS

Pod Hostname

cluster.local

default/nginx

default/web

nginx.default.svc.cluster.local

web-{0..N-1}.nginx.default.svc.cluster.local

web-{0..N-1}

cluster.local

foo/nginx

foo/web

nginx.foo.svc.cluster.local

web-{0..N-1}.nginx.foo.svc.cluster.local

web-{0..N-1}

kube.local

foo/nginx

foo/web

nginx.foo.svc.kube.local

web-{0..N-1}.nginx.foo.svc.kube.local

web-{0..N-1}

注意 Cluster Domain 将被设置成 cluster.local 除非进行了其他配置。

稳定存储

部署和 Scale 保证

  • 对于有 N 个副本的 StatefulSet,Pod 将按照 {0..N-1} 的顺序被创建和部署。

  • 当 删除 Pod 的时候,将按照逆序来终结,从{N-1..0}

  • 对 Pod 执行 scale 操作之前,它所有的前任必须处于 Running 和 Ready 状态。

  • 在终止 Pod 前,它所有的继任者必须处于完全关闭状态。

如果用户通过修补 StatefulSet 来 scale 部署的示例,以使 replicas=1,则 web-2 将首先被终止。 在 web-2 完全关闭和删除之前,web-1 不会被终止。 如果 web-0 在 web-2 终止并且完全关闭之后,但是在 web-1 终止之前失败,则 web-1 将不会终止,除非 web-0 正在运行并准备就绪。

更新 StatefulSet

v1.7 + 支持 StatefulSet 的自动更新,通过 spec.updateStrategy 设置更新策略。目前支持两种策略

  • OnDelete:当 .spec.template 更新时,并不立即删除旧的 Pod,而是等待用户手动删除这些旧 Pod 后自动创建新 Pod。这是默认的更新策略,兼容 v1.6 版本的行为

  • RollingUpdate:当 .spec.template 更新时,自动删除旧的 Pod 并创建新 Pod 替换。在更新时,这些 Pod 是按逆序的方式进行,依次删除、创建并等待 Pod 变成 Ready 状态才进行下一个 Pod 的更新。

Partitions

RollingUpdate 还支持 Partitions,通过 .spec.updateStrategy.rollingUpdate.partition 来设置。当 partition 设置后,只有序号大于或等于 partition 的 Pod 会在 .spec.template 更新的时候滚动更新,而其余的 Pod 则保持不变(即便是删除后也是用以前的版本重新创建)。

# 设置 partition 为 3$ kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'statefulset "web" patched​# 更新 StatefulSet$ kubectl patch statefulset web --type='json' -p='[{"op":"replace","path":"/spec/template/spec/containers/0/image","value":"gcr.io/google_containers/nginx-slim:0.7"}]'statefulset "web" patched​# 验证更新$ kubectl delete po web-2pod "web-2" deleted$ kubectl get po -lapp=nginx -wNAME      READY     STATUS              RESTARTS   AGEweb-0     1/1       Running             0          4mweb-1     1/1       Running             0          4mweb-2     0/1       ContainerCreating   0          11sweb-2     1/1       Running             0          18s

Pod 管理策略

v1.7 + 可以通过 .spec.podManagementPolicy 设置 Pod 管理策略,支持两种方式

  • OrderedReady:默认的策略,按照 Pod 的次序依次创建每个 Pod 并等待 Ready 之后才创建后面的 Pod

  • Parallel:并行创建或删除 Pod(不等待前面的 Pod Ready 就开始创建所有的 Pod)

Parallel 示例

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  podManagementPolicy: "Parallel"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: gcr.io/google_containers/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

可以看到,所有 Pod 是并行创建的

$ kubectl create -f webp.yaml
service "nginx" created
statefulset "web" created
​
$ kubectl get po -lapp=nginx -w
NAME      READY     STATUS              RESTARTS  AGE
web-0     0/1       Pending             0         0s
web-0     0/1       Pending             0         0s
web-1     0/1       Pending             0         0s
web-1     0/1       Pending             0         0s
web-0     0/1       ContainerCreating   0         0s
web-1     0/1       ContainerCreating   0         0s
web-0     1/1       Running             0         10s
web-1     1/1       Running             0         10s

参考:

在上文中,稳定是 Pod (重新)调度中持久性的代名词。 如果应用程序不需要任何稳定的标识符、有序部署、删除和 scale,则应该使用提供一组无状态副本的 controller 来部署应用程序,例如 或 可能更适合您的无状态需求

StatefulSets 目前要求 负责 Pod 的网络身份。 您有责任创建此服务。

volumeClaimTemplates 使用 PersistentVolume Provisioner 提供的 作为稳定存储。

StatefulSet 可以使用 来控制其 Pod 的域。此服务管理的域的格式为:$(服务名称).$(namespace).svc.cluster.local,其中 “cluster.local” 是集群域。

Kubernetes 为每个 VolumeClaimTemplate 创建一个 。上面的 nginx 的例子中,每个 Pod 将具有一个由 anything 存储类创建的 1 GB 存储的 PersistentVolume。当该 Pod (重新)调度到节点上,volumeMounts 将挂载与 PersistentVolume Claim 相关联的 PersistentVolume。请注意,与 PersistentVolume Claim 相关联的 PersistentVolume 在 产出 Pod 或 StatefulSet 的时候不会被删除。这必须手动完成。

不应该将 StatefulSet 的 pod.Spec.TerminationGracePeriodSeconds 设置为 0。这样是不安全的且强烈不建议您这样做。进一步解释,请参阅 。

上面的 nginx 示例创建后,3 个 Pod 将按照如下顺序创建 web-0,web-1,web-2。在 web-0 处于 状态之前,web-1 将不会被部署,同样当 web-1 处于运行并就绪状态之前 web-2也不会被部署。如果在 web-1 运行并就绪后,web-2 启动之前, web-0 失败了,web-2 将不会启动,直到 web-0 成功重启并处于运行并就绪状态。

kubernetes contrib - statefulsets
Deployment
ReplicaSet
Headless Service
PersistentVolumes
Headless Service
PersistentVolume
强制删除 StatefulSet Pod
运行并就绪
StatefulSet · kubernetes-handbook
Logo