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.pswp.cn/news/696443.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696443.shtml
英文地址,請注明出處:http://en.pswp.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…