Kubernetes之十八---K8s准入控制基礎應用

1、訪問控制概述

       API Server 作爲 Kubernetes 集羣系統的網關,是訪問及管理資源對象的唯一人口,餘 下所有需要訪問集羣資源的組件,包括 kube-controller-manager、 kube-scheduler、 kubelet 和 kube-proxy 等集羣基礎組件、 CoreDNS 等集羣的附加組件以及此前使用的 kubectl 命令等都 要經由此網關進行集羣訪問和管理。 這些客戶端均要經由 API Server 訪問或改變集羣狀態並 完成數據存儲,並由它對每一次的訪問請求進行合法性檢驗,包括用戶身份鑑別、 操作權限 驗證以及操作是否符合全局規範的約束等。 所有檢查均正常完成且對象配置信息合法性檢驗 無誤之後才能訪問或存人數據於後端存儲系統 etcd 中。

 

2、准入控制基礎

 1)爲了覈驗用戶的操作許可,成功通過身份認證後的操作請求還需要轉交給授權插件進 行許可權限檢查,以確保其擁有執行相應的操作的許可。 API Server 主要支持使用四類內建 的授權插件來定義用戶的操作權限。 

  • Node : 基於 Pod 資源的目標調度節點來實現的對 kubelet 的訪問控制。
  • ABAC: attribute-based access control, 基於屬性的訪問控制。
  • RBAC: role-based access control,基於角色的訪問控制。
  • Webhook: 基於 HTTP 回調機制通過外部 REST 服務檢查確認用戶授權的訪問控制。 

        另外,還有 AlwaysDeny 和 AlwaysAllow 兩個特殊的授權插件,其中 AlwaysDeny (總 是拒絕)僅用於測試,而 AlwaysAllow (總是允許) 則用於不期望進行授權檢查時直接於授 權檢查階段放行的所有操作請求。 啓動 API Server 時, “ --authorization-mode”選項用於定 義要啓用的授權機制,多個選項彼此之間以逗號分隔。 

 

  2)而准入控制器 ( Admission Controller)則用於在客戶端請求經過身份驗證和授權檢查之 後,但在對象持久化存儲 etcd 之前攔截請求,用於實現在資源的創建、 更新和刪除操作期 間強制執行對象的語義驗證等功能 ,讀取資源信息的操作請求不會經由准入控制器的檢查。 API Server 內置了許多准入控制器,常用的包含如下幾種。 不過, 其中的個別控制器僅在較 新版本的 Kubernetes 中才受支持。 

  1. AlwaysAdmit:允許所有請求。
  2. AlwaysDeny:拒絕所有請求 ,僅應該用於測試。
  3. AlwaysPulllmages :總是下載鏡像,即每次創建 Pod 對象之前都要去下載鏡像,常用於多租戶環境中以確保私有鏡像僅能夠被擁有權限的用戶使用。
  4. NamespaceLifecycle :拒絕於不存在的名稱空間中創建資源,而刪除名稱空間將會 級聯刪除其下的所有其他資源。
  5. LimitRanger :可用資源範圍界定,用於監控對設置了 LimitRange 的對象所發出的 所有請求,以確保其資源、請求不會超限。
  6. ServiceAccount :用於實現 Service Account 管控機制的自動化,實現創建 Pod 對象 時自動爲其附加相關的 Service Account 對象。
  7. PersistentVolumeLabel :爲那些由雲計算服務商提供的 PV 自動附加 region 或 zone 標籤,以確保這些存儲卷能夠正確關聯且僅能關聯到所屬的 region 或 zone。
  8. DefaultStorageClass :監控所有創建 PVC 對象的請求,以保證那些沒有附加任何專 用 Storag巳Class 的請求會自動設定一個默認值。
  9. ResourceQuota : 用於對名稱空間設置可用資源的上限,並確保在其中創建的任何設 置了資源限額的對象都不會超出名稱空間的資源配額。
  10. DefaultTolerationSeconds :如果 Pod 對象上不存在污點寬容期限,則爲它們設置默 認的寬容期,以寬容“ notready:N oExecute”和“ unreachable:N oExctute ”類的污點 5 分鐘 時間。
  11. ValidatingAdmission Webhook :並行調用匹配當前請求的所有驗證類的 Webhook, 任何一個校驗失敗,請求即失敗。
  12. MutatingAdmissionWebhook :串行調用匹配當前請求的所有變異類的 Webhook, 每個調用都可能會更改對象。

  3)在經由認證插件和授權插件分別完成身份認證和權限檢查之後,准入控制器將攔截 那些創建、 更新和刪除相關的操作請求以強制實現控制器中定義的功能,包括執行對象的 語義驗證、設置缺失字段的默認值、 限制所有容器使用的鏡像文件必須來 自 某個特定的 Registry、檢查 Pod 對象的資源需求是否超出了指定的限制範圍等。

       在具體運行時,准入控制可分爲兩個階段, 第一個階段串行運行各變異型控制器, 第 二個階段串行運行各驗證型控制器,在此過程中,一旦任一階段中的任何控制器拒絕請求, 則立即拒絕整個請求,並向用戶返回錯誤。

 

3、限制CPU使用大小

3.1 LimitRange 資源與 LimitRanger 准入控制器

        雖然用戶可以爲容器指定資源需求及資源限制,但未予指定資源限制屬性的容器 應用很有可能因故吞掉所在工作節點上的所有可用計算資源,因此妥當 的做法是使用 LimitRange 資源在每個名稱空間中爲每個容器指定最小及最大計算資源用量,甚至是設置 默認的計算資源需求和計算資源限制。 在名稱空間上定義了 LimitRange 對象之後, 客戶端 提交創建或修改的資源對象將受到 LimitRanger 控制器的檢查,任何違反 LimitRang巳對象 定義的資源最大用量的請求將被直接拒絕。 

        LimitRange 資源支持限制容器、 Pod 和 PersistentVolumeClaim 三種資源對象的系統資 源用量,其中 Pod 和容器主要用於定義可用的 CPU 和內存資源範圍,而 PersistentVolumeClaim 則主要定義存儲空間的限制範圍。 下面的配置清單以容器的 CPU 資源爲例, default 用於定義默認的資源限制 , defaultRequest 定義默認的資源需求, min 定義最小的資源用量,而最大的資源用量既可以使用 max 給出固定值, 也可以使用 maxLimitRequestRatio 設定爲 最小用量的指定倍數:

 

1、創建限制CPU大小規則

1、創建一個使用CPU限制的yaml文件,可以看出此時使用的最小CPU爲500m,最大是2000m,maxLimitRequestRatio表示最大和最小的CPU倍數,如果創建的pod沒指定使用CPU大小,默認就是1000m。 

[root@master ~]# kubectl create ns myns   # 創建myns名稱空間,方便做實驗
namespace/myns created

[root@master ~]# cat limitrange-demo.yaml  # 創建限制CPU信息
apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-limit-range
spec:
  limits:
  - default:
      cpu: 1000m
    defaultRequest:
      cpu: 1000m
    min:
      cpu: 500m
    max:
      cpu: 2000m
    maxLimitRequestRatio:                   # 限制最大CPU和最小CPU的倍數
      cpu: 4
    type: Container

  

2、基於limitrange-demo.yaml文件,創建限制CPU大小的規則

[root@master ~]# kubectl apply -f limitrange-demo.yaml -n myns
limitrange/cpu-limit-range created

  

3、查看此時創建limitrange詳細信息

[root@master ~]# kubectl get limitrange  -n myns  # 查看此時的limitrange信息
NAME              CREATED AT
cpu-limit-range   2020-08-09T02:10:21Z

[root@master ~]# kubectl describe limitrange -n myns
Name:       cpu-limit-range
Namespace:  myns
Type        Resource  Min   Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---   ---  ---------------  -------------  -----------------------
Container   cpu       500m  2    1                1              4

  

2、自定義一個默認pod資源

1、定義一個pod,此時我們並未做任何的資源限制,就會創建默認的1000m的CPU,目的只是爲了驗證默認CPU佔用效果

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp

  

2、基於yaml文件創建pod

[root@master ~]# kubectl apply -f pod-demo.yaml -n myns
pod/pod-demo created

  

3、查看此時Pod運行的CPU大小和狀態

[root@master ~]# kubectl get pods -n myns
NAME       READY   STATUS    RESTARTS   AGE
pod-demo   1/1     Running   0          41s

[root@master ~]# kubectl describe pods pod-demo -n myns         # 查看pod的詳細信息
Containers:
  myapp:
    Container ID:   
    .........  # 省略信息
    State:          Running
      Started:      Sun, 09 Aug 2020 10:15:51 +0800
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:  1        # 限制CPU個數爲1
    Requests:        # 限制CPU請求個數爲1
      cpu:        1

  

3、自定義限制最小CPU請求

1、刪除前面未限制的CPU請求的pod

[root@master ~]# kubectl delete -f pod-demo.yaml -n myns
pod "pod-demo" deleted

  

2、開始創建限制CPU使用大小的數量,限制最小請求數爲200m。

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 200m

  

3、執行yaml文件,創建新的pod,此時創建pod就會報錯,是因爲前面我們對容器限制最小請求500m,而我們只限制請求了200m,小於最小請求的大小,就無法創建pod。

[root@master ~]# kubectl apply -f pod-demo.yaml 
Error from server (Forbidden): error when creating "pod-demo.yaml": pods "pod-demo" is forbidden: [minimum cpu usage per Container is 500m, but request is 200m, cpu max limit to request ratio per Container is 4, but provided ratio is 5.000000]

  

4、限制最大請求CPU數

1、將CPU請求的值設置爲最小請求3000m

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 3000m

  

2、執行yaml文件並創建pod,此時由於我們設置的最大CPU是2000m,而我們創建pod時,設置到了最小請求爲3000m,也無法創建pod。

[root@master ~]# kubectl apply -f pod-demo.yaml 
The Pod "pod-demo" is invalid: spec.containers[0].resources.requests: Invalid value: "3": must be less than or equal to cpu limit

  

4、自定義一個合理範圍內的CPU數

1、創建一個與limitrange限制最小請求CPU數一樣,最大請求書比自定義limitrange限制CPU大的pod

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: myns
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 500m
      limits:
        cpu: 1500m

  

2、基於yaml文件創建Pod,此時定義在正常的範圍內,上限比容器限制的大也無所謂,也可以運行,取決於運行pod的實際佔用CPU大小

[root@master ~]# kubectl apply -f pod-demo.yaml -n myns
pod/pod-demo created

  

4、ResourceQuota 資源與准入控制器

       儘管 LimitRange 資源能限制單個容器、 Pod 及 PVC 等相關計算資源或存儲資源的用量, 但用戶依然可以創建數量衆多的此類資源對象進而侵佔所有的系統資源。 於是, Kubernetes 提供了 ResourceQuota 資源用於定義名稱空間的對象數量或系統資源配額,它支持限制每種 資源類型的對象總數,以及所有對象所能消耗的計算資源及存儲資源總量等。 ResourceQuota 准入控制器負責觀察傳入的請求,並確保它沒有違反相應名稱空間中 ResourceQuota 對象定 義的任何約束。 

      於是,管理員可爲每個名稱空間分別創建一個 ResourceQuota 對象,隨後 ,用戶在名 稱空間中創建資源對象, ResourceQuota 准入控制器將跟蹤使用情況以確保它不超過相應 ResourceQuota 對象中定義的系統資源限制。 用戶創建或更新資源的操作違反配額約束將導 致請求失敗, API Server 以 HTTP 狀態代碼“403 FORBIDDEN ”作爲響應,並顯示一條消 息以提示可能違反的約束。 不過,在名稱空間上啓用了 CPU 和內存等系統資源的配額後, 用戶創建 Pod 對象時必須指定資源需求或資源限制,否則,會觸發 ResourceQuota 准入控制 器拒絕執行相應的操作。

ResourceQuota 對象可限制指定名稱空間中非終止狀態的所有 Pod 對象的計算資源需求 及計算資源限制總量。 

  • cpu 或 requests.cpu: CPU 資源需求的總量限額。
  • memory 或 requests.cpu:內存資源需求的總量限額。
  • limits.cpu: CPU 資源限制的總量限額。
  • limits.memory:內存資源限制的總量限額。 

ResourceQuota 對象支持限制特定名稱空間中可以使用的 PVC 數量和這些 PVC 資源 的空間大小總量,以及特定名稱空間中可在指定的 StorageC!ass 上使用的 PVC 數量和這些 PVC 資源的總數: 

  • requests.storage :所有 PVC 存儲需求的總量限額。
  • persistentvolumeclaims :可以創建的 PVC 總數。
  • <stor噸e-class-name>.storagecl ass. storage.k8s. io/requests. storage :指定存儲類上可使 用的所有 PVC 存儲需求的總量限額。
  • <storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims :指定存儲類 上可使用的 PVC 總數。
  • requests.ephemeral-storage :所有 Pod 可用的本地臨時存儲需求的總量。
  • limits.ephemeral-storage :所有 Pod 可用的本地臨時存儲限制的總量。

 

1、創建ResourceQuota控制規則

1、創建限制內存和CPU大小的yaml文件

[root@master ~]# cat resoucequota-demo.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-example
spec:
  hard:
    pods: "5"
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
    count/deployments.apps: "2"
    count/deployments.extensions: "2"
    persistentvolumeclaims: "2"

  

2、基於yaml文件創建規則

[root@master ~]# kubectl apply -f resoucequota-demo.yaml -n myns
resourcequota/quota-example created

  

3、查看 resourcequota規則詳細信息

[root@master ~]# kubectl get resourcequota -n myns
NAME            CREATED AT
quota-example   2020-08-09T02:54:33Z

[root@master ~]# kubectl describe resourcequota quota-example -n myns   # 查看詳細信息
Name:                         quota-example
Namespace:                    myns
Resource                      Used   Hard
--------                      ----   ----
count/deployments.apps        0      2
count/deployments.extensions  0      2
limits.cpu                    1500m  2      # CPU最大使用了1500m,1500m代表1.5,硬限制到2
limits.memory                 0      2Gi    # 硬限制內存多少
persistentvolumeclaims        0      2
pods                          1      5
requests.cpu                  500m   1      # CPU下限多少
requests.memory               0      1Gi

  

2、創建一個新pod,進行測試

1、此時創建一個新的上限爲1000m的cpu限制pod

[root@master ~]# cat pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo-2
  labels:
    app: pod-demo
    rel: stable
  annotations:
    ik8s.io/project: hello
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 500m
        memory: 500Mi
      limits:
        cpu: 1000m       # 創建一個上限爲1000m的pod
        memory: 1Gi

  

2、此時由於前面最大已經使用了1500m,這裏創建的新pod的CPU使用設置最大上限值爲1000m,超過了硬限制的hard值2,此時就無法創建新的pod資源

[root@master ~]# kubectl apply -f  pod-demo1.yaml -n myns
Error from server (Forbidden): error when creating "pod-demo1.yaml": pods "pod-demo-2" is forbidden: exceeded quota: quota-example, requested: limits.cpu=1, used: limits.cpu=1500m, limited: limits.cpu=2

  

3、創建合理大小的Pod資源

1、此時將此Pod的最大CPU使用個數改爲500m,與前面已經使用了1500m相加,剛好是2個CPU,就可以創建新的Pod

[root@master ~]# cat  pod-demo1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo-2
  labels:
    app: pod-demo
    rel: stable
  annotations:
    ik8s.io/project: hello
spec:
  containers:
  - image: ikubernetes/myapp:v1
    imagePullPolicy : IfNotPresent
    name: myapp
    resources:
      requests:
        cpu: 500m
        memory: 500Mi
      limits:
        cpu: 500m
        memory: 1Gi

  

2、此時執行yaml文件,就可以創建新的pod

[root@master ~]# kubectl apply -f  pod-demo1.yaml -n myns
pod/pod-demo-2 unchanged

  

3、查看resourcequota詳細信息,此時創建的2個pod使用的最大值就是2G,硬限制也是2G

[root@master ~]# kubectl describe resourcequota quota-example -n myns
Name:                         quota-example
Namespace:                    myns
Resource                      Used   Hard
--------                      ----   ----
count/deployments.apps        0      2
count/deployments.extensions  0      2
limits.cpu                    2      2    # 此時使用的最大值就是2G,硬限制也是2G
limits.memory                 1Gi    2Gi
persistentvolumeclaims        0      2
pods                          2      5
requests.cpu                  1      1
requests.memory               500Mi  1Gi

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章