K8S数据管理

news2024/12/24 10:06:35

K8S数据管理

  • 1 数据管理
    • 1.1 数据持久化
      • 1.1.1 存储方案
      • 1.1.2 EmptyDir实践
      • 1.1.3 hostPath实践
      • 1.1.4 NFS实践
    • 1.2 持久化进阶
      • 1.2.1 数据对象
      • 1.2.2 PV&PVC实践
      • 1.2.3 SC解析
      • 1.2.4 SC实践
    • 1.3 配置管理
      • 1.3.1 配置基础
      • 1.3.2 CM
      • 1.3.3 CM案例
      • 1.3.4 Secret
      • 1.3.5 Secret案例
    • 1.4 状态管理
      • 1.4.1 状态基础
      • 1.4.2 sts基础

1 数据管理

1.1 数据持久化

1.1.1 存储方案

学习目标

这一节,我们从 存储原理、方案解读、小结 三个方面来学习。

存储原理

容器存储

	Docker的文件系统 与Docker容器具有相同的生命周期,但是Docker容器肯定会遇到同时运行到多节点场景中,这个时候,会因为节点崩溃、服务崩溃、网络原因,导致容器异常退出,所以一旦我们将数据存储到容器内部,肯定会导致数据丢失。
		- Docker镜像是只读的文件,Docker容器可读可写,但是不能够数据持久化。
	所以为了避免这种数据异常丢失的情况,我们一般会将 容器的数据(程序状态数据、应用存储数据等),存储在容器的文件系统之外。
		- 通过引入外部的存储空间来实现 数据的可持久化效果。

存储方式

host存储方式
	- 通过数据卷 或者 数据卷容器,将当前宿主机上面的文件系统目录与容器里面的工作目录进行一一的关联。
	- 即使我们对本地是磁盘做 raid等冗余功能,但是这种等级的安全很鸡肋。
网络存储方式
	- 通过网络的方式,将外部的存储空间挂载到当前宿主机,然后借助于host机制实现容器数据的可持久化。

在这里插入图片描述

k8s支持的存储类型

本地数据卷 	emptyDir、hostPath、local等
云存储数据卷	gcePersistentDisk、awsElasticBlockStore等
网络存储卷	NFS、gitRepo、NAS、SAN等
分布式存储卷	GlusterFS、CephFS、rdb(块设备)、iscsi等
信息数据卷	flocker、secret等

资源对象属性

spec:
  volumes:
  - name <string>  				# 存储卷名称标识,仅可使用DNS标签格式的字符,在当前Pod中必须唯一
    VOL_TYPE <Object>  			# 存储卷插件及具体的目标存储供给方的相关配置
  containers:
  - name: …
    image: …
    volumeMounts:
    - name <string>  			# 要挂载的存储卷的名称,必须匹配存储卷列表中某项的定义
      mountPath <string> 		# 容器文件系统上的挂载点路径
      readOnly <boolean>  		# 是否挂载为只读模式,默认为“否”
      subPath <string>     		# 挂载存储卷上的一个子目录至指定的挂载点
      subPathExpr <string>  	# 挂载由指定的模式匹配到的存储卷的文件或目录至挂载点

方案解读

场景需求

虽然这种借助于k8s存储插件的方式,为pod应用引入各种存储机制,但是这种方案有天然的劣势:
	1 要保证所有的pod节点支持后端的指定类型的存储服务。
	2 所有的后端指定服务的配置都要在pod上自定义
	3 这些卷插件将pod定制的配置属性传递给kubelet,然后实现对应的效果。
	-- 从字面上来理解,如果一个开发者要开发一个pod对象,必须首先是一个存储专家
	-- 而这是不可能的。
	所以,使用k8s的门槛高多了。而k8s为了避免这种为用户带来不好影响的现象,引入了两个非常重要的存储资源对象 -- PV 和 PVC
kubernetes根据资源对象创建的灵活的度实现了两种数据持久化解决方案:
	手工方式: PVC + PV
	自动方式: VCT + SC

在这里插入图片描述

1 由专业的存储管理员来管理所有的存储后端:
	- 在专用的存储设备上,创建各种类型级别的PV(Persistent Volume)
	- 或者通过存储模板文件SC(storageclasses)来自动创建大量不同类型的PV对象。
2 由开发人员定制需要的PVC(Persistent Volume Claim),然后关联到pod上
3 Pod通过PVC到PV上请求一块独立大小的网络存储空间,然后直接使用
这样的话,通过这种分层的管理机制,让开发人员和存储人员专人做专事,大大的减轻工作的负载。

小结


1.1.2 EmptyDir实践

学习目标

这一节,我们从 原理解读、简单实践、小结 三个方面来学习。

基础知识

简介

一个emptyDir volume在pod被调度到某个Node时候自动创建的,无需指定宿主机上对应的目录。特点如下:
1、跟随Pod初始化而来,开始是空数据卷
2、Pod移除,emptyDir中数据随之永久消除
3、emptyDir一般做本地临时存储空间使用
4、emptyDir数据卷介质种类跟当前主机的磁盘一样。

属性解析

kubectl explain pod.spec.volumes.emptyDir
    medium   	指定媒介类型,主要有 disk  Memory(默认) 两种
    sizeLimit  	现在资源使用情况
    
kubectl explain pod.spec.containers.volumeMounts
    mountPath   挂载到容器中的路径
    name 		指定挂载的volumes名称
    readOnly   	是否只读挂载
    subPath   	是否挂载子路径

配置样式

# volume配置样式
  volumes:
  - name: volume_name
    emptyDir: {}

# volume使用样式
  containers:
    - volumeMounts:
       - name: volume_name
         mountPath: /path/to/container/
                  
注意:
	关于volume和容器的关系,每个容器都可以单独挂载多个volume,每种volume都可以被多个容器挂载

简单实践

临时存储演示

准备清单目录
[root@kubernetes-master1 ~]# mkdir /data/kubernetes/storage -p ;cd /data/kubernetes/storage
[root@kubernetes-master1 /data/kubernetes/storage]#
准备资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# cat 01_kubernetes-storage_emptydir.yml 
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-emptydir
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
    volumeMounts:
    - name: nginx-index
      mountPath: /usr/share/nginx/html
  - name: change-index
    image: kubernetes-register.superopsmsb.com/superopsmsb/busybox:1.28
    # 每过2秒更改一下文件内容
    command: ['sh', '-c', 'for i in $(seq 100); do echo index-$i > /testdir/index.html;sleep 2;done']
    volumeMounts:
    - name: nginx-index
      mountPath: /testdir
  volumes:
  - name: nginx-index
    emptyDir: {}
执行资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 01_kubernetes-storage_emptydir.yml
pod/superopsmsb-emptydir created

查看效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get pod -o wide
NAME                   READY   ...  IP           NODE              ...
superopsmsb-emptydir   2/2     ...  10.244.1.5   kubernetes-node1  ...
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.1.5
index-38
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.1.5
index-39
查看描述信息
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl describe pod superopsmsb-emptydir
Name:         superopsmsb-emptydir
...
Containers:
  nginx-web:
    ...
    Mounts:
      /usr/share/nginx/html from nginx-index (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-gbwh8 (ro)
  change-index:
    ...
    Mounts:
      /testdir from nginx-index (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-gbwh8 (ro)
...
Volumes:
  nginx-index:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    ...

文件在哪里?

关于临时存储的文件存放的位置在指定节点的/var/lib/kubelet目录下

查找文件
[root@kubernetes-node1 ~]# find /var/lib/kubelet/ -name "index.html"
/var/lib/kubelet/pods/9b086c71-ad40-4c59-8525-17a97ae0a95b/volumes/kubernetes.io~empty-dir/nginx-index/index.html

查看文件
[root@kubernetes-node1 ~]# cat /var/lib/kubelet/pods/9b086c71-ad40-4c59-8525-17a97ae0a95b/volumes/kubernetes.io~empty-dir/nginx-index/index.html
index-46
结果显示:
	文件是随着pod而存在的,一旦pod删除了,文件也丢失了。

小结


1.1.3 hostPath实践

学习目标

这一节,我们从 原理解读、简单实践、小结 三个方面来学习。

基础知识

场景需求

hostPath将宿主机上的目录挂载到Pod中作为数据的存储目录,一般用在如下场景:
1、容器应用程序中某些文件需要永久保存
2、某些容器应用需要用到容器的内部数据结构,可将宿主机的/var/lib/docker挂载到Pod中
3、Pod删除,宿主机文件不受影响

hostPath使用注意事项:
1、不同宿主机的文件内容不一定完全相同,所以Pod迁移前后的访问效果不一样
2、宿主机的目录不属于资源对象的资源,所以我们对资源设置的资源配额限制对hostPath目录无效

配置属性

配置格式:
  volumes:
  - name: volume_name
    hostPath:
     path: /path/to/host
配置属性解读
	kubectl explain pod.spec.volumes.hostPath
    path  指定宿主机的路径
    type  指定路径的类型,一共有7种,默认的类型是没有指定的话则自己创建
    	DirectoryOrCreate  宿主机上不存在,创建此0755权限的空目录,属主属组均为kubelet  
    	Directory 必须存在挂载已存在的目录,最常用
    	FileOrCreate 宿主机上不存在挂载文件,就创建0644权限的空文件,属主和属组同为kubelet  
    	File 必须存在文件 
    	Socket 事先必须存在的Socket文件路径
    	CharDevice 事先必须存在的字符设备文件路径
    	BlockDevice 事先必须存在的块设备文件路径
		参考资料:https://kubernetes.io/docs/concepts/storage/volumes#hostpath

简单实践

准备工作

获取互联网镜像
[root@kubernetes-master1 ~]# docker pull redis
[root@kubernetes-master1 ~]# docker history redis | grep REDIS_VER
<missing>      3 days ago    /bin/sh -c #(nop)  ENV REDIS_VERSION=7.0.4      0B
[root@kubernetes-master1 ~]# docker tag redis:latest kubernetes-register.superopsmsb.com/superopsmsb/redis:7.0.4
[root@kubernetes-master1 ~]# docker push kubernetes-register.superopsmsb.com/superopsmsb/redis:7.0.4
[root@kubernetes-master1 ~]# docker rmi redis:latest

创建所有主机的备份目录
[root@kubernetes-master1 ~]# for i in 15 16 17;do ssh root@10.0.0.$i "mkdir /data/backup/redis -p"; done

定制redis的数据备份功能

准备资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# cat 02_kubernetes-storage_hostpath.yml 
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-hostpath
spec:
  volumes:
  - name: redis-backup
    hostPath:
     path: /data/backup/redis
  containers:
    - name: hostpath-redis
      image: kubernetes-register.superopsmsb.com/superopsmsb/redis:7.0.4
      volumeMounts:
       - name: redis-backup
         mountPath: /data
	注意:
	redis的镜像将数据保存到了容器的/data 目录下。
创建资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 02_kubernetes-storage_hostpath.yml
pod/superopsmsb-hostpath created

[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get pod -o wide
NAME                   READY   ...  IP           NODE              ...
superopsmsb-hostpath   1/1     ...  10.244.3.3   kubernetes-node3  ...

查看描述信息
查看描述信息
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl describe pod superopsmsb-emptydir
Name:         superopsmsb-emptydir
...
Containers:
   hostpath-redis:
    ...
    Mounts:
      /data from redis-backup (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8x257 (ro)
...
Volumes:
  redis-backup:
    Type:          HostPath (bare host directory volume)
    Path:          /data/backup/redis
    ...
进入容器确认效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl exec -it superopsmsb-hostpath -- /bin/bash
root@superopsmsb-hostpath:/data# redis-cli
127.0.0.1:6379> set volume hostpath
OK
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> exit
root@superopsmsb-hostpath:/data# exit
exit

到指定的node3上看效果
[root@kubernetes-master1 /data/kubernetes/storage]# ssh root@10.0.0.17 ls /data/backup/redis
dump.rdb

小结


1.1.4 NFS实践

学习目标

这一节,我们从 原理解读、简单实践、小结 三个方面来学习。

基础知识

简介

	根据我们对hostpath的了解,我们发现,虽然hostpath可以根据pod的配置自动创建关联的宿主机目录,但是宿主机目录下面没有我们想要的数据文件,所以,在集群场景中,我们想要基于hostpath方式实现更强大的配置效果,就需要把所有的数据文件进行同步,而这不是我们想要的。
	基于此,我们需要一种可以实现网络存储的方式,NFS就是一种很好的网络存储解决方案。
	使用NFS网络文件系统提供的共享目录存储数据时,需要在系统中部署一个NFS环境,通过volume的配置,实现pod内的容器间共享nfs目录。

属性解析

配置属性:
kubectl explain pod.spec.volumes.nfs
    path		指定nfs服务器暴露的共享地址
    readOnly	是否只能读,默认false
    server		指定nfs服务器的地址
配置格式:
  volumes:
  - name: 卷名称
    nfs:
     server: nfs_server_address
     path: "共享目录"
注意事项:
	要求k8s所有集群都必须支持nfs命令,即所有结点都必须执行 yum install nfs-utils -y

NFS环境准备

我们将10.0.0.18作为NFS服务环境,这里加载一块磁盘并进行格式化
[root@kubernetes-ha1 ~]# fdisk -l | grep 'sdb'
磁盘 /dev/sdb:21.5 GB, 21474836480 字节,41943040 个扇区

磁盘格式化
[root@kubernetes-ha1 ~]# mkfs.ext4 /dev/sdb
mke2fs 1.42.9 (28-Dec-2013)
[root@kubernetes-ha1 ~]# blkid | grep sdb
/dev/sdb: UUID="b01ca48c-f8a6-4817-a9b4-7bb7a53c03c2" TYPE="ext4"

创建数据目录
[root@kubernetes-ha1 ~]# mkdir /superopsmsb/nfs-data -p
部署nfs服务
[root@kubernetes-ha1 ~]# yum install -y rpcbind nfs-utils

配置共享目录
echo '/superopsmsb/nfs-data *(rw,no_root_squash,sync)' > /etc/exports
注意:
 	*:表示允许所有连接,该值可以是一个网段|IP|域名的形式
 	rw 表示读写共享权限
 	no_root_squash 表示root登录nfs资源的时候,虽然是以nobody身份,单不压缩其权限
 	sync 	所有操作数据会同时写入硬盘和内存
 	
配置生效
[root@kubernetes-ha1 ~]# exportfs -r

重启服务
[root@kubernetes-ha1 ~]# systemctl start rpcbind.service
[root@kubernetes-ha1 ~]# systemctl start nfs.service
[root@kubernetes-ha1 ~]# systemctl enable rpcbind.service nfs.service

确认效果
[root@kubernetes-ha1 ~]# showmount -e localhost
Export list for localhost:
/superopsmsb/nfs-data *
所有的k8s节点部署nfs命令
[root@kubernetes-master1 ~]# for i in {12..17};do ssh root@10.0.0.$i "yum install nfs-utils -y";done

确认效果
[root@kubernetes-master1 ~]# showmount -e 10.0.0.18
Export list for 10.0.0.18:
/superopsmsb/nfs-data *

挂载测试
[root@kubernetes-master1 ~]# mount -t nfs 10.0.0.18:/superopsmsb/nfs-data /tmp
[root@kubernetes-master1 ~]# mount | grep nfs
10.0.0.18:/superopsmsb/nfs-data on /tmp type nfs4 (rw,relatime,vers=4.1,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.12,local_lock=none,addr=10.0.0.18)
[root@kubernetes-master1 ~]# umount /tmp

简单实践

定制数据功能

准备资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# cat 03_kubernetes-storage_nfs.yml 
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-nfs
spec:
  volumes:
    - name: redis-backup
      nfs:
        server: 10.0.0.18
        path: /superopsmsb/nfs-data
  containers:
    - name: nfs-redis
      image: kubernetes-register.superopsmsb.com/superopsmsb/redis:7.0.4
      volumeMounts:
       - name: redis-backup
         mountPath: /data
创建资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 03_kubernetes-storage_nfs.yml
pod/superopsmsb-nfs created

[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get pod -o wide
NAME                   READY   ...  IP           NODE              ...
superopsmsb-nfs        1/1     ...  10.244.3.4   kubernetes-node3  ...
查看描述信息
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl describe pod superopsmsb-nfs
Name:         superopsmsb-emptydir
...
Containers:
   nfs-redis:
    ...
    Mounts:
      /data from redis-backup (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pfz9h (ro)
...
Volumes:
  redis-backup:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    10.0.0.18
    Path:      /superopsmsb/nfs-data
    ...
进入容器确认效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl exec -it superopsmsb-nfs -- /bin/bash
root@superopsmsb-nfs:/data# redis-cli
127.0.0.1:6379> set volumes nfs
OK
127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> exit
root@superopsmsb-nfs:/data# exit
exit

到nfs上看效果
[root@kubernetes-master1 /data/kubernetes/storage]# ssh root@10.0.0.18 ls /superopsmsb/nfs-data
dump.rdb

小结


1.2 持久化进阶

1.2.1 数据对象

学习目标

这一节,我们从 存储机制、对象解读、小结 三个方面来学习。

存储机制

资源对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V2HsvuDa-1688394662411)(image/image-20220715012035435.png)]

存储方案

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fi6Cnni8-1688394662412)(image/image-20220722084705991.png)]

对象解读

	之前我们提到的Volume可以提供多种类型的资源存储(可持久或不持久),但是它定义在Pod上的,是属于"资源对象"的一部分。工作中的存储资源一般都是独立的,这就是资源对象Persistent Volume(PV),是由管理员设置的存储,它是群集的一部分,PV 是 Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。。

Persistent Volume 跟Volume类似,区别就是:
    PV就是Kubernetes集群中的网络存储,不属于Node、Pod等资源,但可以被他们访问。
	PV是独立的网络存储资源对象,有自己的生命周期,支持很多种volume类型
	
 Persistent Volume Claim(PVC) 是一个网络存储服务的请求。PVC和PV与Pod之间的关系。
    Pod只能通过PVC到PV上请求一块独立大小的网络存储空间,而PVC 可以动态的根据用户请求去申请PV资源,不仅仅涉及到存储空间,还有对应资源的访问模式。
   
 StorageClass(SC)
 	管理员可以根据 Kubernetes 的 StorageClass 对象来动态的定义各种类型的资源。

存储流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n1j1RQin-1688394662415)(image/image-20210928143219693.png)]

1 用户创建了一个包含 PVC 的 Pod,该 PVC 要求使用动态存储卷;
2 Scheduler 根据 Pod 配置、节点状态、PV 配置等信息,把 Pod 调度到一个合适的 Worker 节点上;
3 PV 控制器 watch 到该 Pod 使用的 PVC 处于 Pending 状态,于是调用 Volume Plugin(in-tree)创建存储卷,并创建 PV 对象(out-of-tree 由 External Provisioner 来处理);
4 AD 控制器发现 Pod 和 PVC 处于待挂接状态,于是调用 Volume Plugin 挂接存储设备到目标 Worker 节点上
5 在 Worker 节点上,Kubelet 中的 Volume Manager 等待存储设备挂接完成,并通过 Volume Plugin 将设备挂载到全局目录:		**/var/lib/kubelet/pods/[pod uid]/volumes/kubernetes.io~iscsi/[PVname]**(以 iscsi 为例);
6 Kubelet 通过 Docker 启动 Pod 的 Containers,用 bind mount 方式将已挂载到本地全局目录的卷映射到容器中。

对象解读

资源关系

用户需要存储资源的时候:
	0 提取准备好对应的PV资源
	1 用户根据资源需求创建PVC,由PVC自动匹配(权限、容量)合适的PV对象
	2 在pod内部通过PVC将pv绑定到当前的空间,进行使用
	3 如果用户不使用存储资源的话,解绑pvc和pod即可。
	
注意
	原则上来说,pod、pvc、pv 必须在同一个命名空间

pod生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vmxc6UJ6-1688394662416)(image/image-20210927151520502.png)]

状态管理

Availabled 	空闲状态,表示pv没有被其他对象使用
Bound		绑定状态,表示pv已经被其他对象使用
Released	未回收状态,表示pvc已经被删除了,但是资源没有被回收
Faild		资源回收失败

在这里插入图片描述

访问权限

AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括
    ReadWriteOnce(RWO)单节点读写
    ReadOnlyMany(ROX)多节点只读
    ReadWriteMany(RWX)多节点读写
    ReadWriteOncePod(RWOP)单pod读写

小结


1.2.2 PV&PVC实践

学习目标

这一节,我们从 配置解析、简单实践、小结 三个方面来学习。

配置解析

简介

PV 作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略等关键信息
	kubectl explain pv.spec
        capacity  定义pv使用多少资源,仅限于空间的设定
        accessModes   访问模式
        存储类型	每种存储类型的样式的属性名称都是专有的。
        persistentVolumeReclaimPolicy	资源回收策略,主要三种Retain、Delete、Recycle
pvc是属于名称空间级别的资源对象,也就是说只有特定的资源才能使用
	kubectl explain pods.spec.volumes.persistentVolumeClaim
        claimName	定义pvc的名称
        readOnly	设定pvc是否只读
    kubectl  explain pvc.spec
        accessModes 			访问模式	*
        resources  				资源限制	*
        selector  			   标签选择器
        storageClassName  		动态存储名称
        volumeMode  			后端存储卷的模式
        volumeName  			指定卷(pv)的名称
注意:
	只有 accessModes 和 resources 都匹配成功后,PVC 才会与 PV 绑定在一起。

简单实践

PV&PVC实践

定制资源清单
[root@kubernetes-master1 /data/kubernetes/storage]# vim 04_kubernetes-storage_pv_pvc.yml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: superopsmsb-pv
spec:
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /superopsmsb/nfs-data
    server: 10.0.0.18

---
apiVersion: v1	
kind: PersistentVolumeClaim
metadata:
  name: superopsmsb-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
      
创建资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 04_kubernetes-storage_pv_pvc.yml
persistentvolume/superopsmsb-pv created
persistentvolumeclaim/superopsmsb-pvc created
检查效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
superopsmsb-pv   3Gi        RWO            Retain           Bound    default/superopsmsb-pvc                           36s
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pvc
NAME              STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
superopsmsb-pvc   Bound    superopsmsb-pv   3Gi        RWO                           39s
结果显示:
	PVC 和 PV 已经绑定到一起了

pod使用PVC

定制资源清单
[root@kubernetes-master1 /data/kubernetes/storage]# vim 05_kubernetes-storage-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-nginx
spec:
  volumes:
    - name: nginx-volume
      persistentVolumeClaim:
        claimName: superopsmsb-pvc
  containers:
    - name: nginx-web
      image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
      volumeMounts:
      - name: nginx-volume
        mountPath: "/usr/share/nginx/html"
    属性解析:
    	spec.volumes 是针对pod资源申请的存储资源来说的,我们这里使用的主要是pvc的方式。
    	spec.containers.volumeMounts 是针对pod资源对申请到的存储资源的具体使用信息。
		这里将本地的nfs目录挂载到

创建资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 05_kubernetes-storage-pod.yml
pod/superopsmsb-nginx created
查看Pod对象信息
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl describe pod superopsmsb-nginx
Name:		superopsmsb-nginx
...
Containers:
  nginx-pv:
    ...
    Mounts:
      /usr/share/nginx/html from nginx-volume (rw)
... 
Volumes:
  nginx-volume:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  superopsmsb-pvc
...

查看pod地址
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get pod -o wide
NAME                   READY   ...  IP           NODE              ...
superopsmsb-nginx      1/1     ...  10.244.3.5   kubernetes-node3  ...
浏览器访问效果
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.3.5
Hello Nginx, superopsmsb-nginx-1.23.0

查看nfs地址效果
[root@kubernetes-ha1 ~]# cat /superopsmsb/nfs-data/index.html
Hello Nginx, superopsmsb-nginx-1.23.0
结果显示:
	默认将nginx的首页存放到了nfs中

修改nfs的首页内容
[root@kubernetes-ha1 ~]# echo 'Hello NFS Nginx Website' > /superopsmsb/nfs-data/index.html

浏览器访问效果
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.3.5
Hello NFS Nginx Website

小结


1.2.3 SC解析

学习目标

这一节,我们从 原理解读、环境实践、小结 三个方面来学习。

原理解读

简介

	Kubernetes 提供了一种StorageClass的资源对象:在StorageClass的环境基础上,它可以让我们用户将存储资源定义为某种类型的资源,比如存储质量、快速存储、慢速存储等,然后自由的去申请合适的存储资源了。
	StorageClass根据自由申请后端存储的类型,有很多不同的实现方式,在我们的试验环境中,我们这里用nfs-client-provisioner的方式来演示StorageClass。

SC原理解读

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d1ty2VeM-1688394662416)(image/image-20220722104753612.png)]

实践步骤

1 部署 SC的提供者环境
2 设置 SC的存储属性
3 定制 Pod资源对象属性(PVC采用SC机制)
4 综合测试

环境现状

	自从kubernetes 1.20版本禁用了 selfLink,所以默认情况下,我们在创建SC提供者环境的时候,会发生报错,只能首先修改kubernetes的启动属性。
参考资料:
	https://stackoverflow.com/questions/65376314/kubernetes-nfs-provider-selflink-was-empty
	https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/issues/25
编辑/etc/kubernetes/manifests/kube-apiserver.yaml
	...
spec:
  containers:
  - command:
    - kube-apiserver
    - --feature-gates=RemoveSelfLink=false   # 添加这条配置
    
由于是静态文件,所以该pod会自动更改属性,查看效果
[root@kubernetes-master1 ~]# kubectl get pod -n kube-system -l component=kube-apiserver
NAME                                READY   STATUS    RESTARTS   AGE
kube-apiserver-kubernetes-master1   1/1     Running   0          79s
kube-apiserver-kubernetes-master2   1/1     Running   0          41s
kube-apiserver-kubernetes-master3   1/1     Running   0          40s

环境实践

准备资源清单文件

准备专属目录
[root@kubernetes-master1 /data/kubernetes/storage]# mkdir sc-provider
[root@kubernetes-master1 /data/kubernetes/storage]# cd sc-provider/
[root@kubernetes-master1 /data/kubernetes/storage/sc-provider]#

准备镜像
docker pull registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
docker tag registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner kubernetes-register.superopsmsb.com/google_containers/nfs-client-provisioner:latest
docker push kubernetes-register.superopsmsb.com/google_containers/nfs-client-provisioner:latest
docker rmi registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
准备NFS的控制器
[root@kubernetes-master1 /data/kubernetes/storage/sc-provider]# cat 01_kubernetes_sc_provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  # 命名空间要与定制的rbac的一致
  namespace: superopsmsb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccount: nfs-provisioner
      containers:
      - name: nfs-client-provisioner
        image: kubernetes-register.superopsmsb.com/google_containers/nfs-client-provisioner:latest
        volumeMounts:
        - name: nfs-client-root
          mountPath: /persistentvolumes
        env:
        - name: PROVISIONER_NAME
             # 该变量的值,必须与nfs的storageclass的provisioner的值一致
          value: "nfsprovisioner"
        - name: NFS_SERVER
              # 设置NFS服务器的ip地址
          value: "10.0.0.18"
        - name: NFS_PATH
              # 设置NFS服务器分享的目录
          value: "/superopsmsb/nfs-data"
      volumes:
      - name: nfs-client-root
        nfs:
          # 直接使用nfs来挂载该目录,方便storageclass基于该pod对pv和pvc进行自动处理
          server: "10.0.0.18"
          path: "/superopsmsb/nfs-data"
准备NFS操作k8s资源的权限
[root@kubernetes-master1 /data/kubernetes/storage/sc-provider]# cat 02_kubernetes_sc_rbac.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: nfsstorageclass
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-provisioner
  namespace: superopsmsb
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
   name: nfs-provisioner
   namespace: superopsmsb
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: ["watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["services", "endpoints"]
    verbs: ["get","create","patch","list", "watch","update"]
  - apiGroups: ["extensions"]
    resources: ["podsecuritypolicies"]
    resourceNames: ["nfs-provisioner"]
    verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-provisioner
  namespace: superopsmsb
subjects:
  - kind: ServiceAccount
    name: nfs-provisioner
    namespace: superopsmsb
roleRef:
  kind: ClusterRole
  name: nfs-provisioner
  apiGroup: rbac.authorization.k8s.io
准备NFS操作的StorageClass资源
[root@kubernetes-master1 /data/kubernetes/storage/sc-provider]# cat 03_kubernetes_sc_pv.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: storageclass
  namespace: superopsmsb
# 每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段
# provisioner用来决定使用哪个卷插件分配PV,必须与nfs-client的容器内部的 PROVISIONER_NAME 变量一致
# reclaimPolicy指定创建的Persistent Volume的回收策略
provisioner: "nfsprovisioner"
reclaimPolicy: Retain
parameters:
  # archiveOnDelete: "false"表示在删除时不会对数据进行打包,当设置为true时表示删除时会对数据进行打包
  archiveOnDelete: "false"
注意:
	StorageClass 的name不允许出现 大写字母

创建环境

创建专属命名空间
[root@kubernetes-master1 /data/kubernetes/storage/sc-provider]# kubectl  create ns superopsmsb
namespace/superopsmsb created

创建资源对象
[root@kubernetes-master1 /data/kubernetes/storage/sc-provider]# kubectl  apply -f ./
deployment.apps/nfs-client-provisioner created
namespace/nfsstorageclass created
serviceaccount/nfs-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-provisioner created
clusterrolebinding.rbac.authorization.k8s.io/nfs-provisioner created
storageclass.storage.k8s.io/storageclass created

检查效果
[root@kubernetes-master1 /data/kubernetes/storage/sc-provider]# kubectl  get all -n superopsmsb
NAME                                          READY   STATUS    RESTARTS   AGE
pod/nfs-client-provisioner-797775d949-pf9x2   1/1     Running   0          38s

NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nfs-client-provisioner   1/1     1            1           38s

NAME                                                DESIRED   CURRENT   READY   AGE
replicaset.apps/nfs-client-provisioner-797775d949   1         1         1       38s

小结


1.2.4 SC实践

学习目标

这一节,我们从 案例解读、简单实践、小结 三个方面来学习。

基础知识

简介

	我们准备将nginx的web数据存储通过Sc的方式来实现。

简单实践

创建资源清单

定制PVC使用SC的资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# cat 06_kubernetes_sc_nginx_pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sc-pvc
  namespace: superopsmsb
spec:
  storageClassName: storageclass
  accessModes:
    - ReadWriteOnce
  # 定义资源要求PV满足这个PVC的要求才会被匹配到
  resources:
    requests:
      storage: 200Mi
定制pod使用pvc
[root@kubernetes-master1 /data/kubernetes/storage]# cat 07_kubernetes_sc_nginx_pod.yaml
kind: Pod
apiVersion: v1
metadata:
  name: storageclass-nginx
  namespace: superopsmsb
spec:
  containers:
  - name: nginx-web
    image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
    volumeMounts:
    - name: test-storage
      mountPath: /usr/share/nginx/html
  - name: storageclass-pod-test
    image: kubernetes-register.superopsmsb.com/superopsmsb/busybox:1.28
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "while true; do echo $(date) > /data/index.html; sleep 2; done"
    volumeMounts:
      - name: test-storage
        mountPath: "/data"
  restartPolicy: "Never"
  volumes:
    - name: test-storage
      persistentVolumeClaim:
        claimName: sc-pvc

应用资源对象

使用资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 06_kubernetes_sc_nginx_pvc.yaml -f 07_kubernetes_sc_nginx_pod.yaml
persistentvolumeclaim/sc-pvc created
pod/storageclass-nginx created

检查效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pod -n superopsmsb
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-797775d949-pf9x2   1/1     Running   0          9m13s
storageclass-nginx                        2/2     Running   0          29s

查看pv 和pvc
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pv,pvc -n superopsmsb
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                     STORAGECLASS   REASON   AGE
persistentvolume/pvc-6e467991-e4b0-45dd-a3e0-e28b15fd3762   200Mi      RWO            Delete           Bound    superopsmsb/sc-pvc        storageclass            64s
persistentvolume/superopsmsb-pv                             3Gi        RWO            Retain           Bound    default/superopsmsb-pvc                           153m

NAME                           STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/sc-pvc   Bound    pvc-6e467991-e4b0-45dd-a3e0-e28b15fd3762   200Mi      RWO            storageclass   67s
查看nfs的自动创建的数据
[root@kubernetes-ha1 ~]# tree /superopsmsb/nfs-data/
/superopsmsb/nfs-data/
└── superopsmsb-sc-pvc-pvc-6e467991-e4b0-45dd-a3e0-e28b15fd3762
    └── index.html

1 directory, 1 file
结果显示:
	nfs的存储目录下,自动生成了pvc专属的pv目录

小结


1.3 配置管理

1.3.1 配置基础

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

场景需求

	生产中所有的应用程序中,都涉及到配置文件,而配置文件经常会有变更,比如数据库连接、代码版本号等,最典型场景就是:
	项目经历开发环境、测试环境、预发布环境、线上环境才能完成发布,而每个环境都有定义其独立的各种配置,这些配置手工操作很繁杂,所以好多大公司专门开发了专用配置管理中心,如百度的disconf等。

如何为容器化应用提供配置信息?

1 启动容器时,直接向应用程序传递参数,args: []
2 将定义好的配置文件焙进镜像之中;
3 通过环境变量向容器传递配置数据:有个前提要求,应用得支持从环境变量加载配置信息; 
4 制作镜像时,使用entrypoint脚本来预处理变量,常见的做法就是使用非交互式编辑工具,将环境变量的值替换到应用的配置文件中; 
5 基于存储卷向容器传递配置文件; 
注意:
	对于运行容器中的配置改变,需要通过应用程序重载相关配置

k8s的配置管理

	kubernetes作为分布式容器调度平台,肯定会遇到同样的问题,那么遇到这种问题后,我们不可能把资源删除后,重新修改一下,然后在启动生成,这种方法就太繁琐的。kubernetes提供了对pod中容器应用的集中配置管理组件:ConfigMap、Secret、downwardAPI。通过这些组件来实现向pod中的容器中注入配置信息的机制。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a4ihkrJd-1688394662417)(image/image-20220715012035435.png)]

简单实践

Configmap

	Configmap是k8s集群中非常重要的一种配置管理资源对象。借助于ConfigMap API向pod中的容器中注入配置信息的机制。ConfigMap不仅仅可以保存单个属性,也可以用来保存整个配置文件或者JSON二进制文件。
	各种配置属性和数据以 k/v或嵌套k/v 样式  存在到Configmap中
	
注意:
	所有的配置信息都是以明文的方式来进行传递,实现资源配置的快速获取或者更新。

secret

	在k8s集群中,有一些核心的配置属性信息是非常敏感的,所以这些信息在传递的过程中,是不希望外人能够看到的,所以,k8s提供了一种加密场景中的配置管理资源对象 -- secret。它在进行数据传输之前,会对数据进行编码,在数据获取的时候,会对数据进行解码。从而保证整个数据传输过程的安全。
注意:
	这些数据是根据不同的应用场景,采用不同的加密机制。

downwardAPI

	从严格意义上来说,downwardAPI不是存储卷,它自身就存在。相较于configmap、secret等资源对象需要创建后才能使用,而downwardAPI引用的是Pod自身的运行环境信息,这些信息在Pod启动的时候就存在。

	downwardAPI 为运行在pod中的应用容器提供了一种反向引用。让容器中的应用程序了解所处pod或Node的一些基础属性信息。

小结


1.3.2 CM

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

k8s的配置管理

	kubernetes作为分布式容器调度平台,肯定会遇到同样的问题,那么遇到这种问题后,我们不可能把资源删除后,重新修改一下,然后在启动生成,这种方法就太繁琐的。kubernetes提供了对pod中容器应用的集中配置管理组件:ConfigMap。通过ConfigMap来实现,借助于ConfigMap API向pod中的容器中注入配置信息的机制。
ConfigMap不仅仅可以保存单个属性,也可以用来保存整个配置文件或者JSON二进制文件。
注意:
	虽然configmap可以对各种应用程序提供定制配置服务,但是我们不能用它来替代专门的配置文件,我们可以简单的把它理解为Linux系统中的/etc目录,专门用来存储配置文件的目录

基本属性

确认属性
	kubectl explain cm
        binaryData  	使用二进制传递数据
        data    		传递数据
    注意:
        基于data的方式传递信息的话,他会在pod的容器内部生成一个单独的数据文件
数据的表现样式:
	普通数据:
		属性名称: 属性值
	文件数据:
		文件名称: |
		  文件内容
	注意:
    	|"多行键值"的标识符
注意:
	cm资源配置文件修改完毕后,会自动更新到所有应用该CM的pod里面

简单实践

准备工作

准备nginx容器的配置目录
[root@kubernetes-master1 /data/kubernetes/storage]# mkdir nginx-conf

创建主配置文件 
[root@kubernetes-master1 /data/kubernetes/storage]# vim nginx-conf/superopsmsb.conf
server {
    listen 8080;
    server_name www.superopsmsb.com;
    include /etc/nginx/conf.d/superopsmsb-*.cfg;
    location / {
        root /usr/share/nginx/html;
    }
}

创建状态配置片段文件 
[root@kubernetes-master1 /data/kubernetes/storage]# vim nginx-conf/superopsmsb-status.cfg
location /nginx-status {
    stub_status on;
}

创建资源对象

方法1:制定文件方法
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl create configmap nginx-conf1 --from-file=nginx-conf/superopsmsb.conf --from-file=nginx-conf/superopsmsb-status.cfg

方法2:指定目录方法
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl create configmap nginx-conf2 --from-file=nginx-conf/
确认效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get cm
NAME               DATA   AGE
kube-root-ca.crt   1      6h39m
nginx-conf1        2      38s
nginx-conf2        2      29s

[root@kubernetes-master1 /data/kubernetes/storage]# kubectl describe cm nginx-conf1
Name:         nginx-conf1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
superopsmsb.conf:
----
server {
    listen 8080;
    server_name www.superopsmsb.com;
    include /etc/nginx/conf.d/superopsmsb-*.cfg;
    location / {
        root /usr/share/nginx/html;
    }
}

superopsmsb-status.cfg:
----
location /nginx-status {
    stub_status on;
}


BinaryData
====

Events:  <none>

小结


1.3.3 CM案例

学习目标

这一节,我们从 案例解读、简单实践、小结 三个方面来学习。

案例解读

简介

在这里插入图片描述

简单实践

资源对象

准备资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get cm nginx-conf1 -o yaml > 08_kubernetes_cm_nginx_conf.yml

修改资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# cat 08_kubernetes_cm_nginx_conf.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: superopsmsb-nginxconf
data:
  superopsmsb-status.cfg: |
    location /nginx-status {
        stub_status on;
    }
  default.conf: |
    server {
        listen 80;
        server_name www.superopsmsb.com;

        include /etc/nginx/conf.d/superopsmsb-*.cfg;

        location / {
            root /usr/share/nginx/html;
        }
    }
准备nginx的首页文件内容
[root@kubernetes-master1 /data/kubernetes/storage]# cat 09_kubernetes_cm_nginx_index.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: superopsmsb-nginx-index
data:
  index.html: "Hello Nginx, This is Configmap\n"
创建nginx的清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# vim 10_kubernetes_cm_nginx_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-nginx
spec:
  containers:
  - image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
    name: nginx-web
    volumeMounts:
    - name: nginxconf
      mountPath: /etc/nginx/conf.d/
      readOnly: true
    - name: nginxindex
      mountPath: /usr/share/nginx/html/
      readOnly: true
  volumes:
  - name: nginxconf
    configMap:
      name: superopsmsb-nginxconf
      optional: false
  - name: nginxindex
    configMap:
      name: superopsmsb-nginx-index
      optional: false 
应用资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 08_kubernetes_cm_nginx_conf.yml -f 09_kubernetes_cm_nginx_index.yml -f 10_kubernetes_cm_nginx_pod.yml
configmap/superopsmsb-nginxconf created
configmap/superopsmsb-nginx-index created
pod/superopsmsb-nginx created

查看效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP           NODE               NOMINATED NODE   READINESS GATES
superopsmsb-nginx   1/1     Running   0          16s   10.244.3.8   kubernetes-node2   <none>           <none>
页面访问效果
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.3.8
Hello Nginx, This is Configmap
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.3.8/nginx-status
Active connections: 1
server accepts handled requests
 2 2 2
Reading: 0 Writing: 1 Waiting: 0

修改配置

修改配置文件
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  edit cm superopsmsb-nginxconf
...
apiVersion: v1
data:
  default.conf: |
    server {
        listen 8080;
        ...
        
确认效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl exec -it superopsmsb-nginx -- grep listen /etc/nginx/conf.d/default.conf
    listen 8080;
cm同步成功了,但是nginx的程序没有加载,我们重载一下配置文件
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl exec -it superopsmsb-nginx -- nginx -s reload
2022/07/22 05:33:33 [notice] 16#16: signal process started
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.3.8
curl: (7) Failed connect to 10.244.3.8:80; 拒绝连接
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.3.8:8080
Hello Nginx, This is Configmap

小结


1.3.4 Secret

学习目标

这一节,我们从 属性解读、命令实践、小结 三个方面来学习。

基础知识

简介

	secret volume为Pod提供加密的信息,相比于直接将敏感数据配置在Pod的定义或者镜像中,Secret提供了更加安全的机制,将共享的数据进行加密,防止数据泄露。
	Secret的对象需要单独定义并创建,然后以数据卷的形式挂载到Pod中,Secret的数据将以文件的形式保存,容器通过读取文件可以获取需要的数据。
	secret volume是通过tmpfs(内存文件系统)实现的,所以这种类型的volume不是永久存储的。

创建方式

手动创建:大部分情况用来存储用户私有的一些信息
		-- 创建方式与CM的方式一致
自动创建:用来作为集群中各个组件之间通信的身份校验使用

secret类型

generic
	通用类型,基于base64编码的,长用来存储密码,公钥之类的。常见的子类型有:kubernetes.io/basic-auth、kubernetes.io/rbd、kubernetes.io/ssh-auth(比较重要)
	
docker-registry
	专用于让kubelet启动Pod时从私有镜像仓库pull镜像时,首先认证到Registry时使用
	
tls
	专门用于保存tls/ssl用到证书和配对儿的私钥

简单实践

准备信息

我们以用户名和密码的加密方式进行认证,首先对用户名和密码进行base64加密
]# echo -n 'admin' | base64
YWRtaW4=
]# echo -n 'password' | base64
cGFzc3dvcmQ=

注意:
	-n的作用是仅仅传递字符串内容,而不包括字符串末尾的换行符

创建资源对象

secret资源定义文件 
[root@kubernetes-master1 /data/kubernetes/storage]# cat 11_kubernetes_secret_data.yml
apiVersion: v1
kind: Secret
metadata:
 name: superopsmsb-secret
type: kubernetes.io/basic-auth
data:
 username: YWRtaW4=
 password: cGFzc3dvcmQ=
	
生成新的对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 11_kubernetes_secret_data.yml
secret/superopsmsb-secret created

pod应用资源对象

创建资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# vim 12_kubernetes_secret_nginx_pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: superopsmsb-secret
spec:
  volumes:
  - name: secret
    secret:
     secretName: superopsmsb-secret
  containers:
    - name: nginx-web
      image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
      volumeMounts:
       - name: secret
         mountPath: /nginxsecret/
         readOnly: true
         
创建资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl apply -f 12_kubernetes_secret_nginx_pod.yml
pod/superopsmsb-secret created

查看效果

[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  describe  pod superopsmsb-secret
Name:         superopsmsb-secret
...
Containers:
  nginx-web:
    ...
    Mounts:
      /nginxsecret/ from secret (ro)
		...
Volumes:
  secret:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  superopsmsb-secret
    Optional:    false
查看文件内容效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  exec -it superopsmsb-secret -- /bin/bash
root@superopsmsb-secret:/# ls /nginxsecret/
password  username
root@superopsmsb-secret:/# cat /nginxsecret/password
passwordroot@superopsmsb-secret:/#
root@superopsmsb-secret:/# cat /nginxsecret/username
adminroot@superopsmsb-secret:/#

小结


1.3.5 Secret案例

学习目标

这一节,我们从 案例解读、简单实践、小结 三个方面来学习。

案例解读

需求

实践一个基于https来访问的nginx的web服务

准备工作

准备nginx容器的配置目录
[root@kubernetes-master1 /data/kubernetes/storage]# mkdir nginx-conf-tls

创建主配置文件 
[root@kubernetes-master1 /data/kubernetes/storage]# vim nginx-conf-tls/superopsmsb.conf
server {
    listen 443 ssl;
    server_name www.superopsmsb.com;
    ssl_certificate /etc/nginx/certs/tls.crt; 
    ssl_certificate_key /etc/nginx/certs/tls.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
    ssl_prefer_server_ciphers on;
    include /etc/nginx/conf.d/myserver-*.cfg;
    location / {
        root /usr/share/nginx/html;
    }
}

server {
    listen 80;
    server_name www.superopsmsb.com; 
    return 301 https://$host$request_uri; 
}

创建证书

准备nginx容器的配置目录
[root@kubernetes-master1 /data/kubernetes/storage]# mkdir tls-key

做证书
[root@kubernetes-master1 /data/kubernetes/storage]# openssl  genrsa -out tls-key/tls.key 2048

做成自签证书
[root@kubernetes-master1 /data/kubernetes/storage]# openssl req  -new -x509 -key tls-key/tls.key  -out tls-key/tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=www.superopsmsb.com
注意:
	域名必须是我们使用的域名信息

简单实践

创建资源对象文件

创建cm资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl create configmap nginx-ssl-conf --from-file=nginx-conf-tls/

创建secret资源对象
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl create secret tls nginx-ssl-secret --cert=tls-key/tls.crt --key=tls-key/tls.key

创建应用资源对象

创建资源配置文件
[root@kubernetes-master1 /data/kubernetes/storage]# vim 13_kubernetes_cm_secret_nginx.yml
apiVersion: v1
kind: Pod
metadata:
  name: superops-nginx-ssl
spec:
  containers:
  - image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
    name: nginx-web
    volumeMounts:
    - name: nginxcerts
      mountPath: /etc/nginx/certs/
      readOnly: true
    - name: nginxconfs
      mountPath: /etc/nginx/conf.d/
      readOnly: true
  volumes:
  - name: nginxcerts
    secret:
      secretName: nginx-ssl-secret
  - name: nginxconfs
    configMap:
      name: nginx-ssl-conf
      optional: false
      
应用资源配置文件
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl apply -f 13_kubernetes_cm_secret_nginx.yml

检查效果

[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pods -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP             NODE    ...
superops-nginx-ssl   1/1     Running   0          79s   10.244.2.6     node2

使用https测试
[root@kubernetes-master1 /data/kubernetes/storage]#  curl -H "Host:www.superopsmsb.com" https://10.244.2.6
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
结果提示:
	由于是自签证书,所以默认不允许通过,我们可以通过 -k的方式,让它忽略警告。
	
[root@kubernetes-master1 /data/kubernetes/storage]# curl -k -H "Host:www.superopsmsb.com" https://10.244.2.6
Hello Nginx, superops-nginx-ssl-1.23.0

使用http访问
[root@kubernetes-master1 /data/kubernetes/storage]# curl  http://10.244.2.6
<html>
<head><title>301 Moved Permanently</title></head>
...
结果显式:
	这个 301 就是我们定制的返回信息。

小结


1.4 状态管理

1.4.1 状态基础

学习目标

这一节,我们从 原理解读、资源对象、小结 三个方面来学习。

原理解读

简介

	我们知道,http协议是无状态的,而http应用是有状态的。所谓的无状态指的是 -- 每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况。也就是说,对于http协议本身的请求-应答模式来说它是独立的,彼此之间没有关联关系。
	而我们使用的web程序是需要有大量的业务逻辑相互关联才可以实现最终的目标,也就是说基于http协议的web应用程序是有状态的。只不过这个状态是需要借助于其他的机制来实现,比如 cookies、session、token以及其他辅助的机制。

在这里插入图片描述

场景需求

生产中,一些中间件业务集群,比如MySQL集群、MongoDB集群、Zookeeper集群等,这些应用集群有一下特点:
	1、每个节点都有固定的身份ID,集群成员通过身份ID进行通信
	2、集群的规模是比较固定的,一般不能随意变动
	3、节点都是由状态的,而且状态数据会做持久化存储
	4、集群中某个节点出现故障,集群功能肯定受到影响。
像这种状态类型的服务,只要过程中存在一点问题,那么影响及范围都是不可预测。

	到目前为止,我们学习到了Pod的管理对象有RC、Rs、Deployment,这三个都是面向无状态的服务,满足不了上述的有状态集群的场景需求,所以Kubernetes从V1.4版本引入了集群状态管理的功能,V1.5版本更名为StatefulSet[有状态应用副本集]

简单实践

简介

	StatefulSets 旨在与有状态的应用及分布式系统一起使用。然而在 Kubernetes 上管理有状态应用和分布式系统是一个宽泛而复杂的话题。StatefulSet有以下特点(使用场景)- 每个Pod都有稳定、唯一的网络标识,彼此间可以通信
	- StatefulSet控制的Pod副本启动、扩展、删除、更新等操作都是有顺序的。
	- StatefulSet里的Pod采用独立的持久化存储卷,存储状态数据

在这里插入图片描述

	Headless service会给一个StatufulSet控制的Pod提供一个唯一的DNS域名来作为每个成员的网络标识,集群内部成员之间使用域名通信。
	
DNS域名格式:
	$(podname).$(headless service name).$(namespace name).svc.cluster.local

StatefulSet组件

headless service
	自启动/重启pod名称是随机的,而为了statefulset特性一,所以借用headless service通过唯一的"网络标识"来直接指定的pod应用,所以它要求我们的dns环境是完好的。
	当一个StatefulSet挂掉,新创建的StatefulSet会被赋予跟原来的Pod一样的名字,通过这个名字来匹配到原来的存储,实现了状态保存。
volumeClaimTemplate
	自启动/重启pod的存储是共享的,但是集群中的副本数据是不一样的(例:redis),如果用共享存储的话,会导致多副本间的数据被覆盖,为了statefulsed的特性三,我们需要将pod和其申请的数据卷隔离开,每一种pod都有其对应的数据卷配置模板,来满足该要求。

小结


1.4.2 sts基础

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

属性解析

apiVersion: apps/v1  				# API群组及版本;
kind: StatefulSet  					# 资源类型的特有标识
metadata:
  name <string>  					# 资源名称,在作用域中要唯一
  namespace <string>  				# 名称空间;StatefulSet隶属名称空间级别
spec:
  replicas <integer> 				# 期望的Pod副本数,默认为1
  selector <object> 				# 标签选择器,须匹配Pod模板中的标签,必选字段
  template <object>  				# Pod模板对象,必选字段
  revisionHistoryLimit <integer> 	# 滚动更新历史记录数量,默认为10
  updateStrategy <Object>	 		# 滚动更新策略
    type <string>  					# 滚动更新类型,可用值有OnDelete和Rollingupdate
    rollingUpdate <Object>  		# 滚动更新参数,专用于RollingUpdate类型
      partition <integer>  			# 分区指示索引值,默认为0,一般用于版本分区域更新场景
  serviceName  <string>  			# 相关的Headless Service的名称,必选字段
  volumeClaimTemplates <[]Object>  	# 存储卷申请模板
    apiVersion <string>  			# PVC资源所属的API群组及版本,可省略
    kind <string>  					# PVC资源类型标识,可省略
    metadata <Object>  				# 卷申请模板元数据
    spec <Object>  					# 期望的状态,可用字段同PVC
  podManagementPolicy  <string> 	# Pod管理策略,默认的“OrderedReady”表示顺序创建并逆序删
  									# 除,另一可用值“Parallel”表示并行模式

简单实践

实践

定制资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# cat 14_kubernetes_sts_nginx.yml
apiVersion: v1
kind: Service
metadata:
  name: superopsmsb-sc-headless-svc
spec:
  ports:
  - name: myweb
    port: 80
  selector:
    app: sts-nginx-web
  clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset
spec:
  serviceName: storageclass-headless-svc
  replicas: 5
  selector:
    matchLabels:
      app: sts-nginx-web
  template:
    metadata:
      labels:
        app: sts-nginx-web
    spec:
      containers:
      - name: nginx-web
        image: kubernetes-register.superopsmsb.com/superopsmsb/nginx_web:v0.1
        volumeMounts:
        - name: nginx-storage
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: nginx-storage
    spec:
      storageClassName: storageclass
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 100Mi
应用资源清单文件
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 14_kubernetes_sts_nginx.yml
service/superopsmsb-sc-headless-svc created
statefulset.apps/statefulset created

查看资源对象创建
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get pod
NAME                 READY   STATUS    RESTARTS   AGE
statefulset-0        1/1     Running   0          40s
statefulset-1        1/1     Running   0          34s
statefulset-2        1/1     Running   0          31s
statefulset-3        1/1     Running   0          26s
statefulset-4        1/1     Running   0          17s
结果显示:
	pod的名称按照顺序进行基于statefulset拼接而成的
查看pvc效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pvc
NAME                          STATUS   VOLUME                                   ... AGE
nginx-storage-statefulset-0   Bound    pvc-1d90d499-7c03-4422-b593-4f8d5fa8ba5d ... 2m47s
nginx-storage-statefulset-1   Bound    pvc-ee5753a1-4e5b-4d17-846f-79c1e2efe79c ... 2m41s
nginx-storage-statefulset-2   Bound    pvc-74210b7a-3f16-491b-9e53-b30f616008d8 ... 2m38s
nginx-storage-statefulset-3   Bound    pvc-b88e378f-c025-469f-9409-4f062ae107cc ... 2m33s
nginx-storage-statefulset-4   Bound    pvc-e6bb732e-cc5e-4aaa-b8e9-566521f5a79a ... 2m24s

查看pv效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl get pv
NAME                                       ... STORAGECLASS ... AGE
pvc-1d90d499-7c03-4422-b593-4f8d5fa8ba5d   ... storageclass ... 2m53s
pvc-74210b7a-3f16-491b-9e53-b30f616008d8   ... storageclass ... 2m47s
pvc-b88e378f-c025-469f-9409-4f062ae107cc   ... storageclass ... 2m39s
pvc-e6bb732e-cc5e-4aaa-b8e9-566521f5a79a   ... storageclass ... 2m29s
pvc-ee5753a1-4e5b-4d17-846f-79c1e2efe79c   ... storageclass ... 2m50s

结果显示:
	所有的资源对象(pod+pv)都是按照顺序创建的,而且每个pv都有自己独有的标识符

定制各自的首页

定制各自nginx的首页
[root@kubernetes-ha1 /superopsmsb/nfs-data]# echo nginx-1 > default-nginx-storage-statefulset-0-pvc-1d90d499-7c03-4422-b593-4f8d5fa8ba5d/a.html
[root@kubernetes-ha1 /superopsmsb/nfs-data]# echo nginx-2 > default-nginx-storage-statefulset-1-pvc-ee5753a1-4e5b-4d17-846f-79c1e2efe79c/a.html
[root@kubernetes-ha1 /superopsmsb/nfs-data]# echo nginx-3 > default-nginx-storage-statefulset-2-pvc-74210b7a-3f16-491b-9e53-b30f616008d8/a.html
[root@kubernetes-ha1 /superopsmsb/nfs-data]# echo nginx-4 >default-nginx-storage-statefulset-3-pvc-b88e378f-c025-469f-9409-4f062ae107cc/a.html
[root@kubernetes-ha1 /superopsmsb/nfs-data]# echo nginx-5 > default-nginx-storage-statefulset-4-pvc-e6bb732e-cc5e-4aaa-b8e9-566521f5a79a/a.html
...

资源的关闭和删除

关闭资源
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  delete -f 14_kubernetes_sts_nginx.yml

pv和pvc效果
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get pvc
NAME                          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nginx-storage-statefulset-0   Bound    pvc-1d90d499-7c03-4422-b593-4f8d5fa8ba5d   100Mi      RWO            storageclass   16m
nginx-storage-statefulset-1   Bound    pvc-ee5753a1-4e5b-4d17-846f-79c1e2efe79c   100Mi      RWO            storageclass   16m
nginx-storage-statefulset-2   Bound    pvc-74210b7a-3f16-491b-9e53-b30f616008d8   100Mi      RWO            storageclass   16m
nginx-storage-statefulset-3   Bound    pvc-b88e378f-c025-469f-9409-4f062ae107cc   100Mi      RWO            storageclass   16m
nginx-storage-statefulset-4   Bound    pvc-e6bb732e-cc5e-4aaa-b8e9-566521f5a79a   100Mi      RWO            storageclass   16m
结果显示:
	由于pod 和 pv、pvc是独立的生命周期,所以他们之间互不影响。仅仅是通过名称关联在一起的。
启动资源
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  apply -f 14_kubernetes_sts_nginx.yml

查看资源启动
[root@kubernetes-master1 /data/kubernetes/storage]# kubectl  get pod -o wide
NAME            READY... AGE   IP            ...
statefulset-0   1/1  ... 10s   10.244.3.12   ...
statefulset-1   1/1  ... 8s    10.244.2.8    ...
statefulset-2   1/1  ... 7s    10.244.1.9    ...
statefulset-3   1/1  ... 6s    10.244.3.13   ...
statefulset-4   1/1  ... 4s    10.244.2.9    ...
可以看到:
	资源启动的方式仍然是按照顺序来启动的,因为名称不变,所以pvc会自动关联原来的pod,从而实现每个pod访问的都是之前的数据
	
尝试访问数据
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.2.8/a.html
nginx-2
[root@kubernetes-master1 /data/kubernetes/storage]# curl 10.244.2.9/a.html
nginx-5
结果显示:
	仍然是各自的数据

小结


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/714801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

36. QT中使用QFtp实现文件传输1 -- 本地文件或文件夹上传到远程服务器

1. 说明 在使用QT进行嵌入式开发或者是使用到TCP控制传输时,有时程序的正常运行会用到某一个文件或者整个文件夹,此时就需要软件方面将需要的文件或者文件夹传输到远程服务器上。在QT中主要有两种方式可以实现这个功能,一个是QT4中使用QFtp这个类来实现,这个类提供了很丰富…

每天一点Python——day48

#第四十八天 #什么是元组为什么元组没有增删改操作和生成式&#xff1f; 元组&#xff1a;Python内置的数据结构之一&#xff0c;是一个不可变序列 不可变序列&#xff1a;没有增删改操作【例如字符串&#xff0c;元组】 可变序列&#xff1a;可以执行增删改操作&#xff0c;操…

记录好项目D21

记录好项目 你好呀&#xff0c;这里是我专门记录一下从某些地方收集起来的项目&#xff0c;对项目修改&#xff0c;进行添砖加瓦&#xff0c;变成自己的闪亮项目。修修补补也可以成为毕设哦 本次的项目是个基于Springbootvue的景区旅游系统 一、系统介绍 本项目分为管理员与…

534 · 打劫房屋 II

链接&#xff1a;LintCode 炼码 - ChatGPT&#xff01;更高效的学习体验&#xff01; 题解&#xff1a;九章算法 - 帮助更多程序员找到好工作&#xff0c;硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧 处理循环数组问题&#xff1a;分类&#xff0c;重复&#xff0c;取反…

信息安全概述笔记

保密性、完整性、可用性是传统的信息安全的原则和目标&#xff0c;目前随着信息安全问题的日益严峻&#xff0c;信息安全的原则和目标衍生为诸如可控性、不可否认性等其他的原则和目标。 保密性&#xff08;Confidentiality&#xff09;:确保信息只能由那些被授权使用的人获取…

Web服务器群集:四层代理与七层代理

目录 一、理论 1.OSI七层模型 2.四层代理 3.七层代理 4.四层代理与七层代理区别 5.负载均衡器 6.常见的代理组件 7.应用场景 二、总结 一、理论 1.OSI七层模型 &#xff08;1&#xff09;概念 标准的七层网络分层是OSI七层模型&#xff0c;TCP/IP五层模型和TCP/IP四…

Android Matrix的理解

文章目录 前言一.基础1.1 Matrix1.2 使用Matrix的准备知识 二.preXXX和postXXX2.1 右乘和左乘2.2 验证规律 三.坐标原点结束 前言 Android绘制中最重要的要算Matrix类了&#xff0c;同时也是不太好理解的。以前也用过&#xff0c;但是掌握的也不是太好&#xff0c;刚好有时间好…

GO语言包相关总结 -引用(本地和远程),自定义,安装,使用

本篇文章总结以下go语言包相关的知识。 目录 一.导入包 &#xff08;1&#xff09;常规导入 &#xff08;2&#xff09;别名导入 &#xff08;3&#xff09;特殊导入 二.自定义包 三.安装自定义包 四.调用自定义包调用 五.获取远程包 六.go中的保留函数 七.实战 - G…

Python自动化测试实战篇(12),一文学完,Pytest 常用11种第三方插件

这些是之前的文章&#xff0c;里面有一些基础的知识点在前面由于前面已经有写过&#xff0c;所以这一篇就不再详细对之前的内容进行描述 Python自动化测试实战篇&#xff08;1&#xff09; Python自动化测试实战篇&#xff08;2&#xff09; Python自动化测试实战篇&#xff…

解决python-opencv:(-215:Assertion failed) _img.empty() in function ‘cv::imwrite‘在将视频分成帧图片,写入时出现的问题

最近在搞视频检测问题&#xff0c;在用到将视频分帧保存为图片时&#xff0c;图片可以保存&#xff0c;但是会出现(-215:Assertion failed) !_img.empty() in function cv::imwrite问题而不能正常运行&#xff0c;在检查代码、检查路径等措施均无果后&#xff0c;了解了视频分帧…

rk3399 调试ap6354

电路如下: wifi&#xff1a; 按照rk3399 sdk默认配置&#xff0c;修改相应的引脚 sdio_pwrseq: sdio-pwrseq { compatible "mmc-pwrseq-simple"; clocks <&rk808 1>; clock-names "ext_clock"; pinctrl-nam…

filter功能演示-鉴权、声明缓存

文章目录 Filter定义工作原理Filter所处环节 Demo示例总结 Filter定义 在Java EE&#xff08;Java Platform, Enterprise Edition&#xff09;中&#xff0c;过滤器&#xff08;Filter&#xff09;是一种强大的组件&#xff0c;用于在Web应用程序中拦截和处理传入的请求和响应…

银河麒麟服务器V10 SP1 .Net6.0 开机自启动

开机自动启动&#xff0c;折腾了一小天&#xff0c;设置/etc/init.d/ 、update-rc.d&#xff0c;可能刚开始用&#xff0c;经验不多吧&#xff0c;尝试多种方式我的服务怎么都启动不起来&#xff0c;根据之前nginx和redis的自动启动经验&#xff0c;使用systemd管理服务&#x…

Unity基础 物理系统 刚体组件下的移动.碰撞.触发检测

当在Unity中创建游戏或应用程序时&#xff0c;重力系统是一个非常重要的组成部分。它可以模拟物体受到地球引力的影响&#xff0c;并产生逼真的物理效果。在Unity中&#xff0c;我们可以使用刚体组件和重力向量来控制重力系统。 首先&#xff0c;在Unity中创建一个物体&#xf…

数据表示与数据编码

数据表示与数据编码 数据表示 bit:二进制位 例如:480Mbps(Mb/s) 小写字母b代表bitbyte:字节 1byte8bit 使用大写字母B表示 byte最初从IBM360中开始表示word:字长 在32bit计算机中一个字长为32位&#xff0c;在64bit计算机中一个字长为64位 最早的微处理器字长为4位 章节学习内…

Windows的基本操作

Windows的基本操作 一、用户管理1.1、用户帐户1.2、用户管理 二、网络配置2.1、配置和查看命令 三、常用命令 一、用户管理 1.1、用户帐户 系统中的一种对象&#xff08;用户、组、计算机&#xff09;包含多种属性&#xff0c;如用户名、密码等不同用户帐户的用户名和密码等一…

插入排序--直接插入排序,折半插入排序,希尔排序

插入排序是一种简单直观的排序方法&#xff0c;其基本思想是每次将一个待排序的记录按其关键词大小插入前面已经排好的子序列&#xff0c;直到全部记录插入完成。 一&#xff0c;直接插入排序&#xff1a;从小到大排序 数组序号01234567待排序列4938659776132749第一轮384965…

【数据算法与结构】用按层次顺序遍历二叉树的方法,统计树中具有度为1的结点数目

题目&#xff1a; Qestion: 用按层次顺序遍历二叉树的方法&#xff0c;统计树中具有度为1的结点数目。 数据结构定义 typedef struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right; } TreeNode;样例二叉树的形状 核心代码 // 统计具有度为1的节点数目的…

解决idea默认配置maven仓库地址的问题

我的maven配置地址 一直没注意 jar包什么的全部都是C盘默认的路径&#xff0c;导入项目更改后&#xff0c;再次导入项目 路径还是会变成C盘的路径&#xff1b; 上网搜索找到了解决的办法&#xff1b; 一、File——>New Projects Setup ———>Settings for New Projects…

React hooks之useCallback的使用与性能分析

使用useCallback优化代码 useCallback是对传过来的回调函数优化&#xff0c;返回的是一个函数&#xff1b;useMemo返回值可以是任何&#xff0c;函数&#xff0c;对象等都可以。 简单来说就是返回一个函数&#xff0c;只有在依赖项发生变化的时候才会更新&#xff08;返回一个…