目录
[1 configmap](#1 configmap)
[1.1 configmap的功能](#1.1 configmap的功能)
[1.2 configmap的使用场景](#1.2 configmap的使用场景)
[1.3 configmap创建方式](#1.3 configmap创建方式)
[1.3.1 字面值创建](#1.3.1 字面值创建)
[1.3.2 通过文件创建](#1.3.2 通过文件创建)
[1.3.3 通过目录创建](#1.3.3 通过目录创建)
[1.3.4 通过yaml文件创建](#1.3.4 通过yaml文件创建)
[1.3.5 configmap的使用方式](#1.3.5 configmap的使用方式)
[1.3.5.1 使用configmap填充环境变量](#1.3.5.1 使用configmap填充环境变量)
[1.3.5.2 通过数据卷使用configmap](#1.3.5.2 通过数据卷使用configmap)
[1.3.5.3 利用configMap填充pod的配置文件](#1.3.5.3 利用configMap填充pod的配置文件)
[1.3.5.4 通过热更新cm修改配置](#1.3.5.4 通过热更新cm修改配置)
[2 secrets配置管理](#2 secrets配置管理)
[2.1 secrets的功能介绍](#2.1 secrets的功能介绍)
[2.2 secrets的创建](#2.2 secrets的创建)
[2.2.2 编写yaml文件](#2.2.2 编写yaml文件)
[2.3 Secret的使用方法](#2.3 Secret的使用方法)
[2.3.1 将Secret挂载到Volume中](#2.3.1 将Secret挂载到Volume中)
[2.3.2 向指定路径映射 secret 密钥](#2.3.2 向指定路径映射 secret 密钥)
[2.3.3 将Secret设置为环境变量](#2.3.3 将Secret设置为环境变量)
[2.3.4 存储docker registry的认证信息](#2.3.4 存储docker registry的认证信息)
[3 volumes配置管理](#3 volumes配置管理)
[3.1 kubernets支持的卷的类型](#3.1 kubernets支持的卷的类型)
[3.2 emptyDir卷](#3.2 emptyDir卷)
[3.3 hostpath卷](#3.3 hostpath卷)
[3.4 nfs卷](#3.4 nfs卷)
[3.4.1 部署一台nfs共享主机并在所有k8s节点中安装nfs-utils](#3.4.1 部署一台nfs共享主机并在所有k8s节点中安装nfs-utils)
[3.4.2 部署nfs卷](#3.4.2 部署nfs卷)
[3.5 PersistentVolume持久卷](#3.5 PersistentVolume持久卷)
[3.5.1 静态持久卷pv与静态持久卷声明pvc](#3.5.1 静态持久卷pv与静态持久卷声明pvc)
[3.5.1.1 PersistentVolume(持久卷,简称PV)](#3.5.1.1 PersistentVolume(持久卷,简称PV))
[3.5.1.2 PersistentVolumeClaim(持久卷声明,简称PVC)](#3.5.1.2 PersistentVolumeClaim(持久卷声明,简称PVC))
[3.5.1.3 volumes访问模式](#3.5.1.3 volumes访问模式)
[3.5.1.4 volumes回收策略](#3.5.1.4 volumes回收策略)
[3.5.1.5 volumes状态说明](#3.5.1.5 volumes状态说明)
[3.5.2 静态pv实例](#3.5.2 静态pv实例)
[3.5.3 在pod中使用pvc](#3.5.3 在pod中使用pvc)
[4 存储类storageclass](#4 存储类storageclass)
[4.1 StorageClass说明](#4.1 StorageClass说明)
[4.2 StorageClass的属性](#4.2 StorageClass的属性)
[4.3 存储分配器NFS Client Provisioner](#4.3 存储分配器NFS Client Provisioner)
[4.4 部署NFS Client Provisioner](#4.4 部署NFS Client Provisioner)
[4.4.1 创建sa并授权](#4.4.1 创建sa并授权)
[4.4.2 部署应用](#4.4.2 部署应用)
[4.4.3 创建存储类](#4.4.3 创建存储类)
[4.4.4 创建pvc](#4.4.4 创建pvc)
[4.4.5 创建测试pod](#4.4.5 创建测试pod)
[4.4.6 设置默认存储类](#4.4.6 设置默认存储类)
[5 statefulset控制器](#5 statefulset控制器)
[5.1 功能特性](#5.1 功能特性)
[5.2 StatefulSet的组成部分](#5.2 StatefulSet的组成部分)
[5.3 构建方法](#5.3 构建方法)
[5.4 测试:](#5.4 测试:)
[5.5 statefulset的弹缩](#5.5 statefulset的弹缩)
1 configmap
1.1 configmap的功能
-
configMap用于保存配置数据,以键值对形式存储。
-
configMap 资源提供了向 Pod 注入配置数据的方法。
-
镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。
-
etcd限制了文件大小不能超过1M
1.2 configmap的使用场景
-
填充环境变量的值
-
设置容器内的命令行参数
-
填充卷的配置文件
1.3 configmap创建方式
1.3.1 字面值创建
kubectl create cm lee-config --from-literal fname=timing --from-literal name=lee
kubectl describe cm lee-config

1.3.2 通过文件创建
cat /etc/resolv.conf
kubectl create cm lee2-config --from-file /etc/resolv.conf
kubectl describe cm lee2-config

1.3.3 通过目录创建
mkdir leeconfig
cp /etc/fstab /etc/rc.d/rc.local leeconfig/
ls /root/leeconfig/
kubectl create cm lee3-config --from-file leeconfig/
kubectl describe cm lee3-config

1.3.4 通过yaml文件创建
kubectl create cm lee4-config --from-literal db_host=192.168.36.10 --from-literal db_port=3306 --dry-run=client -o yaml > lee-config.yaml
kubectl apply -f lee-config.yaml
kubectl describe cm lee4-config
cat lee-config.yaml
apiVersion: v1
data:
db_host: 192.168.36.10
db_port: "3306"
kind: ConfigMap
metadata:
name: lee4-config

1.3.5 configmap的使用方式
-
通过环境变量的方式直接传递给pod
-
通过pod的 命令行运行方式
-
作为volume的方式挂载到pod内
1.3.5.1 使用configmap填充环境变量
1.将configmap中的内容映射为指定变量
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus:latest
name: testpod
command:
- /bin/sh
- -c
- env
env:
- name: key1
valueFrom:
configMapKeyRef:
name: lee4-config
key: db_host
- name: key2
valueFrom:
configMapKeyRef:
name: lee4-config
key: db_port
restartPolicy: Never
kubectl apply -f test1.yml
kubectl logs pods/testpod

2.将cm中的值直接映射为变量
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus:latest
name: testpod
command:
- /bin/sh
- -c
- env
envFrom:
- configMapRef:
name: lee4-config
restartPolicy: Never
kubectl delete -f test1.yml
kubectl apply -f testpod2.yml
kubectl logs pods/testpod

3.在pod命令行中使用变量
kubectl delete -f testpod2.yml
vim testpod3.yml
cat testpod3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus:latest
name: testpod
command:
- /bin/sh
- -c
- echo ${db_host} ${db_port} #变量调用需
envFrom:
- configMapRef:
name: lee4-config
restartPolicy: Never
kubectl apply -f testpod3.yml
pod/testpod created
kubectl logs pods/testpod

1.3.5.2 通过数据卷使用configmap
kubectl delete -f testpod3.yml
vim testpod4.yml
cat testpod4.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus:latest
name: testpod
command:
- /bin/sh
- -c
- cat /config/db_host
volumeMounts: #调用卷策略
- name: config-volume #卷名称
mountPath: /config
volumes: #声明卷的配置
- name: config-volume #卷名称
configMap:
name: lee4-config
restartPolicy: Never
kubectl apply -f testpod4.yml
pod/testpod created
kubectl logs testpod
192.168.36.10

1.3.5.3 利用configMap填充pod的配置文件
# 建立配置文件模板
vim nginx.conf
cat nginx.conf
server {
listen 8000;
server_name _;
root /usr/share/nginx/html;
index index.html;
}
# 利用模板生成cm
kubectl create cm nginx-conf --from-file nginx.conf
kubectl apply -f nginx.yml
deployment.apps/nginx created
kubectl describe cm nginx-conf
kubectl delete -f nginx.yml
#建立nginx控制器文件
kubectl create deployment nginx --image nginx:latest --replicas 1 --dry-run=client -o yaml > nginx.yml
# 设定nginx.yml中的卷
vim nginx.yml
cat nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: nginx-conf
kubectl apply -f nginx.yml
kubectl get pods -o wide


1.3.5.4 通过热更新cm修改配置
# 修改cm配置
kubectl edit cm nginx-conf
apiVersion: v1
data:
nginx.conf: |
server {
listen 8080; #端口改为8080
server_name _;
root /usr/share/nginx/html;
index index.html;
}
# 查看配置文件是否更改成功
kubectl exec pods/nginx-8487c65cfc-zt4s2 -- cat /etc/nginx/conf.d/nginx.conf
server {
listen 8080;
server_name _;
root /usr/share/nginx/html;
index index.html;
}
# 删除pod让控制器重新生成新的pod,重新读取配置文件
kubectl delete pod nginx-8487c65cfc-qhxpx
kubectl get pod -o wide
# 测试是否能够访问
curl 10.244.166.177:8080


注意:配置文件修改后不会生效,需要删除pod后控制器会重建pod,这时就生效了
2 secrets配置管理
2.1 secrets的功能介绍
-
Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。
-
敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活
-
Pod 可以用两种方式使用 secret:
-
作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里。
-
当 kubelet 为 pod 拉取镜像时使用。
-
-
Secret的类型:
-
Service Account:Kubernetes 自动创建包含访问 API 凭据的 secret,并自动修改 pod 以使用此类型的 secret。
-
Opaque:使用base64编码存储信息,可以通过base64 --decode解码获得原始数据,因此安全性弱。
-
kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息
-
2.2 secrets的创建
在创建secrets时我们可以用命令的方法或者yaml文件的方法
2.2.1从文件创建
echo -n timinglee > username.txt
echo -n lee > password.txt
kubectl create secret generic userlist --from-file username.txt --from-file password.txt
secret/userlist created
kubectl get secrets userlist -o yaml


2.2.2 编写yaml文件
echo -n timinglee | base64
echo -n lee | base64
kubectl create secret generic userlist --dry-run=client -o yaml > userlist.yml
vim userlist.yml
cat userlist.yml
apiVersion: v1
kind: Secret
metadata:
creationTimestamp: null
name: userlist
type: Opaque
data:
username: dGltaW5nbGVl
password: bGVl
kubectl apply -f userlist.yml
kubectl describe secrets userlist

2.3 Secret的使用方法
2.3.1 将Secret挂载到Volume中
kubectl apply -f userlist.yml
kubectl describe secrets userlist
kubectl run nginx --image nginx --dry-run=client -o yaml > pod1.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: secrets
mountPath: /secret # 向固定路径映射
readOnly: true
volumes:
- name: secrets
secret:
secretName: userlist
kubectl apply -f pod1.yml
kubectl describe pod/nginx

2.3.2 向指定路径映射 secret 密钥
向指定路径映射
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx1
name: nginx1
spec:
containers:
- image: nginx
name: nginx1
volumeMounts:
- name: secrets
mountPath: /secret
readOnly: true
volumes:
- name: secrets
secret:
secretName: userlist
items:
- key: username
path: my-users/username
kubectl apply -f pod2.yaml
kubectl exec pods/nginx1 -it -- /bin/bash

2.3.3 将Secret设置为环境变量
kubectl delete -f pod2.yaml
pod "nginx1" deleted
vim pod3.yml
cat pod3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: busybox
name: busybox
spec:
containers:
- image: busybox
name: busybox
command:
- /bin/sh
- -c
- env
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: userlist
key: username
- name: PASS
valueFrom:
secretKeyRef:
name: userlist
key: password
restartPolicy: Never
kubectl apply -f pod3.yml
kubectl logs pods/busybox

2.3.4 存储docker registry的认证信息
建立私有仓库并上传镜像
1.登录仓库
docker login harbor.timinglee.org

2.上传镜像
docker tag timinglee/game2048:latest harbor.timinglee.org/test/game2048:latest
docker push harbor.timinglee.org/test/game2048:latest


3.建立用于docker认证的secret
kubectl create secret docker-registry docker-auth --docker-server harbor.timinglee.org --docker-username admin --docker-password 123456 --docker-email timinglee@timinglee.org
apiVersion: v1
kind: Pod
metadata:
labels:
run: game2048
name: game2048
spec:
containers:
- image: harbor.timinglee.org/test/game2048:latest
name: game2048
imagePullSecrets: #不设定docker认证时无法下载镜像
- name: docker-auth

3 volumes配置管理
-
容器中文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题
-
当容器崩溃时,kubelet将重新启动容器,容器中的文件将会丢失,因为容器会以干净的状态重建。
-
当在一个 Pod 中同时运行多个容器时,常常需要在这些容器之间共享文件。
-
Kubernetes 卷具有明确的生命周期与使用它的 Pod 相同
-
卷比 Pod 中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留
-
当一个 Pod 不再存在时,卷也将不再存在。
-
Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。
-
卷不能挂载到其他卷,也不能与其他卷有硬链接。 Pod 中的每个容器必须独立地指定每个卷的挂载位置。
3.1 kubernets支持的卷的类型
k8s支持的卷的类型如下:
-
awsElasticBlockStore 、azureDisk、azureFile、cephfs、cinder、configMap、csi
-
downwardAPI、emptyDir、fc (fibre channel)、flexVolume、flocker
-
gcePersistentDisk、gitRepo (deprecated)、glusterfs、hostPath、iscsi、local、
-
nfs、persistentVolumeClaim、projected、portworxVolume、quobyte、rbd
-
scaleIO、secret、storageos、vsphereVolume
3.2 emptyDir卷
功能:
当Pod指定到某个节点上时,首先创建的是一个emptyDir卷,并且只要 Pod 在该节点上运行,卷就一直存在。卷最初是空的。 尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,但是这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会永久删除
emptyDir 的使用场景:
-
缓存空间,例如基于磁盘的归并排序。
-
耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
-
在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。
示例:
apiVersion: v1
kind: Pod
metadata:
name: vol1
spec:
containers:
- image: busyboxplus:latest
name: vm1
command:
- /bin/sh
- -c
- sleep 30000000
volumeMounts:
- mountPath: /cache
name: cache-vol
- image: nginx:latest
name: vm2
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-vol
volumes:
- name: cache-vol
emptyDir:
medium: Memory
sizeLimit: 100Mi
kubectl apply -f pod1.yml
kubectl describe pods vol1


测试
kubectl exec -it pods/vol1 -c vm1 -- /bin/sh

3.3 hostpath卷
功能:
hostPath 卷能将主机节点文件系统上的文件或目录挂载到您的 Pod 中,不会因为pod关闭而被删除
hostPath 的一些用法
-
运行一个需要访问 Docker 引擎内部机制的容器,挂载 /var/lib/docker 路径。
-
在容器中运行 cAdvisor(监控) 时,以 hostPath 方式挂载 /sys。
-
允许 Pod 指定给定的 hostPath 在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在
hostPath的安全隐患
-
具有相同配置(例如从 podTemplate 创建)的多个 Pod 会由于节点上文件的不同而在不同节点上有不同的行为。
-
当 Kubernetes 按照计划添加资源感知的调度时,这类调度机制将无法考虑由 hostPath 使用的资源。
-
基础主机上创建的文件或目录只能由 root 用户写入。您需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath 卷。
示例:
apiVersion: v1
kind: Pod
metadata:
name: vol1
spec:
containers:
- image: nginx:latest
name: vm1
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-vol
volumes:
- name: cache-vol
hostPath:
path: /data
type: DirectoryOrCreate #当/data目录不存在时自动建立
kubectl apply -f pod2.yml
kubectl get pods -o wide


3.4 nfs卷
NFS 卷允许将一个现有的 NFS 服务器上的目录挂载到 Kubernetes 中的 Pod 中。这对于在多个 Pod 之间共享数据或持久化存储数据非常有用
例如,如果有多个容器需要访问相同的数据集,或者需要将容器中的数据持久保存到外部存储,NFS 卷可以提供一种方便的解决方案。
3.4.1 部署一台nfs共享主机并在所有k8s节点中安装nfs-utils
1.部署nfs主机
dnf install nfs-utils -y
systemctl enable --now nfs-server.service
vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
exportfs -rv
exporting *:/nfsdata
showmount -e harbor.timinglee.org
Export list for harbor.timinglee.org:
/nfsdata *

2.在k8s所有节点中安装nfs-utils
dnf install nfs-utils -y


3.4.2 部署nfs卷
apiVersion: v1
kind: Pod
metadata:
name: vol1
spec:
containers:
- image: nginx:latest
name: vm1
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-vol
volumes:
- name: cache-vol
nfs:
server: 192.168.36.100 # nfs服务主机IP
path: /nfsdata


3.5 PersistentVolume持久卷
3.5.1 静态持久卷pv与静态持久卷声明pvc
3.5.1.1 PersistentVolume(持久卷,简称PV)
-
pv是集群内由管理员提供的网络存储的一部分。
-
PV也是集群中的一种资源。是一种volume插件,
-
但是它的生命周期却是和使用它的Pod相互独立的。
-
PV这个API对象,捕获了诸如NFS、ISCSI、或其他云存储系统的实现细节
-
pv有两种提供方式:静态和动态
-
静态PV:集群管理员创建多个PV,它们携带着真实存储的详细信息,它们存在于Kubernetes API中,并可用于存储使用
-
动态PV:当管理员创建的静态PV都不匹配用户的PVC时,集群可能会尝试专门地供给volume给PVC。这种供给基于StorageClass
-
3.5.1.2 PersistentVolumeClaim(持久卷声明,简称PVC)
-
是用户的一种存储请求
-
它和Pod类似,Pod消耗Node资源,而PVC消耗PV资源
-
Pod能够请求特定的资源(如CPU和内存)。PVC能够请求指定的大小和访问的模式持久卷配置
-
PVC与PV的绑定是一对一的映射。没找到匹配的PV,那么PVC会无限期得处于unbound未绑定状态
3.5.1.3 volumes访问模式
-
ReadWriteOnce -- 该volume只能被单个节点以读写的方式映射
-
ReadOnlyMany -- 该volume可以被多个节点以只读方式映射
-
ReadWriteMany -- 该volume可以被多个节点以读写的方式映射
-
在命令行中,访问模式可以简写为:
- RWO - ReadWriteOnce
-
ROX - ReadOnlyMany
-
RWX -- ReadWriteMany
3.5.1.4 volumes回收策略
-
Retain:保留,需要手动回收
-
Recycle:回收,自动删除卷中数据(在当前版本中已经废弃)
-
Delete:删除,相关联的存储资产,如AWS EBS,GCE PD,Azure Disk,or OpenStack Cinder卷都会被删除
注意:
只有NFS和HostPath支持回收利用
AWS EBS,GCE PD,Azure Disk,or OpenStack Cinder卷支持删除操作。
3.5.1.5 volumes状态说明
-
Available 卷是一个空闲资源,尚未绑定到任何申领
-
Bound 该卷已经绑定到某申领
-
Released 所绑定的申领已被删除,但是关联存储资源尚未被集群回收
-
Failed 卷的自动回收操作失败
3.5.2 静态pv实例
1.在nfs主机中建立实验目录

2.编写创建pv的yml文件,pv是集群资源,不在任何namespace中
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.36.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
capacity:
storage: 15Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/pv2
server: 192.168.36.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv3
spec:
capacity:
storage: 25Gi
volumeMode: Filesystem
accessModes:
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/pv3
server: 192.168.36.100
kubectl apply -f pv.yml
kubectl get pv

3.建立pvc,pvc是pv使用的申请,需要保证和pod在一个namesapce中
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
storageClassName: nfs
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2
spec:
storageClassName: nfs
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc3
spec:
storageClassName: nfs
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 15Gi

3.5.3 在pod中使用pvc
apiVersion: v1
kind: Pod
metadata:
name: timinglee
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: vol1
volumes:
- name: vol1
persistentVolumeClaim:
claimName: pvc1
kubectl apply -f pod.yml
1.在nfs目录中写入测试文件

2.测试pvc创建是否成功

4 存储类storageclass
4.1 StorageClass说明
-
StorageClass提供了一种描述存储类(class)的方法,不同的class可能会映射到不同的服务质量等级和备份策略或其他策略等。
-
每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 这些字段会在StorageClass需要动态分配 PersistentVolume 时会使用到
4.2 StorageClass的属性
Provisioner(存储分配器):用来决定使用哪个卷插件分配 PV,该字段必须指定。可以指定内部分配器,也可以指定外部分配器。外部分配器的代码地址为: kubernetes-incubator/external-storage,其中包括NFS和Ceph等。
Reclaim Policy(回收策略):通过reclaimPolicy字段指定创建的Persistent Volume的回收策略,回收策略包括:Delete 或者 Retain,没有指定默认为Delete。
4.3 存储分配器NFS Client Provisioner
-
NFS Client Provisioner是一个automatic provisioner,使用NFS作为存储,自动创建PV和对应的PVC,本身不提供NFS存储,需要外部先有一套NFS存储服务。
-
PV以 {namespace}-{pvcName}-${pvName}的命名格式提供(在NFS服务器上)
-
PV回收的时候以 archieved-{namespace}-{pvcName}-${pvName} 的命名格式(在NFS服务器上)
4.4 部署NFS Client Provisioner
4.4.1 创建sa并授权
apiVersion: v1
kind: Namespace
metadata:
name: nfs-client-provisioner
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: nfs-client-provisioner
---
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: ServiceAccount
name: nfs-client-provisioner
namespace: nfs-client-provisioner
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: nfs-client-provisioner
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
namespace: nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: nfs-client-provisioner
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
查看rbac信息

4.4.2 部署应用
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
namespace: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: sig-storage/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.36.100
- name: NFS_PATH
value: /nfsdata
volumes:
- name: nfs-client-root
nfs:
server: 192.168.36.100
path: /nfsdata

4.4.3 创建存储类
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "false"

4.4.4 创建pvc
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1G

4.4.5 创建测试pod
kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: busybox
command:
- "/bin/sh"
args:
- "-c"
- "touch /mnt/SUCCESS && exit 0 || exit 1"
volumeMounts:
- name: nfs-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-claim
查看是否创建成功

4.4.6 设置默认存储类
-
在未设定默认存储类时pvc必须指定使用类的名称
-
在设定存储类后创建pvc时可以不用指定storageClassName
1.一次性指定多个pvc
[root@k8s-master pvc]# vim pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc3
spec:
storageClassName: nfs-client
accessModes:
- ReadOnlyMany
resources:
requests:
storage: 15Gi

2.设定默认存储类
kubectl edit sc nfs-client

3.测试,未指定storageClassName参数
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test1-claim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi

5 statefulset控制器
5.1 功能特性
-
Statefulset是为了管理有状态服务的问提设计的
-
StatefulSet将应用状态抽象成了两种情况:
-
拓扑状态:应用实例必须按照某种顺序启动。新创建的Pod必须和原来Pod的网络标识一样
-
存储状态:应用的多个实例分别绑定了不同存储数据。
-
StatefulSet给所有的Pod进行了编号,编号规则是:(statefulset名称)-(序号),从0开始。
-
Pod被删除后重建,重建Pod的网络标识也不会改变,Pod的拓扑状态按照Pod的"名字+编号"的方式固定下来,并且为每个Pod提供了一个固定且唯一的访问入口,Pod对应的DNS记录。
5.2 StatefulSet的组成部分
-
Headless Service:用来定义pod网络标识,生成可解析的DNS记录
-
volumeClaimTemplates:创建pvc,指定pvc名称大小,自动创建pvc且pvc由存储类供应。
-
StatefulSet:管理pod的
5.3 构建方法
1.建立无头服务
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
kubectl apply -f headless.yml

2.建立statefulset
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx-svc"
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi


5.4 测试:
1.为每个pod建立index.html文件
echo web0 > default-www-web-0-pvc-d2b24655-659d-45c5-91c4-92e3878130e3/index.html
echo web1 > default-www-web-1-pvc-3f38fce9-5f36-41fa-ab78-183b1087ccdb/index.html
echo web2 > default-www-web-2-pvc-1afa550d-e867-43ac-b2c7-c052840ab43f/index.html

2.建立测试pod访问web-0~2

3.删除后再重新建立statefulset数据依旧存在

5.5 statefulset的弹缩
首先,想要弹缩的StatefulSet. 需先清楚是否能弹缩该应用
用命令改变副本数
$ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
通过编辑配置改变副本数
$ kubectl edit statefulsets.apps <stateful-set-name>
statefulset有序回收
kubectl scale statefulset web --replicas 0
kubectl delete -f statefulset.yml
kubectl delete pvc --all