当前位置: 首页 > news >正文

c2c网站的主要功能wordpress页面文章

c2c网站的主要功能,wordpress页面文章,搜索引擎seo关键词优化方法,搜索引擎优化指的是第七章 Kubernetes存储 1、数据卷与数据持久卷 为什么需要数据卷#xff1f; 容器中的文件在磁盘上是临时存放的#xff0c;这给容器中运行比较重要的应用程序带来一些问题。 问题1#xff1a;当容器升级或者崩溃时#xff0c;kubelet会重建容器#xff0c;容器内文件会…第七章 Kubernetes存储 1、数据卷与数据持久卷 为什么需要数据卷 容器中的文件在磁盘上是临时存放的这给容器中运行比较重要的应用程序带来一些问题。 问题1当容器升级或者崩溃时kubelet会重建容器容器内文件会丢失 问题2一个Pod中运行多个容器并需要共享文件 Kubernetes 卷Volume 这一抽象概念能够解决这两个问题。 1. 数据持久化 容器的无状态性Kubernetes 中的容器是无状态的这意味着它们在重启或重新调度时容器内的数据会丢失。持久化数据通过使用数据卷可以将数据持久化到外部存储系统中确保数据在容器生命周期外仍然存在。 2. 数据共享 多容器共享数据在某些情况下同一个 Pod 中的多个容器需要共享数据。数据卷允许这些容器共享同一个存储卷。跨容器协作例如一个容器生成日志文件另一个容器需要读取这些日志文件。 3. 数据隔离 独立存储不同的 Pod 可以使用不同的数据卷确保数据隔离避免数据冲突。安全性通过将敏感数据存储在独立的数据卷中可以提高安全性。 4. 简化配置 统一管理使用数据卷可以简化应用程序的配置因为存储配置可以在 Kubernetes 中集中管理。灵活性可以根据需要选择不同的存储后端如本地存储、云存储、网络文件系统等而不需要修改应用程序代码。 5. 生命周期管理 数据生命周期数据卷可以独立于 Pod 的生命周期管理确保数据在 Pod 重启或删除后仍然可用。自动挂载Kubernetes 可以自动挂载和卸载数据卷简化操作。 常用的数据卷 官网Volumes | Kubernetes 节点本地存储hostPathemptyDir网络存储NFSCephGlusterFS公有云存储AWS EBSK8S资源存储configmapsecret 1.1 临时数据卷emptyDir emptyDir卷是一个临时存储卷与Pod生命周期绑定一起如果 Pod删除了卷也会被删除。 应用场景Pod中容器之间数据共享 选项 sizeLimit500Mi       //限制共享空间大小比较少用 示例Pod内容器之间共享数据 apiVersion: v1 kind: Pod metadata: name: emptydir-test spec:containers:- name: write-container //程序讲数据写入到文件image: centoscommand: [bash,-c,for i in {1..100};do echo $i /data/hello;sleep 1;done]volumeMounts:- name: data-volume //通过volume卷名称引用mountPath: /data- name: read-container //程序从文件中读取数据image: centoscommand: [bash,-c,tail -f /data/hello]volumeMounts:- name: data-volumemountPath: /datavolumes: //定义卷的来源- name: data-volumeemptyDir: {} //{}中为空值 验证1验证容器之间是否能够共享数据 [rootk8s-master-1-71 ~]# kubectl apply -f emptydir-test.yaml [rootk8s-master-1-71 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE emptydir-test 2/2 Running 1 (21s ago) 3m14s # 进入write-container查看 [rootk8s-master-1-71 ~]# kubectl exec -it emptydir-test -- bash[rootemptydir-test /]# tail -f /data/hello ... 99 100 command terminated with exit code 137 [rootemptydir-test /]# touch /data/aaa ; ls /data/ //往容器中写入临时文件 aaa hello## 注脚本循环结束后退出容器按照默认的策略Always进行容器重启。 # 进入read-container查看 [rootk8s-master-1-71 ~]# kubectl exec -it emptydir-test -c read-container -- bash [rootemptydir-test /]# ls /data/ aaa hello 验证2实际存储位置基于节点的存储 补充Kubelet的工作目录为/var/lib/kubelet/负载维护Pod数据的 [rootk8s-master-1-71 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES emptydir-test 2/2 Running 2 (45s ago) 5m3s 10.244.114.48 k8s-node2-1-73 none none# 根据查看到的Pod所在节点找到相应的容器ID [rootk8s-node2-1-73 ~]# docker ps | grep emptydir-test例如7c26307b-b290-4bac-9a3b-6f18ffc26776 6deb6dc27ab2 centos bash -c for i in {… 44 seconds ago Up 43 seconds k8s_write-container_emptydir-test_default_7c26307b-b290-4bac-9a3b-6f18ffc26776_3 7bb46657087b centos bash -c tail -f /d… 7 minutes ago Up 7 minutes k8s_read-container_emptydir-test_default_7c26307b-b290-4bac-9a3b-6f18ffc26776_0 fd4c6c671807 registry.aliyuncs.com/google_containers/pause:3.7 /pause 7 minutes ago Up 7 minutes k8s_POD_emptydir-test_default_7c26307b-b290-4bac-9a3b-6f18ffc26776_0# 找到相关Pod关联的empty-dir目录即可看到挂载的empty-dir目录内容 [rootk8s-node2-1-73 kubernetes.io~empty-dir]# pwd /var/lib/kubelet/pods/7c26307b-b290-4bac-9a3b-6f18ffc26776/volumes/kubernetes.io~empty-dir[rootk8s-node2-1-73 kubernetes.io~empty-dir]# ls data-volume/ aaa bbb hello Pod是节点级别的Pod中的容器都是捆绑在一个节点上所以 Pod删除了卷也会被删除 [rootk8s-master-1-71 ~]# kubectl delete -f emptydir-test.yaml [rootk8s-node2-1-73 kubernetes.io~empty-dir]# ls data-volume/ ls: 无法访问data-volume/: 没有那个文件或目录1.2 节点数据卷hostPath hostPath卷挂载Node的文件系统即Pod所在节点上文件或者目 录到Pod中的容器。 应用场景Pod中容器需要访问宿主机的文件 选项 path:    //将宿主机的目录或文件映射到容器中去 type:    //指定类型目录或文件 示例将宿主机/tmp目录挂载到容器/data目录 apiVersion: v1 kind: Pod metadata:name: hostpath-test spec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 36000volumeMounts:- name: data-volumemountPath: /datavolumes:- name: data-volumehostPath:path: /tmp //Pod所在节点的/tmp目录type: Directory 验证 [rootk8s-master-1-71 ~]# kubectl apply -f hostpath-test.yaml[rootk8s-master-1-71 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES hostpath-test 1/1 Running 0 86s 10.244.114.49 k8s-node2-1-73 none none# 查看Pod所在节点的/tmp目录 [rootk8s-node2-1-73 ~]# ls /tmp/ systemd-private-85c79618aae44d7cbb01bccc046ecb10-chronyd.service-UMOhQf systemd-private-fdf2b8d40ff841319feb738a463a8f6f-chronyd.service-GJT2Mn# 进入容器查看/data目录是否有相关映射文件 [rootk8s-master-1-71 ~]# kubectl exec -it hostpath-test -- sh / # ls /data/ systemd-private-85c79618aae44d7cbb01bccc046ecb10-chronyd.service-UMOhQf systemd-private-fdf2b8d40ff841319feb738a463a8f6f-chronyd.service-GJT2Mn1.3 网络数据卷NFS NFS是一个主流的文件共享服务器注每个Node上都要安装nfs-utils包 # 服务端部署 [rootk8s-node1-1-72 ~]# yum install -y nfs-utils [rootk8s-node1-1-72 ~]# vi /etc/exports //NFS共享配置目录 /ifs/kubernetes *(rw,no_root_squash) # 解释 共享目录 访问来源限制权限 [rootk8s-node1-1-72 ~]# mkdir -p /ifs/kubernetes[rootk8s-node1-1-72 ~]# systemctl enable nfs --now# 客户端测试 [rootk8s-node2-1-73 ~]# yum install -y nfs-utils [rootk8s-node2-1-73 ~]# mount -t nfs 192.168.1.72:/ifs/kubernetes /mnt [rootk8s-node2-1-73 ~]# df -Th | grep /ifs/kubernetes 192.168.1.72:/ifs/kubernetes nfs4 37G 4.3G 33G 12% /mntNFS卷提供对NFS挂载支持可以自动将NFS共享路径 挂载到Pod中 选项 server: //指定NFS地址 path: /指定NFS共享目录 示例将Nginx网站程序根目录持久化到 NFS存储为多个Pod提供网站程序文件 apiVersion: apps/v1 kind: Deployment metadata:labels:app: nfs-podname: nfs-pod spec:selector:matchLabels:app: nginxreplicas: 3template:metadata:labels:app: nginxspec:containers:- name: webimage: nginxvolumeMounts:- name: data-volumemountPath: /usr/share/nginx/html //挂载的目录volumes:- name: data-volume //volume卷名称nfs:server: 192.168.1.72 //指定NFS地址path: /ifs/kubernetes //NFS共享目录验证1容器之间的数据是否共享 [rootk8s-node2-1-73 ~]# kubectl apply -f nfs-pod.yaml [rootk8s-master-1-71 ~]# kubectl get pods NAME READY STATUS RESTARTS AGEnfs-pod-9b57f886-d8rzx 1/1 Running 0 10m nfs-pod-9b57f886-tk99z 1/1 Running 0 55s nfs-pod-9b57f886-wpr9q 1/1 Running 0 10m# 进入容器1创建文件测试 [rootk8s-node2-1-73 ~]# kubectl exec -it nfs-pod-9b57f886-d8rzx -- bash rootnfs-pod-9b57f886-d8rzx:/# df -Th |grep /ifs/kubernetes 192.168.1.72:/ifs/kubernetes nfs4 37G 4.3G 33G 12% /usr/share/nginx/html rootnfs-pod-9b57f886-d8rzx:~# touch /usr/share/nginx/html/aaaaa rootnfs-pod-9b57f886-d8rzx:~# ls /usr/share/nginx/html/ aaaaa# 进入容器2查看文件 [rootk8s-node2-1-73 ~]# kubectl exec -it nfs-pod-9b57f886-tk99z -- bash rootnfs-pod-9b57f886-tk99z:/# ls /usr/share/nginx/html/ aaaaa验证2增加/删除Pod是否能继续使用共享存储数据 # 删除Pod查看是否能继续使用共享存储数据 [rootk8s-master-1-71 ~]# kubectl delete pod nfs-pod-9b57f886-tk99z[rootk8s-master-1-71 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE nfs-pod-9b57f886-d8rzx 1/1 Running 0 10m nfs-pod-9b57f886-fg7n7 1/1 Running 0 55s //新增Pod nfs-pod-9b57f886-wpr9q 1/1 Running 0 10m[rootk8s-node2-1-73 ~]# kubectl exec -it nfs-pod-9b57f886-fg7n7 -- bash rootnfs-pod-9b57f886-fg7n7:/# ls /usr/share/nginx/html/ aaaaa# 增加Pod查看是否能继续使用共享存储数据 [rootk8s-master-1-71 ~]# kubectl scale deployment nfs-pod --replicas5 [rootk8s-node2-1-73 ~]# kubectl exec -it nfs-pod-9b57f886-sj7m6 -- bash rootnfs-pod-9b57f886-sj7m6:/# df -Th | grep /ifs/kubernetes 192.168.1.72:/ifs/kubernetes nfs4 37G 4.3G 33G 12% /usr/share/nginx/html rootnfs-pod-9b57f886-sj7m6:/# ls /usr/share/nginx/html/ aaaaa1.4 持久数据卷概述 持久卷Persistent Volumes, PV 是用于管理存储的重要概念。 安全性如果要设置安全方面的认证都需要提前将安全配置写入YAML因此将会暴露在YAML文件中导致安全性减低 专业性在应用的部署上使用者对K8S、存储的不了解对于建设者来说倡导职责上的分离。 1.4.1 PV、PVC 持久卷Persistent Volumes, PV 定义持久卷是集群中的一块存储由管理员配置和管理。它们独立于 Pod 的生命周期可以被多个 Pod 使用。生命周期持久卷的生命周期独立于 Pod即使 Pod 被删除数据仍然保留。 对存储资源创建和使用的抽象使得存储作为集群中的资源管理定义后端存储 持久卷声明Persistent Volume Claims, PVC 定义持久卷声明是用户对持久卷的请求。用户不需要了解底层存储的细节只需要声明所需的存储大小和访问模式。生命周期持久卷声明的生命周期与 Pod 的生命周期无关可以独立存在。绑定持久卷声明会被绑定到一个满足其请求的持久卷上。一旦绑定PVC 和 PV 之间是一对一的关系。 让用户不需要关心具体的Volume实现细节访问模式、存储容量大小 Pod申请PVC作为卷来使用Kubernetes通过PVC查找绑定的PV并Mount给Pod。 支持持久卷的存储插件Persistent Volumes | Kubernetes 1.4.2 PV与PVC使用流程 官网配置 Pod 以使用 PersistentVolume 作为存储 | Kubernetes PVC配置示例 --- //容器应用 apiVersion: apps/v1 kind: Deployment metadata: labels:app: my-podname: my-pod spec:selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: webimage: nginxvolumeMounts:- name: data-volumemountPath: /usr/share/nginx/html //挂载的目录volumes:- name: data-volumepersistentVolumeClaim:claimName: my-pvc--- //PVC 卷需求模板 apiVersion: v1 kind: PersistentVolumeClaim metadata:name: my-pvc //与claimName对应进行关联 spec:accessModes:- ReadWriteManyresources:requests:storage: 5Gi 查看PVC命令kubectl get pvc [rootk8s-master-1-71 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE my-pod-6fbc98b678-42m29 0/1 Pending 0 10s [rootk8s-master-1-71 ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-pvc Pending 18s注意如果没有可用的PVPVC无法进行资源分配会处于在Pending状态 PV配置示例 apiVersion: v1 kind: PersistentVolume metadata:name: my-pv //随便定义 spec:capacity:storage: 5Gi //后端存储定义资源accessModes:- ReadWriteManynfs:path: /ifs/kubernetesserver: 192.168.1.72 查看PV命令kubectl get pv [rootk8s-master-1-71 ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE my-pv 5Gi RWX Retain Bound default/my-pvc 11s [rootk8s-master-1-71 ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-pvc Bound my-pv 5Gi RWX 2m30s [rootk8s-master-1-71 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE my-pod-6fbc98b678-42m29 1/1 Running 0 3m5s测试 [rootk8s-master-1-71 ~]# kubectl exec -it my-pod-6fbc98b678-42m29 -- bash rootmy-pod-6fbc98b678-42m29:/# df -Th | grep /ifs/kubernetes 192.168.1.72:/ifs/kubernetes nfs4 37G 4.3G 33G 12% /usr/share/nginx/html rootmy-pod-6fbc98b678-42m29:/# ls /usr/share/nginx/html/ aaaaa 思考多PV配置 挂载PV的时候不能将挂载点挂到同一目录为保证应用的唯一性需要在挂载点的节点上创建各自的目录避免冲突 多PV配置示例 apiVersion: v1 kind: PersistentVolume metadata:name: pv001 //随便定义 spec:capacity:storage: 5Gi //后端存储定义资源accessModes:- ReadWriteManynfs:path: /ifs/kubernetes/pv001server: 192.168.1.72 --- apiVersion: v1 kind: PersistentVolume metadata:name: pv002 //随便定义 spec:capacity:storage: 15Gi //后端存储定义资源accessModes:- ReadWriteManynfs:path: /ifs/kubernetes/pv002server: 192.168.1.72 总结 1、PV与PVC怎么匹配 主要根据PVC的存储容量和访问模式进行匹配 2、存储容量怎么匹配 容量只会向上匹配如已有未使用PV有10G、20G申请5G向上取最近的PV容量10G 3、PV与PVC的关系 一对一存在绑定关系 4、容量请求是否有实际的限制 目前容量请求主要用作于PVC与PV进行匹配的只是抽象的存在而具体的限制取决于后端存储即请求容量不能超过共享存储的实际容量 1.4.3 PV 生命周期 1AccessModes访问模式 AccessModes 是用来对 PV 进行访问模式的设置用于描述用户应用对存储资源的访问权限访问权限包括下面几种方式 ReadWriteOnceRWO读写权限但是只能被单个节点挂载 ReadOnlyManyROX只读权限可以被多个节点挂载 ReadWriteManyRWX读写权限可以被多个节点挂载 备注块存储单节点、文件系统、对象存储多节点 2RECLAIM POLICY回收策略 目前 PV 支持的策略有三种 Retain保留 保留数据需要管理员手工清理数据默认策略 Recycle回收清除 PV 中的数据效果相当于执行 rm -rf /ifs/kuberneres/*一般结合StorageClass使用NFS暂时无法看出效果 Delete删除与 PV 相连的后端存储同时删除一般结合StorageClass使用NFS暂时无法看出效果 persistentVolumeReclaimPolicy: 回收策略 3STATUS状态 一个 PV 的生命周期中可能会处于4中不同的阶段 Available可用表示可用状态还未被任何 PVC 绑定 Bound已绑定表示 PV 已经被 PVC 绑定 Released已释放PVC 被删除但是资源还未被集群重新声明 Failed失败 表示该 PV 的自动回收失败 示例观察回收状态和默认的Retain回收策略 [rootk8s-master-1-71 ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE my-pv 5Gi RWX Retain Bound default/my-pvc 7h7m## 解释目前回收策略为 Retain 状态为 Bound表示 PV 已经被 PVC 绑定 [rootk8s-master-1-71 ~]# kubectl delete -f my-pvc.yaml [rootk8s-master-1-71 ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE my-pv 5Gi RWX Retain Released default/my-pvc 7h18m## 解释连着删除Pod和PCV后回收策略为 Retain 状态为 ReleasedPVC 被删除但是资源还未被集群重新声明 [rootk8s-node1-1-72 ~]# ls /ifs/kubernetes/ //PV中的资源依旧保留需要管理员手工清理数据 aaaaa 注意删除PVC后原来Bound的PV就无法继续使用即使重新apply pvc.yaml也是Pending状态。 思考现在PV使用方式称为静态供给需要K8s运维工程师提前创 建一堆PV供开发者使用 1.5 PV 动态供给StorageClass PV静态供给明显的缺点是维护成本太高了需要提前创建PV且不灵活 因此K8s开始支持PV动态供给使用StorageClass对象实现。StorageClass可以根据客户的PVC需求通过PVC需求自动创建后端存储PV且自动去绑定无需像NFS还要创建目录隔离应用。 优点 PV无需额外的提前独立创建 PVC直接获取也不用等待合适的PV 支持动态供给的存储插件Storage Classes | Kubernetes 相关GitHub部署https://github.com/kubernetes-sigs/sig-storage-lib-external-provisioner 了解Volume Plugin是支持存储的类型Internal Provisioner内部是否支持 例如NFS内部是不支持的不能直接PVC动态供给且K8s默认不支持NFS动态供给需要单独部署社区开发的插件 项目地址https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner 部署StorageClass插件需要的3个文件 cd deploy kubectl apply -f rbac.yaml # 授权访问apiserver kubectl apply -f deployment.yaml # 部署插件需修改里面NFS服务器地址与共享目录 kubectl apply -f class.yaml # 创建存储类(标识使用哪个存储)kubectl get sc # 查看存储类补充一个集群中可以有多个存储类而一个存储类一般对应一个存储 流程图 rbac.yaml 示例 [rootk8s-master-1-71 nfs-external-provisioner]# cat 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: [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.ioclass.yaml 配置示例 [rootk8s-master-1-71 nfs-external-provisioner]# cat class.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:name: managed-nfs-storage //StroagaClass存储类在PVC中需要指定的标识类似ingressclass选择Nginx provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployments env PROVISIONER_NAME //与Deployment的变量PROVISIONER_NAME保持一致 parameters:archiveOnDelete: false deployment.yaml 配置示例 [rootk8s-master-1-71 nfs-external-provisioner]# cat deployment.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: 1strategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisioner //部署了NFS供给程序的容器image: lizhenliang/nfs-subdir-external-provisioner:v4.0.1 //镜像地址volumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAME //class.yaml中的PROVISIONER_NAMEvalue: k8s-sigs.io/nfs-subdir-external-provisioner- name: NFS_SERVERvalue: 192.168.1.72 //需要指定后端NFS存储- name: NFS_PATHvalue: /ifs/kubernetesvolumes:- name: nfs-client-rootnfs:server: 192.168.1.72 //需要指定后端NFS存储path: /ifs/kubernetes PVC指定存储类配置示例 --- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: my-pvc spec:storageClassName: managed-nfs-storage //指定StorageClass存储类class.yamlaccessModes:- ReadWriteMany resources:requests:storage: 5Gi测试1基于NFS提供PVC动态供给 步骤1部署NFS-StorageClass 存储类插件 [rootk8s-master-1-71 nfs-external-provisioner]# kubectl apply -f . storageclass.storage.k8s.io/managed-nfs-storage created deployment.apps/nfs-client-provisioner created 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 role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created# 创建的Pod为deployment.yaml中的NFS供给程序容器 [rootk8s-master-1-71 nfs-external-provisioner]# kubectl get pods NAME READY STATUS RESTARTS AGEnfs-client-provisioner-5848c9cddc-zkts2 1/1 Running 0 2m27s# 创建的storageclass为class.yaml中指定的存储类 [rootk8s-master-1-71 nfs-external-provisioner]# kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE managed-nfs-storage k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 2m54s步骤2在PVC中指定存储类名称 [rootk8s-master-1-71 ~]# kubectl apply -f my-pvc.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: my-podname: my-pod spec:selector:matchLabels:app: my-podtemplate:metadata:labels:app: my-podspec:containers:- name: my-podimage: nginxvolumeMounts:- name: data-volumemountPath: /usr/share/nginx/htmlvolumes:- name: data-volumepersistentVolumeClaim:claimName: my-pvc --- apiVersion: v1 kind: PersistentVolumeClaim metadata:name: my-pvcspec:storageClassName: managed-nfs-storageaccessModes:- ReadWriteManyresources:requests:storage: 5Gi[rootk8s-master-1-71 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE my-pod-6fbc98b678-t2gvg 1/1 Running 0 4m11s nfs-client-provisioner-5848c9cddc-zkts2 1/1 Running 0 24m[rootk8s-master-1-71 ~]# kubectl get pvc //查看PVC NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-pvc Bound pvc-51d00de4-52ea-4f1a-988a-bc3e5b7e961e 5Gi RWX managed-nfs-storage 3s[rootk8s-master-1-71 ~]# kubectl get pv //查看PV NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-51d00de4-52ea-4f1a-988a-bc3e5b7e961e 5Gi RWX Delete Bound default/my-pvc managed-nfs-storage 6s# 进入容器查看挂载 [rootk8s-master-1-71 ~]# kubectl exec -it my-pod-6fbc98b678-t2gvg -- bash rootmy-pod-6fbc98b678-t2gvg:/# df -Th | grep pvc-51d00de4-52ea-4f1a-988a-bc3e5b7e961e 192.168.1.72:/ifs/kubernetes/default-my-pvc-pvc-51d00de4-52ea-4f1a-988a-bc3e5b7e961e nfs4 37G 4.4G 33G 12% /usr/share/nginx/html # 查看NFS服务器的挂载目录可看到随机生成的PV目录 结论通过基于NFS提供PVC动态供给无需再定义单独的PV也无需为了指定到某个NFS目录手动创建子目录动态供给会自动帮忙实现PV及随机生成NFS子目录 注意由于NFS提供PVC动态供给的PV的默认回收策略是 Delete 所以在删除PVC的同时也会将PV一起删除在NFS目录上的文件也一并删除。 测试2 [rootk8s-master-1-71 ~]# kubectl apply -f my-pvc2.yaml [rootk8s-node1-1-72 ~]# ls /ifs/kubernetes/ aaaaa default-my-pvc2-pvc-b7769112-aea6-4533-9e5c-5d14cd67fc65 default-my-pvc-pvc-51d00de4-52ea-4f1a-988a-bc3e5b7e961e[rootk8s-master-1-71 ~]# kubectl delete -f my-pvc2.yaml [rootk8s-node1-1-72 ~]# ls /ifs/kubernetes/ aaaaa default-my-pvc-pvc-51d00de4-52ea-4f1a-988a-bc3e5b7e961e由于考虑数据的重要性希望删除PVC时保留数据备份 [rootk8s-master-1-71 nfs-external-provisioner]# vi class.yaml ...archiveOnDelete: True //将archiveOnDelete修改为 True即可在删除PVC时保留备份# 需要删除class.yaml并重新apply应用 [rootk8s-master-1-71 nfs-external-provisioner]# kubectl delete -f class.yaml[rootk8s-master-1-71 nfs-external-provisioner]# kubectl apply -f class.yaml # 测试删除PVC [rootk8s-master-1-71 ~]# kubectl delete -f my-pvc.yaml# 查看NFS服务器的挂载目录原来的PV目录已重新命名备份 2、有状态应用部署初探 无状态与有状态 Deployment控制器设计原则管理的所有Pod一模一样且提供同一个服务replicas使用共享存储之间没有连接关系也不考虑在哪台Node运 行可随意扩容和缩容。这种应用称为“无状态”例如Web服务 在实际的场景中这并不能满足所有应用尤其是分布式应用会部署多个实例这些实例之间往往有 依赖关系部署的角色也不一样例如主从关系、主备关系这种应用称为“有状态”例如MySQL主从、Etcd集群 无状态特点 每个Pod都一样且提供同一种服务 Pod之间没有连接关系 使用共享存储 有状态特点 每个Pod不对等角色属性也不同 Pod之间有连接关系类似数据库主从 每个Pod的数据都是有差异化的需要独立的存储进行持久化否则会产生冲突 2.1 StatefulSet 控制器介绍 StatefulSet控制器用于部署有状态应用满足一些有状态应用的需求 Pod有序的部署、扩容、删除和停止 Pod分配一个稳定的且唯一的网络标识 Pod分配一个独享的存储 2.2 StatefulSet 部署应用实践 1稳定的网络ID域名 使用 Headless Service相比普通Service只是将spec.clusterIP定义为None来维护Pod网络身份。 并且添加 serviceName: “headless-svc” 字段指定 StatefulSet控制器 要使用这个Headless Service。让StatefulSet控制器为其创建每个Pod固定的域名解析地址。 DNS解析名称statefulsetName-index.service-name .namespace-name.svc.cluster.local [rootk8s-master-1-71 ~]# kubectl create deployment stateful-pod --imagenginx [rootk8s-master-1-71 ~]# kubectl expose deployment stateful-pod --port80 --target-port80 --dry-runclient -o yaml headless-svc.yaml [rootk8s-master-1-71 ~]# kubectl apply -f headless-svc.yaml apiVersion: v1 kind: Service metadata:labels:app: headless-svcname: headless-svc spec:clusterIP: None //指定SVC的clusterIP为Noneports:- port: 80protocol: TCPtargetPort: 80selector:app: stateful-pod[rootk8s-master-1-71 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE headless-svc ClusterIP None none 80/TCP 8s补充Cluster-IP为None标识该Service为headlress无头服务这种Service将没有负载均衡转发的功能 2稳定的存储 StatefulSet的存储卷 使用VolumeClaimTemplate创建称为卷申请模板针对StatefulSet专门设置的类型当StatefulSet使用VolumeClaimTemplate创建 一个PersistentVolume时同样也会为每个Pod分配并创建一个编号的PVC一个PV对应一个PVC 参考文档StatefulSets | Kubernetes 参考https://github.com/lizhenliang/k8s-statefulset 示例StatefulSet部署包括无头服务、StatefulSet卷申请模 [rootk8s-master-1-71 ~]# kubectl apply -f statefulset-test.yaml # headless Service 服务配置示例 apiVersion: v1 kind: Service metadata:name: nginx-headless //headlessService服务名称需要和StatefulSet的ServiceName保持一致labels:app: nginx spec:ports:- port: 80name: webclusterIP: None //设置cluster-IP为Noneselector:app: nginx //指定StatefulSet的Pod# StatefulSet 配置示例 --- apiVersion: apps/v1 kind: StatefulSet metadata:name: web spec:selector:matchLabels:app: nginx # has to match .spec.template.metadata.labelsserviceName: nginx-headless # 指定 headless Service 服务名称replicas: 3 # by default is 1minReadySeconds: 10 # by default is 0template:metadata:labels:app: nginx # has to match .spec.selector.matchLabelsspec:terminationGracePeriodSeconds: 10containers:- name: nginximage: nginxports:- containerPort: 80name: webvolumeMounts:- name: www-datamountPath: /usr/share/nginx/htmlvolumeClaimTemplates: //卷申请模板为StatefulSet专门设置的类型- metadata:name: www-dataspec:accessModes: [ ReadWriteOnce ]storageClassName: managed-nfs-storage # 指定 storageClasskubectl get scresources:requests:storage: 1Gi 查看信息 [rootk8s-master-1-71 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 4m32s web-1 1/1 Running 0 3m31s web-2 1/1 Running 0 2m51s# 查看 headless Service [rootk8s-master-1-71 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-headless ClusterIP None none 80/TCP 9m52s# 查看 headless Service 对应后端的Pod [rootk8s-master-1-71 ~]# kubectl get ep NAME ENDPOINTS AGE nginx-headless 10.244.114.10:80,10.244.117.50:80,10.244.117.51:80 13m# 查看 PVC [rootk8s-master-1-71 ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-data-web-0 Bound pvc-c8f06f51-5048-4a43-b822-9f6bcd1bd20c 1Gi RWO managed-nfs-storage 10m www-data-web-1 Bound pvc-ae9c2a66-0bcb-489e-98d0-0350d480fb68 1Gi RWO managed-nfs-storage 9m37s www-data-web-2 Bound pvc-50d69a6e-d3ef-42e2-bd13-e6c954d78677 1Gi RWO managed-nfs-storage 8m57s# 查看 PV [rootk8s-master-1-71 ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAG ECLASS REASON AGE pvc-50d69a6e-d3ef-42e2-bd13-e6c954d78677 1Gi RWO Delete Bound default/www-data-web-2 manage d-nfs-storage 9m1s pvc-ae9c2a66-0bcb-489e-98d0-0350d480fb68 1Gi RWO Delete Bound default/www-data-web-1 manage d-nfs-storage 9m41s pvc-c8f06f51-5048-4a43-b822-9f6bcd1bd20c 1Gi RWO Delete Bound default/www-data-web-0 manage d-nfs-storage 10m测试网络 ① 一个普通的headless-service对应Deplyment的域名解析以及headless-service对应statefulset的域名解析② 测试 statefulset的域名 网络连通性 # 创建普通的headless-service对应Deplyment的域名解析 [rootk8s-master-1-71 ~]# kubectl create deployment web --imagenginx[rootk8s-master-1-71 ~]# kubectl expose deployment web --port80 --target-port80 --dry-runclient -o yaml test-svc.yaml [rootk8s-master-1-71 ~]# kubectl apply -f test-svc.yaml //修改 clusterIP: None [rootk8s-master-1-71 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-headless ClusterIP None none 80/TCP 30m web ClusterIP None none 80/TCP 6m45s [rootk8s-master-1-71 ~]# kubectl get ep NAME ENDPOINTS AGE nginx-headless 10.244.114.10:80,10.244.117.50:80,10.244.117.51:80 31m web 10.244.117.52:80 7m34s# 创建测试bs镜像pod [rootk8s-master-1-71 ~]# kubectl run bs --imagebusybox:1.28.4 -- sleep 24h [rootk8s-master-1-71 ~]# kubectl exec -it bs -- sh / # nslookup web Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: web Address 1: 10.244.117.52 10-244-117-52.web.default.svc.cluster.local ## DNS解析名称PodIP.service-name .namespace-name.svc.cluster.local/ # nslookup nginx-headless Server: 10.96.0.10 Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local Name: nginx-headless Address 1: 10.244.114.10 web-1.nginx-headless.default.svc.cluster.local Address 2: 10.244.117.50 web-0.nginx-headless.default.svc.cluster.local Address 3: 10.244.117.51 web-2.nginx-headless.default.svc.cluster.local ## DNS解析名称statefulsetName-index.service-name .namespace-name.svc.cluster.local[rootk8s-master-1-71 ~]# kubectl exec -it bs -- sh / # ping web-1.nginx-headless.default.svc.cluster.local PING web-1.nginx-headless.default.svc.cluster.local (10.244.114.10): 56 data bytes 64 bytes from 10.244.114.10: seq0 ttl62 time0.539 ms 64 bytes from 10.244.114.10: seq1 ttl62 time0.474 ms 测试存储 [rootk8s-node1-1-72 ~]# ls /ifs/kubernetes/ //自动生成独立的PV default-www-data-web-1-pvc-ae9c2a66-0bcb-489e-98d0-0350d480fb68 default-www-data-web-2-pvc-50d69a6e-d3ef-42e2-bd13-e6c954d78677 default-www-data-web-0-pvc-c8f06f51-5048-4a43-b822-9f6bcd1bd20c[rootk8s-master-1-71 ~]# kubectl exec -it web-0 -- bash rootweb-0:/# cd /usr/share/nginx/html/ ; echo 111 index.html[rootk8s-node1-1-72 ~]# cat /ifs/kubernetes/default-www-data-web-0-pvc-c8f06f51-5048-4a43-b822-9f6bcd1bd20c/index.html 111 [rootk8s-node1-1-72 ~]# ls /ifs/kubernetes/default-www-data-web-2-pvc-50d69a6e-d3ef-42e2-bd13-e6c954d78677///目录为空 ## 因此Statefulset控制器创建的每个Pod的存储为独立的 思考在有状态环境部署下分布式应用组件的角色不同每个Pod也不相同而在上述 StatefulSet部署示例中假设运行一个etcd数据集群有3个副本且肯定只有一个指定的镜像镜像相同如何区分这3个Pod的角色 解答通过配置文件区分每个节点的名称、IP、存储目录区分需要保证启动的3个副本容器每一个都能按照自己的角色配置文件进行启动。而配置文件则需要根据statefulset控制器部署的Pod容器编号进行区分判断当前启动的是第几个容器就使用哪个配置文件进行启动从而实现Pod的角色。例如etcd-0.conf、etcd-1.conf、etcd-2.conf 参考同类型的案例运行 ZooKeeper一个分布式协调系统 | Kubernetes — StatefulSet 与 Deployment区别有身份的 身份三要素唯一性 域名 主机名 存储PVC 3、应用程序数据存储 ConfigMap存储配置文件Secret存储敏感数据 3.1 ConfigMap 存储应用配置 创建ConfigMap后数据实际会持久化存储在K8s中Etcd然后通过创建Pod时引用该数据。 应用场景应用程序配置类似配置管理中心如apollo、nacos Pod使用configmap数据有两种方式 变量注入到容器里 数据卷挂载 两种数据类型 键值多行数据 相关命令 创建ConfigMapkubectl create configmap --from-filepath/to/bar kubectl create configmap my-configmap --from-literalabc123 --from-literalcde456 查看ConfigMapkubectl get configmap 官方ConfigMap | Kubernetes ConfigMap 配置示例 1部署ConfigMap的YAML [rootk8s-master-1-71 ~]# kubectl apply -f configmap-demo.yaml apiVersion: v1 kind: ConfigMap metadata:name: configmap-demo data:abc: 123 //key/value键值方式字符串需要“”cde: 456redis.properties: | //多行数据方式port: 6379host: 192.168.31.10# 查看创建的ConfigMap [rootk8s-master-1-71 ~]# kubectl get configmap NAME DATA AGE configmap-demo 3 7s ## 备注DATA显示为3表示存储了3个数据包括abc、cde、redis.properties2部署Pod的YAML [rootk8s-master-1-71 ~]# kubectl apply -f configmap-pod.yaml apiVersion: v1 kind: Pod metadata:name: configmap-demo-pod spec:containers:- name: nginximage: nginx# 定义环境变量env:- name: ABCD # 容器中的变量请注意这里和 ConfigMap 中的键名是不一样的valueFrom:configMapKeyRef:name: configmap-demo # 这个值来自 ConfigMapkey: abc # 需要取值的键- name: CDEFvalueFrom:configMapKeyRef:name: configmap-demokey: cdevolumeMounts:- name: configmountPath: /config # 挂载到哪个目录readOnly: true # 挂载文件为只读volumes:# 在 Pod 级别设置卷然后将其挂载到 Pod 内的容器中- name: configconfigMap:name: configmap-demo # 提供想要挂载的 ConfigMap 的名字# 来自 ConfigMap 的一组键将被创建为文件items:- key: redis.properties # configmap-demo的Keypath: redis.conf # 挂载后的名字 测试进入pod中验证是否注入变量和挂载 [rootk8s-master-1-71 ~]# kubectl exec -it configmap-test-pod-5dff5f64c6-ncmnd -- bash rootconfigmap-test-pod-5dff5f64c6-ncmnd:/# echo $ABCD 123 rootconfigmap-test-pod-5dff5f64c6-ncmnd:/# echo $CDEF 456 rootconfigmap-test-pod-5dff5f64c6-ncmnd:/# cat /config/redis.conf port: 6379 host: 192.168.31.103.2 Secret 存储敏感信息 与ConfigMap类似区别在于Secret主要存储敏感数据所有的数据要经过base64编码。 应用场景凭据 kubectl create secret 支持三种数据类型 docker-registry存储镜像仓库认证信息镜像仓库需要账户密码认证generic存储用户名、密码 例如kubectl create secret generic ssh-key-secret --from-filessh-privatekey/path/to/.ssh/id_rsa --from-filessh-publickey/path/to/.ssh/id_rsa.pub例如kubectl create secret generic my-secret --from-literalusernameproduser --from-literalpassword123456tls存储证书kubectl create secret tls --certpath/to/tls.cert --keypath/to/tls.key 例如 :05 K8s网络 使用ingress - tls 部署https 相关命令 查看Secretkubectl get secret 相关base64命令: # echo -n admin | base64          //加密YWRtaW4# echo YWRtaW4 | base64 -d  //解密admin 补充 在Secret 配置文件中未作显式设定时默认的 Secret 类型是 Opaque 命令示例 [rootk8s-master ~]# kubectl create secret generic my-secret --from-literalusernameadmin --from-literalpassword123456 YAML示例 1将用户名密码进行编码 [rootk8s-master-1-71 ~]# echo -n admin | base64 //用户名加密 YWRtaW4 [rootk8s-master-1-71 ~]# echo -n 123456 | base64 //密码加密 MTIzNDU2 2部署Secret的YAML [rootk8s-master-1-71 ~]# vi secret-demo.yaml apiVersion: v1 kind: Secret metadata:name: my-secret type: Opaque //默认的 Secret 类型是 Opaque data:username: YWRtaW4password: MTIzNDU2# 查看创建的ConfigMap [rootk8s-master-1-71 ~]# kubectl get secret NAME TYPE DATA AGE secret-demo Opaque 2 5s TYPE类型参考Secrets | Kubernetes 3部署Pod的YAML apiVersion: v1 kind: Pod metadata:name: secret-demo-pod spec:containers:- name: nginximage: nginx env:- name: USERNAME # 容器中的变量valueFrom:secretKeyRef:name: secret-demokey: username- name: PASSWORD # 容器中的变量valueFrom:secretKeyRef:name: secret-demokey: passwordvolumeMounts:- name: configmountPath: /configreadOnly: truevolumes:- name: configsecret:secretName: secret-demoitems:- key: username path: username.txt- key: passwordpath: password.txt 备注Pod使用Secret数据与ConfigMap方式一样 测试进入pod中验证是否注入变量和挂载 [rootk8s-master-1-71 ~]# kubectl exec -it secret-test-pod-6554b98c8-8hrbb -- bash rootsecret-test-pod-6554b98c8-8hrbb:/# echo $USERNAME admin rootsecret-test-pod-6554b98c8-8hrbb:/# echo $PASSWORD 123456 rootsecret-test-pod-6554b98c8-8hrbb:/# ls /config/ password.txt username.txt 课后作业 1、创建一个secret并创建2个podpod1挂载该secret路径为/secretpod2使用环境变量引用该 secret该变量的环境变量名为ABC secret名称my-secretpod1名称pod-volume-secretpod2名称pod-env-secret 2、 创建一个pv再创建一个pod使用该pv 容量5Gi访问模式ReadWriteOnce 3、创建一个pod并挂载数据卷不可以用持久卷 卷来源emptyDir、hostPath任意挂载路径/data 4、将pv按照名称、容量排序并保存到/opt/pv文件 小结 本篇为 【Kubernetes CKA认证 Day7】的学习笔记希望这篇笔记可以让您初步了解到 数据卷与数据持久卷、有状态应用部署、应用程序数据存储案例 课后还有扩展实践不妨跟着我的笔记步伐亲自实践一下吧 Tip毕竟两个人的智慧大于一个人的智慧如果你不理解本章节的内容或需要相关笔记、视频可私信小安请不要害羞和回避可以向他人请教花点时间直到你真正的理解。
http://www.w-s-a.com/news/354369/

相关文章:

  • 网站服务器出错是什么意思做餐饮酒店网站
  • 房地产网站建设策划方案网站建设教程简笔画
  • 3d室内设计软件wordpress本地优化加速版
  • 南京高新区规划建设局网站石家庄哪里做网站比较好
  • 免费培训课程网站优化的方式
  • 做网站要固定电话在家自己做网站
  • 招聘网站开发视频新手如何做网站维护
  • flash 网站欣赏国外做的比较好的网站有哪些
  • 推广一个网站需要什么官网首页设计
  • 淘宝建设网站的理由企业官网建设哪家好
  • 青岛网站推wordpress主题切换
  • 天元建设集团有限公司资质郑州网站seo推广
  • 免费网站后台管理系统模板下载百度网盘app下载安装
  • 开封网站建设培训郑州高端网站建设哪家好
  • 东莞哪家做网站很有名的公司即墨专业医院网站制作公司
  • 做面食网站china cd wordpress
  • 门户网站 营销优秀建筑模型案例作品
  • 训做网站的心得体会范文中山市 有限公司网站建设
  • 服装电子商务网站建设过程与实现两学一做学习教育网站
  • 住房和城建设网站怎么用源码建站
  • 监理工程师证查询网站百度关键词优化软件网站
  • 关于建筑建设的网站asp网站建设报告书
  • 服务二级公司网站建设平台销售模式有哪些
  • 南昌县建设局网站微信分销小程序开发
  • 网站设计师需要什么知识与技能wordpress个性
  • 做茶叶网站的目的和规划有什么做照片书的网站
  • 开福区城乡建设局门户网站关键词挖掘查询工具爱站网
  • 网站建设全国排名沈阳seo按天计费
  • 成都公司网站设计无锡seo网站推广费用
  • 建网站平台要多少钱购物网站界面设计策划