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

k8s的存储卷、数据卷---动态PV创建

当发布PVC之后可以生成PV,还可以在动态服务器上直接生成挂载目录。PVC直接绑定和使用PV。

动态PV需要两个组件

  1. 存储卷插件:Provisioner(存储分配器)根据定义的属性创建PV

  2. StorageClass:定义属性

存储卷插件

存储卷插件:k8s本身不支持动态PV创建,不包括NFS。所以需要声明和安装一个外部插件Provisioner(存储分配器)

Provisioner(存储分配器)可以动态的创建PV。根据PVC的请求自动绑定和使用。

StorageClass

StorageClass来定义PV属性、存储类型、大小、回收策略等等。

使用NFS实现动态PV。NFS支持的方式NFS-client。先创建Provisioner来适配NFS-client

需要先创建nfs-client-Provisioner

动态PV实验举例

实验架构图:

serviceAccount:NFS PRovisioner:是一个插件,没有权限是无法在集群当中获取k8s的信息的。插件要有权限才能监听APIserver。获取get,list(获取集中列表资源)create delete.

开始实验:

实验架构:
master01: 20.0.0.32
ndoe01: 20.0.0.34
node02: 20.0.0.35
k8s5: 20.0.0.36  NFS服务k8s5
mkdir k8s
chmod 777 k8s/
vim /etc/exports
/opt/k8s 20.0.0.0/24(rw,no_root_squash,sync)systemctl restart rpcbind
systemctl restart nfs
showmount -e
确定每台主机上都能查看serviceAccount:NFS PRovisioner:是一个插件,没有权限是无法在集群当中获取k8s的信息的。插件要有权限才能监听APIserver。获取get,list(获取集中列表资源)create delete.给NFS PRovisioner创建一个账户
[root@master01 ~]# cd /opt/
[root@master01 opt]# vim nfs-client-rbac.yaml
#定义账户类型和名称
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner
#定义账户的名称叫nfs-client-provisioner
---#定义类型名称和权限以及动作
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: nfs-client-provisioner-role
rules:
#定义权限- apiGroups: [""]
#apiGroups定义规则可以使用哪个api组的权限
#[""]:如果为空表示直接使用api的核心资源resources: ["persistentvolumes"]
#定义在核心组中需要的资源.定义获取PV的相关资源verbs: ["get","list","watch","create","delete"]
#表示权限需要哪些动作
#watch表示监听
#表示声明的账号可以对PV进行这些操作- apiGroups: [""]resources: ["persistentvolumeclaims"]
#定义获取pvc的相关组件verbs: ["watch","get","list","update"]
#表示权限需要哪些动作- apiGroups: ["storage.k8s.io"]resources: ["storageclass"]verbs: ["get","watch","get"]- apiGroups: [""]
#获取核心组件中的事件信息
#api在调用时候的所有事件信息resources: ["events"]verbs: ["get","create","watch","update","patch"]- apiGroups: [""]resources: ["endpoints"]
#获取服务节点的终端IP地址verbs: ["delete","create","get","watch","update","patch","list"]
#获取权限需要哪些动作---#开始绑定角色和权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: nfs-client-provisioner-bind
subjects:
- kind: ServiceAccountname: nfs-client-provisioner
#声明账户的名称需要一一对应namespace: default
#要在哪个有权限就声明使用哪个命名空间
roleRef:kind: ClusterRolename: nfs-client-provisioner-role
#声明调用权限的名称apiGroup: rbac.authorization.k8s.io
#声明api的组名
#将定义好的集群规则定义好的权限都赋给nfs-client-provisioner账户
kubectl apply -f nfs-client-rbac.yaml
角色和权限都创建完毕

部署插件


NFS-privisioner。使用deployment来部署插件 pod
1.20之后又一个新的机制
selfLink:API的资源对象之一,消失资源对象在集权当中滋生的一个连接。self Link是一个唯一表示符号。可以用于表示k8s集群当中每个资源的对象。
selfLink的值是一个URL。指向该资源对象的k8s的api路径
更好的实现资源对象的查找和引用。

[root@master01 opt]# vim /etc/kubernetes/manifests/kube-apiserver.yaml 
- --feature-gates=RemoveSelfLink=false
#feature-gates:在不破坏现在又规则以及功能基础上引入新功能或者修改现在又的功能机制。禁用不影响之前的规则
[root@master01 opt]# kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
[root@master01 opt]# kubectl get pod -n kube-system 
kubectl delete pod -n kube-system kube-apiserver部署nfs-provisioner的插件
nfs的provisioner的客户端,以pod的方式运行在集群中监听k8s当中的pv请求。动态的创建于nfs服务相关的PV
容器使用的配置,在provisioner当中定义好环境变量。传给容器。storageclass的名称、nfs服务器的地址以及nfs的目录
开始部署:
[root@master01 opt]# vim nfs-client-provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-provisionerlabels:app: nfs1
spec:replicas: 1selector:matchLabels:app: nfs1template:metadata:labels:app: nfs1spec:serviceAccountName: nfs-client-provisionercontainers:
#指定容器- name: nfs1image: quay.io/external_storage/nfs-client-provisioner:latestvolumeMounts:- name: nfsmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: nfs-storage
#配置provisioner的账户名称。要和storageclass的资源名称一致- name: NFS_SERVER
#nfs共享服务器的地址value: 20.0.0.36- name: NFS_PATHvalue: /opt/k8s
#把变量传递给内部容器,设置共享服务器和共享目录volumes:- name: nfsnfs:server: 20.0.0.36path: /opt/k8s
#表示后续在哪创建存储卷。定义后续存储卷存储的位置。
#provisioner的作用就是创建pv
#定义pv的属性
#告诉你nfs共享的服务器
#告诉你共享目录
#容器和本地目录进行挂载
#当有符合storageclass的pvc请求来了之后
#这个nfs-client-provisioner就会往定义的服务器上自动创建存储目录[root@master01 opt]# kubectl apply -f nfs-client-provisioner.yaml

 

部署PVC的存储卷和策略

[root@master01 opt]# vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass
#匹配provisioner
provisioner: nfs-storage
#定义pv的相关属性
parameters:archiveOnDelete: "false"
#表示当pvc被删除之后pv的状态。有false和true两种
#如果是false。pvc如果被删除那么pv的状态将是released。可以人工调整继续使用
#如果定义是true,那么pv的状态将是Archived。表示pv将不再可用。
#一般来说都用false
reclaimPolicy: Retain
#定义pv的回收策略。reclaimPolicy定义的只支持两种retain和delete
allowVolumeExpansion: true
#pv的存储空间可以动态的扩缩容[root@master01 opt]# kubectl apply -f nfs-client-storageclass.yaml 
[root@master01 opt]# kubectl get storageclasses.storage.k8s.io
NAME                      PROVISIONER   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client-storageclass   nfs-storage   Retain          Immediate           true     
name:storageclass的名称
PROVISIONER:对应的创建pv的PROVISIONER插件
RECLAIMPOLICY:回收策略。保留
VOLUMEBINDINGMODE:卷绑定模式。lmmediate表示pvc请求创建pv时,系统会立即绑定一个可用的pv
waitForFirstConsumer:第一个使用者出现之后再绑定pv
ALLOWVOLUMEEXPANSION:true表示可以再运行时对pv进行扩容
AGE:生命周期

 

开始创建pod

[root@master01 opt]# vim pvc-pod.yaml
#创建PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nfs-pvc
spec:accessModes:- ReadWriteManystorageClassName: nfs-client-storageclassresources:requests:storage: 2Gi
#创建一个pvc,名称为nfs-pvc,使用的pv属性是nfs-client-storageclass定义的属性
#创建的pv大小是2Gi最后由provisioner---apiVersion: apps/v1
kind: Deployment
metadata:name: nginx1labels:app: nginx1
spec:replicas: 1selector:matchLabels:app: nginx1template:metadata:labels:app: nginx1spec:containers:- name: nginx1image: nginx:1.22volumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlpersistentVolumeClaim:
#指定pvcclaimName: nfs-pvc
#pod引用上面的pvc

检验实验结果

[root@k8s5 k8s]# cd /opt/k8s
[root@k8s5 k8s]# ls
[root@k8s5 k8s]# cd default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc/
[root@k8s5 default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc]# ls
[root@k8s5 default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc]# echo 123 > index.html
[root@k8s5 default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc]# ls[root@master01 opt]# curl 10.244.2.147:80
123

检验回收策略

Retain策略

[root@master01 opt]# vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass
#匹配provisioner
provisioner: nfs-storage
#定义pv的相关属性
parameters:archiveOnDelete: "false"
#表示当pvc被删除之后pv的状态。有false和true两种
#如果是false。pvc如果被删除那么pv的状态将是released。可以人工调整继续使用
#如果定义是true,那么pv的状态将是Archived。表示pv将不再可用。
#一般来说都用false
reclaimPolicy: Retain
allowVolumeExpansion: true
#pv的存储空间可以动态的扩缩容开始测试资源回收策略:
reclaimPolicy: Retainroot@k8s5 k8s]# cd default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc/
[root@k8s5 default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc]# ls
[root@k8s5 default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc]# echo 123 > index.html
[root@k8s5 default-nfs-pvc-pvc-3771a7a5-381e-4934-a9a7-ae3a675628fc]# ls
index.html[root@master01 opt]# kubectl get pod -o wide
[root@master01 opt]# curl 10.244.2.147:80
[root@master01 opt]# kubectl delete deployments.apps nginx2
#删除控制器
[root@master01 opt]# kubectl delete pvc nfs-pvc2 
#删除PVC
[root@master01 opt]# kubectl delete pv pvc-c15e8810-62e5-49eb-a7f1-282b5292347
#删除PV
回到k8s5查看共享目录依旧存在

 

Delete策略

[root@master01 opt]# vim nfs-client-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs-client-storageclass
#匹配provisioner
provisioner: nfs-storage
#定义pv的相关属性
parameters:archiveOnDelete: "false"
#表示当pvc被删除之后pv的状态。有false和true两种
#如果是false。pvc如果被删除那么pv的状态将是released。可以人工调整继续使用
#如果定义是true,那么pv的状态将是Archived。表示pv将不再可用。
#一般来说都用false
reclaimPolicy: Delete
allowVolumeExpansion: true
#pv的存储空间可以动态的扩缩容reclaimPolicy: Delete[root@k8s5 k8s]# cd default-nfs-pvc2-pvc-c15e8810-62e5-49eb-a7f1-282b5292347b
[root@k8s5 default-nfs-pvc2-pvc-c15e8810-62e5-49eb-a7f1-282b5292347b]# ls
[root@k8s5 default-nfs-pvc2-pvc-c15e8810-62e5-49eb-a7f1-282b5292347b]# echo 456 > index.html
[root@k8s5 default-nfs-pvc2-pvc-c15e8810-62e5-49eb-a7f1-282b5292347b]# cd /opt/k8s/
[root@k8s5 k8s]# ls[root@master01 opt]# kubectl delete deployments.apps nginx2
#删除控制器
[root@master01 opt]# kubectl delete pvc nfs-pvc2 
#删除PVC
[root@master01 opt]# kubectl delete pv pvc-c15e8810-62e5-49eb-a7f1-282b5292347
#删除PV
回到k8s5查看共享目录自动消失
实验完成!!!!

 

rbac:Role-based ACCESS CONTROL:基础权限配置。用来定义角色在集群当中可以使用的权限。

provisioner的作用就是创建pv

nfs-client-provisioner.yaml的作用就是定义pv的属性告诉你nfs共享的服务器。告诉你共享目录。容器和本地目录进行挂载。当有符合storageclass的pvc请求来了之后这个nfs-client-provisioner就会往定义的服务器上自动创建存储目录

工作流程图:

 

总结

动态pv的两个组件:

provisioner插件:支持nfs。创建pv目录

strogeclass:定义pv的属性。

动态pv的默认策略是删除

动态pv删除pvc的状态。最好设置为releassed

  1. 给卷插件创建账号,确保集群可以在集群内部通信,获取资源,监听事件。创建和删除以及更新pv

  2. 创建卷插件的pod。由卷插件的pod创建pv

  3. 定义storageclass给pv赋予属性。属性包括:pvc被删除之后pv的状态,以及回收策略。

  4. 创建pvc

  5. 实验完成

相关文章:

k8s的存储卷、数据卷---动态PV创建

当发布PVC之后可以生成PV,还可以在动态服务器上直接生成挂载目录。PVC直接绑定和使用PV。 动态PV需要两个组件 存储卷插件:Provisioner(存储分配器)根据定义的属性创建PV StorageClass:定义属性 存储卷插件 存储卷插件:k8s本…...

go最佳实践:如何舒适地编码

什么是 "最佳 "做法? 有很多做法:你可以自己想出来,在互联网上找到,或者从其他语言中拿来,但由于其主观性,并不总是容易说哪一个比另一个好。”最佳”的含义因人而异,也取决于其背景…...

C# 消息队列、多线程、回滚、并行编程、异步编程、反射

消息队列 消息队列是一种在应用程序之间传递消息的异步通信机制。它可以使应用程序解耦并提高系统的可伸缩性和可靠性。在 C# 中,你可以使用多个消息队列技术,其中一种广泛使用的技术是 RabbitMQ。 RabbitMQ 是一个开源的消息代理,实现了高…...

汇编代码生成和编译器的后端

1.前置程序:语义分析和中间代码生成 基于SLR(1)分析的语义分析及中间代码生成程序-CSDN博客https://blog.csdn.net/lijj0304/article/details/135097554?spm1001.2014.3001.5501 2.程序目标 在前面编译器前端实现的基础上,将所生成的中间代码翻译成某…...

MySQL 8.0中新增的功能(九)

FROM_UNIXTIME()、UNIX_TIMESTAMP()和CONVERT_TZ()的64位支持 根据MySQL 8.0.28版本的更新,FROM_UNIXTIME()、UNIX_TIMESTAMP() 和 CONVERT_TZ() 函数现在在支持64位的平台上处理64位值。这包括64位版本的Linux、MacOS和Windows。在兼容的平台上,UNIX_T…...

QT基础篇(8)QT5模型视图结构

1.概述 QT5的模型视图结构主要包括模型(Model)、视图(View)和委托(Delegate)三个部分。 模型(Model):模型是数据的抽象表示,负责存储和管理数据。它可以是自…...

vue3-响应式基础之reactive

reactive() 还有另一种声明响应式状态的方式&#xff0c;即使用 reactive() API。与将内部值包装在特殊对象中的 ref 不同&#xff0c;reactive() 将使对象本身具有响应性&#xff1a; 「点击按钮1」 <script lang"ts" setup> import { reactive } from vuec…...

【ceph】如何将osd的内容挂载出来---ceph-objectstore-tool 实现

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…...

怎样实现安全便捷的网间数据安全交换?

数据安全交换是指在数据传输过程中采取一系列措施来保护数据的完整性、机密性和可用性。网间数据安全交换&#xff0c;则是需要进行跨网络、跨网段甚至跨组织地进行数据交互&#xff0c;对于数据的传输要求会更高。 大部分企业都是通过网闸、DMZ区、VLAN、双网云桌面等方式实现…...

微信小程序定义并获取日志/实时log信息

步骤一&#xff1a;开通实时日志 可以在开发者工具->详情->性能质量->实时日志&#xff0c;点击前往&#xff0c;在浏览器打开we分析界面&#xff1a; 也可登录小程序管理后台&#xff0c;点击统计进入we分析&#xff1a; 在we分析界面找到性能质量&#xff0c;打开实…...

海外代理IP怎么用?常见使用问题及解决方案

海外代理IP是指提供全球范围内的代理服务器&#xff0c;代理服务器充当IP与目标网站之间的中介&#xff0c;可以起到安全匿名、提高网速、突破网络壁垒的作用。在使用代理IP的过程中&#xff0c;用户可能会遇到各种挑战&#xff0c;如连接问题、速度慢等。理解这些问题的原因并…...

DP:数位DP

数位DP的大致思想&#xff1a;枚举每一位能选取的合法值。 1. LC 2376 统计特殊整数 说是DP&#xff0c;但实际上状态转移方程挺难写的&#xff0c;毕竟是枚举集合论&#xff0c;这里就不贴状态转移方程了。总体的写法其实是搜索记忆化。之所以称之为DP&#xff0c;是因为&am…...

js逆向第21例:猿人学第20题新年挑战

文章目录 一、前言二、定位加密参数1、定位wasm加密2、反编译wasm3、定位sign加密三、代码实现四、参考文献一、前言 新春福利:抓取这5页的数字,计算加和并提交结果 二、定位加密参数 通过get请求地址可以看到需要搞定参数有page、sign、t如下图: 进入堆栈不难发现这样一…...

贪心+蓝桥杯

原题路径 题目思路 : 思路很简单&#xff0c;肯定是贪心做法&#xff0c;要使总代价最小&#xff0c;需用那些出现次数比avg多的数来替换那些没有出现或者是出现次数少于avg的数, 所以我们存当前数每次出现的代价是多少 ,枚举每一个 0 - 9 之间的数 &#xff0c;如果当前数出现…...

第二篇:新建node项目并运行

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 安装 Node.js&#xff1a;首先&#xff0c;确保你的…...

阳光保险选择OceanBase稳定运行超700天

阳光保险集团成立于 2005 年 7 月&#xff0c;旗下拥有财产保险、人寿保险、信用保证保险、资产管理等多家专业子公司&#xff0c;是全球市场化企业中成长最快的集团公司之一&#xff0c;目前位列中国保险行业前八。随着数字化升级趋势的不断加速&#xff0c;很多企业产生将软硬…...

最强大脑闪电心算草稿1

#include<bits/stdc.h> #include<windows.h> using namespace std; int main() {double speed,n,op,sum0;int ans;srand(time(NULL));cout<<"请输入加(1)/减(2)/加减混合(3):";cin>>op;cout<<"请输入题目数量:";cin>>…...

融优学堂-艺术史

导论4 1.【单选题】根据导论的讲解&#xff0c;下列表述正确的是&#xff08;&#xff09;。&#xff08;1&#xff09;艺术品是因人的活动而被创造出来的人工制品。&#xff08;2&#xff09;许多物品被制造出来时&#xff0c;最初的目的是满足某种实用的用途&#xff0c;而不…...

༺༽༾ཊ—设计-七个-07-原则-模式—ཏ༿༼༻

第七原则&#xff1a;迪米特职责 类与类之间的耦合度尽可能低 换言之&#xff0c;我们可以理解成———只与直接朋友说话&#xff0c;不跟陌生人说话 直接朋友&#xff1a; 通过方法传参传进来的朋友&#xff0c; 类自己的字段&#xff0c; 构造函数进来的也是直接朋友&…...

一篇文章带你搞懂---全排序

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 全排序&#xff08;Permutation&#xff09;是指将一组元素按照一定的顺序进行排列的过程。在计算机科学中&#xff0c;全排序是一…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...