Kubernetes中的secrets存储
华子目录
- 2.secrets
- 2.1secrets功能介绍
- 2.2secrets的创建
- 2.2.1从文件创建
- 2.2.2编写yaml文件
- 2.3secret的使用案例
- 2.3.1将secret挂载到volume中
- 2.3.2设置`子目录`映射`secret`密钥
- 2.3.3将secret设置为环境变量
- 2.3.4存储`docker register`的认证信息`spec.imagePullSecrets[]`
2.secrets
2.1secrets功能介绍
-
secret
对象类型用来保存敏感信息
,如密码
,Oauth令牌
和ssh key
-
敏感信息
放在secret
中比放在Pod
的定义
或者容器镜像
中来说更加安全
和灵活
-
Pod
可以用两种
方式使用secret
:- 作为
volume
中的文件
被挂载
到pod
中的一个或者多个容器
里 - 当
kubelet
为pod
拉取镜像
时使用
- 作为
-
secret
的类型
:Service Account
:Kubernetes
自动创建
包含访问api凭据
的secret
,并自动
修改pod
以使用此类型
的secret
Opaque
:使用base64
编码存储信息
,可以通过base64 --decode
解码获得原始数据
,因此安全性弱
。kubernetes.io/dockerconfigjson
:用于存储docker registry
的认证信息
[root@k8s-master ~]# mkdir secret
[root@k8s-master ~]# cd secret/
2.2secrets的创建
在创建secrets
时,我们可以使用create命令的方式创建
或者yaml文件的方式创建
#secret有3中类型
[root@k8s-master secret]# kubectl create secret
docker-registry (创建一个给 Docker registry 使用的 Secret)
generic (Create a secret from a local file, directory, or literal value)
tls (创建一个 TLS secret)
2.2.1从文件创建
先创建文件
#-n取消换行
[root@k8s-master secret]# echo -n huazi > username.txt
[root@k8s-master secret]# echo -n 12345 > password.txt
[root@k8s-master secret]# ls
password.txt username.txt
#创建一个名为userlist的generic类型的secret资源
[root@k8s-master secret]# kubectl create secret generic userlist --from-file username.txt --from-file password.txt
secret/userlist created
#查看
[root@k8s-master secret]# kubectl get secrets
NAME TYPE DATA AGE
userlist Opaque 2 3m13s[root@k8s-master secret]# kubectl describe secrets userlist
Name: userlist
Namespace: default
Labels: <none>
Annotations: <none>Type: OpaqueData
====
password.txt: 5 bytes
username.txt: 5 bytes
#以yaml格式查看,我们发现文件名作为了键,文件内容作为了值
[root@k8s-master secret]# kubectl get secrets userlist -o yaml
apiVersion: v1
data:password.txt: MTIzNDU=username.txt: aHVhemk=
kind: Secret
metadata:creationTimestamp: "2024-11-02T10:40:13Z"name: userlistnamespace: defaultresourceVersion: "811492"uid: 198d8aae-b738-4289-bb67-3d23c94ba909
type: Opaque
2.2.2编写yaml文件
#先将内容做base64编码
[root@k8s-master secret]# echo -n huazi | base64
aHVhemk=
[root@k8s-master secret]# echo -n 12345 | base64
MTIzNDU=
#创建一个名为userlist1的generic类型的secret资源
[root@k8s-master secret]# kubectl create secret generic userlist1 --dry-run=client -o yaml > secret-generic.yml[root@k8s-master secret]# vim secret-generic.yml
[root@k8s-master secret]# cat secret-generic.yml
apiVersion: v1
kind: Secret
metadata:name: userlist1
type: Opaque
data:username: aHVhemk=password: MTIzNDU=
[root@k8s-master secret]# kubectl apply -f secret-generic.yml
secret/userlist1 created
[root@k8s-master secret]# kubectl get secrets
NAME TYPE DATA AGE
userlist Opaque 2 11m
userlist1 Opaque 2 56s
[root@k8s-master secret]# kubectl describe secrets userlist1
Name: userlist1
Namespace: default
Labels: <none>
Annotations: <none>Type: OpaqueData
====
password: 5 bytes
username: 5 bytes
[root@k8s-master secret]# kubectl get secrets userlist1 -o yaml
apiVersion: v1
data:password: MTIzNDU=username: aHVhemk=
kind: Secret
metadata:annotations:kubectl.kubernetes.io/last-applied-configuration: |{"apiVersion":"v1","data":{"password":"MTIzNDU=","username":"aHVhemk="},"kind":"Secret","metadata":{"annotations":{},"name":"userlist1","namespace":"default"},"type":"Opaque"}creationTimestamp: "2024-11-02T10:50:32Z"name: userlist1namespace: defaultresourceVersion: "812512"uid: b29dc86a-d8f6-4eb3-88ea-11eb3fb707e0
type: Opaque
2.3secret的使用案例
#查看名为userlist1的secret类型
[root@k8s-master ~]# kubectl describe secrets userlist1
Name: userlist1
Namespace: default
Labels: <none>
Annotations: <none>Type: OpaqueData
====
password: 5 bytes
username: 5 bytes
#发现有两个键值对,一个password,一个username
2.3.1将secret挂载到volume中
#创建自主式pod,去使用userlist1
[root@k8s-master secret]# vim pod1.yml
[root@k8s-master secret]# cat pod1.yml
apiVersion: v1
kind: Pod
metadata:labels:run: testpodname: testpod
spec:containers:- image: busyboxplusname: busyboxpluscommand: ["/bin/sh","-c","sleep 10000"]volumeMounts: ##这是一个列表,定义了Pod中容器要挂载的卷。- name: secret-volume # #指定了要挂载的卷的名称,这个名称必须与volumes列表中定义的某个卷的名称相匹配。mountPath: /secret ##卷在容器内的挂载路径。readOnly: true #/secret这个目录只读权限volumes: #定义了Pod中可以使用的卷- name: secret-volume #定义了卷的名称,这个名称将在volumeMounts中被引用secret: #表示这个卷是由一个secrets支持的secretName: userlist1 #指定了secrets的名称为userlist1
[root@k8s-master secret]# kubectl apply -f pod1.yml
pod/testpod created
[root@k8s-master secret]# kubectl describe pods testpod
[root@k8s-master secret]# kubectl exec -it pods/testpod -- /bin/sh
/ # ls
bin etc lib linuxrc mnt proc run secret tmp var
dev home lib64 media opt root sbin sys usr
/ # cd secret/
/secret # ls
password username
/secret # ls -l
total 0
lrwxrwxrwx 1 root root 15 Nov 3 02:29 password -> ..data/password
lrwxrwxrwx 1 root root 15 Nov 3 02:29 username -> ..data/username
/secret # cat username
huazi
/secret # cat password
12345
我们发现userlist1
中的键
变成了文件名
,值
变成了文件内容
,其中文件
是一个软连接文件
#回收
[root@k8s-master secret]# kubectl delete -f pod1.yml
pod "testpod" deleted
2.3.2设置子目录
映射secret
密钥
[root@k8s-master secret]# vim pod2.yml
[root@k8s-master secret]# cat pod2.yml
apiVersion: v1
kind: Pod
metadata:labels:run: testpodname: testpod
spec:containers:- image: busyboxplusname: busyboxpluscommand: ["/bin/sh","-c","sleep 10000"]volumeMounts: #Pod中容器要挂载的卷- name: secret-volume #挂载的卷的名称,这个名称必须与volumes列表中定义的某个卷的名称相匹配。mountPath: /secret #容器中的挂载目录readOnly: true #只读volumes: #声明pod的数据卷- name: secret-volume #数据卷的名字为secret-volumesecret: #表示这个卷是由一个secrets支持的secretName: userlist1 #指定了secrets的名称为userlist1items:- key: username1path: users/username #username为userlist1中的键,会变为文件名,值会变为文件内容- key: password1path: auth/password #password为userlist1中的键,会变为文件名,值会变为文件内容
users
和auth
是/secret
下的子目录
,子目录
下分别有名为username
和password
的文本文件
[root@k8s-master secret]# kubectl apply -f pod2.yml
pod/testpod created
[root@k8s-master secret]# kubectl describe pods testpod
[root@k8s-master secret]# kubectl exec -it pods/testpod -- /bin/sh
/ # ls
bin etc lib linuxrc mnt proc run secret tmp var
dev home lib64 media opt root sbin sys usr
/ # cd secret/
/secret # ls
auth users
/secret # cd auth/
/secret/..2024_11_03_02_57_47.438164553/auth # ls
password
/secret/..2024_11_03_02_57_47.438164553/auth # ls -l
total 4
-rw-r--r-- 1 root root 5 Nov 3 02:57 password
/secret/..2024_11_03_02_57_47.438164553/auth # cat password
12345/secret/..2024_11_03_02_57_47.438164553/users # cat username
huazi
#回收
[root@k8s-master secret]# kubectl delete -f pod2.yml
pod "testpod" deleted
2.3.3将secret设置为环境变量
[root@k8s-master secret]# vim pod3.yml
[root@k8s-master secret]# cat pod3.yml
apiVersion: v1
kind: Pod
metadata:labels:run: testpodname: testpod
spec:containers:- image: busyboxplusname: busyboxpluscommand: ["/bin/sh","-c","env"]env:- name: Username #容器中的环境变量名valueFrom: #指定环境变量值的来源secretKeyRef: #表示环境变量的值是从一个secret中获取的name: userlist1 #secret资源的名字key: username #在指定的secret中,username键对应的值将用作环境变量Username的值- name: Password #容器中的环境变量名valueFrom: #指定环境变量值的来源secretKeyRef: #表示环境变量的值是从一个secret中获取的name: userlist1 #secret资源的名字key: password #在指定的secret中,password键对应的值将被用作环境变量Password的值restartPolicy: Never
[root@k8s-master secret]# kubectl apply -f pod3.yml
pod/testpod created
[root@k8s-master secret]# kubectl get pods
NAME READY STATUS RESTARTS AGE
testpod 0/1 Completed 0 7s
[root@k8s-master secret]# kubectl logs pods/testpod -c busyboxplus
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=testpod
SHLVL=1
HOME=/
Username=huazi #我们发现了创建的环境变量
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
Password=12345 #我们发现了创建的环境变量
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
#回收
[root@k8s-master secret]# kubectl delete -f pod3.yml --force
2.3.4存储docker register
的认证信息spec.imagePullSecrets[]
在做这个案例之前,我们先介绍一下docker
的公有仓库
和私有仓库
公有仓库
:上传镜像
需要认证
,下载镜像
不需要认证
私有仓库
:上传
和下载
都需要认证
先在harbor
上创建一个私有仓库
因为node1
主机上,我们之前做过认证
,这里我们先退出登录
[root@k8s-node1 ~]# docker logout harbor.huazi.org
Removing login credentials for harbor.huazi.org
node2
做过认证
,在node2
上传myapp:v1
镜像到huazi
这个私有仓库
中
[root@k8s-node2 ~]# docker images
myapp v1 d4a5e0eaa84f 6 years ago 15.5MB[root@k8s-node2 ~]# docker tag myapp:v1 harbor.huazi.org/huazi/myapp:v1
[root@k8s-node2 ~]# docker push harbor.huazi.org/huazi/myapp:v1
The push refers to repository [harbor.huazi.org/huazi/myapp]
a0d2c4392b06: Pushed
05a9e65e2d53: Pushed
68695a6cfd7d: Pushed
c1dc81a64903: Pushed
8460a579ab63: Pushed
d39d92664027: Pushed
v1: digest: sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e size: 1569
验证node1
上是否退出成功
#发现下载私有仓库中的myapp:v1镜像失败,说明退出成功
[root@k8s-node1 ~]# docker pull harbor.huazi.org/huazi/myapp:v1
Error response from daemon: unauthorized: unauthorized to access repository: huazi/myapp, action: pull: unauthorized to access repository: huazi/myapp, action: pull
创建名为docker-auth
的类型为docker-registry
的secret资源
#创建名为docker-auth的类型为docker-registry的secret资源
[root@k8s-master secret]# kubectl create secret docker-registry \
> docker-auth \ #secret名字
> --docker-server harbor.huazi.org \
> --docker-username admin \
> --docker-password 123456 \
> --docker-email huazi@huazi.org
secret/docker-auth created
#查看创建的docker-auth
[root@k8s-master secret]# kubectl get secrets
NAME TYPE DATA AGE
docker-auth kubernetes.io/dockerconfigjson 1 112s
userlist Opaque 2 17h
userlist1 Opaque 2 17h[root@k8s-master secret]# kubectl describe secrets docker-auth
Name: docker-auth
Namespace: default
Labels: <none>
Annotations: <none>Type: kubernetes.io/dockerconfigjsonData
====
.dockerconfigjson: 123 bytes
创建pod
去使用名为docker-auth
的secret资源
[root@k8s-master secret]# vim pod4.yml
[root@k8s-master secret]# cat pod4.yml
apiVersion: v1
kind: Pod
metadata:labels:run: testpodname: testpod
spec:nodeSelector:kubernetes.io/hostname: k8s-node1.org #指定让它在node1上运行containers:- image: harbor.huazi.org/huazi/myapp:v1 #指定拉取的镜像是huazi这个私有仓库的name: myappv1
# imagePullSecrets: #我们先把这里注释了
# - name: docker-auth
[root@k8s-master secret]# kubectl apply -f pod4.yml
pod/testpod created#我们发现这里的状态是ErrImagePull,表示镜像拉取失败
[root@k8s-master secret]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
testpod 0/1 ErrImagePull 0 6s 10.244.1.13 k8s-node1.org <none> <none>#回收
[root@k8s-master secret]# kubectl delete -f pod4.yml
pod "testpod" deleted
再去掉注释
[root@k8s-master secret]# vim pod4.yml
[root@k8s-master secret]# cat pod4.yml
apiVersion: v1
kind: Pod
metadata:labels:run: testpodname: testpod
spec:nodeSelector:kubernetes.io/hostname: k8s-node1.orgcontainers:- image: harbor.huazi.org/huazi/myapp:v1 #指定拉取的镜像是huazi这个仓库的name: myappv1imagePullSecrets:- name: docker-auth
#发现运行成功,说明node1上已经成功拉取了私有
[root@k8s-master secret]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
testpod 1/1 Running 0 7s 10.244.1.14 k8s-node1.org <none> <none>
#我们发现node1已经成功拉取了私有仓库中myapp:v1这个镜像
[root@k8s-node1 ~]# docker images
harbor.huazi.org/huazi/myapp v1 d4a5e0eaa84f 6 years ago 15.5MB
imagePullSecrets
是一个在Kubernetes
中用于配置Pod
以拉取私有Docker镜像
的字段
。当你在Kubernetes
集群中部署应用时,如果应用依赖于存储在私有Docker仓库
中的镜像
,你就需要配置imagePullSecrets
来确保Kubernetes
能够访问这些私有镜像
相关文章:

Kubernetes中的secrets存储
华子目录 2.secrets2.1secrets功能介绍2.2secrets的创建2.2.1从文件创建2.2.2编写yaml文件 2.3secret的使用案例2.3.1将secret挂载到volume中2.3.2设置子目录映射secret密钥2.3.3将secret设置为环境变量2.3.4存储docker register的认证信息spec.imagePullSecrets[] 2.secrets …...

使用 Elastic、OpenLLMetry 和 OpenTelemetry 跟踪 LangChain 应用程序
作者:来自 Elastic Bahubali Shetti Langchain 应用程序的使用正在增长。构建基于 RAG 的应用程序、简单的 AI 助手等的能力正在成为常态。观察这些应用程序更加困难。考虑到现有的各种选项,本博客展示了如何将 OpenTelemetry 检测与 OpenLLMetry 结合使…...

【论文复现】VALL-E:语音合成的新里程
📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐、摄影的一位博主。 📗本文收录于论文复现系列,大家有兴趣的可以看一看。 📘相关专栏C语言初阶、…...

java项目之微服务在线教育系统设计与实现(springcloud)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的闲一品交易平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 项目简介: 微服务在线教育系统设计与…...

P3-1.【结构化程序设计】第一节——知识要点:算法、顺序结构程序设计、if语句的语法结构及各种用法
讲解视频: P3-1.【结构化程序设计】第一节——知识要点:算法、顺序结构程序设计、if语句的语法结构及各种用法 知识要点:算法、顺序结构程序设计、if语句的语法结构及各种用法 一、算法、顺序结构程序设计任务分析 知识要点:算法…...

Vue2——单页应用程序路由的使用
一.单页应用程序与多页应用程序之间的比较 二.单页的应用场景 系统类网站 / 内部网站 / 文档类网站 / 移动端网站 三.路由的介绍 1. 什么是路由 路由是一种映射关系 2. Vue中的路由是什么 路径和组件的映射关系 四.VueRouter的使用 5个基础步骤(固定) …...
变分法(Calculus of Variations)
变分法(Calculus of Variations)是数学的一个分支,主要研究函数的极值问题,即寻找一个函数,使得某个泛函达到最大值或最小值。泛函是将函数作为变量的函数,与通常的函数不同,泛函的变量是函数本…...
包括 Nginx、Gateway、Nacos、Dubbo、Sentinel、RocketMQ 和 Seata 的调用链路描述:
以下是一个更详细和清晰的客户端请求在 Spring Cloud Alibaba 框架中,包括 Nginx、Gateway、Nacos、Dubbo、Sentinel、RocketMQ 和 Seata 的调用链路描述: 1. 客户端请求 用户在浏览器或移动应用中发起请求(例如,获取用户信息的…...

【P2-1】ESP8266 WIFI模块STA、AP、STA+AP、TCP/UDP透传工作模式介绍与AT指令介绍
前言:本文对ESP8266 WIFI模块STA、AP、STA+AP、TCP/UDP透传工作模式进行介绍;以及AT指令介绍,包括基础AT指令,WIFI功能AT指令、TCP/IP相关AT指令、常用AT指令实例进行介绍。 ESP8266 WIFI模块的接线及固件烧写可参考我的这篇博客:正点原子ATK-ESP8266 WIFI模块接线及固件…...

《C#语法一篇通》,20万字,48小时阅读,持续完善中。。。
本文摘录了C#语法的主要内容,接近20万字。 所有鸡汤的味道都等于马尿! 如果你相信任何所谓的鸡汤文章,智商堪忧。 计算机语言没有”好不好“之说,骗子才会告诉你哪个语言好,学好任何一本基础语言(C&#…...
[node] 2 fs文件系统模块
前言 fs模块是Node.js官方提供的内置Api,用来操作文件的模块。它提供了一系列的属性和方法,来满足用户对文件的操作需求 目标 1 掌握fs中文件处理方法readFile、writeFile等的基础用法 2 node如何安装 3 一些常用的终端快捷键 #mermaid-svg-rPp2nDYrW33gLvuI {font-family:&q…...

【react】基础知识点学习
1. 创建项目 npm install -g create-react-app npx create-react-app my-app cd my-app npm startindex.js为入口文件,App.js为根组件。 如何将react应用挂载在页面上? 将App组件渲染到id为root的DOM元素中 2. JSX JSX是|avaScript和XML(HTML)的缩写…...
D4--哈夫曼树和不等式
看文先三连,养成好习惯~看文先三连,养成好习惯~看文先三连,养成好习惯~ 目录 知识点: 堆排序: 优先队列: 定义:(默认大顶堆) 入队: 出队: 取队顶&…...

详解RabbitMQ三种队列类型
RabbitMQ 是一个强大的消息队列系统,它提供了多种队列类型以满足不同的使用需求。本文将探讨三种主要队列类型:经典队列、仲裁队列和流式队列,并讨论它们的区别和选型建议。 经典队列(Classic Queues) 简介ÿ…...

openGauss数据库-头歌实验1-3 创建和管理模式
一、创建和使用模式 (一)任务描述 本关任务:基于 openGauss 学习创建模式的相关知识。 (二)相关知识 为了完成本关任务,你需要掌握:1.openGauss 的常用操作,2.SQL 创建模式相关语…...
森林火灾检测数据集(猫脸码客 第233期)
森林火灾检测数据集 森林火灾是一种具有巨大破坏性的自然灾害,每年在全球范围内造成巨大损失。为了有效应对森林火灾,及早发现和快速响应是至关重要的。传统上,森林火灾的检测主要依赖于人工巡逻和卫星遥感技术。然而,这些方法存…...
LeetCode100之找到字符串中所有字母异位词(438)--Java
1.问题描述 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 示例1 输入: s "cbaebabacd", p "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba", 它是 …...

【Python】Python自习课:第一个python程序
【Python】Python自习课:第一个python程序...

DICOM标准:解析DICOM属性中的病人模块
目录 病人模块概述 1. 病人关系模块(Patient Relationship Module) 2. 病人识别模块(Patient Identification Module) 3. 病人统计模块(Patient Demographic Module) 4. 病人医学模块(Pati…...

C++设计模式创建型模式———生成器模式
文章目录 一、引言二、生成器/建造者模式三、总结 一、引言 上一篇文章我们介绍了工厂模式,工厂模式的主要特点是生成对象。当对象较简单时,可以使用简单工厂模式或工厂模式;而当对象相对复杂时,则可以选择使用抽象工厂模式。 工…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...

【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...