一、直接使用nfs挂载
一、首先准备nfs服务器
1、安装nfs服务
yum install nfs-utils -y
2、准备一个共享目录
mkdir /opt/data/mysql -p
3、将共享目录以读写权限暴露给10.0.19.0/24网段中的所有主机
cat > /etc/exports <<EOF
/opt/data/mysql 10.0.19.0/24(rw,sync,no_root_squash)
EOF
4、启动nfs
systemctl start nfs
二、接下来,要在每个k8s的node节点都安装nfs,这样的目的是为了node节点可以驱动nfs设备
yum install nfs-utils -y
三、使用nfs挂载
1、接下创建deployment.yaml 来应用nfs
[root@k8s-master1 ~]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql #为该Deployment设置key为app,value为mysql的标签
name: mysql
namespace: test
spec:
replicas: 1 #副本数量
selector: #标签选择器,与上面的标签共同作用
matchLabels: #选择包含标签app:nginx的资源
app: mysql
template: #这是选择或创建的Pod的模板
metadata: #Pod的元数据
labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
app: mysql
spec: #期望Pod实现的功能(即在pod中部署)
containers: #生成container,与docker中的container是同一种
- name: mysql
image: mysql:5.7 #使用镜像mysql: 创建container,该container默认3306端口可访问
ports:
- containerPort: 3306 # 开启本容器的3306端口可访问
env:
- name: MYSQL_ROOT_PASSWORD
value: hjj123456
volumeMounts: #挂载持久存储卷
- name: mysql-data #挂载设备的名字,与volumes[*].name 需要对应
mountPath: /var/lib/mysql #挂载到容器的某个路径下
volumes:
- name: mysql-data #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
nfs:
server: 10.0.19.127 #nfs服务器地址
path: /opt/data/mysql #此路径需要实现创建
2、然后应用到k8s中
kubectl apply -f deployment.yaml
3、进入nfs服务器,查看nfs共享目录是否有数据
[root@k8s-master1 ~]# ls /opt/data/mysql/
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 performance_schema public_key.pem server-key.pem test
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 mysql private_key.pem server-cert.pem sys
四、测试
1、查看mysql的pod在那个节点上
[root@k8s-master1 ~]# kubectl get pod -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-54cdbb65d-mt645 1/1 Running 0 2m55s 10.244.1.51 k8s-node2 <none> <none>
2、进入mysql创建数据库
[root@k8s-master1 ~]# kubectl exec -it mysql-54cdbb65d-mt645 sh -n test
# mysql -uroot -phjj123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.37 MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database test;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.01 sec)
3、进入node2,停掉node2节点测试数据库是否存在,pod迁移需要5,6分钟左右k8s默认的
[root@k8s-node2 ~]# init 0
[root@k8s-master1 ~]# kubectl get pod -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-54cdbb65d-dm6zn 0/1 Terminating 0 8m51s 10.244.1.52 k8s-node2 <none> <none>
mysql-54cdbb65d-gmvws 1/1 Running 0 62s 10.244.0.49 k8s-node1 <none> <none>
[root@k8s-master1 ~]# kubectl exec -it mysql-54cdbb65d-gmvws sh -n test
# mysql -uroot -phjj123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.37 MySQL Community Server (GPL)
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
二、使用pv/pvc(NFS挂载)
一、准备nfs环境
1、创建目录
mkdir /opt/data/{mysql,nginx} -pv
2、将共享目录以读写权限暴露给10.0.19.0/24网段中的所有主机
cat > /etc/exports <<EOF
/opt/data/mysql 10.0.19.0/24(rw,sync,no_root_squash)
/opt/data/nginx 10.0.19.0/24(rw,sync,no_root_squash)
EOF
3、重启nfs服务器
systemctl restart nfs
二、创建pv
1、编写pv.yaml文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1 # pv 名字
spec:
capacity:
storage: 5Gi # 定义容量
accessModes:
- ReadWriteMany # 访问模式
persistentVolumeReclaimPolicy: Retain # 回收策略
storageClassName: mysql # 定义 storageClassName 只有相同名字的才能绑定在一起
nfs:
path: /opt/data/mysql #共享目录
server: 10.0.19.127 #nfs服务器地址
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2 # pv 名字
spec:
capacity:
storage: 5Gi # 定义容量
accessModes:
- ReadWriteMany # 访问模式
persistentVolumeReclaimPolicy: Retain # 回收策略
storageClassName: nginx # 定义 storageClassName 只有相同名字的才能绑定在一起
nfs:
path: /opt/data/nginx #共享目录
server: 10.0.19.127 #nfs服务器地址
2、创建pv1,pv2并查看
[root@k8s-master1 ~]# kubectl apply -f pv.yaml
persistentvolume/pv1 created
persistentvolume/pv2 created
[root@k8s-master1 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv1 5Gi RWX Retain Available mysql 10s
pv2 5Gi RWX Retain Available nginx 10s
[root@k8s-master1 ~]#
三、创建pvc,申请pv
1、编写pvc.yaml文件
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc1 # pvc 名字
namespace: dev
spec:
storageClassName: mysql #定义 storageClassName 只有相同名字的才能绑定在一起
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi # 用户需要多少容量
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc3 # pvc 名字
namespace: dev
spec:
storageClassName: nginx #定义 storageClassName 只有相同名字的才能绑定在一起
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi # amout of Storage request
2、创建pvc1,pvc3并查看
[root@k8s-master1 ~]# kubectl create namespace dev
namespace/dev created
[root@k8s-master1 ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc3 created
[root@k8s-master1 ~]# kubectl get pvc -n dev
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound pv1 5Gi RWX mysql 10s
pvc3 Bound pv2 5Gi RWX nginx 10s
四、使用pvc挂载
1、接下创建deployment.yaml 来应用pvc
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql #为该Deployment设置key为app,value为mysql的标签
name: lnmp
namespace: dev #和pvc在同一个namespace
spec:
replicas: 1 #副本数量
selector: #标签选择器,与上面的标签共同作用
matchLabels: #选择包含标签app:lnmp的资源
app: lnmp
template: #这是选择或创建的Pod的模板
metadata: #Pod的元数据
labels: #Pod的标签,上面的selector即选择包含标签app:lnmp的Pod
app: lnmp
spec: #期望Pod实现的功能(即在pod中部署)
containers: #生成container,与docker中的container是同一种
- name: mysql
image: mysql:5.7 #使用镜像mysql: 创建container,该container默认3306端口可访问
ports:
- containerPort: 3306 # 开启本容器的3306端口可访问
env:
- name: MYSQL_ROOT_PASSWORD
value: hjj123456
volumeMounts: #挂载持久存储卷
- name: mysql-data #挂载设备的名字,与volumes[*].name 需要对应
mountPath: /var/lib/mysql #挂载到容器的某个路径下
- name: nginx
image: nginx:1.8 #使用镜像mysql: 创建container,该container默认3306端口可访问
ports:
- containerPort: 80 # 开启本容器的80端口可访问
volumeMounts: #挂载持久存储卷
- name: nginx-data #挂载设备的名字,与volumes[*].name 需要对应
mountPath: /var/log/nginx #挂载到容器的某个路径下
volumes:
- name: mysql-data #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
persistentVolumeClaim:
claimName: pvc1 #pvc名称
readOnly: false #设置成false可读可写,设成true表示只读
- name: nginx-data #和上面保持一致 这是本地的文件路径,上面是容器内部的路径
persistentVolumeClaim:
claimName: pvc3 #pvc名称
readOnly: false #设置成false可读可写,设成true表示只读
2、然后应用到k8s中
kubectl apply -f deployment.yaml
3、进入nfs服务器,查看nfs共享目录是否有数据
[root@k8s-master1 ~]# ls /opt/data/mysql/
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 performance_schema public_key.pem server-key.pem test
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 mysql private_key.pem server-cert.pem sys
[root@k8s-master1 ~]# ls /opt/data/nginx/
access.log error.log
五、测试选择mysql(这里和上面直接nfs效果一样)
[root@k8s-master1 ~]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
lnmp-7d76dd865d-6qdpm 2/2 Running 0 5m38s 10.244.0.59 k8s-node1 <none> <none>
[root@k8s-node2 ~]# mysql -uroot -phjj123456 -h10.244.0.59
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.01 sec)
停掉k8s-node1节点在测试,pod迁移需要5,6分钟左右k8s默认的
[root@k8s-master1 ~]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
lnmp-7d76dd865d-6qdpm 2/2 Terminating 0 9m44s 10.244.0.59 k8s-node1 <none> <none>
lnmp-7d76dd865d-hbwx7 2/2 Running 0 42s 10.244.1.60 k8s-node2 <none> <none>
[root@k8s-node2 ~]# mysql -uroot -phjj123456 -h 10.244.1.60
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.37 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.01 sec)
以上就是通过pv和pvc挂载
参数介绍
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
- ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
- ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
- ReadWriteMany(RWX):读写权限,可以被多个节点挂载
persistentVolumeReclaimPolicy(回收策略) 这里指定的 PV 的回收策略为 Recycle,目前 PV 支持的策略有三种:
- Retain(保留)- 保留数据,需要管理员手工清理数据
- Recycle(回收)- 清除 PV 中的数据,效果相当于执行 rm -rf /thevoluem/*
- Delete(删除)- 与 PV 相连的后端存储完成 volume 的删除操作,当然这常见于云服务商的存储服务,比如 ASW EBS。
不过需要注意的是,目前只有 NFS 和 HostPath 两种类型支持回收策略。当然一般来说还是设置为 Retain 这种策略保险一点。
PV 的生命周期中的状态,可能会处于4中不同的阶段:
- Available(可用):表示可用状态,还未被任何 PVC 绑定
- Bound(已绑定):表示 PVC 已经被 PVC 绑定
- Released(已释放):PVC 被删除,但是资源还未被集群重新声明
- Failed(失败): 表示该 PV 的自动回收失败
StorageClassName
相同的PV和PVC才能够绑定到一起。
例如:PVC 的StorageClassName设置为 "nfs",那么它只会和 StorageClassName 也为 "nfs" 的 PV 绑定到一起。
三、使用持久化存储StorageClass(NFS挂载)
一、准备好NFS服务器
确保nfs可以正常工作,创建持久化需要的目录。【前面的验证过程中已部署好NFS服务器这里直接引用】
path: /opt/data/nginx
server: 10.0.19.127
二、开启rbac权限
RBAC基于角色的访问控制–全拼Role-Based Access Control
根据rbac.yaml 文件创建Service Account
apiVersion: v1
kind: ServiceAccount #创建一个账户,主要用来管理NFS provisioner在k8s集群中运行的权限
metadata:
name: nfs-client-provisioner
namespace: kube-system
---
kind: ClusterRole #创建集群角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner #角色名
rules: #角色权限
- 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: ["list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "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: kube-system
roleRef:
kind: ClusterRole # 集群角色
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
这个文件是创建授权账户。为什么要授权?在K8S中,我们知道有 ApiServer 组件,它可以管理我们创建的 deployment, pod,service等资源,但是有些资源它是管不到的,比如说 K8S本身运行需要的组件等等,同样StorageClass这种资源它也管不到,所以,需要授权账户。
我们在master节点执行
[root@k8s-master1 ~]# kubectl apply -f rbac.yaml
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
三、 创建StorageClass,指定provisioner
nfs-client-provisioner镜像包下载链接: https://pan.baidu.com/s/1jQc8pPj2piQjtaVG4od6UA?pwd=uu82
提取码: uu82 复制这段内容后打开百度网盘手机App,操作更方便哦
创建nfs-client-provisioner.yaml文件
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-provisioner-01
namespace: kube-system #与RBAC文件中的namespace保持一致
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: nfs-provisioner-01
template:
metadata:
labels:
app: nfs-provisioner-01
spec:
serviceAccountName: nfs-client-provisioner # 指定serviceAccount!
containers:
- name: nfs-client-provisioner
image: jmgao1983/nfs-client-provisioner:latest #镜像地址
imagePullPolicy: IfNotPresent
volumeMounts: # 挂载数据卷到容器指定目录
- name: nfs-client-root
mountPath: /persistentvolumes #不需要修改
env:
- name: PROVISIONER_NAME
value: nfs-provisioner-01 # 此处供应者名字供storageclass调用
- name: NFS_SERVER
value: 10.0.19.127 # 填入NFS的地址
- name: NFS_PATH
value: /opt/data/nginx # 填入NFS挂载的目录
volumes:
- name: nfs-client-root
nfs:
server: 10.0.19.127 # 填入NFS的地址
path: /opt/data/nginx # 填入NFS挂载的目录
---
apiVersion: storage.k8s.io/v1
kind: StorageClass # 创建StorageClass
metadata:
name: nfs-boge
provisioner: nfs-provisioner-01 #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
# Supported policies: Delete、 Retain , default is Delete
reclaimPolicy: Retain #清除策略
PS:nfs-client-provisioner这个镜像的作用,它通过k8s集群内置的NFS驱动,挂载远端的NFS服务器到本地目录,然后将自身作为storageprovisioner,然后关联到storageclass资源。
在master上创建
[root@k8s-master1 ~]# kubectl apply -f nfs-client-provisioner1.yaml
deployment.apps/nfs-provisioner-01 created
storageclass.storage.k8s.io/nfs-boge created
四、基于StorageClass创建一个pvc,看看动态生成的pv是什么效果:
[root@k8s-master1 ~]# cat pvc-sc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx
spec:
storageClassName: nfs-boge
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
[root@k8s-master1 ~]# kubectl apply -f pvc-sc.yaml
persistentvolumeclaim/nginx created
[root@k8s-master1 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx Bound pvc-7fc6a049-79b9-4561-9d35-4d271327d4eb 5Gi RWX nfs-boge 10s
[root@k8s-master1 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-7fc6a049-79b9-4561-9d35-4d271327d4eb 5Gi RWX Retain Bound default/nginx nfs-boge 11s
五、创建pod测试
创建pod,申明PVC进行测试
[root@k8s-master1 ~]# cat nginx.yaml
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
name: nginx
volumeMounts: # 我们这里将nginx容器默认的页面目录挂载
- name: html-files
mountPath: "/usr/share/nginx/html"
volumes:
- name: html-files
persistentVolumeClaim:
claimName: nginx #pvc的name
清空前面实验的pvc,由于pvc绑定了pv,直接删除pv删除不掉:kubectl delete pvc –all 先删pvc再删pv
如果有pod绑定,则需要先删除pod然后删除pvc,再删除pv,如果还需要清理后端存储,则最后根据情况删除后端存储数据
测试
在master上创建
[root@k8s-master1 ~]# kubectl apply -f nginx.yaml
deployment.apps/nginx unchanged
[root@k8s-master1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-5bf46c4cc6-snx2d 1/1 Running 0 5m45s 10.244.0.70 k8s-node1 <none> <none>
[root@k8s-node1 ~]# curl 10.244.0.70 #访问
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.21.6</center>
</body>
</html>
[root@k8s-master1 ~]# echo "node1" > /opt/data/nginx/default-nginx-pvc-7fc6a049-79b9-4561-9d35-4d271327d4eb/index.html #修改挂载文件
[root@k8s-node1 ~]# curl 10.244.0.70 #访问
node1
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/75671.html