Kubernetes 和 KubeSphere 集群安装配置持久化存储(nfs)并通过StatefulSet动态为pod生成pv挂载

  • 简介
  • 1. 安装配置前置环境
    • 1.1 安装nfs文件系统
      • 1.1.1 安装nfs-server
      • 1.1.2 配置nfs-client
      • 1.1.3 测试nfs
  • 2. 配置默认存储(Storageclass)
    • 2.1 创建默认公共存储类
      • 2.1.1 创建nfs-storage存储类
      • 2.1.2 创建RBAC权限
      • 2.1.3 创建PV的Provisioner(存储插件)
      • 2.1.4 创建PVC持久化卷
    • 2.2 使用statefulset动态为pod生成pv
      • 2.2.1 创建测试pod
  • 3. KubeSphere存储持久化和其他组件安装
    • 3.1 存储持久化和其他组件安装
      • 3.1.1 存储持久化和配置其他组件

简介

持久化存储是安装 KubeSphere 的必备条件。使用 KubeKey 搭建 KubeSphere 集群时,可以安装不同的存储系统作为插件。如果 KubeKey 检测到未指定默认存储类型,则将默认安装 OpenEBS。

同样使用Kubernetes部署我们自己的服务时,也需要为对应的pod挂载pv持久卷,以实现服务数据本地持久化 。

本章演示如何使用nfs文件系统,配置持久化k8s集群本地文件存储并通过StatefulSet动态为pod生成pv挂载。

往期文章参考:
01.使用 KubeKey 在Linux上预配置生产就绪的 Kubernetes 和 KubeSphere 集群

版本如下

名称 版本
CentOS 7.6+
Kubernetes 1.23.8
KubeSphere 3.3.1

主机分配

主机名称 IP 角色 容器运行时 容器运行时版本
master01 192.168.0.3 control plane, etcd, worker docker 19.3.8+
node01 192.168.0.5 worker docker 19.3.8+
node02 192.168.0.7 worker docker 19.3.8+
node03 192.168.0.8 worker docker 19.3.8+

1. 安装配置前置环境

1.1 安装nfs文件系统

1.1.1 安装nfs-server

# 集群每台主机执行以下命令,启动 nfs 服务;创建共享目录yum install -y nfs-utilsmkdir -p /nfs/data# 在master01 执行以下命令 可以根据实际情况选择硬盘存储量比较大的作为nfs服务器echo "/nfs/data/ *(rw,insecure,sync,no_subtree_check,no_root_squash)" > /etc/exports# 在master01执行systemctl enable rpcbindsystemctl enable nfs # systemctl enable nfs-serversystemctl start rpcbindsystemctl start nfsexportfs -r # 使配置生效exportfs #检查配置是否生效# 指定网段共享可参考如下
# mkdir -p /data/volumes/{v1,v2,v3}
# 编辑master节点/etc/exports文件,将目录共享到192.168.0.0/24这个网段中(网段可根据自己环境来填写,exports文件需要在每台master节点上进行配置)
# vim /etc/exports
# /data/volumes/v1 192.168.0.0/24(rw,no_root_squash,no_all_squash)
# 发布
# exportfs -arv
# exporting 192.168.0.0/24:/data/volumes/v1
# 查看
# showmounte -e
# Export list for master01:
# /data/volumes/v1 192.168.0.0/24
常见的参数则有:
**rw** read-write 读写
**ro** read-only 只读
**sync** 请求或写入数据时,数据同步写入到NFS server的硬盘后才返回。数据安全,但性能降低了
**async** 优先将数据保存到内存,硬盘有空档时再写入硬盘,效率更高,但可能造成数据丢失。
**root_squash** 当NFS 客户端使用root用户访问时,映射为NFS 服务端的匿名用户
**no_root_squash** 当NFS 客户端使用root 用户访问时,映射为NFS服务端的root 用户
**all_squash** 不论NFS 客户端使用任何帐户,均映射为NFS 服务端的匿名用户

1.1.2 配置nfs-client

IP地址为master(nfs服务器)的IP地址

# 查看showmount -e 192.168.0.3# 除了nfs服务器节点,其他节点都要执行
# 挂载到nfs服务器mount -t nfs 192.168.0.3:/nfs/data /nfs/data
# 设置开机自动挂载 echo "192.168.0.3:/nfs/data      /nfs/data       nfs     defaults       0 0"  >> /etc/fstab

1.1.3 测试nfs

# 在master01的/home目录下新建test-nfs.yml
apiVersion: v1
kind: Pod
metadata:name: test-nfs-pod
spec:containers:- name: busyboximage: busyboxcommand:- sh- -c- 'echo hello world > /mnt/hello'imagePullPolicy: IfNotPresentvolumeMounts:- mountPath: "/mnt"name: nfsvolumes:- name: nfsnfs: # 使用NFS存储path: /nfs/data # NFS存储路径server: 192.168.0.3 # NFS服务器地址# 上面busybox的逻辑就是将“hello world”写入/mnt/hello文件中,而/mnt目录和NFS挂载,所以理论上,nfs虚拟机的/nfs目录下也会有个hello文件。
# 创建后,运行kubectl apply -f test-nfs.yml
# 查看nfs虚拟机(master),查看/nfs/data目录下是否有hello文件
# 测试成功后,可以删除hello文件:rm -rf /nfs/hello
# 执行以下命令删除刚刚的测试Pod:kubectl delete -f test-nfs.yml

2. 配置默认存储(Storageclass)

Storageclass解决PV手动创建需求,当每次创建 PVC 声明使用存储时,都需要去手动的创建 PV,来满足 PVC 的使用。
可以用一种机制来根据用户声明的存储使用量(PVC)来动态的创建对应的持久化存储卷(PV),k8s 用 StorageClass 来实现动态创建 持久化存储。
目前支持的类参考:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/
在NFS StorageClass中最核心概念为Provisioner,那什么是Provisioner?
Provisioner是StorageClass中必须的一个资源,它是存储资源自动调配器,可以将其看作是后端存储驱动。对于NFS类型,K8S没有提供内部Provisioner,但可以使用外部的Provisioner。Provisioner必须符合存储卷的开发规范(CSI)。本文档中使用NFS提供的Provisioner。
流程分解:
①pod挂载pvc
②pvc配置存储类请求pv
③storageclass找到provisioner申请pv
④nfs provisioner生成pvc需要的pv,提供给pod做存储

2.1 创建默认公共存储类

以下操作在master01主节点执行即可
需注意,StorageClass为全局资源,所以命名空间为default,不影响其他命名空间调用 如果*K8s版本为1.20.x *
且nfs-subdir-external-provisioner(nfs-client)的版本低于4.0
在/etc/kubernetes/manifests/kube-apiserver.yaml的command中添加:
- –feature-gates=RemoveSelfLink=false 否则会报错: Kubernetes v1.20.13 报"unexpected error getting claim reference: selfLink was
empty, can’t make reference"

2.1.1 创建nfs-storage存储类

# 创建 sc.yaml 并执行 kubectl apply -f sc.yaml 创建名为nfs-storage的存储类
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-storage ## 可以改成自己的存储名称annotations:storageclass.beta.kubernetes.io/is-default-class: 'true'storageclass.kubernetes.io/is-default-class: "true"  ## true 默认空间,false 不是默认空间
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner ## 这里指定存储供应者来源名称
reclaimPolicy: Delete  ## 指定回收策略,在这里选择的是Delete,与PV相连的后端存储完成Volume的删除操作
volumeBindingMode: Immediate ## 指定绑定模式,在这里选择的是即刻绑定,也就是存储卷声明创建之后,立刻动态创建存储卷饼将其绑定到存储卷声明,另外还有"WaitForFirstConsumer",直到存储卷声明第一次被容器组使用时,才创建存储卷,并将其绑定到存储卷声明
parameters:archiveOnDelete: "true"  ## 删除pv的时候,pv的内容是否要备份##pathPattern: "${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}"  ## 配置默认没有,支持NFS创建子目录,用于不同应用使用NFS的不同目录
# kubectl get sc 查看
# local为KubeKey默认安装的 OpenEBS 类型存储
# nfs-storage为我们刚才生成的
[root@master01 ~]# kubectl get sc
NAME                    PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local (default)         openebs.io/local                              Delete          WaitForFirstConsumer   false                  3d22h
nfs-storage (default)   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate              false                  17h

2.1.2 创建RBAC权限

创建Service Account,用来管控NFS provisioner在k8s集群中的运行权限 rbac (Role-Based Access Control 基于角色的访问控制,就是用户通过角色与权限进行关联),是一个从认证—>授权—>准入机制

# 创建 rbac.yaml 并执行 kubectl apply -f rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: nfs-client-provisioner-runner
rules:- apiGroups: [""]resources: ["nodes"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["persistentvolumes"]verbs: ["get", "list", "watch", "create", "delete"]- apiGroups: [""]resources: ["persistentvolumeclaims"]verbs: ["get", "list", "watch", "update"]- apiGroups: ["storage.k8s.io"]resources: ["storageclasses"]verbs: ["get", "list", "watch"]- apiGroups: [""]resources: ["events"]verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: run-nfs-client-provisioner
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
rules:- apiGroups: [""]resources: ["endpoints"]verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: leader-locking-nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
roleRef:kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io

2.1.3 创建PV的Provisioner(存储插件)

创建PV存储插件,这样才能实现自动创建PV,一是在NFS共享目录下创建挂载点(volume),二是建立PV并将PC与NFS挂载建立关联。
本文采用高可用配置 如不需要可将replicas设置为1,env中ENABLE_LEADER_ELECTION高可用选举环境变量注释掉

# 创建 rbac.yaml 并执行 kubectl apply -f rbac.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisionerlabels:app: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
spec:replicas: 3  # 想做高可用的话这里可以改成3,一般为大于等于3的奇数strategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisioner# 注意该NFS-client镜像一定要与k8s版本相匹配,如果不兼容那么就无法绑定image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nfs-subdir-external-provisioner:v4.0.2# resources:#    limits:#      cpu: 10m#    requests:#      cpu: 10mvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: k8s-sigs.io/nfs-subdir-external-provisioner- name: ENABLE_LEADER_ELECTIONvalue: "True"      ## 设置高可用允许选举- name: NFS_SERVERvalue: 192.168.0.5 ## 指定自己nfs服务器地址- name: NFS_PATH  value: /nfs/data  ## nfs服务器共享的目录volumes:- name: nfs-client-rootnfs:server: 192.168.0.3path: /nfs/data
# 通过检查容器日志查看启动的NFS插件是否正常
# 如果出现error等相关信息一定仔细排查,否则会导致NFS-celient一直处于pending状态
# https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/issues/25
[root@master01 ~]# kubectl get pod | grep nfs
nfs-client-provisioner-86b55c565d-fqmm5   1/1     Running   0          20h
nfs-client-provisioner-86b55c565d-p2sks   1/1     Running   0          20h
nfs-client-provisioner-86b55c565d-r5stq   1/1     Running   0          20h

2.1.4 创建PVC持久化卷

# # 创建 pvc.yaml 并执行 kubectl apply -f pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-pvcnamespace: default
spec:accessModes:- ReadWriteManyresources:requests:storage: 200MistorageClassName:  nfs-storage   ## 这里不加就是默认存储
# kubectl get pvc 查看
[root@master01 nfs]# kubectl get pvc
NAME       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-pvc   Bound    pvc-dd852bab-8b86-4d42-8666-9b2b550597aa   200Mi      RWX            nfs-storage    8s
[root@master01 nfs]# kubectl delete -f pvc.yaml

2.2 使用statefulset动态为pod生成pv

RC、Deployment、DaemonSet都是面向无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态的服务,比如MySQL、MongoDB集群等。
StatefulSet本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
在Deployment中,与之对应的服务是service,而在StatefulSet中与之对应的headless
service,headless service,即无头服务,与service的区别就是它没有Cluster
IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。
除此之外,StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名,这个域名的格式为:

$(podname).(headless server name)
FQDN:$(podname).(headless server name).namespace.svc.cluster.local

2.2.1 创建测试pod

# 创建 test.yaml 并执行 kubectl apply -f test.yaml
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: nfs-web
spec:serviceName: "nginx"replicas: 3selector:matchLabels:app: nfs-web # has to match .spec.template.metadata.labelstemplate:metadata:labels:app: nfs-webspec:terminationGracePeriodSeconds: 10containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80name: webvolumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates:  # pvc模板- metadata:name: wwwnamespace: default # 要和pod的namspace一致annotations:volume.beta.kubernetes.io/storage-class: nfs-storagespec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 10Mi
# kubectl get pvc 查看 可以看到为pod动态生成了pvc,pv
# 在StatefulSet中动态生成的pv不会随着pod的删除而被删除
# 它是和pod一一对应,pod恢复后,数据依然存在
[root@master01 nfs]# kubectl get pvc
NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
www-nfs-web-0   Bound    pvc-bdd6ff3e-9524-4e21-8cb6-29aebfd67e6f   10Mi       RWO            nfs-storage    4s
www-nfs-web-1   Bound    pvc-9eea90b4-3ac7-4a7d-a037-301c96eb707e   10Mi       RWO            nfs-storage    0s
[root@master01 nfs]#
[root@master01 nfs]# kubectl delete -f test.yaml

3. KubeSphere存储持久化和其他组件安装

3.1 存储持久化和其他组件安装

3.1.1 存储持久化和配置其他组件

1、以 admin 用户登录控制台,点击左上角的平台管理,选择集群管理。
2、点击定制资源定义,在搜索栏中输入 ClusterConfiguration,点击搜索结果查看其详细页面。

3、在自定义资源中,点击 ks-installer 右侧的操作,选择编辑 YAML。。

4、在该 YAML 文件中,修改配置内容完成后,点击右下角的确定,保存配置,组件就开始安装,安装需要一定的时间,需要耐心等待。

1、kubesphere平台上操作:metrics_server 改为 true

  metrics_server:enabled: true

2、kubesphere平台上操作:建议将存储配置进行修改: storageClass: “nfs-storage” ,不修改会默认创建一个存储空间 local (default)

  monitoring:gpu:nvidia_dcgm_exporter:enabled: falsenode_exporter:port: 9100storageClass: 'nfs-storage'
# 监控如果开启建议修改为nfs-storagemonitoring:gpu:nvidia_dcgm_exporter:enabled: falsenode_exporter:port: 9100storageClass: 'nfs-storage'

3、kubesphere平台上操作: network配置改为如下:

  network:ippool:type: caliconetworkpolicy:enabled: truetopology:type: weave-scope

4、kubesphere平台上操作: 应用商店开启:

  openpitrix:store:enabled: true

传送门:KubeSphere启用可插拔组件官方文档

5、在 kubectl 中执行以下命令检查安装过程:
 kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f

往期文章参考:
01.使用 KubeKey 在Linux上预配置生产就绪的 Kubernetes 和 KubeSphere 集群

02.Kubernetes 和 KubeSphere 集群安装配置持久化存储(nfs)并通过StatefulSet动态为pod生成pv挂载相关推荐

  1. ZooKeeper-3.3.4集群安装配置

    "ZooKeeper-3.3.4集群安装配置": 关键词:zookeeper-3.3.4 集群 安装 配置 zookeeper是一个分布式开源框架,提供了协调分布式应用的基本服务, ...

  2. redis cluster 集群 安装 配置 详解

    redis cluster 集群 安装 配置 详解 张映 发表于 2015-05-01 分类目录: nosql 标签:cluster, redis, 安装, 配置, 集群 Redis 集群是一个提供在 ...

  3. 一步步教你Hadoop多节点集群安装配置

    一步步教你Hadoop多节点集群安装配置 1.集群部署介绍 1.1 Hadoop简介  Hadoop是Apache软件基金会旗下的一个开源分布式计算平台.以Hadoop分布式文件系统HDFS(Hado ...

  4. 原创:centos7.1下 ZooKeeper 集群安装配置+Python实战范例

    centos7.1下 ZooKeeper 集群安装配置+Python实战范例 下载:http://apache.fayea.com/zookeeper/zookeeper-3.4.9/zookeepe ...

  5. websphere一直安装部署_WebSphere集群安装配置及部署应用说明

    <WebSphere集群安装配置及部署应用说明>由会员分享,可在线阅读,更多相关<WebSphere集群安装配置及部署应用说明(27页珍藏版)>请在人人文库网上搜索. 1.We ...

  6. RabbitMQ集群安装配置+HAproxy+Keepalived高可用

    RabbitMQ集群安装配置+HAproxy+Keepalived高可用 转自:https://www.linuxidc.com/Linux/2016-10/136492.htm rabbitmq 集 ...

  7. Greenplum集群安装配置及最佳实践

    Greenplum集群安装配置及最佳实践 目录 Greenplum集群安装配置及最佳实践 1 目录 1 1 总体介绍 2 1.1 硬件平衡 2 1.2 高可用 2 1.3 部署方案 2 1.3.1 G ...

  8. Ceph分布式集群安装配置

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到网站:https://www.captainai.net/dongkelun 前言 记录Ceph分布式集群安 ...

  9. Openpbs centos7集群安装配置心得

    Openpbs centos7集群安装配置心得 写在前面 准备工作 1.安装虚拟机 2.创建虚拟机集群 SSH免密登陆 网络环境配置 ssh免密登陆 建立NFS共享目录 关闭各节点防火墙和Selinu ...

最新文章

  1. tomcat安装apr优化
  2. UC伯克利摘最佳论文、Hugging Face获最佳demo,EMNLP 2020奖项公布
  3. Fedora 20 安装后的一些事情
  4. apache mysql php 安装配置_Windows下Apache,MySql,PHP安装配置
  5. JS实现让页脚一直固定在页面底部
  6. sync/atomic 库使用小结
  7. latex中的对号和错号
  8. (day 15 - 双指针)剑指 Offer 18. 删除链表的节点
  9. [直观学习排序算法] 视觉直观感受若干常用排序算法
  10. 单片机调试 — Event Recorder 的使用
  11. 单片机开发产品流程,照这个来没错!
  12. iOS UILable换行相关设置
  13. 《隐私政策》及《用户服务协议》
  14. 这套精美的开源数据报表模板,美呆了
  15. Android短彩信源码解析-短信发送流程(一)
  16. Android应用接入微信开放平台
  17. Ubuntu共享文件夹设置
  18. Word复制粘贴两端不整齐
  19. 1+X中级商城集群搭建(三台主机)
  20. 写作小课堂:【写好简历】强调效果胜过强调水平、保持一致性和向上的趋势、在简历中要用好主题词。通常不超过两页(A4纸正反两面)为佳

热门文章

  1. 格式化输出:fmt库用法
  2. vue+elementUI点击菜单添加tab
  3. 2022山东理工大学pta程序设计---实验五(一维数组)详解
  4. Android 系统的分区和文件系统(1)- Android 系统源码结构分析
  5. 疯狂Android讲义(第3版)学习笔记(第二章---界面编程)
  6. 【网络流与线性规划24题】【机器人路径规划问题】【IDA*】【题解】
  7. 关于Android项目相机使用(二)-------相册调用
  8. Ubuntu下包管理
  9. WeiPHP5.0 任意用户Cookie伪造
  10. 介绍两款App敏感信息收集工具