Kubernetes那点事儿——statefulset控制器

statefulset控制器

  • 前言
  • 一、statefulset控制器
  • 二、示例
  • 三、示例:consul statefulset


前言

statefulset控制器用于部署无状态应用,所谓无状态应用简单理解就是各个节点存在主从关系,如ZK集群存在leader、fllower,mysql集群的master和slave,他们各个独立有序运行,有单独的存储,这里存储就要用到前面咱们学习的PV/PVC。

一、statefulset控制器

特点:

  1. 部署有状态应用(deployment部署都是无状态应用)
  2. 解决Pod独立生命周期,保持Pod启动顺序和唯一性
  3. 稳定,唯一的网络标识符,持久存储
  4. 有序,优雅的部署和扩展、删除和终止
  5. 有序,滚动更新

应用场景:分布式应用、数据库集群

K8s中实现statefulset控制器两个必备条件,网络和存储

  • 稳定的网络ID

    使用Headless Service(相比普通Service只是将spec.clusterIP定义为None)来维护Pod网络身份。
    并且添加serviceName: "nginx"字段指定StatefulSet控制器要使用这个Headless Service。
    DNS解析名称:...svc.cluster.local

  • 稳定的存储

    StatefulSet的存储卷使用VolumeClaimTemplate创建,称为卷申请模板,当StatefulSet使用
    VolumeClaimTemplate创建一个PersistentVolume时,同样也会为每个Pod分配并创建一个编号的PVC。

二、示例

# cat statefulset.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web-statefulset
spec:
  selector:
    matchLabels:
      app: nginx1 # has to match .spec.template.metadata.labels
  serviceName: "nginx-svc"   # match service
  replicas: 2 # by default is 1
  template:
    metadata:
      labels:
        app: nginx1 # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www-volume
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates: # auto pvc
  - metadata:
      name: www-volume
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "managed-nfs-storage"
      resources:
        requests:
          storage: 1Gi

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  labels:
    app: nginx-svc
spec:
  ports:
  - port: 80
  clusterIP: None   # Headless Service
  selector:
    app: nginx1
# kubectl get pods -w
web-statefulset-0                         0/1     ContainerCreating   0          5s
web-statefulset-0                         0/1     ContainerCreating   0          10s
web-statefulset-0                         1/1     Running             0          12s
web-statefulset-1                         0/1     Pending             0          0s
web-statefulset-1                         0/1     Pending             0          3s
web-statefulset-1                         0/1     ContainerCreating   0          3s
web-statefulset-1                         0/1     ContainerCreating   0          4s
web-statefulset-1                         1/1     Running             0          6s

# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                  STORAGECLASS          REASON   AGE
my-pv                                      5Gi        RWX            Retain           Bound    default/my-pvc                                                        3h44m
pvc-05d4fed1-8b2d-4352-bf62-dc3e26211c24   1Gi        RWO            Delete           Bound    default/www-volume-web-statefulset-1   managed-nfs-storage            33s
pvc-968e4f9f-f347-419a-a6c4-292a1871f69a   1Gi        RWO            Delete           Bound    default/www-volume-web-statefulset-0   managed-nfs-storage            45s
pvc-b5b27e9a-8741-497f-a1a0-cda57de73421   30Gi       RWX            Delete           Bound    default/my-autopvc                     managed-nfs-storage            172m
# kubectl get pvc
NAME                           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
my-autopvc                     Bound    pvc-b5b27e9a-8741-497f-a1a0-cda57de73421   30Gi       RWX            managed-nfs-storage   172m
my-pvc                         Bound    my-pv                                      5Gi        RWX                                  5h50m
www-volume-web-statefulset-0   Bound    pvc-968e4f9f-f347-419a-a6c4-292a1871f69a   1Gi        RWO            managed-nfs-storage   47s
www-volume-web-statefulset-1   Bound    pvc-05d4fed1-8b2d-4352-bf62-dc3e26211c24   1Gi        RWO            managed-nfs-storage   35s

可以看到,statefulset启动pod会有先后顺序,逐个去启动。
statefuleset不用单独创建pvc,使用"volumeClaimTemplates"

使用nslookup分别对deployment svc以及statefulset svc进行解析,deployment只可以解析到CLUSTER-IP,statefulset可以解析到所有pod
每个pod命名格式为"...svc.cluster.local",这是一个固定名称,所有的连接均可使用该命令。

# nslookup web-service
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      web-service
Address 1: 10.109.33.190 web-service.default.svc.cluster.local

# nslookup nginx-svc
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      nginx-svc
Address 1: 10.244.36.123 web-statefulset-1.nginx-svc.default.svc.cluster.local
Address 2: 10.244.169.180 web-statefulset-0.nginx-svc.default.svc.cluster.local

总结:

StatefulSet与Deployment区别:有身份
身份三要素:

  • 域名
  • 主机名
  • 存储(PVC)

三、示例:consul statefulset

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: consul
spec:
  serviceName: consul
  replicas: 3
  selector:
    matchLabels:
      k8s-app: consul
  template: 
    metadata:
      labels:
        k8s-app: consul
    spec:
      containers:
      - name: consul
        image: consul:latest
        args:
             - "agent"
             - "-server"
             - "-bootstrap-expect=3"
             - "-ui"
             - "-config-file=/consul/config"
             - "-data-dir=/consul/data"
             - "-log-file=/consul/log"
             - "-bind=0.0.0.0"
             - "-client=0.0.0.0"
             - "-advertise=$(PODIP)"
             - "-retry-join=consul-0.consul.$(NAMESPACE).svc.cluster.local"
             - "-retry-join=consul-1.consul.$(NAMESPACE).svc.cluster.local"
             - "-retry-join=consul-2.consul.$(NAMESPACE).svc.cluster.local"
             - "-domain=cluster.local"
             - "-disable-host-node-id"
        volumeMounts:
            - name: nfs
              mountPath: /consul/data
              subPathExpr: data/$(PODNAME)
            - name: nfs
              mountPath: /consul/config
              subPathExpr: config/$(PODNAME)
        env:
            - name: PODIP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: PODNAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
        ports:
            - containerPort: 8500
              name: ui-port
            - containerPort: 8400
              name: alt-port
            - containerPort: 53
              name: udp-port
            - containerPort: 8443
              name: https-port
            - containerPort: 8080
              name: http-port
            - containerPort: 8301
              name: serflan
            - containerPort: 8302
              name: serfwan
            - containerPort: 8600
              name: consuldns
            - containerPort: 8300
              name: server
      volumes:
        - name: nfs
          persistentVolumeClaim:
            claimName: nfs

你可能感兴趣的:(Kubernetes,kubernetes,容器,云原生)