Kubernetes(k8s)实战:深入详解Volume,详解k8s文件同步存储

news2024/9/22 7:23:03

文章目录

  • 一、Volume
    • 1、什么是Volume
    • 2、Host类型volume实战(不推荐)
      • (1)小总结
  • 二、PersistentVolume持久化volume(推荐)
    • 1、什么是PersistentVolume
    • 2、什么是PersistentVolumeClaim
    • 3、Pod中如何使用PVC
  • 三、Pod中使用PVC实战
    • 1、搭建NFS
    • 2、创建PV&PVC&Nginx
      • (1)在nfs服务器创建所需要的目录
      • (2)定义PV,PVC和Nginx的yaml文件
      • (3)根据yaml文件创建资源并查看资源
      • (4)测试持久化存储
  • 四、StorageClass
    • 1、什么是StorageClass
    • 2、StorageClass实战
      • (1)准备好NFS服务器[并且确保nfs可以正常工作],创建持久化需要的目录
      • (2)根据rbac.yaml文件创建资源
      • (3)根据deployment.yaml文件创建资源
      • (4)根据class.yaml创建资源
      • (5)根据pvc.yaml创建资源
      • (6)根据nginx-pod.yaml创建资源
  • 五、PV的状态和回收策略

一、Volume

1、什么是Volume

Volume官网:https://kubernetes.io/docs/concepts/storage/volumes/

On-disk files in a Container are ephemeral, which presents some problems for non-trivial applications when running in Containers. First, when a Container crashes, kubelet will restart it, but the files will be lost - the Container starts with a clean state. Second, when running Containers together in a Pod it is often necessary to share files between those Containers. The Kubernetes Volume abstraction solves both of these problems.

容器中的磁盘上文件是短暂的,这给在容器中运行的重要应用程序带来了一些问题。首先,当一个容器崩溃时,kubelet会重启它,但是文件会丢失——容器以干净的状态开始。其次,当在一个Pod中一起运行容器时,通常需要在这些容器之间共享文件。Kubernetes的Volume 抽象解决了这两个问题。

2、Host类型volume实战(不推荐)

定义一个Pod,其中包含两个Container,都使用Pod的Volume

创建volume-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: volume-pod
spec:
  containers:
  - name: nginx-container # nginx container
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts: # 使用某个volume
    - name: volume-pod # volume名称
      mountPath: /nginx-volume # 对应container中的目录
  - name: busybox-container # busybox的container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
    volumeMounts:
    - name: volume-pod
      mountPath: /busybox-volume # 对应container目录
  volumes: # 定义volume
  - name: volume-pod # volume名称
    hostPath: # volume类型
      path: /tmp/volume-pod  # 对应宿主机的位置
# 运行
kubectl apply -f volume-pod.yaml
# 查看pod,发现pod运行在了w1节点
kubectl get pods -o wide
# 进入w1的容器
docker exec -it a2e9dbc52a11 /bin/bash
docker exec -it 27c66caa2b85 sh
# 看容器的/nginx-volume目录中的内容与宿主机的/tmp/volume-pod内容是不是一样,再折腾一下看文件会不会同步,看两个pod中的内容是否会同步

(1)小总结

我们发现,使用volume形式,会与宿主机共享目录,里面数据内容是一致的。

如果pod挂掉了,宿主机的文件仍然不会丢失,可以完美解决数据保存的问题,保证数据不丢失。

但是host的方式,只能保证pod与当前宿主机目录的绑定关系,集群下无法保证(如果下次pod运行在另一台宿主机,文件仍然无法关联)。

或许我们可以使用打标签的方式,指定该pod永远部署在某一台机器,但是如果该机器挂了,就无法使用了。

二、PersistentVolume持久化volume(推荐)

1、什么是PersistentVolume

官网:https://kubernetes.io/docs/concepts/storage/persistent-volumes/

# 实例 ,定义一个PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi    # 存储空间大小
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce     # 只允许一个Pod进行独占式读写操作
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp            # 远端服务器的目录
    server: 172.17.0.2    # 远端的服务器

说白了,PV是K8s中的资源,volume的plugin实现,生命周期独立于Pod,封装了底层存储卷实现的细节。这种资源可以和第三方存储技术绑定,比如DFS。
注意:PV的维护通常是由运维人员、集群管理员进行维护的。

2、什么是PersistentVolumeClaim

官网:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims

有了PV,那Pod如何使用呢?为了方便使用,我们可以设计出一个PVC(PersistentVolumeClaim)来绑定PV,然后把PVC交给Pod来使用即可。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

说白了,PVC会匹配满足要求的PV[是根据size和访问模式进行匹配的],进行一一绑定,然后它们的状态都会变成Bound。

也就是PVC负责请求PV的大小和访问方式,然后Pod中就可以直接使用PVC咯。

注意:PVC通常由开发小伙伴维护,开发小伙伴无需关注与存储细节,开发小伙伴只需要声明使用的资源大小,由PVC来声明,PVC会去找合适的PV。

3、Pod中如何使用PVC

官网:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#claims-as-volumes

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim # 指定pvc

三、Pod中使用PVC实战

在这里插入图片描述

(1)共享存储使用nfs,我们选择在m节点
(2)创建pv和pvc
(3)nginx pod中使用pvc

NFS(network file system)网络文件系统,是FreeBSD支持的文件系统中的一种,允许网络中的计算机之间通过TCP/IP网络共享资源。

1、搭建NFS

在master节点(192.168.56.100)上搭建一个NFS服务器,目录为/nfs/data

01 选择master节点作为nfs的server,所以在master节点上
	# 安装nfs
	yum install -y nfs-utils
	# 创建nfs目录
	mkdir -p /nfs/data/
	mkdir -p /nfs/data/mysql
	# 授予权限
	chmod -R 777 /nfs/data
	# 编辑export文件,输入下面一行
	vi /etc/exports
	  /nfs/data *(rw,no_root_squash,sync)
	# 使得配置生效
	exportfs -r
	# 查看生效 显示:/nfs/data     	<world>
	exportfs
	# 启动rpcbind、nfs服务
	systemctl restart rpcbind && systemctl enable rpcbind
	systemctl restart nfs && systemctl enable nfs
	# 查看rpc服务的注册情况
	rpcinfo -p localhost
	# showmount测试	showmount -e 192.168.56.100
	showmount -e master-ip
	
02 所有node上安装客户端 
	yum -y install nfs-utils
	systemctl start nfs && systemctl enable nfs

2、创建PV&PVC&Nginx

(1)在nfs服务器创建所需要的目录

mkdir -p /nfs/data/nginx

(2)定义PV,PVC和Nginx的yaml文件

nginx-pv-demo.yaml

# 定义PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv # pv名字
spec:
  accessModes:
    - ReadWriteMany # 多个pod多次访问模式
  capacity:
    storage: 2Gi     # 大小
  nfs:
    path: /nfs/data/nginx     # 服务器path
    server: 192.168.56.100 # 服务器ip  
    
---
# 定义PVC,用于消费PV
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc # pvc名称
spec:
  accessModes:
    - ReadWriteMany # 访问模式,需要与pv对应,会进行匹配
  resources:
    requests:
      storage: 2Gi # 需要的空间大小
  
---
# 定义Pod,指定需要使用的PVC
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels: 
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-persistent-storage
          mountPath: /usr/share/nginx/html # container共享目录
      volumes:
      - name: nginx-persistent-storage
        persistentVolumeClaim:
          claimName: nginx-pvc # 指定pvc

(3)根据yaml文件创建资源并查看资源

# 启动
[root@m ~]# kubectl apply -f nginx-pv-demo.yaml
persistentvolume/nginx-pv created
persistentvolumeclaim/nginx-pvc created
deployment.apps/nginx created
# 查看pv和pvc
[root@m ~]# kubectl get pv,pvc
NAME                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/nginx-pv   2Gi        RWX            Retain           Bound    default/nginx-pvc                           10s

NAME                              STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/nginx-pvc   Bound    nginx-pv   2Gi        RWX                           9s
# 查看pod
[root@m ~]# kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP               NODE   NOMINATED NODE   READINESS GATES
nginx-77945f44db-8rfhr   1/1     Running   0          53s   192.168.80.207   w2     <none>           <none>

# 删除
kubectl delete -f nginx-pv-demo.yaml

(4)测试持久化存储

01 在nfs服务器的/nfs/data/nginx新建文件1.html,写上内容hello nginx

02 kubectl get pods -o wide 得到nginx-pod的ip地址 :192.168.80.207

03 curl nginx-pod-ip/1.html
curl 192.168.80.207/1.html :打印hello nginx

04 kubectl exec -it nginx-pod bash 进入/usr/share/nginx/html目录查看,发现有了1.html

05 kubectl delete pod nginx-pod
发现原来的pod被删了,又自动启动了一个新的pod,新的pod地址为:192.168.80.208

06 查看新nginx-pod的ip并且访问nginx-pod-ip/1.html
curl 192.168.80.208/1.html 确实仍然能够访问,打印出hello nginx

四、StorageClass

1、什么是StorageClass

上面手动管理PV的方式还是有点low,能不能更加灵活一点呢?
官网:https://kubernetes.io/docs/concepts/storage/storage-classes/
nfs github:github:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs

A StorageClass provides a way for administrators to describe the “classes” of storage they offer. Different classes might map to quality-of-service levels, or to backup policies, or to arbitrary policies determined by the cluster administrators. Kubernetes itself is unopinionated about what classes represent. This concept is sometimes called “profiles” in other storage systems.

Each StorageClass contains the fields provisioner, parameters, and reclaimPolicy, which are used when a PersistentVolume belonging to the class needs to be dynamically provisioned.

The name of a StorageClass object is significant, and is how users can request a particular class. Administrators set the name and other parameters of a class when first creating StorageClass objects, and the objects cannot be updated once they are created.

StorageClass声明存储插件,用于自动创建PV。

说白了就是创建PV的模板,其中有两个重要部分:PV属性和创建此PV所需要的插件。

这样PVC就可以按“Class”来匹配PV。

可以为PV指定storageClassName属性,标识PV归属于哪一个Class。

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
  - debug
volumeBindingMode: Immediate

01 对于PV或者StorageClass只能对应一种后端存储
02 对于手动的情况,一般我们会创建很多的PV,等有PVC需要使用的时候就可以直接使用了
03 对于自动的情况,那么就由StorageClass来自动管理创建
04 如果Pod想要使用共享存储,一般会在创建PVC,PVC中描述了想要什么类型的后端存储、空间等,K8s从而会匹配对应的PV,如果没有匹配成功,Pod就会处于Pending状态。Pod中使用只需要像使用volumes一样,指定名字就可以使用了
05 一个Pod可以使用多个PVC,一个PVC也可以给多个Pod使用
06 一个PVC只能绑定一个PV,一个PV只能对应一种后端存储

有了StorageClass之后的PVC可以变成这样:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim1
spec:
accessModes:
    - ReadWriteMany
resources:
 requests:
    storage: 1Mi
  storageClassName: nfs

StorageClass之所以能够动态供给PV,是因为Provisioner,也就是Dynamic Provisioning

但是NFS这种类型,K8s中默认是没有Provisioner插件的,需要自己创建。

2、StorageClass实战

github:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs
在这里插入图片描述

(1)准备好NFS服务器[并且确保nfs可以正常工作],创建持久化需要的目录

mkdir -p /nfs/data/cxf
chmod 777 /nfs/data

# server: 192.168.56.100

(2)根据rbac.yaml文件创建资源

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-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"]
  - apiGroups: [""]
    resources: ["services", "endpoints"]
    verbs: ["get"]
  - apiGroups: ["extensions"]
    resources: ["podsecuritypolicies"]
    resourceNames: ["nfs-provisioner"]
    verbs: ["use"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-provisioner
     # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-provisioner
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-provisioner
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac.yaml

(3)根据deployment.yaml文件创建资源

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-provisioner
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner
    spec:
      serviceAccount: nfs-provisioner
      containers:
        - name: nfs-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: example.com/nfs
            - name: NFS_SERVER
              value: 192.168.56.100 # 指定nfs地址
            - name: NFS_PATH
              value: /nfs/data/cxf # 指定nfs目录
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.56.100 # 指定nfs地址
            path: /nfs/data/cxf # 指定nfs目录
# 创建
kubectl apply -f deployment.yaml

(4)根据class.yaml创建资源

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: example-nfs
provisioner: example.com/nfs
# 创建
kubectl apply -f class.yaml

(5)根据pvc.yaml创建资源

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi
  # 这个名字要和上面创建的storageclass名称一致
  storageClassName: example-nfs
# 创建
kubectl apply -f pvc.yaml
# 获取pvc,发现状态已经是Bound了
kubectl get pvc
# 获取pv,发现自动创建了pv
kubectl get pv

(6)根据nginx-pod.yaml创建资源

kind: Pod
apiVersion: v1
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
      - name: my-pvc # 指定pvc
        mountPath: "/usr/cxf" # 容器地址
  restartPolicy: "Never"
  volumes:
    - name: my-pvc # 指定pvc
      persistentVolumeClaim:
        claimName: my-pvc
# 创建
kubectl apply -f nginx-pod.yaml
# 查看pod
kubectl get pods -o wide
# 进入nginx
kubectl exec -it nginx bash
cd /usr/cxf
# 进行同步数据测试 

五、PV的状态和回收策略

  • PV的状态

Available:表示当前的pv没有被绑定

Bound:表示已经被pvc挂载

Released:pvc没有在使用pv, 需要管理员手工释放pv

Failed:资源回收失败

  • PV回收策略

Retain:表示删除PVC的时候,PV不会一起删除,而是变成Released状态等待管理员手动清理

Recycle:在Kubernetes新版本就不用了,采用动态PV供给来替代

Delete:表示删除PVC的时候,PV也会一起删除,同时也删除PV所指向的实际存储空间

注意:目前只有NFS和HostPath支持Recycle策略。AWS EBS、GCE PD、Azure Disk和Cinder支持Delete策略

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

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

相关文章

初中学物理实验室教学装备配置标准

初中物理实验室建设&#xff0c;以现行义务教育物理教科书为基本参照&#xff0c;以学生学科核心素养发展为基本遵循&#xff0c;以加强实验等实践性教学活动&#xff0c;落实立德树人根本任务为目标。因此&#xff0c;初中物理实验室的建设实施过程中&#xff0c;需结合校情、…

PCB封装设计指导(三)如何创建PAD

PCB封装设计指导(三)如何创建PAD 当我们完全看完了Datasheet之后,确定了需要建立的封装类型,以及尺寸之后,这一步就可以开始创建封装的PAD了。 下面介绍如何创建各种类型的PAD和一些技巧和注意点,包括创建flash的注意事项。 1.如何创建PAD 1. 打开pad designer ,根据尺…

STL源码刨析 string实现

目录 一. string 类介绍 二. string 的简单实现 1. 类内成员变量 2. Member functions string ~string operator string(const string& str) 3. Capacity size capacity empty clear reserve resize 4.Modifiers push_back append operator insert era…

【回溯算法part05】| 491.递增子序列、46.全排列、47.全排列||

目录 &#x1f388;LeetCode491.递增子序列 &#x1f388;LeetCode46.全排列 &#x1f388;LeetCode47.全排列|| &#x1f388;LeetCode491.递增子序列 链接&#xff1a;491.递增子序列 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xf…

【玩转Linux操作】详细讲解Linux的 权限 操作

&#x1f38a;专栏【​​​​​​​玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【Love Story】 &#x1f970;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f354;权限的基本介绍⭐具体分析&…

【复习1-2天的内容】【我们一起60天准备考研算法面试(大全)-第六天 6/60】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

网络编程---day4

广播发送方&#xff1a; 广播接收方&#xff1a; 组播发射方&#xff1a; 组播接收方&#xff1a;

OpenCV的remap实现图像垂直翻转

以下是完整的代码: #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream>int main() {

从“存算一体”到“存算分离”:金融核心数据库改造的必经之路

科技云报道原创。 近年来&#xff0c;数据库国产化趋势愈发明显&#xff0c;上百家金融业试点单位在数据库国产化的进程中&#xff0c;进一步增强信心&#xff0c;向50%国产化率大步迈进。 但随着数据库国产化的深入&#xff0c;一些金融机构采用国产数据库服务器本地盘的“存…

【微信小程序创作之路】- 小程序中WXML、JS、JSON、WXSS作用

【微信小程序创作之路】- 小程序中WXML、JS、JSON、WXSS作用 第三章 微信小程序WXML、JS、JSON、WXSS作用 文章目录 【微信小程序创作之路】- 小程序中WXML、JS、JSON、WXSS作用前言一、WXML是什么&#xff1f;二、JS是什么&#xff1f;三、JSON是什么&#xff1f;四、WXSS是什…

IPC 进程间通讯 (1)

目录 1.1 为什么要通信 1.2 为什么能通信 2.1 进程间通信机制的结构 2.2 进程间通信机制的类型 2.3 进程间通信机制的接口设计 3.1 SysV共享内存 3.2 POSIX共享内存 3.3 共享内存映射 3.4 Android ION 3.5 dma-buf heaps 3.6 匿名管道 3.7 命名管道 3.8 SysV消息队列…

基于Java实验室考勤管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

buuctf pwn入门1

目录 1. test_your_nc(简单nc ) pwn做题过程 2. rip(简单栈溢出) 3. warmup_csaw_2016(栈溢出 覆盖Return_Address) 4. ciscn_2019_n_1(栈溢出 浮点数十六进制) (1) 覆盖v2值 (2) 利用system("cat /flag"); 5. pwn1_sctf_2016(字符逃逸栈溢出 32位) 6. jarvis…

实现【Linux--NTP 时间同步服务搭建】

实现【Linux--NTP 时间同步服务搭建】 &#x1f53b; 前言&#x1f53b; 一、NTP 校时&#x1f530; 1.1 NTP 服务校时与 ntpdate 校时的区别&#x1f530; 1.2 NTP 校时服务搭建&#x1f530; 1.2.1 确认 ntp 的安装&#x1f530; 1.2.2 配置 ntp 服务&#x1f530; 1.2.3 启动…

QTday1

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->resize(500,600);this->setFixedSize(500,600);//设置窗口标题this->setWindowTitle("盗版qq");//设置窗口图标this->setWindowIcon(QIcon("D://QQ下载//ic…

【C++STL】list的反向迭代器

list的反向迭代器 文章目录 list的反向迭代器reverse.h疑问1&#xff1a;为什么在迭代器当中不需要写深拷贝、析构函数疑问2&#xff1a;为什么在迭代器当中需要三个模板参数&#xff1f;疑问3&#xff1a;反向迭代器是怎么实现的&#xff1f;疑问4&#xff1a;为什么*解引用不…

LCD_1602 显示单个字符

目录 效果图&#xff1a;​ 硬件接线&#xff1a; 源代码&#xff1a; Lcd1602.c lcd1602.h main.c 硬件&#xff1a;lcd1602 51单片机 串口 软件&#xff1a;stc keil 效果图&#xff1a; 硬件接线&#xff1a; LCD1602 RW RS E 分别接51单片机的P25 P26 P27 LCD1602…

决策树分析特征重要性可视化无监督特征筛选

from sklearn.tree import DecisionTreeClassifierdtc DecisionTreeClassifier() # 初始化 dtc.fit(x_train, y_train) # 训练# 获取特征权重值 weights dtc.feature_importances_ print(>>>特征权重值\n, weights)# 索引降序排列 sort_index np.argsort(weights…

【学习】ChatGPT对问答社区产生了哪些影响?

引用 StackExchange 社区 CEO Prashanth Chandrasekar 的一篇博客标题 “Community is the future of AI”&#xff0c;引出本文的观点&#xff0c;即ChatGPT对问答社区产生了颠覆性影响&#xff0c;问答社区必须釜底抽薪、涅槃重生&#xff0c;但我们必须坚信“社区才是AI的未…

慎用QGraphicsDropShadowEffect绘制阴影,会导致部分控件一直resizeEvent、重新绘制

我的程序还在创作中&#xff0c;代码还只是UI部分&#xff0c;数据都是固定的&#xff0c;也没有定时刷新之类代码&#xff0c;样式也只是使用了一小部分。有一天我发现我在QTableWidget添加自定义控件的时候&#xff0c;效应特别慢&#xff0c;而自定义控件只是在鼠标进入或离…