k8s-权限管理

1. 身份认证

我们在目前的k8s集群环境里面,只能在master节点上执行kubectl的一些命令,在其他节点上执行就会报错

# 看一下是不是
[root@node1 ~]# kubectl get nodes
E0220 12:50:15.695133    6091 memcache.go:238] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0220 12:50:15.695771    6091 memcache.go:238] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0220 12:50:15.697555    6091 memcache.go:238] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0220 12:50:15.699191    6091 memcache.go:238] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
E0220 12:50:15.700655    6091 memcache.go:238] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused
The connection to the server localhost:8080 was refused - did you specify the right host or port?

我们可以看到在node1上执行kubectl get nodes都会报错,那就更不谈创建pod之类的操作了,那为什么master可以而其他节点不行呢?这是因为在master节点上是有一个kubeconfig的

[root@master ~]# env |grep -i kubeconfig
KUBECONFIG=/etc/kubernetes/admin.conf

我们可以看到在master节点上是有一个环境变量加载了这个admin.conf这个文件的,这个文件就是k8s集群默认的管理员文件,换一种说法,只要你有本事偷走这个文件并且保障你的网络跟这个集群的网络是通的,那么恭喜你,得到了一个k8s集群

node节点操作

我们现在来将这个admin.conf传到node1上,再来看看node1能不能去执行命令

# 传文件
[root@master ~]# scp /etc/kubernetes/admin.conf node1:~
admin.conf                                                                    100% 5669     6.2MB/s   00:00  
# 在node1上执行命令看看效果
[root@node1 ~]# kubectl get node --kubeconfig=admin.conf
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   43d   v1.26.0
node1    Ready    node1                  43d   v1.26.0
node2    Ready    node2                  43d   v1.26.0

我们通过这个小实验看到,node1节点确实是可以获取到节点信息了,但是他执行的命令跟master上有所不同,在node1上执行的时候他是需要执行配置文件的,如果你不想执行的话可以将这个注册到环境变量里面

[root@node1 ~]# echo "export KUBECONFIG=/root/admin.conf" >> /etc/profile
[root@node1 ~]# tail -1 /etc/profile
export KUBECONFIG=/root/admin.conf

只需要这样就好了

但是这样存在一个问题,他们用的都是管理员的配置文件,那么就相当于他们都是管理员,对集群有全部权限,我们追求是的最小权限原则,就是我给你的权限正好能够让你完成属于你自己的任务,多的权限不应该有,那么我们能不能像Linux一样创建普通用户,给普通用户定制权限呢?当然是可以的

创建普通用户并授权

我们现在来创建一个普通用户zhangsan并授权

1. 生成私钥

# 使用openssl生成一个rsa类型的私钥,私钥文件名是client.key 2048位
[root@master ca]# openssl genrsa -out client.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
........................+++++
...............................................................................................................................................................................................................................................+++++
e is 65537 (0x010001)
[root@master ca]# ls
client.key

2. 生成zhangsan用户证书请求文件

# 使用client.key 生成一个新的文件叫做client.csr
[root@master ca]# openssl req -new -key client.key -subj "/CN=zhangsan" -out client.csr
[root@master ca]# ls
client.csr  client.key

3. 为zhangsan用户颁发证书

zhangsan用户如何将请求发送给k8s的ca进行证书颁发呢?这个时候我们可以使用k8s自带的ca来颁发证书

# k8s的ca在/etc/kubernetes/pki下
[root@master ca]# openssl x509 -req -in client.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out client.crt -days 3650
Signature ok
subject=CN = zhangsan
Getting CA Private Key
# 拷贝ca到当前目录
[root@master ca]# cp /etc/kubernetes/pki/ca.crt .
[root@master ca]# ls
ca.crt  client.crt  client.csr  client.key

4. 创建命名空间及pod

[root@master ca]# kubectl create ns zhangsan
namespace/zhangsan created
# 切到这个命名空间
[root@master ca]# kubectl config set-context --current --namespace zhangsan
Context "kubernetes-admin@kubernetes" modified.
# 创建一个pod
[root@master ca]# kubectl run test01 --image nginx --image-pull-policy IfNotPresent
pod/test01 created
[root@master ca]# kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
test01   1/1     Running   0          13s

5. 创建角色

角色是什么呢?我们可以这样想,假如我们现在有增删改查4个权限,用户用张三,李四,王五,那我们现在给他们授权的话只能是一个权限一个权限的去给,万一后面又新增了用户我们依旧是一个个去指定,过于麻烦,而角色就是介于权限与用户之间的一个模板,就像这样我们指定了一个角色是管理员,拥有增删改查4个权限一个是开发的角色,拥有增改查的权限一个是普通用户角色,只有查的权限我们指定好这3个模板之后,后面新来的用户只需要知道他的作用是什么,比如他就是一个普通用户,那我们直接把这个模板给他套上,那他就只有查的权限,来了一个开发者,那我们就给他开发的这个角色模板,他就自然而然的拥有增改查的权限

# 这里的pod-reader是role的名字 后面的--verb就是这个角色所包含哪些权限,并且这个角色所能操作的资源对象仅仅只有pod
[root@master ca]# kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
role.rbac.authorization.k8s.io/pod-reader created

6. 绑定角色给用户

# 创建一个rolebinding名字叫zhangsan,这个zhangsan并不是用户张三,而是这个rolebinding的名字,后面--user这个才是用户张三
[root@master ca]# kubectl create rolebinding zhangsan --role pod-reader --user zhangsan
rolebinding.rbac.authorization.k8s.io/zhangsan created
[root@master ca]# kubectl get rolebindings.rbac.authorization.k8s.io 
NAME       ROLE              AGE
zhangsan   Role/pod-reader   4s

7. 编辑kubeconfig文件

关于这个文件的框架,我们可以到官网去找到

地址 使用 kubeconfig 文件组织集群访问 | Kubernetes在官网找到之后我们只需要做一些修改就行,改成这样就可以,直接复制这个去改也行

apiVersion: v1
kind: Configclusters:
- cluster:name: cluster-zsusers:
- name: zhangsancontexts:
- context:name: context-zsnamespace: zhangsan
current-context: "context-zs"

这个文件就写好了,但是目前来看他与管理员的那个admin.conf好像不一样,那个文件里面内容很多,这个很少这是因为我们还没有将刚刚创建出来的那些密钥文件嵌入进去

8. 嵌入密钥文件

# 1. 嵌入ca文件
# set-cluster与刚刚文件里的一样就好了 server地址就是master的ip加上6443端口 
[root@master ca]# kubectl config --kubeconfig=kube-zhangsan set-cluster cluster-zs --server=https://192.168.200.200:6443 --certificate-authority=ca.crt --embed-certs=true
Cluster "cluster-zs" set.
# 2. 嵌入client
[root@master ca]# kubectl config --kubeconfig=kube-zhangsan set-credentials zhangsan --client-certificate=client.crt --client-key=client.key --embed-certs=true
User "zhangsan" set.
# 3. 设置上下文信息
[root@master ca]# kubectl config --kubeconfig=kube-zhangsan set-context context-zs --cluster=cluster-zs --namespace=zhangsan --user=zhangsan
Context "context-zs" modified.

这3个操作搞定之后,你再去看看这个文件,你会发现他跟admin.conf是一样一样的了

9. 验证权限

这个文件我们就算搞定了,我们来看看使用这个文件所拥有的权限是否是与我们预期的一样

[root@node1 ~]# kubectl get pods --kubeconfig=kube-zhangsan
NAME     READY   STATUS    RESTARTS   AGE
test01   1/1     Running   0          9m
# 可以看到pod,我们尝试一下能否创建pod
[root@node1 ~]# kubectl run test02 --image nginx --kubeconfig=kube-zhangsan
Error from server (Forbidden): pods is forbidden: User "zhangsan" cannot create resource "pods" in API group "" in the namespace "zhangsan"
# 我们看报错信息,用户zhangsan是不能创建的,我们来看看除了pod之外的其他资源是否可见
[root@node1 ~]# kubectl get ns --kubeconfig=kube-zhangsan
Error from server (Forbidden): namespaces is forbidden: User "zhangsan" cannot list resource "namespaces" in API group "" at the cluster scope

现在这个文件符合我们预期的权限,那么这就是创建一个用户并授权的过程

静态token登录

这个方法用人话来讲就是,账号密码登录静态的方式就是创建一个csv文件,csv文件的格式是token,user,idtoken这一栏我们可以使用openssl生成

1. 生成token

# 注意文件位置,最好放在/etc/kubernetes/pki下,因为k8s默认只对/etc/kubernetes这个目录有权限操作,放在其他位置可能会产生权限错误
[root@master pki]# openssl rand -hex 10 > jerry.csv
[root@master pki]# cat jerry.csv
# 这里的用户名和id可以自己改动
3127c2e2b863d4c23878a,jerry,2000

在apiserver加入参数

# 默认情况下你刚刚写的文件与集群是没有任何关联的,如果想要产生作用需要在kube-apiserver文件加入参数
[root@master manifests]# vim /etc/kubernetes/manifests/kube-apiserver.yaml
spec:containers:- command:- kube-apiserver
# 在这里加上 --token-auth-file后面就是你刚刚的那个文件- --token-auth-file=/etc/kubernetes/pki/jerry.csv- --advertise-address=192.168.200.200- --allow-privileged=true
# 然后重启kubelet
[root@master pki]# systemctl restart kubelet

2. 尝试登录集群

[root@node1 pki]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a" get pod -n default
Unable to connect to the server: x509: certificate signed by unknown authority

他会有一个报错,但是我们现在没有使用x509的证书啊,所以我们需要让他跳过安全认证

3. 带上参数再次尝试

[root@node1 pki]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a" get pod  --insecure-skip-tls-verify=true -n zhangsan
Error from server (Forbidden): pods is forbidden: User "jerry" cannot list resource "pods" in API group "" in the namespace "zhangsan"

现在我们再来看,他报的错是不是跟刚刚不一样了,这个报错说的是jerry这个用户没有权限能看到这个其实就说明我们已经可以登录了,只是没有权限看到一些信息罢了

2. 角色授权

上面我们提到了用户的登录,提到了一点点授权,现在开始聊授权的那些事默认情况下k8s采用的是Node和RBAC的鉴权模式RBAC就是基于角色的访问控制 R就是role嘛我们可以在kube-apiserver文件里面看到

spec:containers:- command:- kube-apiserver- --token-auth-file=/etc/kubernetes/pki/jerry.csv- --advertise-address=192.168.200.200- --allow-privileged=true
# 就是这一行- --authorization-mode=Node,RBAC

刚刚我们不是使用jerry用户登录但是没有任何权限吗?我们现在将这一行参数改掉

# 将之前的注释掉,然后写一行新的# - --authorization-mode=Node,RBAC
# 这个是总是允许,不会鉴权,你能登录就有权限,这个模式仅用于测试- --authorization-mode=AlwaysAllow
# 重启kubelet
[root@master manifests]# systemctl restart kubelet

然后我们来到node节点再尝试一下jerry用户

[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a" get pod  --insecure-skip-tls-verify=true -n zhangsan
NAME     READY   STATUS    RESTARTS   AGE
test01   1/1     Running   0          56m

我们发现他确实有权限查看了,好了但是我们的重点并不是这个,我们将他改回来

role与rolebinding

是通过命名空间来授权的,你在哪个命名空间创建的角色,那么这个角色只有这个命名空间下的权限rolebinding就是将角色与用户进行绑定

1. 创建角色

刚刚我们不是有一个Jerry用户可以登录集群,但是没有任何权限吗?那我们现在来授权

# 不知道参数是怎么来的可以使用kubectl create role --help 里面有示例
[root@master role]# kubectl create role jerry --verb=get --verb=list --verb=watch --resource=pods --dry-run=client -o yaml > jerry.yaml
[root@master role]# kubectl apply -f jerry.yaml 
role.rbac.authorization.k8s.io/jerry created
[root@master role]# kubectl get role
NAME         CREATED AT
jerry        2024-02-20T09:31:35Z
pod-reader   2024-02-20T05:23:30Z

我们现在有2个role一个是之前的,一个jerry就是刚刚我们创建出来的现在我们角色有了,但是jerry用户依旧是查不到任何信息的,因为我们没有对他进行绑定

2. rolebinding

# 注意一个坑,当这个用户是token登录的时候必须指定他的token,老版本不会有这个问题,新版本不指定的话依然是没有权限的,注意一下
[root@master role]#  kubectl create rolebinding jerry --role=jerry --user=jerry --token="3127c2e2b863d4c23878a" --dry-run=client -o yaml > rolebinding.yaml
[root@master role]# kubectl apply -f rolebinding.yaml 
rolebinding.rbac.authorization.k8s.io/jerry created
[root@master role]# kubectl get rolebindings.rbac.authorization.k8s.io 
NAME       ROLE              AGE
jerry      Role/jerry        5s
zhangsan   Role/pod-reader   4h3m

这里的每一步操作都应该能看懂吧,然后我们回到node节点上使用jerry来查一下zhangsan命名空间下的pod

3. 验证权限

[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a" get pod  --insecure-skip-tls-verify=true -n zhangsan
NAME     READY   STATUS    RESTARTS   AGE
test01   1/1     Running   0          4h24m

我们可以看到,他现在就可以看到pod的信息了,但是我们在指定权限的时候是没有给他创建的权限的,那么他肯定不能创建pod,但是我们现在想要他可以创建pod怎么办呢?也是很简单,只需要给角色加上一个权限就可以了

4. 修改权限

修改权限我们只需要修改jerry.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:creationTimestamp: nullname: jerry
rules:
- apiGroups:- ""resources:- podsverbs:- get- list- watch
# 加上这个他就可以创建pod了,如果加上delete那么他就可以删除- create

然后我们再apply这个文件

[root@master role]# kubectl apply -f jerry.yaml 
role.rbac.authorization.k8s.io/jerry configured

5. 验证是否成功增加权限

[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a"   --insecure-skip-tls-verify=true -n zhangsan run test02 --image nginx
pod/test02 created

我们可以看到pod被创建出来了,说明刚刚的权限已经增加上了这里我们仅仅只是针对pod的操作,如果我要创建一个deployment控制器呢?上操作

6. deploymentde的操作

我们仔细观察一下jerry.yaml这个文件,发现里面有一行写的是pods,那我们是不是直接在这里加上deployments就好了呢?我们来试试

# 修改yaml文件
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:creationTimestamp: nullname: jerry
rules:
- apiGroups:- ""resources:- pods- deploymentsverbs:- get- list- watch- create

然后我们apply这个文件

[root@master role]# kubectl apply -f jerry.yaml 
role.rbac.authorization.k8s.io/jerry configured

我们来看看是不是能够创建deployment了

[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a"   --insecure-skip-tls-verify=true -n zhangsan create deployment test03 --image nginx
error: failed to create deployment: deployments.apps is forbidden: User "jerry" cannot create resource "deployments" in API group "apps" in the namespace "zhangsan"

喔嚯,报错了,我们不是加上了deployment吗?这其实是因为我们还需要给他指定apiGroup,光指定资源是不行的,能创建pod是因为pod他的apiVersion就是v1,而deployment的apiVersion是apps/v1所以他会报错,那我们再来修改一下文件

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:creationTimestamp: nullname: jerry
rules:
- apiGroups:- ""
# 加上这个,如果你想要创建其他的资源,那么你也要在这里写上
# 查询apiVersion很简单,你可以使用kubectl create xxx --dry-run 的方式,也可以直接 kubectl api-version去查,查到之后填到这里- "apps"resources:- pods- deploymentsverbs:- get- list- watch- create

然后我们apply之后再来创建

[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a"   --insecure-skip-tls-verify=true -n zhangsan create deployment test03 --image nginx
deployment.apps/test03 created

我们现在是可以创建deployment了,那我们想更新他的副本数量也是可以的嘛?来看看

[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a"   --insecure-skip-tls-verify=true -n zhangsan scale deployment test03 --replicas 3
Error from server (Forbidden): deployments.apps "test03" is forbidden: User "jerry" cannot patch resource "deployments/scale" in API group "apps" in the namespace "zhangsan"

他又报错了,他说不能patch,那我们在verb里面加上个试试看呢,等一下,注意看完报错,他说resource里面是deployments/scale我们好像也没有给他这个资源,一并加上最终的yaml文件是这样的

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:creationTimestamp: nullname: jerry
rules:
- apiGroups:- ""- "apps"resources:- pods- deployments/scale- deploymentsverbs:- get- patch- list- watch- create

我们apply之后再来试试看呢

[root@master role]# kubectl apply -f jerry.yaml 
role.rbac.authorization.k8s.io/jerry configured
# 修改副本数
[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="3127c2e2b863d4c23878a"   --insecure-skip-tls-verify=true -n zhangsan scale deployment test03 --replicas 3
deployment.apps/test03 scaled

我们可以看到现在他可以了这个yaml文件还可以有另外一种格式

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:creationTimestamp: nullname: jerry
rules:
- apiGroups: ["","apps"]resources: ["pods","deployments"]verbs: ["get","delete","watch"]

这种方式也可以,喜欢用哪种就用哪种,无所谓的嘛这个就是role和rolebinding

clusterrole和clusterrolebinding

clusterrole对于role来说,role是属于某个命名空间的,而clusterrole是属于整个集群的,clusterrole可以进行clusterrolebinding,也可以进行rolebinding,rolebinding的时候指定一下命名空间就可以了使用rolebinding的时候它就相当于是将clusterrole的权限模板给了某个命名空间下的某个用户,也就是说在你进行rolebinding的时候你就当这个clusterrole就是一个普通的没有指定特定命名空间的role我们可以这样想一下,我们有很多个命名空间,然后每个命名空间里的用户权限其实都是差不多的,那么如果我要是使用role的话,我就需要每个命名空间下都要去创建role,费时费力但是我们使用clusterrole的话,所有命名空间都可以看到这个clusterrole,那么就无需每个命名空间都去创建role了,直接rolebingding就好了

1. 创建一个新的用户,使用token

[root@master pki]# openssl rand -hex 10 >> /etc/kubernetes/pki/jerry.csv
[root@master pki]# cat jerry.csv
# 这里的token不一样长可能是因为我按a插入的时候多按了一下,没什么太大的问题,token是可以自己写的
3127c2e2b863d4c23878a,jerry,2000
958a15cfa9431e088e0b,tom,2001

2. 创建clusterrole

这个创建方法与role是一样的

[root@master role]# kubectl create clusterrole cluster-pod --verb=get,list,watch --resource=pods --dry-run=client -o yaml > clusterrole.yaml
[root@master role]# cat clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:creationTimestamp: nullname: cluster-pod
rules:
- apiGroups:- ""resources:- podsverbs:- get- list- watch

3. clusterrolebinding

[root@master role]# kubectl create clusterrolebinding cluster-tom --clusterrole=cluster-pod --user=tom --token="958a15cfa9431e088e0b"

4. 验证权限

在验证权限之前我建议退出shell重新登录一下,或者重启一下节点,因为你直接登录的话他可能会报错error: You must be logged in to the server (Unauthorized)我就遇到这个问题了,我的解决方式是将kube-system里面的apiserver这个pod重启了

# 查看pod
[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="958a15cfa9431e088e0bb"   --insecure-skip-tls-verify=true -n zhangsan get pods
NAME                      READY   STATUS    RESTARTS   AGE
test01                    1/1     Running   0          6h29m
test03-6484c64bb6-88xlr   1/1     Running   0          81m
test03-6484c64bb6-9hf4l   1/1     Running   0          75m
test03-6484c64bb6-w4zwk   1/1     Running   0          75m
# 查看其他命名空间的pod
[root@node1 manifests]# kubectl --server="https://192.168.200.200:6443" --token="958a15cfa9431e088e0bb"   --insecure-skip-tls-verify=true -n kube-system get pods
NAME                             READY   STATUS    RESTARTS        AGE
coredns-5bbd96d687-9tsbb         1/1     Running   38 (7h6m ago)   42d
coredns-5bbd96d687-q6dl8         1/1     Running   38 (7h6m ago)   42d
etcd-master                      1/1     Running   42 (7h6m ago)   44d
kube-apiserver-master            1/1     Running   0               13m
kube-controller-manager-master   1/1     Running   63 (3h1m ago)   44d
kube-proxy-mp98s                 1/1     Running   40 (7h6m ago)   44d
kube-proxy-snk8k                 1/1     Running   46 (7h6m ago)   44d
kube-proxy-xmxpj                 1/1     Running   38 (7h6m ago)   44d
kube-scheduler-master            1/1     Running   61 (3h1m ago)   44d
metrics-server-54b5b8fb6-v4cqx   1/1     Running   29 (7h4m ago)   7d1h

我们可以看到,他可以看到其他命名空间下的pod,这就是role和clusterrole的区别了至于他能不能创建pod,能不能创建deployment,这些东西就是跟role是一样的了

文章转载自:FuShudi

原文链接:https://www.cnblogs.com/fsdstudy/p/18023589

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

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

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

相关文章

云打印api搭建,云打印api怎么对接?

相信近来一段时间云打印概念的火热让很多企业和App都有开展打印业务的想法,但是云打印技术的开发又需要有打印设备的支持,这个时候我们可以找到专业的云打印服务平台进行api对接。那么云打印api搭建,云打印api怎么对接?今天来一起…

es6 中字符串、函数、对象、数组分别新增了哪些扩展

es6 中字符串的扩展 includesstartsWithendsWith padStartpadEnd模版字符串 es6 中函数的扩展 箭头函数 this 对象指向定义时所在的对象不可以当作构造函数,不可以使用 new 命令不可以使用 arguments 对象,可以使用 rest 参数不可以适用 yield 命令&a…

C语言自定义类型:结构体的使用及其内存对齐【超详细建议点赞收藏】

目录 1. 结构体类型的声明1.1 结构的声明1.2 结构体变量的创建和初始化1.3 结构的特殊声明---匿名结构体1.4 结构的自引用 2.结构体内存对齐(重点!!)2.1 对齐规则2.2 例题讲解2.3 为什么存在内存对齐?2.4 修改默认对齐…

OpenGauss数据库本地搭建并结合内网穿透实现远程访问

文章目录 前言1. Linux 安装 openGauss2. Linux 安装cpolar3. 创建openGauss主节点端口号公网地址4. 远程连接openGauss5. 固定连接TCP公网地址6. 固定地址连接测试 前言 openGauss是一款开源关系型数据库管理系统,采用木兰宽松许可证v2发行。openGauss内核深度融合…

云渲染农场服务给力吗?全天候不间断服务如何保障?

近年来,云渲染农场以其强大的计算能力和高效的渲染速度而闻名,为各行各业的视觉创作提供了不可或缺的支持。但是,人们普遍关心的是,云渲染农场服务是否真的给力?全天候的服务又是如何保障呢? 实际上&#…

用Python插入页码到PDF文档

页码是许多类型文件中的重要内容,它能方便读者在文档中的导航。在创建PDF文档时,添加页码对于组织和引用内容特别有用。在本文中,我们将探讨如何利用Python程序高效地插入页码到PDF文档中,简化工作流程并创建出精美、结构合理的PD…

【JavaEE】_synchronized关键字——监视器锁monitor lock

目录 1. synchronized的特性 2. synchronized的使用 3. Java标准库中的线程安全类 1. synchronized的特性 (1)互斥: 前文已经介绍,某个线程执行到某个对象的synchronized中时,其他线程如果也执行到同一个对象&…

2024 Sora来了!“手机Agent智能体”也来了!

近日,Open AI发布了能够根据文本生成超现实视频的工具Sora,多款震撼视频引爆科技圈刷屏,热度持续发酵占据AI领域话题中心,被认为是AGI实现过程里的重大里程碑事件。新一轮的人工智能浪潮给人类未来的生产和生活方式带来巨大而深远…

VPN | 世界那么大,我想“魔法”上网看看,可以吗?

Hi,大家好,我是半亩花海。世界那么大,我想“魔法”上网看看,可以吗?随着网络的发展与普及,畅游网络世界已成为人们生活的一部分。它给我们开拓了视野,增长了见闻,丰富了知识&#xf…

FISCO BCOS(二)———配置及使用控制台

一、前言 FISCO BCOS是由金融区块链合作联盟(深圳)与微众银行共同发起的开源区块链项目,支持多链多账本,满足金融行业复杂业务需求。本文将介绍如何在Ubuntu操作系统上使用Linux命令配置FISCO BCOS的控制台并进行get/set操作。 目…

React 模态框的设计(一)拖动组件的设计

春节终结束了,忙得我头疼。终于有时间弄自己的东西了。今天来写一个关于拖动的实例讲解。先看效果: 这是一个简单的组件设计,如果用原生的js设计就很简单,但在React中有些事件必须要多考虑一些。这是一个系列的文章,…

SpringBoot3整合elasticsearch8

版本 SpringBoot 3.0 Elasticsearch 8.12.1 依赖 我使用的 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> 还可以用&#xff0c;但我没用…

YOLOv9来咧!

文章目录 论文:主要内容一、提出使用PGI&#xff08;Programmable Gradient Information&#xff0c;可编程梯度信息&#xff09;来解决信息瓶颈问题和深度监督机制不适合轻量级神经网络的问题。二、设计了GELAN&#xff08;Generalized ELAN &#xff0c;广义ELAN&#xff09;…

LLM 模型融合实践指南:低成本构建高性能语言模型

编者按&#xff1a;随着大语言模型技术的快速发展&#xff0c;模型融合成为一种低成本但高性能的模型构建新途径。本文作者 Maxime Labonne 利用 mergekit 库探索了四种模型融合方法&#xff1a;SLERP、TIES、DARE和passthrough。通过配置示例和案例分析&#xff0c;作者详细阐…

Ansible playbook 剧本部署WEB NFS rsync sersync(及时监控)架构

ansible playbook剧本介绍&#xff1a; playbook 是ansible用于配置&#xff0c;部署和管理被节点的剧本 由一个或多个模块组成&#xff0c;完成统一的目的&#xff0c;实现自动化操作 剧本编写需遵循yaml语法 yaml的三要素&#xff1a; 缩进&#xff1a;两个字符&#xff0c;默…

【Vue3】toRefs和toRef在reactive中的一些应用

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

快速上手vue指南

Vue.js 是一款非常流行且易于上手的前端框架&#xff0c;用于构建用户界面和单页应用程序&#xff08;SPA&#xff09;。它以其简洁的API、灵活的组件系统和高效的性能著称。如果你是初学者&#xff0c;以下是一些关键步骤和建议&#xff0c;可以帮助你快速上手 Vue.js。 1. 理…

【Qt】实现 Ctrl + 鼠标滚轮 缩放文本功能

【Qt】实现 Ctrl 鼠标滚轮 缩放文本功能 文章目录 I - 实现自定义控件II - 完整代码III - 参考链接 I - 实现自定义控件 主要原理 继承 QTextEdit 或者 QPlainTextEdit 类&#xff0c;重写滚轮事件 wheelEvent, QTextEdit 和 QPlainTextEdit 中均包含此函数 头文件 TextEdit…

学习springMVC第二天

REST简介 REST(Representational State Transfer)&#xff0c;表现形式状态转换 传统风格资源描述形式 http://localhost/user/getById?id1 http://localhost/user/saveUser REST风格描述形式 http://localhost/user/1 http://localhost/user 优点&#xff1a; 隐藏资源的访问…

C++模板->模板的概念、函数模板基本语法、函数模板注意事项、普通函数与函数模板区别、普通函数与函数模板调用规则、模板的局限性

#include<iostream> using namespace std; //交换两个整型函数 void swapInt(int& a, int& b) { int temp a; a b; b temp; } //交换两个浮点型函数 void swapDouble(double& a, double& b) { double temp a; a b; b te…