Skip to content

Latest commit

 

History

History
588 lines (390 loc) · 12.3 KB

File metadata and controls

588 lines (390 loc) · 12.3 KB

第13节 存储抽象


❤️💕💕新时代拥抱云原生,云原生具有环境统一、按需付费、即开即用、稳定性强特点。Myblog:http://nsddd.top


[TOC]

存储抽象

::: danger STOP 这一部分内容非常重要~

我们在前面学docker的时候实现挂载–mount

同样对于k8s来说,我们也需要这个挂载的实现,而且挂载功能更强。

我们如果使用了k8s,这样挂载会有一个很严重的问题,如果pod宕机,重新启动到别的机器~那么此时可能会出现挂载失败。

⚡ k8s将所有的挂载的层次统一管理起来,形成存储层。

:::

kubernetes 集群不会为你处理数据的存储,我们可以为数据库挂载一个磁盘来确保数据的安全。 你可以选择云存储、本地磁盘、NFS。

  • 本地磁盘:可以挂载某个节点上的目录,但是这需要限定 pod 在这个节点上运行
  • 云存储:不限定节点,不受集群影响,安全稳定;需要云服务商提供,裸机集群是没有的。
  • NFS:不限定节点,不受集群影响

环境准备NFS

所有结点

安装NFS:

:::: code-group ::: code-group-item Ubuntu

apt install -y nfs-utils

::: ::: code-group-item Centos

yum install -y nfs-utils

::: ::::

主节点

给master结点暴露文件夹/nfs/data/

#nfs 主节点
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

创建文件夹:

mkdir -p /nfs/data

启动rpc远程绑定(设置开机启动):

systemctl enable rpcbind --now
systemctl enable nfs-server --now

检查:

exportfs

image-20221022204801491

查看私有网络的ip地址给从结点使用:

[root@k8s-master01 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 192.168.0.2/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0

从结点

测试结点检查:

[root@k8s-master03 ~]# showmount -e 192.168.0.2
Export list for 192.168.0.2:
/nfs/data *

创建/nfs/data

mkdir -p /nfs/data

同步:

mount -t nfs 192.168.0.2:/nfs/data /nfs/data

验证

在主节点中,创建文件,在其他结点就可以发现同步了~

[root@k8s-master01 ~]# mount -t nfs 192.168.0.2:/nfs/data /nfs/data
[root@k8s-master01 ~]# cd /nfs/data/
[root@k8s-master01 data]# echo "111" >> README.md

image-20221022210439304

原生方式数据挂载

创建文件deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-pv-demo
  name: nginx-pv-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-pv-demo
  template:
    metadata:
      labels:
        app: nginx-pv-demo
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          nfs:
            server: 172.31.0.4
            path: /nfs/data/nginx-pv

::: tip /usr/share/nginx/html/nfs/data/nginx-pv形成一个映射关系(类似于docker -v

:::

🚀 编译结果如下:

image-20221022213410525

::: tip 提醒 我们发现一直没办法刷新出来(0/1),我们使用描述命令来打开看看

kubectl describe pod nginx-pv-demo-75ff4fbcf7-5prbw 

image-20221022214019506

failedmount表示挂载失败

⬇️ 重新部署一下:

[root@k8s-master02 data]# kubectl delete -f deploy.yaml 
deployment.apps "nginx-pv-demo" deleted
[root@k8s-master02 data]# kubectl apply -f deploy.yaml 
deployment.apps/nginx-pv-demo created

:::

PV&PVC

::: warning pv & pvc 原生方式的问题: 删除deploy.yaml 文件不会删除,浪费空间。

PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置,比如Volume的类型、挂载目录、远程存储服务器地址等

PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格,比如存储大小、读写权限等。

image-20221022220215815

我们的pod需要用多大的空间,需要用PVC写一份申请书,按照申请书给出一个实际的大小空间,申请书删除掉,那么这个空间就会被回收,空间删除掉,申请书也被删除了~

:::

StorageClass:充当PV的模板,自动为PVC创建PV

存储的时候需要StorageClass指定块存储或者文件存储~

我们在前面也是知道了存储是分类的,我们需要指定StorageClass

image-20221022220407744

创建pv池

#nfs主节点
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03

::: warning 创建PV 注意:server修改为自己的eth0地址

[root@k8s-master01 data]# ip a | grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 192.168.0.2/24 brd 192.168.0.255 scope global dynamic noprefixroute eth0

写入配置文件pv.yaml

apiVersion: v1
kind: PersistentVolume  # 资源类型pv
metadata:
  name: pv01-10m  # 名字无所谓
spec:
  capacity:   # 限制容量
    storage: 10M
  accessModes:
    - ReadWriteMany  # 可读可写
  storageClassName: nfs   # 指定为nfs
  nfs:
    path: /nfs/data/01 # 01文件夹位置
    server: 192.168.0.2  # 修改eth0地址
---  # 三个横线代表分割完整文档
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv02-1gi
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/02
    server: 192.168.0.2
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv03-3gi
spec:
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/03
    server: 192.168.0.2

🚀 编译结果如下:

[root@k8s-master01 data]# kubectl apply -f pv.yaml 
persistentvolume/pv01-10m created
persistentvolume/pv02-1gi created
persistentvolume/pv03-3gi created

:::

获取系统资源命令:

kubectl get persistentvolume
# 也可以简写
kubectl get pv

image-20221022221346394

::: warning PVC创建与绑定 ⚡ 创建PVC pvc.ymal

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 200Mi  # 我需要200M,找到合适的空间绑定
  storageClassName: nfs  # 对应的是上面的空间名称(分组)

image-20221022222002874

📜 对上面的解释:

绑定了合适的PV

⚡ 创建Pod绑定PVC

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-pvc
  name: nginx-deploy-pvc
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy-pvc
  template:
    metadata:
      labels:
        app: nginx-deploy-pvc
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: nginx-pvc

:::

删除策略

删除PVC时候是有回收策略的,比如说是要一起删除掉或者是把PV保留。

ConfigMap

::: tip 为什么需要ConfigMap 我们在使用docker的时候,通常是将某一个容器创建时候就挂载,这样就会保存下来。

ConfigMap就是把之前的配置文件创建为配置集合

:::

redis把之前文件创建为一个配置集

创建文件:

[root@k8s-master03 data]#  echo "appendonly yes # 表示数据需要持久化存储" >> redis.conf && cat redis.conf
appendonly yes # 表示数据需要持久化存储

创建一个配置集:

[root@k8s-master03 data]# kubectl create cm redis-conf --from-file=redis.conf
configmap/redis-conf created
[root@k8s-master03 data]# rm redis.conf -f
[root@k8s-master03 data]# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      2d11h
redis-conf         1      19s

::: danger 注意: 这个配置集存在etcd档案库中,只要k8s还活着,配置集就不会丢。

查看配置集:

kubectl get cm redis-conf -oyaml

image-20221022224249770

:::

⚠️ 如何引用上面的配置集:

::: tip 创建一个Pod

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    command:
      - redis-server
      - "/redis-master/redis.conf"  #指的是redis容器内部的位置
    ports:
    - containerPort: 6379
    volumeMounts:
    - mountPath: /data
      name: data
    - mountPath: /redis-master  # 挂载路径
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap: # 你想要的配置文件从配置集configMap中取出
        name: redis-conf  # 取出上面redis-conf 配置集
        items:
        - key: redis.conf
          path: redis.conf

测试

我们修改配置文件:

kubectl edit cm redis-conf

在redis-config下面:

  redis.conf: |
    appendonly yes # 表示数据需要持久化存储
    requirepass 123456  # 添加

::: danger 记住

  • 挂载目录用PV & PVC
  • 挂载配置文件用configMap

:::

统一管理的思想很重要:

  • 所有的配置文件统一管理,这就是调度的特色
  • 类似还有用户名和密码统一管理~

Secret

::: tip Secret作用和介绍 secret用来保存小片敏感数据的k8s资源,例如密码,token,或者秘钥。这类数据当然也可以存放在Pod或者镜像中,但是放在Secret中是为了更方便的控制如何使用数据,并减少暴露的风险。

  • 用户可以创建自己的secret,系统也会有自己的secret

  • Pod需要先引用才能使用某个secret

Secret 类似于 ConfigMap 但专门用于保存机密数据。

:::

secret的使用

Pod有2种方式来使用secret

  1. 作为volume的一个域被一个或多个容器挂载
  2. 在拉取镜像的时候被kubelet引用。
  3. 或许也可以作为容器的环境变量

::: warning 注意 默认情况下,Kubernetes Secret 未加密地存储在 API 服务器的底层数据存储(etcd)中。 任何拥有 API 访问权限的人都可以检索或修改 Secret,任何有权访问 etcd 的人也可以。 此外,任何有权限在命名空间中创建 Pod 的人都可以使用该访问权限读取该命名空间中的任何 Secret; 这包括间接访问,例如创建 Deployment 的能力。

:::

创建一个secret:

kubectl create secret docke-registry xiongxinwei-docker \
--docker-username=3293172751 \
--docker-password=24643..... \
[email protected]

::: tip 命令格式: 🧷命令格式:

  • --docker-server:Docker仓库地址。
  • --docker-username:Docker仓库用户名。
  • --docker-password:Docker仓库密码。
  • --docker-email:Docker仓库邮箱。

:::

获取secret:

kuberctl get secret

END 链接