Create StatefulSet in K8s

Problems encountered:

The Pod created by Deployment is stateless. After hanging on the Volume, if the Pod hangs, the Replication Controller will run another one to ensure availability, but because it is stateless, the relationship between the Pod and the previous Volume when it hangs It has been disconnected, and the newly created Pod cannot find the previous Pod. But for users, they are unaware that the underlying Pod is hung, but when the Pod is hung, the previously mounted disk can no longer be used.

solution

The StatefulSet launched with K8s v1.5 can retain the state of the Pod.

Reference blog

Because the Kubernetes 1.5 version has not been released for a long time, the domestic information is quite small. Except for some StatefulSet information on big blogs such as tonybai, it can only be searched on the Internet. By searching for the creation method of StatefulSet on google, I finally found an English blog, the link is as follows. For this emerging framework, you still have to go to google more.

https://thenewstack.io/deploy-highly-available-wordpress-instance-statefulset-kubernetes-1-5/

How to create

Things that need to be prepared before creating a StatefulSet, it is worth noting that the order of creation is very critical. The order of creation is as follows:

  • 1、Volume
  • 2、Persistent Volume
  • 3、Persistent Volume Claim
  • 4、Service
  • 5、StatefulSet

Volume can have many types, such as nfs, glusterfs, etc., we use ceph RBD here to create.

Create Volume

sudo rbd create {volume_name} --size 1024 -m {ceph-monitor-ip} -k /etc/ceph/ceph.client.admin.keyring
//禁止掉一些rdb的feature,否则挂载会失败
rbd feature disable volume101 exclusive-lock, object-map, fast-diff, deep-flatten

Create PersistentVolume

Create pv.yaml with the following content:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: {pv_name}
  labels:
    {label_key}:{label_value}
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  rbd:
    monitors:
      - {ceph-monitor-ip}
    pool: rbd
    image: {volume_name}
    user: admin
    secretRef:
      name: ceph-secret
    fsType: ext4
    readOnly: false
  persistentVolumeReclaimPolicy: Recycle

use

kubectl create -f pv.yaml

to create the PV.

Create PersistentVolumeClaim

这一步非常非常的关键,因为如果创建的PVC的名称和StatefulSet中的名称没有对应上,那么StatefulSet中的Pod就肯定创建不成功,我在这一步被卡了一天之久,还好看到上面那篇外文博客,才发现PVC和StatefulSet中的命名的规律。接下来细说一下需要注意的地方。

创建pvc.yaml如下:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-mysql-0
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

我们在这里创建了一个叫做db-mysql-0的PVC,这个名字是不是很奇怪,而且在这个yaml里并没有提到PV的名字,所以PV和PVC是怎么bound起来的呢?是通过labels标签下的key:value键值对来进行匹配的,我们在创建PV时指定了label的键值对,在PVC里通过selector可以指定label。

然后再回到这个PVC的名称定义:db-mysql-0,为什么叫这样一个看似有规律的名字呢,这里需要看一下下一小节创建StatefulSet中的yaml,首先我们看到StatefulSet的name叫mysql,设置的replicas为2个,volumeMounts和volumeClaimTemplates的name必须相同,为db,所以StatefulSet创建的第一个Pod的name应该为mysql-0,第二个为mysql-1。这里StatefulSet中的Pod与PVC之间的绑定关系是通过名称来匹配的,即:

PVC_name === volumeClaimTemplates_name + "-" + pod_name

所以这个问题就有点意思了,我们要先创建PVC,但是PVC的名称实际上是由StatefulSet来确定的。我真的是不知道K8S设计者咋想的·····而且官方文档里创建StatefulSet的例子是直接给了个yaml文件,并没有告诉说要先创建什么再创建什么。

创建Service 和 StatefulSet

在上一步中我们已经创建了名为db-mysql-0的PVC了,接下来创建一个service和statefulset,service的名称可以随意取,但是statefulset的名称已经定死了,为mysql,并且statefulset中的volumeClaimTemplates_name必须为db,volumeMounts_name也必须为db。只有这样,statefulset中的pod才能通过命名来匹配到PVC,否则会创建失败。

statefulset.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql-service
  labels:
    app: mysql
spec:
  ports:
  - port: 80
    name: my-port
  clusterIP: None
  selector:
    app: mysql
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql-service"
  replicas: 2
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mysqlpod
        image: mysql:latest
        ports:
        - containerPort: 80
          name: my-port
        volumeMounts:
        - name: db
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: db
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

运行以下命令:

kubectl create -f statefulset.yaml

就可以创建statefulset了。

 

http://www.cnblogs.com/puyangsky/p/6677308.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326507559&siteId=291194637