云原生系列-K8S实战

news2025/4/3 8:08:47

K8S实战

  • 1. K8S 资源创建方式
  • 2. NameSpace 资源创建
  • 3. Pod
  • 4. Deployment
  • 5. Service
  • 6. Ingress
  • 7. 存储抽象
    • 1. 环境准备
    • 2. PV&PVC
      • 1) 创建PV池
      • 2) PVC创建与绑定
    • 3. ConfigMap 抽取应用配置,并且可以自动更新
      • 1) redis 示例
      • 2) 创建pod
      • 3) 检查默认配置
      • 4) 修改 config map
      • 5)检查是否热更新
    • 4. Secret

1. K8S 资源创建方式

  1. 使用命令行创建
  2. 使用YAML文件创建

2. NameSpace 资源创建

命名空间用来对集群资源进行划分。默认只隔离资源,不隔离网络。
在这里插入图片描述

  1. 使用命令行
kubectl create ns hello
kubectl delete ns hello
  1. 使用YAML创建
    先创建hello.yaml,向里面追加以下代码。
    执行命令:kubectl apply -f helo.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: hello
  1. namespace 使用
    namespace 默认命名空间是叫 default ,我们使用kubectl get pods 是获取默认default下的资源,所以我们需要使用 kubectl get pods -A 才能获取所有的资源。
    如果访问某个命名空间下的资源:kubectl get pod -n XXX ,XXX代表命名空间。

3. Pod

运行中的一组容器,pod是k8s的最小单位。
在这里插入图片描述
pod 和 docker 中的容器区别:
在这里插入图片描述在这里插入图片描述

  • 首先先运行一个容器
  • kubectl run mynginx --image=nginx
  • 然后写YAML 定义pod
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: mynginx
  name: mynginx    # pod 名字
#  namespace: default
spec:
  containers:
  - image: nginx
    name: mynginx
  • pod 里面可以启动多个服务
  • 此时的应用还不能外部访问
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: myapp
  name: myapp
spec:
  containers:
  - image: nginx
    name: nginx
    args: ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
    ports:
      - containerPort: 8080  # Nginx 监听 8080 端口
  - image: tomcat:8.5.68
    name: tomcat
    env:
      - name: CATALINA_OPTS
        value: "-Dport.http=9090"  # Tomcat 监听 9090 端口
    ports:
      - containerPort: 9090  # Tomcat 监听 9090 端口

在这里插入图片描述


# 查看default名称空间的Pod
kubectl get pod 
# 描述
kubectl describe pod 你自己的Pod名字
# 删除
kubectl delete pod Pod名字
# 查看Pod的运行日志
kubectl logs Pod名字

# 每个Pod - k8s都会分配一个ip
kubectl get pod -owide
# 使用Pod的ip+pod里面运行容器的端口
curl 192.168.169.136

# 集群中的任意一个机器以及任意的应用都能通过Pod分配的ip来访问这个Pod

  • 可视化界面创建pod在这里插入图片描述

4. Deployment

控制Pod,使Pod拥有多副本,自愈,扩缩容等能力。

  1. 自愈功能
# 清除所有Pod,比较下面两个命令有何不同效果?
kubectl run mynginx --image=nginx     // 最初的方法 

kubectl create deployment mytomcat --image=tomcat:8.5.68   // 创建了一次部署
# 自愈能力  使用deployment启动的应用不怕应用崩溃,有自愈机制

# 查询
kubectl get deploy

#删除
kubectl delete deploy mytomcat 


  1. 多副本能力
  • 使用命令行
kubectl create deployment my-dep --image=nginx --replicas=3  
#  --replicas=3   将一个应用 
  • 使用配置文件
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-dep
  template:
    metadata:
      labels:
        app: my-dep
    spec:
      containers:
      - image: nginx
        name: nginx
  1. 扩缩容
    在这里插入图片描述
kubectl scale --replicas=5 deployment/my-dep

在这里插入图片描述

kubectl edit deployment my-dep
# 修改yaml方式
#修改 replicas 
  1. 自愈、故障转移
    ● 停机
    ● 删除Pod
    ● 容器崩溃

  2. 滚动更新

  • 支持不停机更新。 先启动新pod,新pod运行成功,连接至新pod,删除旧pod连接。
    在这里插入图片描述
# 将 deployment/my-dep nginx 升级成 1.16.1 版本
kubectl set image deployment/my-dep nginx=nginx:1.16.1 --record
kubectl rollout status deployment/my-dep
  1. 版本回退
#历史记录
kubectl rollout history deployment/my-dep


#查看某个历史详情
kubectl rollout history deployment/my-dep --revision=2

#回滚(回到上次)
kubectl rollout undo deployment/my-dep

#回滚(回到指定版本)
kubectl rollout undo deployment/my-dep --to-revision=2

在这里插入图片描述

https://kubernetes.io/zh/docs/concepts/workloads/controllers/

5. Service

  • 将一组 Pods 公开为网络服务的抽象方法。

在这里插入图片描述

  1. ClusterIP
  • 命令行
#暴露Deploy   暴露名为my-dep 的deployment 80端口,用8000 端口访问,使用service的ip:暴漏端口,可以实现负载均衡  
# 还支持 服务名.所在的名称空间.svc     例如:my-dep.default.svc:8000  集群内使用
kubectl expose deployment my-dep --port=8000 --target-port=80

# 查看
kubectl get service

#使用标签检索Pod
kubectl get pod -l app=my-dep
  • YAML
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  selector:
    app: my-dep
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80

在这里插入图片描述

  1. NodePort
    在这里插入图片描述

NodePort 集群外也可以访问

kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: my-dep
  type: NodePort

NodePort范围在 30000-32767 之间

6. Ingress

在这里插入图片描述

  1. 安装
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml

#修改镜像
vi deploy.yaml
#将image的值改为如下值:
registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0

# 检查安装的结果
kubectl get pod,svc -n ingress-nginx

kubectl get ing 

# 最后别忘记把svc暴露的端口要放行
  1. 使用
  • 先做一个测试环境
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-server
  template:
    metadata:
      labels:
        app: hello-server
    spec:
      containers:
      - name: hello-server
        image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/hello-server
        ports:
        - containerPort: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - image: nginx
        name: nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
spec:
  selector:
    app: nginx-demo
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: hello-server
  name: hello-server
spec:
  selector:
    app: hello-server
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 9000
  • 实现域名访问,达到访问不同的服务
apiVersion: networking.k8s.io/v1
kind: Ingress  
metadata:
  name: ingress-host-bar
spec:
  ingressClassName: nginx
  rules:
  - host: "hello.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-server
            port:
              number: 8000
  - host: "demo.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        path: "/nginx"  # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
        backend:
          service:
            name: nginx-demo  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000

/nginx 和 / 效果不同。
在这里插入图片描述

  • 路径重写
apiVersion: networking.k8s.io/v1
kind: Ingress  
metadata:
  annotations: // 注解信息
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: ingress-host-bar
spec:
  ingressClassName: nginx
  rules:
  - host: "hello.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-server
            port:
              number: 8000
  - host: "demo.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        path: "/nginx(/|$)(.*)"  # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
        backend:
          service:
            name: nginx-demo  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000
  • 流量限制
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-limit-rate
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "1"    //每秒放一个请求
spec:
  ingressClassName: nginx
  rules:
  - host: "haha.atguigu.com"
    http:
      paths:
      - pathType: Exact   // 精确匹配 
        path: "/"
        backend:
          service:
            name: nginx-demo
            port:
              number: 8000

7. 存储抽象

在这里插入图片描述
在这里插入图片描述

1. 环境准备

  • 所有节点安装nfs-utils
    yum install -y nfs-utils
  • 主节点
#nfs主节点  在master节点暴漏nfs/data目录 ,* 代表所有人 insecure 非安全 rw 读写 sync 同步
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

mkdir -p /nfs/data
systemctl enable rpcbind --now   启动rpcbind服务
systemctl enable nfs-server --now
#配置生效
exportfs -r
  • 从节点
#172.31.0.4 为 主节点私有IP 
showmount -e 172.31.0.4

#执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /root/nfsmount
mkdir -p /nfs/data

mount -t nfs 172.31.0.4:/nfs/data /nfs/data
# 写入一个测试文件
echo "hello nfs server" > /nfs/data/test.txt
  • 原生方式数据挂载 服务删除后挂在卷的内容不会删除
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-pv-demo
  name: nginx-pv-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-pv-demo
  template:
    metadata:
      labels:
        app: nginx-pv-demo
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          nfs:
            server: 172.31.0.4
            path: /nfs/data/nginx-pv

2. PV&PVC

PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格
在这里插入图片描述

1) 创建PV池

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv01-10m
spec:
  capacity:
    storage: 10M
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/01
    server: 172.31.0.4
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv02-1gi
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/02
    server: 172.31.0.4
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv03-3gi
spec:
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/03
    server: 172.31.0.4

在这里插入图片描述

2) PVC创建与绑定

  • 创建PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 200Mi
  storageClassName: nfs
  • 创建pod绑定PVC
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-pvc
  name: nginx-deploy-pvc
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy-pvc
  template:
    metadata:
      labels:
        app: nginx-deploy-pvc
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: nginx-pvc
  • 查看 kubectl get pvc

在这里插入图片描述

3. ConfigMap 抽取应用配置,并且可以自动更新

配置文件挂载

1) redis 示例

  • 创建配置,redis保存到k8s的etcd;

  • 创建一个configmap
    kubectl create cm redis-conf --from-file=redis.conf

  • 获取配置集 kubectl get cm

  • 查看 kubectl get cm redis-conf -oyaml

apiVersion: v1
data:    #data是所有真正的数据,key:默认是文件名   value:配置文件的内容
  redis.conf: |
    appendonly yes
kind: ConfigMap
metadata:
  name: redis-conf
  namespace: default

2) 创建pod

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    command:
      - redis-server
      - "/redis-master/redis.conf"  #指的是redis容器内部的位置
    ports:
    - containerPort: 6379
    volumeMounts:  # 卷挂载
    - mountPath: /data
      name: data
    - mountPath: /redis-master  # /redis-master 
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: redis-conf
        items:
        - key: redis.conf
          path: redis.conf

在这里插入图片描述

3) 检查默认配置

kubectl exec -it redis -- redis-cli

127.0.0.1:6379> CONFIG GET appendonly
127.0.0.1:6379> CONFIG GET requirepass

4) 修改 config map

在这里插入图片描述
配置文件会自动热更新。

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru 

5)检查是否热更新

kubectl exec -it redis -- redis-cli

127.0.0.1:6379> CONFIG GET maxmemory
127.0.0.1:6379> CONFIG GET maxmemory-policy

检查指定文件内容是否已经更新
修改了CM。Pod里面的配置文件会跟着变
配置值未更改,因为需要重新启动 Pod 才能从关联的 ConfigMap 中获取更新的值。
原因:我们的Pod部署的中间件自己本身没有热更新能力

4. Secret

  • Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全和灵活。
kubectl create secret docker-registry dfh-docker \
--docker-username=123\
--docker-password=123456\
--docker-email=111111@qq.com

##命令格式
kubectl create secret docker-registry regcred \
  --docker-server=<你的镜像仓库服务器> \
  --docker-username=<你的用户名> \
  --docker-password=<你的密码> \
  --docker-email=<你的邮箱地址>
apiVersion: v1
kind: Pod
metadata:
  name: private-nginx
spec:
  containers:
  - name: private-nginx
    image: dfh/guignginx:v1.0
  imagePullSecrets:
  - name: dfh-docker

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

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

相关文章

centos8上实现lvs集群负载均衡nat模式

1.背景&#xff1a; 个人&#xff08;菜鸟&#xff09;学习笔记&#xff0c;学点记下来&#xff0c;给未来的自己看。高手看了也请多指点。 按照课程讲&#xff0c;lvs是我国大神开发的负载均衡程序&#xff0c;被收录进内核&#xff0c;只要安装时内核里有它&#xff0c;它就…

影响HTTP网络请求的因素

影响 HTTP 网络请求的因素 1. 带宽 2. 延迟 浏览器阻塞&#xff1a;浏览器会因为一些原因阻塞请求&#xff0c;浏览器对于同一个域名&#xff0c;同时只能有4个连接&#xff08;这个根据浏览器内核不同可能会有所差异&#xff09;&#xff0c;超过浏览器最大连接数限制&…

(UI自动化测试web端)第二篇:元素定位的方法_css定位之css选择器

看代码里的【find_element_by_css_selector( )】( )里的表达式怎么写&#xff1f; 文章介绍了第三种写法css选择器&#xff0c;你要根据网页中的实际情况来判断自己到底要用哪一种方法来进行元素定位。每种方法都要多练习&#xff0c;全都熟了之后你在工作当中使用起来元素定位…

MPU6050模块详解:从原理到STM32驱动指南(上) | 零基础入门STM32第八十九步

主题内容教学目的/扩展视频加速度传感器电路连接。手册分析。驱动程序&#xff0c;读出数据。能读出3轴数据。 师从洋桃电子&#xff0c;杜洋老师 &#x1f4d1;文章目录 一、MPU6050模块介绍1.1 核心特性1.2 模块化优势 二、MPU6050模块连接方法2.1 硬件连接2.2 电源注意事项 …

STM32 MODBUS-RTU主从站库移植

代码地址 STM32MODBUSRTU: stm32上的modbus工程 从站 FreeModbus是一个开源的Modbus通信协议栈实现。它允许开发者在各种平台上轻松地实现Modbus通信功能&#xff0c;包括串口和以太网。FreeMODBUS提供了用于从设备和主站通信的功能&#xff0c;支持Modbus RTU和Modbus TCP协…

架构师面试(二十二):TCP 协议

问题 今天我们聊一个非常常见的面试题目&#xff0c;不管前端还是后端&#xff0c;也不管做的是上层业务还是底层框架&#xff0c;更不管技术方向是运维还是架构&#xff0c;都可以思考和参与一下哈&#xff01; TCP协议无处不在&#xff0c;我们知道 TCP 是基于连接的端到端…

程序自动化填写网页表单数据

1 背景介绍 如何让程序自动化填写网页表单数据&#xff0c;特别是涉及到批量数据情况时&#xff0c;可以减少人力。下面是涉及到的一些场景&#xff0c;都可以通过相关自动化程序实现。 场景1 场景1&#xff0c;领导安排&#xff0c;通过相关省、市、县、乡镇数据&#xff0…

Razer macOS v0.4.10快速安装

链接点这里下载最新的 .dmg 文件。将下载的 .dmg 映像文件拖入 应用程序 文件夹中。若首次打开时出现安全警告【什么扔到废纸篓】&#xff0c;这时候点击 Mac 的“系统偏好设置”-> “安全性与隐私”-> “通用”&#xff0c;然后点击底部的 “打开”。【或者仍然打开】 对…

如何自动化同义词并使用我们的 Synonyms API 进行上传

作者&#xff1a;来自 Elastic Andre Luiz 了解如何使用 LLM 来自动识别和生成同义词&#xff0c; 使术语可以通过程序方式加载到 Elasticsearch 同义词 API 中。 提高搜索结果的质量对于提供高效的用户体验至关重要。优化搜索的一种方法是通过同义词自动扩展查询词。这样可以更…

一. 相机模组摆放原理

1. 背景&#xff1a; 相机开发时经常出现因模组摆放问题&#xff0c;导致相机成像方向异常。轻则修改软件、模组返工&#xff0c; 重则重新修改堆叠&#xff0c;影响相机调试进度。因此&#xff0c;设计一个模型实现模组摆放纠错很有必要。 2. 原理&#xff1a; 2.1 口诀&am…

【C++游戏引擎开发】《线性代数》(1):环境配置与基础矩阵类设计

一、开发环境配置 1.1 启用C 20 在VS2022中新建项目后右键项目 1.2 启用增强指令集 1.3 安装Google Test vcpkg安装使用指南 vcpkg install gtest:x64-windows# 集成到系统目录&#xff0c;只需要执行一次&#xff0c;后续安装包之后不需要再次执行 vcpkg integrate inst…

sqli-labs靶场 less 8

文章目录 sqli-labs靶场less 8 布尔盲注 sqli-labs靶场 每道题都从以下模板讲解&#xff0c;并且每个步骤都有图片&#xff0c;清晰明了&#xff0c;便于复盘。 sql注入的基本步骤 注入点注入类型 字符型&#xff1a;判断闭合方式 &#xff08;‘、"、’、“”&#xf…

基于大模型的知识图谱搜索的五大核心优势

在传统知识图谱与生成式AI融合的浪潮中&#xff0c;基于大模型的知识图谱搜索正成为新一代智能检索的标杆技术&#xff0c;飞速灵燕智能体平台就使用了该技术&#xff0c;其核心优势体现在&#xff1a; 1. 语义穿透力升级 突破关键词匹配局限&#xff0c;通过大模型的深层语义…

【MySQL】从零开始:掌握MySQL数据库的核心概念(五)

由于我的无知&#xff0c;我对生存方式只有一个非常普通的信条&#xff1a;不许后悔。 前言 这是我自己学习mysql数据库的第五篇博客总结。后期我会继续把mysql数据库学习笔记开源至博客上。 上一期笔记是关于mysql数据库的增删查改&#xff0c;没看的同学可以过去看看&#xf…

Java版Manus实现来了,Spring AI Alibaba发布开源OpenManus实现

此次官方发布的 Spring AI Alibaba OpenManus 实现&#xff0c;包含完整的多智能体任务规划、思考与执行流程&#xff0c;可以让开发者体验 Java 版本的多智能体效果。它能够根据用户的问题进行分析&#xff0c;操作浏览器&#xff0c;执行代码等来完成复杂任务等。 项目源码及…

鸿蒙UI开发

鸿蒙UI开发 本文旨在分享一些鸿蒙UI布局开发上的一些建议&#xff0c;特别是对屏幕宽高比发生变化时的应对思路和好的实践。 折叠屏适配 一般情况&#xff08;自适应布局/响应式布局&#xff09; 1.自适应布局 1.1自适应拉伸 左右组件定宽 TypeScript //左右定宽 Row() { …

Elasticsearch-实战案例

一、没有使用Elasticsearch的查询速度698ms 1.数据库模糊查询不走索引&#xff0c;在数据量较大的时候&#xff0c;查询性能很差。需要注意的是&#xff0c;数据库模糊查询随着表数据量的增多&#xff0c;查询性能的下降会非常明显&#xff0c;而搜索引擎的性能则不会随着数据增…

IP数据报报文格式

一 概述 IP数据报由两部分组成&#xff1a;首部数据部分。首部的前一部分是固定长度&#xff0c;一共20字节大小&#xff0c;是所有IP数据报文必须具有的&#xff1b;固定部分后面是一些可选字段&#xff0c;其长度是可变的。 二 首部固定部分各字段意义 &#xff08;1&…

openEuler24.03 LTS下安装Kafka集群

目录 前提条件 Kafka集群规划 下载Kafka 解压 设置环境变量 配置Kafka 分发到其他机器 分发安装文件 分发环境变量 启动Kafka 测试Kafka 关闭Kafka 集群启停脚本 问题及解决 前提条件 安装好ZooKeeper集群&#xff0c;可参考&#xff1a;openEuler24.03 LTS下安…

qt QQuaternion详解

1. 概述 QQuaternion 是 Qt 中用于表示三维空间中旋转的四元数类。它包含一个标量部分和一个三维向量部分&#xff0c;可以用来表示旋转操作。四元数在计算机图形学中广泛用于平滑的旋转和插值。 2. 重要方法 默认构造函数 QQuaternion::QQuaternion(); // 构造单位四元数 (1…