kubeneter-数据存储

k8s pod 挂载数据卷
挂载基本数据卷有以下几种
emptyDir:kube给创建空目录 不会保存数据 pod删除 数据也会删除,一般用于应用运行时所需要的临时目录

apiVersion: v1
kind: Pod
metadata:
  name: volume-emptydir
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: #设置容器暴露端口
    - name: nginx-port #设置暴露端口名 唯一
      containerPort: 80  #暴露端口 pod内唯一
      protocol: TCP
    volumeMounts: #将logs-volume挂载到nginx容器中,对应的目录为 /var/log/nginx
    - name: logs-volume
      mountPath: /var/log/nginx
      subPath: log1  # 在logs-volume里建立子目录 用于隔离不同容器存储的数据
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","tail -f /logs/access.log"] #初始化命令,动态读取指定文件中内容
    volumeMounts: # 将logs-volume挂载到容器对应目录 /logs
    - name: logs-volume
      mountPath: /logs
      subPath: log2
  volumes: #声明数据卷 volume, name为数据卷名 类型为emptyDir
  - name: logs-volume
    emptyDir: {}

HostPath: 可将数据持久化到主机,绑定到主机的目录上,数据存储在node节点

apiVersion: v1
kind: Pod
metadata:
  name: volume-hostpath
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: #设置容器暴露端口
    - name: nginx-port #设置暴露端口名 唯一
      containerPort: 80  #暴露端口 pod内唯一
      protocol: TCP
    volumeMounts: #将logs-volume挂载到nginx容器中,对应的目录为 /var/log/nginx
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","tail -f /logs/access.log"] #初始化命令,动态读取指定文件中内容
    volumeMounts: # 将logs-volume挂载到容器对应目录 /logs
    - name: logs-volume
      mountPath: /logs
  volumes: #声明数据卷 volume, name为数据卷名 类型为hostPath
  - name: logs-volume
    hostPath:
      path: /root/logs
      type: DirectoryOrCreate #目录存在就使用不存在就创建后使用

type类型说明:
DirectoryOrCreate :目录存在就使用 不存在创建在使用
Directory: 目录必须存在
File: 文件必须存在
Socket : unix 套接字必须存在
CharDevice 字符设备必须存在
BlockDevice 块设备必须存在

NFS : 网络文件存储系统,可以搭建一台NFS服务器 将pod上的数据直接挂载到NFS上 可实现共享数据存储 解决HostPath只能存储在pod所在节点的问题

#安装nfs服务 提供nfs服务的主机
yum install nfs-utils -y
#准备共享目录
mkdir /root/data/nfs -pv
#将共享目录以可读可写的权限暴露给192.168.140.0/24网段中所有主机
#nfs默认读取配置文件
vim /etc/exports
#增加配置 给这个网段主机增加读写权限 不需要root登录
/root/data/nfs     192.168.140.0/24 (rw,no_root_squash)
#启动nfs服务
systemctl start nfs
#所有需要加入nfs的节点都要安装nfs 不需要启动nfs
yum install nfs-utils -y

创建pod

apiVersion: v1
kind: Pod
metadata:
  name: volume-nfs
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: #设置容器暴露端口
    - name: nginx-port #设置暴露端口名 唯一
      containerPort: 80  #暴露端口 pod内唯一
      protocol: TCP
    volumeMounts: #将logs-volume挂载到nginx容器中,对应的目录为 /var/log/nginx
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","tail -f /logs/access.log"] #初始化命令,动态读取指定文件中内容
    volumeMounts: # 将logs-volume挂载到容器对应目录 /logs
    - name: logs-volume
      mountPath: /logs
  volumes: #声明数据卷 volume, name为数据卷名 类型为hostPath
  - name: logs-volume
    nfs:
      server: 192.168.140.3 #nfs服务器地址
      path: /root/data/nfs  #共享文件路径

configmap 存储配置信息 直接把配置文件挂载到容器中 容器可直接访问此配置信息

apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap
  namespace: test
data: #配置内容  键值对形式
  info: | #键 下边都是值 也就是直接存储的数据
    username: admin
    password: 123456

对应pod

apiVersion: v1
kind: Pod
metadata:
  name: pod-configmap
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    volumeMounts: # 将configmap挂载到目录
    - name: config
      mountPath: /configmap/config
  volumes: # 引用configmap
  - name: config
    configMap:
      name: configmap #对应configmap名称
#查看配置
kubectl describe cm -n test
#还可动态修改配置信息 自动更新无需重启pod
kubectl edit cm configmap -n test
#进入pod查看配置
kubectl exec -it pod-configmap -n test /bin/sh

可以从configMap数据生成环境变量
pod内设置

#使用configmap创建环境变量
apiVersion: v1
kind: Pod
metadata:
  name: cm-test-pod
spec:
  restartPolicy: Never
  containers:
  - name: cm-test
    image: busybox
    command: ["/bin/sh", "-c", "env | grep APP"]
    env:
    - name: APPLOGLEVEL
      valueFrom:
        configMapKeyRef:
          name: cm-appconfig #使用的configmap名称
          key: apploglevel  #configmap中定义的key
    - name: APPDATADIR
      valueFrom:
        configMapKeyRef:
          name:  cm-appconfig #使用的configmap名称
          key: appdatadir #configmap中定义的key

configMap的yaml

#pod使用config-map里的数据设置env
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appconfig
data: #配置内容  键值对形式
  apploglevel: info
  appdatadir: /var/logs

从Kubernetes v1.6开始,引入了一个新的字段 envFrom ,实现在Pod环境内将ConfigMap(也可用于Secret资源对象)中所定义的key=value自动生成为环境变量

#envFrom 直接生成环境变量
apiVersion: v1
kind: Pod
metadata:
  name: cm-envfrom-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: cm-appconfig
  restartPolicy: Never

容器获取pod信息方式

#容器内获取pod信息,即容器内获取yaml文件配置信息
apiVersion: v1
kind: Pod
metadata:
 name: dapi-envars-fieldref
spec:
 containers:
  - name: test-container
    image: busybox
    command: ["sh", "-c"]
    args:
    - while true; do
        echo -en '\n';
        printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
        printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
        sleep 10;
      done;
    env:
     - name: MY_NODE_NAME
       valueFrom:
        fieldRef:
         fieldPath: spec.nodeName
     - name: MY_POD_NAME
       valueFrom:
         fieldRef:
          fieldPath: metadata.name
     - name: MY_POD_NAMESPACE
       valueFrom:
        fieldRef:
         fieldPath: metadata.namespace
     - name: MY_POD_IP
       valueFrom:
        fieldRef:
         fieldPath: status.podIP
     - name: MY_POD_SERVICE_ACCOUNT
       valueFrom:
        fieldRef:
         fieldPath: spec.serviceAccountName
 restartPolicy: Never

容器内获取容器配置信息 通过DownwardAPI 获取

#通过DownwardAPI 将容器信息设置为环境变量
apiVersion: v1
kind: Pod
metadata:
 name: dapi-envars-resourcefieldref
spec:
 containers:
  - name: test-container
    image: busybox
    command: ["sh", "-c"]
    args:
    - while true; do
        echo -en '\n';
        printenv MY_CPU_REQUEST MY_CPU_LIMIT;
        printenv MY_MEM_REQUEST MY_MEM_LIMIT;
        sleep 10;
      done;
    resources:
     requests:
      memory: "32Mi"
      cpu: "125m"
     limits:
      memory: "64Mi"
      cpu: "250m"   
    env:
     - name: MY_CPU_REQUEST
       valueFrom:
        resourceFieldRef:
         containerName: test-container
         resource: requests.cpu
     - name: MY_CPU_LIMIT
       valueFrom:
        resourceFieldRef:
         containerName: test-container
         resource: limits.cpu
     - name: MY_MEM_REQUEST
       valueFrom:
        resourceFieldRef:
         containerName: test-container
         resource: requests.memory   
     - name: MY_MEM_LIMIT
       valueFrom:
        resourceFieldRef:
         containerName: test-container
         resource: limits.memory     
 restartPolicy: Never

**通过volume挂载方式 downwardAPI获取容器和pod配置信息 **

#通过DownwardAPI 将容器和pod信息挂载到容器内部
apiVersion: v1
kind: Pod
metadata:
 name: dapi-volume-resourcefieldref
 labels:
  zone: us-est-coast
  cluster: test-cluster1
  rack: rack-22
 annotations:
  build: two
  builder: john-doe 
spec:
 containers:
  - name: test-container
    image: busybox
    resources:
     requests:
      memory: "32Mi"
      cpu: "125m"
     limits:
      memory: "64Mi"
      cpu: "250m"   
    command: ["sh", "-c"]
    args:
    - while true; do
        echo -en '容器在运行\n';
        sleep 10;
      done;
    volumeMounts:
     - name: podinfo
       mountPath: /etc/podinfo
 volumes:
  - name: podinfo
    downwardAPI:
     items:  # 根据items的path生成文件 使用items 可以自定义目录名 否则以KEY为文件名 绑定到容器目录里 configMap也如此使用
      - path: "labels"  #path 自定义文件名路径名
        fieldRef:  #绑定pod信息
         fieldPath: metadata.labels
      - path: "annotations"
        fieldRef:
         fieldPath: metadata.annotations
      - path: "cpu_limit"
        resourceFieldRef:
         containerName: test-container
         resource: limits.cpu
 restartPolicy: Never

secret密文形式存储敏感信息通过base64编码存储 容器访问时会自动解码用法与configmap类似
创建base64加密字符串

echo 'admin' | base64
echo '123456' | base64

创建secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: secret
type: Opaque
data:
  username: YWRtaW4=
  password: MTIzNDU2

查看

#查看
k get secret
#查看详细
k describe secret secret

pod引用

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    volumeMounts:
    - name: secret-config
      mountPath: /secret/config
  volumes:
  - name: secret-config
    secret:
      secretName: secret #对应secret名

查看

#进入pod查看 pod会自动解码base64
k exec -it pod-secret bash

高级存储(静态pv) 使用pv :pv是存储的抽象
pod直接绑定pv pv 在绑定nfs 让用户与底层存储隔离
还可以设置pod使用资源大小

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:
    storage: 3Gi   #该volume的总容量
  accessModes:
  - ReadWriteMany # 该volume可以被多个node上的pod挂载使用且都具有读写权限
  persistentVolumeReclaimPolicy: Retain #该valume使用后被release之后的回收策略 也就是说pod被删除后的回收数据策略
  nfs:
    path: /root/data/nfs
    server: 192.168.140.3

#查看pv
kubectl get pv -o wide

pvc 就是pod对pv的申请使用 系统自动匹配通过pvc申请空间的大小来匹配pv

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1
  namespace: test
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi  #需要使用容量大小
#查看pvc
kubectl get pvc -n test

pod 挂载到pvc

apiVersion: v1
kind: Pod
metadata:
  name: volume-pvc
  namespace: test
spec:
  containers:
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","while true;do echo pod1 >> /root/out.txt;sleep 10;done;"] #初始化命令,动态读取指定文件中内容
    volumeMounts: # 将volume挂载到容器对应目录
    - name: volume
      mountPath: /root/
  volumes: #声明数据卷 volume, name为数据卷名 类型为pvc
  - name: volume
    persistentVolumeClaim:
      claimName: pvc1 #挂载的pvc名称
      readOnly: false  #是否只读

动态创建pv 通过创建StorageClass就像动态创建PV的模板,为创建pv对象提供必要的参数
要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner(制备器),这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

注意:StorageClass一旦被创建,就无法修改,如需修改,只能删除重建
先kubectl delete -f storage-class.yaml 在创建
storageClass模板

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: csi-disk
# (存储分配器):用来决定使用哪个卷插件分配 PV,该字段必须指定。
可以指定内部分配器,也可以指定外部分配器指 定使用什么分配器来分配存储空间 由于使用minikube环境 所有使用minikube字段分配器 分配本地磁盘
provisioner: k8s.io/minikube-hostpath
# 卷绑定模式:该volumeBindingMode字段控制何时应该发生卷绑定和动态配置。未设置时,默认使用“立即”模式。
# 该Immediate模式指示一旦创建 PersistentVolumeClaim,就会发生卷绑定和动态供应。对于拓扑受限且无法从集群中的所有节点全局访问的存储后端,将在不知道 Pod 调度要求的情况下绑定或配置 PersistentVolume。这可能会导致不可调度的 Pod。
# 集群管理员可以通过指定模式来解决此问题,该WaitForFirstConsumer模式将延迟 PersistentVolume 的绑定和配置,直到创建使用 PersistentVolumeClaim 的 Pod。PersistentVolume 将根据 Pod 的调度约束指定的拓扑进行选择或配置
# 默认使用Immediate
volumeBindingMode: Immediate

# 回收策略
# Retain – 手动回收
# Recycle – 需要擦除后才能再次使用
# Delete – 当用户删除对应的 PersistentVolumeClaim 时,动态配置的 volume 将被自动删除
reclaimPolicy: Delete

基于nfs的storageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
  archiveOnDelete: "false" #删除pv的时候,pv的内容是否要备份

查看命令:

#创建
k apply -f storage-class.yaml
#查看
k get storageclass
#简写
k get sc
#查看详情
k describe storageclass csi-disk

创建pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: disk-pvc
spec:
 accessModes:
 - ReadWriteOnce
 resources:
  requests:
   storage: 25Gi
 storageClassName: csi-disk #使用storageClass模板创建pv

创建pod

apiVersion: v1
kind: Pod
metadata:
  name: storage-pod
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.79
    ports:
    - containerPort: 80
    volumeMounts:
    - name: disk-pvc
      mountPath: /data
  volumes:
  - name: disk-pvc
    persistentVolumeClaim:
      claimName: disk-pvc #指定pvc名称

以上是通过minikube制备器创建的storageClass
下边是完整的 基于nfs创建的storageClass示例:

  1. 创建Service Account,这是用来管控NFS Provisioner 在k8s集群中运行的权限
    rbac方式认证,授权 这里主要测试storageclass 直接 给Provisioner 以最高权限cluster-admin权限
# rbac.yaml:#唯一需要修改的地方只有namespace,根据实际情况定义
apiVersion: v1
kind: ServiceAccount #  创建一个账户,主要用来管理NFS provisioner在k8s集群中运行的权限
metadata:
  name: nfs-client-provisioner
  namespace: default
---
kind: ClusterRoleBinding # 集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects: # 角色绑定对象
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole # 哪个角色
  name: cluster-admin #k8s集群中最高权限的角色
  apiGroup: rbac.authorization.k8s.io

2.创建storageClass 跟 创建NFS provisioner(制备器)

# nfs-provisioner.yaml
# 先创建NFS provisioner
apiVersion: apps/v1
kind: Deployment # 部署nfs-client-provisioner
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  namespace: default #与RBAC文件中的namespace保持一致
spec:
  replicas: 1
  strategy: # 指定更新策略 执行删除完毕一个创建一个
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner # 指定serviceAccount!
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest #镜像地址
          volumeMounts: # 挂载数据卷到容器指定目录
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME # 配置provisioner的Name
              value: diy-nfs-storage # 确保该名称与 StorageClass 资源中的provisioner名称保持一致
            - name: NFS_SERVER #绑定的nfs服务器
              value: 192.168.140.131
            - name: NFS_PATH   #绑定的nfs服务器目录
              value: /root/data/nfs #上边安装nfs服务器时的共享目录
      volumes: # 申明nfs数据卷
        - name: nfs-client-root
          nfs:
            server: 192.168.140.131
            path: /root/data/nfs #上边安装nfs服务器时的共享目录

在创建strageClass

# 创建NFS资源的StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass # 创建StorageClass
metadata:
  name: managed-nfs-storage
provisioner: diy-nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
parameters:  
   archiveOnDelete: "false"

3.创建pod,申请PVC进行测试

# 申明一个PVC,指定StorageClass
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
 # annotations: #如果低版本使用注解绑定
    # 通过annotations注解,和storage-class进行关联,为什么不使用storageClassName,因为版本比较低
    # 这里指定的名字就是上面创建的StorageClass的名字,让它帮我们创建PV
    #volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi
  storageClassName: managed-nfs-storage	  #绑定storageClass

如果pvc一直pending状态 查看制备器pod 报如下异常

k logs -f nfs-client-provisioner-6fb86fbbbc-72j7g
E0905 15:08:26.103331       1 controller.go:1004] provision "default/test-claim" class "managed-nfs-storage": unexpected error getting claim reference: selfLink was empty, can't make reference

原因如下:
如果是 v1.20 版本以上 apiserver 默认禁止使用 selfLink,需要手动配置- --feature-gates=RemoveSelfLink=false 开启。

修改kube-apiserver.yaml 文件:

[root@master nfs]# cat /etc/kubernetes/manifests/kube-apiserver.yaml
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=192.168.25.100
    - --feature-gates=RemoveSelfLink=false   # 添加这条信息
    - --allow-privileged=true

systemctl restart kubelet重启 kubelet 服务,然后查看 PVC,PV 信息,可以看到 PVC 申领 PV 卷成功。
注意: 如果不成功,仍然报这个错

可以使用 kubectl get pod -n kube-system 查看 kube-apiserver 是否启动成功
创建pod测试

apiVersion: v1
kind: Pod
metadata:
  name: storage-pod
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nfs-pvc
      mountPath: /var/log/nginx
  volumes:
  - name: nfs-pvc
    persistentVolumeClaim:
      claimName: test-claim #指定pvc名称
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值