Kubernetes(K8S)集羣調度
Scheduler是K8S的調度器,主要是把定義的Pod分配到集羣的節點上。
Scheduler是作爲單獨的程序進行的,啓動之後會一直監聽APIServer,獲取PodSpec.NodeName爲空的Pod,對每個Pod都會創建一個綁定,表明Pod應該放到哪個節點上。
這其中要考慮很多的問題:
公平:如果保證每個節點都能被分配資源。
資源高效利用:集羣所有資源最大化被利用。
效率:調度性能要好,能夠儘快的爲大批量的Pod完成調度工作。
靈活:允許用戶根據自己的需求控制調度的邏輯。
調度過程:
調度分爲幾部分:首先是過濾掉不滿足條件的節點,這個過程稱爲Predicate(斷言);然後對通過的節點按照優先級排序,這個過程稱爲Priority(優先級);最後從中選擇優先級最高的節點。
可以看看回頭第一章https://blog.csdn.net/Su_Levi_Wei/article/details/103410078
Predicate常見的算法:
PodFitsResources:節點上剩餘的資源是否大於Pod請求的資源
PodFitsHost:如果Pod指定了NodeName,檢查節點名稱是否和NodeName匹配
PodFitsHostPorts:節點上已經使用的Port是否和Pod申請的Port衝突。
PodSelectorMatchers:過濾掉和Pod指定的Label不匹配的節點。
NoDiskConflict:已經Mount的Volume和Pod指定的Volume不衝突,除非它們都是隻讀。
如果Predicate過程中沒有合適的節點,Pod會一直在Pending狀態,不斷重試調度,直到有節點滿足條件,經過這個步驟,如果有多個節點滿足條件,就繼續Priorities過程:按照優先級大小對節點排序。
優先級是由一系列鍵值對組成,鍵是該優先級項的名稱,值是它的權重(重要),這些優先級包括:
LestRequestPriority:通過計算CPU和Memory的使用率來決定權重,權重越高,即空閒資源更多的節點。
BalanceResourceAllocation:節點上的CPU和Memory使用率接近,權重越高。這個應該和上面的一起使用,不應該單獨使用。
ImageLocalityPriority:傾向於一家有要使用鏡像的節點,鏡像總大小值越大,權重越高。
即經過算法對所有優先級和權重進行計算,得出最終結果,決定這個Pod到哪裏去。
親和性
節點親和性:
pod.spec.nodeAffinity
requiredDuringSchedulingIgnoredDuringExecution:硬策略,不滿足就不允許。
preferredDuringSchedulingIgnoredDuringExecution:軟策略,有就允許,沒有就算了。
#節點親和性(Pod與Node) - requiredDuringSchedulingIgnoredDuringExecution硬策略
#查看鍵值的標籤的鍵名和鍵值 kubectl get node --show-labels
#鍵值運算關係: #In:label的值在某個列表中 #NotIn:label的值不在某個列表中 #Gt:label的值大於某個值 #Lt:label的值小於某個值 #Exists:某個label存在 #DoesNotExist:某個label不存在
#注意:如果nodeSelectorTerms下面有多個選項的話,滿足任何一個條件就可以了,如果matchExpressions有多個選項的話,則必須同時滿足這些條件才能正常調度Pod
kubectl delete pv --all kubectl delete pvc --all
kubectl get node --show-labels
vi pod1.yaml 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 apiVersion: v1 #資源 kind: Pod metadata: name: affinity #標籤 labels: app: node-affinity-pod spec: #容器 containers: - name: with-node-affinity image: levi.harbor.com/library/nginx:1.9.1 #關聯 affinity: #節點關聯 nodeAffinity: #策略,硬策略 requiredDuringSchedulingIgnoredDuringExecution: #節點選擇 nodeSelectorTerms: - matchExpressions: #Node節點的標籤 - key: kubernetes.io/hostname #NotIn:label的值不在某個列表中 operator: NotIn #operator: In #標籤值 values: - k8s-node02 #- k8s-node03 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
kubectl apply -f pod1.yaml
kubectl get pod
#可以看到是在node1 kubectl get pod -o wide
kubectl describe pod pod名
kubectl get pod -o wide
kubectl delete pod -all
#刪除重新創建,會發現一直在node01 kubectl delete pod --all && kubectl create -f pod1.yaml && kubectl get pod -o wide
#可把yaml找那個的operator改爲In,此時會發現一直在node02 vi pod1.yaml # kubectl delete pod --all && kubectl create -f pod1.yaml && kubectl get pod -o wide
#可以把vlues中的node03改爲03,會發現如果找不到就不運行了,這個就是硬策略 vi pod1.yaml kubectl delete pod --all && kubectl create -f pod1.yaml && kubectl get pod -o wide
#測試:preferredDuringSchedulingIgnoredDuringExecution軟策略 kuctlget node --show-labels
vi pod2.yaml 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 apiVersion: v1 #資源 kind: Pod metadata: name: affinity #標籤 labels: app: node-affinity-pod spec: #容器 containers: - name: wide-node-affinity image: levi.harbor.com/library/nginx:1.9.1 #親和性關聯 affinity: #節點親和性 nodeAffinity: #軟策略 preferredDuringSchedulingIgnoredDuringExecution: #權重越大更親和 - weight: 1 preference: #匹配節點 matchExpressions: #標籤key - key: kubernetes.io/hostname #label存在某個列表中 operator: In #標籤值 values: - k8s-node03 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
#會發現依然運行,軟策略及有就更好,沒有就滿足它即可 kubectl delete pod --all && kubectl create -f pod2.yaml && kubectl get pod -o wide |
Pod的親和性:
pod.spec.affinity.podAffinity(兩個Pod運行在同一個Node)/podAntAffinity(兩個Pod運行在不同的Node)
requiredDuringSchedulingIgnoredDuringExecution:硬策略
preferredDuringSchedulingIgnoredDuringExecution:軟策略
kubeclt delete pod --all
kubectl get pod
#podAffinity(兩個Pod運行在同一個Node)/podAntiAffinity(兩個Pod運行在不同的Node) vi pod3.yaml 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 apiVersion: v1 kind: Pod metadata: name: pod-3 #name: pod-2 labels: app: pod-3 spec: containers: - name: pod-3-container image: levi.harbor.com/library/nginx:1.9.1 affinity: #Pod親和性,運行在同一Node上 podAffinity: #運行在不同Node上 #podAntiAffinity: #硬策略 requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: #匹配規則 matchExpressions: #標籤值和Key是這個 - key: app values: - pod-1 #label的值在某個列表中 operator: In #運行的Node的節點的key topologyKey: kubernetes.io/hostname 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
kubectl create -f pod3.yaml
kubectl get pod -o wide
#給pod打標籤 kubectl label pod pod-3 app=pod-1 --overwrite=true
kubectl get pod --show-labels -o wide
#改爲 pod-2,使用podAntiAffinity親和性策略 vi pod3.yaml kubectl create -f pod3.yaml && kubectl get pod -o wide
#同一節點運行,改爲使用podAffinity vi pod3.yaml kubectl delete pod pod-2 && kubectl create -f pod3.yaml && kubectl get pod --show-labels -o wide |
親和性/反親和性調度策略比較:
調度策略 |
匹配標籤 |
操作符 |
拓撲域支持 |
調度目標 |
nodeAffinity |
主機 |
In、NotIn、Exists、DoesNotExist、Gt、Lt |
否 |
指定主機 |
podAffinity |
Pod |
In、NotIn、Exists、DoesNotExist |
是 |
Pod與指定Pod同一拓撲域 |
podAnitAffinity |
Pod |
In、NoIn、Exists、DoesNotExist |
是 |
Pod與指定Pod不在同一拓撲域 |
小結:就是讓不同的pod處於同一節點或不同節點進行管理
污點與容忍
節點親和性是Pod的一種屬性(偏好或硬件要求),它使得Pod被吸引到一類特定的節點。Taint(污點)則相反,它使節點能夠排斥一類特定的Pod。即一個是拉進來,一個是推出去。
Taint(污點)和Toleration(容忍)相互配合,可以避免Pod被分配到不合適的節點上,每個節點上都可以應用一個或多個Taint(無敵啊),這表示對於那些不能容忍Taint的Pod是不會被該節點接受的。如果將Toleration(容忍)應用於Pod上,則表示這些Pod可以(但不要求)被調度到具有匹配Taint(污點)的節點上。
Taint(污點):
使用kubectl taint命令可以給某個Node節點設置污點,Node被設置上污點之後就和Pod之間存在了一種相斥的關係,可以讓Node拒絕Pod的調度執行,甚至將Node已經存在的Pod驅逐出去。
每個污點的組成:key=value:effect
每個污點都有一個KV作爲污點的標籤,其中value可以爲空,effect則是描述污點的作用。
當前的taint effect(污點影響)支持三個選項:
NoSchedule: K8S不會將Pod調度到據有該污點的Node上。
PreferNoSchedule:K8S將盡量避免將Pod調度到具有該污點的Node上。
NoExecute:K8S不會將Pod調度到具有該污點上的Node,同時會將Node上已經存在的Pod驅逐出去。
#查看污點,可以發現這也是爲什麼不會分配在Master節點上的原因(NoSchedule) kubectl describe node k8s-master01 | grep 'Taints'
#設置污點 kubectl get pod -o wide
#Master是天生就有個污點NoScheduler,給node01和node02也打上污點 kubectl taint nodes k8s-node01 testk=test2:NoExecute kubectl taint nodes k8s-node02 testk=test2:NoExecute
#會發現pod去掉了 kubectl get pod -o wide
#運行pod會發現一直處於pending kubectl create -f pod3.yaml
#刪除污點 kubectl taint nodes k8s-node01 testk=test2:NoExecute- kubectl taint nodes k8s-node02 testk=test2:NoExecute-
kubectl delete pod --all |
Tolerations(容忍):
設置了污點的Node將根據Taint(污點)的effect:NoSchedule、PreferNoSchedule、NoExecute和Pod之間產生互斥關係,Pod將在一定程度上不會被調度到Node上。但可以在Pod上設置Tolerations(容忍),意思是設置了容忍的Pod將可以容忍污點的存在,可以被調度到存在污點的Node上。
pod.spec.tolerations
tolerations: #要與Node上設置的taint的key保持一致 - key: "123" #要與Node上設置的taint的value保持一致 value: "321" #要與Node上設置的taint的effect保持一致 effet: "NoSchedule" #operator的值爲Exists時,將會忽略value值 operator: "Equal" #描述當前Pod需要驅逐時可以在Pod上繼續保留運行的時間 tolerationSeconds: 3600 |
#當不指定key值時,表示容忍所有的污點key: tolerations - operaor: "Exists"
#當不指定effect值時,表示容忍所有的污點作用 tolerations: - key: "key" operator: "Exists" |
#先給node01和02打上污點 kubectl taint nodes k8s-node01 testk=test2:NoExecute kubectl taint nodes k8s-node02 testk=test2:NoExecute kubectl describe node k8s-node01 | grep 'Taints'
#取出污點的key和value,effect要爲之前設置的對應的 vi pod.yaml 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 apiVersion: v1 kind: Pod metadata: #name: pod-3 name: pod-2 labels: app: pod-3 spec: containers: - name: pod-3-container image: levi.harbor.com/library/nginx:1.9.1 #污點容忍 tolerations: #污點設置的Key和Value的值 - key: "testk" value: "test2" #運算 operator: "Equal" effect: "NoExecute" #當前Pod需要被驅逐時可以在Pod上繼續保留運行的時間 tolerationSeconds: 3600 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
kubectl delete pod --all
kubectl apply -f pod.yaml
#此時發現有效了 kubectl get pod -o wide |
#有多個master存在時,防止資源浪費,可以在Master節點上運行pod,但是儘量不允許,可以如下設置 kubectl taint nodes k8s-master01 node-rolt.kubernetes.io/master=:PreferNoSchedule
kubectl get node
#去除污點 kubectl taint nodes k8s-node01 testkd=test2:NoExecute- kubectl taint nodes k8s-node02 testkd=test2:NoExecute- |
固定節點調度
#1.Pod.spec.nodeName將Pod直接調度到指定的Node節點上,會跳過Scheduler的調度策略,該匹配規則是強制匹配 kubectl delete deployment --all kubectl delete pod --all kubectl get pod
vi assign-pod.yaml 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 apiVersion: extensions/v1beta1 kind: Deployment metadata: name: myweb spec: #副本 replicas: 7 #運行配置 template: metadata: labels: app: myweb-pod spec: #運行的節點 nodeName: k8s-node01 #容器 containers: - name: myweb image: levi.harbor.com/library/nginx:1.9.1 ports: - containerPort: 80 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
kubectl create -f assign-pod.yaml
kubectl get pod -o wide
#2.Pod.spec.nodeSelector:通過K8S的label-selector機制選擇節點,由調度器調度策略匹配label,而後調度Pod到目標節點,該匹配規則屬於強制約束 kubectl delete deployment --all kubectl delete pod --all kubectl get pod
vi po1.yaml 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 apiVersion: extensions/v1beta1 kind: Deployment metadata: name: myweb221 spec: #副本 replicas: 2 #運行配置 template: metadata: labels: app: myweb22222 spec: #使用節點選擇器 nodeSelector: #節點標籤必須符合test:levi test: levi #容器 containers: - name: myweb-container image: levi.harbor.com/library/nginx:1.9.1 ports: - containerPort: 80 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
kubectl apply -f pod1.yaml
kubectl get pod
#添加標籤 kubectl label node k8s-node02 test=levi
kubectl get pod
kubectl delete deployment --all kubectl delete pod --all |
Kubernetes(K8S)安全
K8S作爲一個分佈式集羣的官吏工具,安全是一個很重要的事情。
APIServer是集羣內部各個組件通信的中介,也是外部控制的入口。所以K8S的安全機制基本是圍繞保護APIServer來設計的。
K8S使用了認證(Authentication)、鑑權(Authorization)、准入控制(Admission Control)三步來保證APIServer的安全。
認證
Http Token認證:用一個很長的特殊編碼方式,且是難易模仿的字符串,Token來表達客戶的一種方式。Tomken是一個很長的很複雜的字符串,每一個Token對應一個用戶名存儲在APIServer能夠訪問的文件中。當客戶端發起API調用請求時,需要再Http Header裏面放入Token。
Http Base認證:通過Base64算法進行編碼後的字符串放到Http Request中的Heather Authorization域裏發送給服務端,服務端接收到後進行編碼,獲取用戶名和密碼。
Https證書認證:基於CA根證書籤名認證客戶端身份,可以說是最嚴格Http驗證。
K8S需要認證的節點:
K8S組件對APIServer的訪問:kubectl、Controller Manager、Scheduler、kubelet、kube-proxy
K8S管理的Pod對容器的訪問:Pod(dashborad也是以Pod形式運行)
安全性說明:
Controller Manager、Sheduler與APIServer在同一臺機器,所以直接使用APIServer的非端口發給我你,--insecure-bin-address=127.0.0.1
kubectl、kubelet、kube-proxy訪問APIServer就都需要進行Https雙向認證。
證書頒發:
手動:通過K8S集羣跟CA進行簽發Https證書。
自動:kubelet首次訪問APIServer時,使用Token做認證,通過後,Controller Manager會爲kubelet生成一個證書,以後的訪問都是用證書做認證了。
kubeconfig:
K8S組件通過啓動時指定不同的kubeconfig文件可以切換到不同的集羣。
kubeconfig這個文件包含:
集羣參數(CA證書、APIServer地址)
客戶端參數(上面生成的證書和私鑰)
集羣context信息(集羣名稱、用戶名)
#查看 cd ~ cd .kube ls cat config |
ServiceAccount:
Pod的容器訪問APIServer。因爲Pod的創建、銷燬是動態的,所以要爲它生成證書就不行了。K8S使用了ServiceAccount解決Pod訪問APIServer的認證問題。
Secret與SA的關係:
K8S設計了一種資源對象叫Secret,分爲兩類:一是用於ServiceAccount的service-account-token;二是用於保護用戶自定義保密信息的Opaque。ServiceAccount中用到包含三個部分:Token、ca.crt、namespace。
Token:使用APIServer私鑰簽名的JWT。用來訪問APIServer時,Server端認證。
ca.crt:根證書,用於Client端驗證APIServer發送的證書。
namespace:標識這個service-account-token的作用域名空間。
JWT(Json Web Token):是爲了在網絡應用環境之間傳遞聲明而執行的一種基於JSON的開放標準(RFC 7519),該Token被設計爲緊湊且安全的,特別使用與分佈式站點的單點登錄SSO場景。JWT的聲明一般被用來身份提供者和服務提供者之間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也可以增加一些額外的其他業務邏輯所必須的聲明信息,該Token也可以直接被用於認證,也可以被用於加密。
#默認情況下每個namespace都會有一個serviceaccount,如果pod在創建時沒有指定serviceaccount,就會使用pod所屬的namespace的serviceaccount #默認掛載目錄/run/secrets/kubernetes.io/serviceaccount kubectl get pod -n kube-system
#進入容器 kubectl exec kube-proxy-xxx -n kube-system -it -- /bin/sh cd /run/secrets/kubernetes.io ls cd serviceaccount ls
kubectl get secret --all-namespaces
kubectl describe secret default-token --namespace=kube-system |
鑑權
認證過程:
這個認證過程只是去人了通信雙方都確認了對方是可信的,可以相互通信。而鑑權是確定請求發有哪些資源的權限。
APIServer目前支持幾種授權策略:(通過APIServer的啓動參數”—authorization-mode”設置)
AlwaysDeny:拒絕所有的請求,一般用於測試。
AlwaysAllow:允許接收所有請求,如果集羣不需要授權流程,則可以採用
ABAC(Attribute-Based Access Control):基於屬性的訪問控制,表示使用用戶配置的授權規則對用戶請求進行匹配和控制。
Webbook:通過調用外部REST服務對用戶進行授權。
RBAC(Role-Based Access Control):基於角色的訪問控制,現行默認規則。
RBAC授權模式:
RBAC(Role-Based Access Control)基於角色的訪問控制,在K8S 1.5中引入,現行版本默認默認標準。
優勢:
對集羣中的資源和非資源均擁有完整的覆蓋。
整個RBAC完全由幾個API對象完成,同其他API對象一樣,可以用kubectl或API進行操作。
可以在運行時進行調整,無需重啓APIServer
RBAC的API資源對象:Role、ClusterRole、RoleBinding、ClusterRolebingding,這四種對象類均可通過kubectl與API操作。
需要注意的是K8S並不會提供用戶管理。K8S組件(kubectl、kube-proxy)或者是其他自定義的用戶在向CA申請證書時,需要提供一個證書請求文件。
{ "CN": "devuser", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "GuangZhou", "L": "GuangZhou", "O": "k8s", "OU": "System" } ] } |
APIServer會把客戶端證書的CN字段作爲User,把name.O字段作爲Group。
kubelet使用TLS Bootstaping認證時,APIServer可以使用Bootstrap Tokens或者Token Authentication File驗證=token,無論哪一種K8S都會爲token綁定一個默認的User和Group
Pod使用ServiceAccount認證時,service-account-token中的JWT會保存User信息。
有了用戶信息,在創建一對角色/角色綁定(集羣角色/集羣角色綁定)資源對象,就可以完成全線綁定了。
Role And ClusterRole:
在RBAC API中,Role表示一組規則權限,權限只會增加(累加權限),不存在一個資源一開始就有很多權限,而通過RBAC對其進行減少的操作;Role可以定義在一個namespace中,如果想要跨越namespace則可以創建ClusterRole。
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: pod-reader namespace: default rules: - apiGroups: [""] # "" indicates the core API group resources: ["pods"] verbs: ["get", "watch", "list"] |
ClusterRole具有與Role相同的權限角色控制能力,不同的是ClusterRole是集羣級別的。
ClusterRole可以用於:
集羣級別的資源控制(例如Node訪問權限)
非資源型endpoints(例如/healthz訪問)
所有命名空間資源控制(利潤pods)
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: #namespace被省略,因爲ClusterRoles沒有名稱空間 name: secret-reader rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] |
RoleBinding And ClusterRoleBinding:
RoleBinding可以將角色中定義的權限授予用戶或用戶組,RoleBinding包含一組權限列表(Subjects),權限列表中包含有不同形式的待授予權限資源類型(users、groups、or service accounts);RoleBinding同樣包含被Bind的Role引用。
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: read-pods namespace: default subjects: - kind: User name: levi apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io |
RoleBinding適用於某個名稱空間的授權,而ClusterRoleBinding適用於集羣範圍內的授權。
RoleBinding同樣可以引用ClusterRole來對當前的namepsace內用戶、用戶組或ServiceAccount進行授權,這種操作允許集羣管理員在整個集羣內定義一些通用的ClusterRole,然後在不同的namespace中使用RoleBinding。
RoleBinding可以綁定ClusterRoleBinding,而ClusterRoleBinding只能綁定ClusterRoleBinding。
Rsources:
對集羣內一些資源一般以名稱字符串來標識,這些字符串一把會在API的URL地址中出現,同時某些資源也會包含子資源,例如logs資源就屬於pods的子資源。
GET /api/v1/namespaces/{namespace}/pods/{name}/log |
如果要在RBAC授權默寫中控制這些子資源的訪問權限可以通過 / 分隔符來實現。
#定義一個pods資源logs訪問權限的Role定義樣例 apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: namespace: default name: pod-and-pod-logs-reader rules: - apiGroups: [""] resources: ["pods/log"] verbs: ["get", "list"] |
To Subjects:
RoeBinding和ClusterRoleBinding可以將Role綁定到Subjects;Subjects可以是groups、users或service accounts。
#新建一個新的用戶 useradd devuser passwd devuser
#使用這個用戶登錄 su devuser #訪問不了,需要創建一個證書請求 kubectl get pod #退出 exit
#回到root用戶 cd /usr/local/kubernetes mkdir cert cd cert mkdir devuser && cd devuser/ vi devuser-cert.json #將JSON複製過來 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓 { "CN": "devuser", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "GuangZhou", "L": "GuangZhou", "O": "k8s", "OU": "System" } ] } 〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
#安裝插件 cd /usr/local/kubernetes/cert wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 cp cfssl* /usr/local/bin mv /usr/local/bin/cfssljson_linux-amd64 /usr/local/bin/cfssljson mv /usr/local/bin/cfssl_linux-amd64 /usr/local/bin/cfssl mv /usr/local/bin/cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo chmod a+x /usr/local/bin/*
#此處存儲的都是祕鑰信息 cd /etc/kubernetes/pki/ cfssl gencert -ca=ca.crt -ca-key=ca.key -profile=kubernetes /usr/local/kubernetes/cert/devuser/devuser-cert.json | cfssljson -bare devuser
#devuser.csr、devuser-key.pem、devuser.pem文件 ls
cd /usr/local/kubernetes/cert/devuser
# 設置集羣參數 export KUBE_APISERVER="https://MasterIP:6443" export KUBE_APISERVER="https://192.168.70.110:6443"
kubectl config set-cluster kubernetes \ --certificate-authority=/etc/kubernetes/pki/ca.crt \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=devuser.kubeconfig
#devuser.kubeconfig文件 ls
cat devuser.kubeconfig
# 設置客戶端認證參數 kubectl config set-credentials devuser \ --client-certificate=/etc/kubernetes/pki/devuser.pem \ --client-key=/etc/kubernetes/pki/devuser-key.pem \ --embed-certs=true \ --kubeconfig=devuser.kubeconfig
#創建名稱空間 kubectl create namespace dev
# 設置上下文參數,綁定至某一個名稱空間 kubectl config set-context kubernetes \ --cluster=kubernetes \ --user=devuser \ --namespace=dev \ --kubeconfig=devuser.kubeconfig
#綁定K8S角色至用戶 kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev
mkdir /home/devuser/.kube/
cp /usr/local/kubernetes/cert/devuser/devuser.kubeconfig /home/devuser/.kube/
chown devuser:devuser -R /home/devuser/.kube/ chmod 766 /home/devuser/.kube/devuser.kubeconfig
chmod 666 /etc/kubernetes/admin.conf
#使用新用戶登錄 su devuser cd ~/.kube/ ls mv devuser.kubeconfig config
#設置默認上下文 - 使用新用戶 kubectl config use-context kubernetes --kubeconfig=config
kubectl get pod
kubectl run --help
kubectl run nginx --image=levi.harbor.com/library/nginx:1.9.1
kubectl get pod
#在master節點上查看 kubectl get pod --all-namespaces -o wide | grep nginx
#新用戶執行 kubectl get pod -n default |
安全准入控制
准入控制是APIServer的插件集合,通過添加不同的插件,實現額外的准入控制規則。甚至與APIServer的一些主要的功能都需要通過AdmissionControllers實現,比如ServiceAccount。
官方V1.14版本的准入控制推薦列表:
NamespaceLifecycle、LimitRanger、ServiceAccount、DefaultStorageClass、DefaultTolerationSeconds、MutatingAdmissionWebhook、ValidatingAdmissionWebhook、ResourceQuota
常用:
NamespaceLifecycle:防止不存在的namespace上創建對象,防止刪除系統預置的namespace,刪除namespace時,會連帶刪除它的所有資源對象。
LimitRanger:確保請求的資源不會超過資源所在Namespace的LimitRange的限制。
ServiceAccount:實現了自動化添加ServiceAccount。
ResourceQuota:確保請求的資源不會超過資源的ResourceQuota限制。