在K8s中创建StatefulSet

遇到的问题:

使用Deployment创建的Pod是无状态的,当挂在Volume之后,如果该Pod挂了,Replication Controller会再run一个来保证可用性,但是由于是无状态的,Pod挂了的时候与之前的Volume的关系就已经断开了,新起来的Pod无法找到之前的Pod。但是对于用户而言,他们对底层的Pod挂了没有感知,但是当Pod挂了之后就无法再使用之前挂载的磁盘了。

解决方案

使用K8s v1.5版本推出的StatefulSet可以保留Pod的状态。

参考博客

因为Kubernetes1.5版本发布也没过多久,国内的资料相当的少,除了tonybai等大牛博客上有一些StatefulSet的资料外,只能去外网上搜索了。通过在google上搜索StatefulSet的创建方式,最终发现了一篇英文博客,链接如下。对于这种新兴框架,还是要多去google啊。

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

如何创建

在创建StatefulSet之前需要准备的东西,值得注意的是创建顺序非常关键,创建顺序如下:

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

Volume可以有很多种类型,比如nfs、glusterfs等,我们这里使用的ceph RBD来创建。

创建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

创建PersistentVolume

创建pv.yaml,内容如下:

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

使用

kubectl create -f pv.yaml

来创建PV。

创建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了。

【Kubernetes】在K8s中创建StatefulSet的更多相关文章

  1. 在K8s中创建StatefulSet

    在K8s中创建StatefulSet 遇到的问题: 使用Deployment创建的Pod是无状态的,当挂在Volume之后,如果该Pod挂了,Replication Controller会再run一个 ...

  2. 在kubernetes集群中创建redis主从多实例

    分类 > 正文 在kubernetes集群中创建redis主从多实例 redis-slave镜像制作 redis-master镜像制作 创建kube的配置文件yaml 继续使用上次实验环境 ht ...

  3. kubernetes(K8S)创建自签TLS证书

    TLS证书用于进行通信使用,组件需要证书关系如下: 组件 需要使用的证书 etcd ca.pem server.pem server-key.pem flannel ca.pem server.pem ...

  4. 【转】K8S中部署Helm

    K8S中的包管理工具 1. 客户端Helm(即Helm)  通过脚本安装:curl https://raw.githubusercontent.com/helm/helm/master/scripts ...

  5. 转 docker创建私有仓库和k8s中使用私有镜像

    docker私有仓库建立 环境说明我们选取192.168.5.2做私有仓库地址yum install docker -y1.启动docker仓库端口服务 docker run -d -p 5000:5 ...

  6. Kubernetes之在k8s中部署Java应用

    部署好了k8s以后 部署参考https://www.cnblogs.com/minseo/p/12055731.html 怎么在k8s部署应用 项目迁移到k8s平台是怎样的流程 1,制作镜像 2,控制 ...

  7. 使用 Skywalking 对 Kubernetes(K8s)中的微服务进行监控

    1. 概述 老话说的好:任何成功都不是轻易得来的,是不断地坚持与面对的结果. 言归正传,之前我们聊了 SpringCloud 开发的微服务是如何部署在  Kubernetes(K8s)集群中的,今天我 ...

  8. k8s中yaml文常见语法

    在k8s中,所有的配置都是 json格式的.但为了读写方便,通常将这些配置写成yaml 格式,其运行的时候,还是会靠yaml引擎将其转化为json,apiserver 也仅接受json的数据类型. y ...

  9. Prometheus K8S中部署Alertmanager

    Prometheus K8S中部署Alertmanager 设置告警和通知的主要步骤如下:一.部署Alertmanager二.配置Prometheus与Alertmanager通信三.配置告警 1. ...

随机推荐

  1. CentOS查看系统版本号

    命令:cat /etc/redhat-release [elsearch@localhost data]$ cat /etc/redhat-release Red Hat Enterprise Lin ...

  2. UITableViewController的使用

    如果整个程序界面都只是使用UITableView来搭建,一般需要如下步骤: (1)向界面上拖一个UITableView (2)设置数据源 (3)设置代理 (4)遵守代理协议  上述过程相对繁琐,为了简 ...

  3. WCF 同一个解决方案中控制台应用添加服务引用报错

    错误提示: “Unable to check out the current file. The file may be read-only or locked, or you may need to ...

  4. 51nod 1190 最小公倍数之和 V2

    给出2个数a, b,求LCM(a,b) + LCM(a+1,b) + .. + LCM(b,b). 例如:a = 1, b = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30 ...

  5. 【BZOJ】2190 [SDOI2008]仪仗队

    [算法]欧拉函数 欧拉线性筛 [题解]将图从左至右,从下至上,分别标号0~n-1. 除了坐标0,一个点会被观察到当且仅当其坐标(i,j)的i与j互质,否则会被(i/d,j/d)挡住. 所以累加2~n- ...

  6. 【bzoj】1717 [Usaco2006 Dec]Milk Patterns 产奶的模式

    [算法]后缀数组 [题解]后缀数组 由于m太大,先离散化. 然后处理SA和LCP. 最后用单调队列处理即可. 注意实际上队列头尾长度限制是K-1. 删队尾不要删过头 i≥K才能开始统计答案. #inc ...

  7. Kubernetes: 集群网络配置 - flannel

    参考: [ Kubernetes 权威指南 ] Kubernetes 集群搭建可以参考 [ Kubernetes : 多节点 k8s 集群实践 ] 在多个 Node 组成的 Kubernetes 集群 ...

  8. bzoj 2434 fail tree+dfs序

    首先比较明显的是我们可以将字符串组建立ac自动机,那么对于询问s1字符串在s2字符串中出现的次数,就是在以s1结尾为根的fail tree中,子树有多少个节点是s2的节点,这样我们处理fail tre ...

  9. C# IEqualityComparer 使用方法 Linq Distinct使用方法

    创建 IEqualityComparer的接口类必须实现Equals和GetHashCode方法 public class TipComparer : IEqualityComparer<Tip ...

  10. jq_常用开发模块

    1.循环模块 var html = ""; $.each(data, function(k, v) { html += '<li>' + '<div>' + ...