1. 程式人生 > >Kubernetes 的安全機制 APIServer 認證、授權、准入控制_Kubernetes中文社群

Kubernetes 的安全機制 APIServer 認證、授權、准入控制_Kubernetes中文社群

本文講解 kubernetes 的安全機制。主要會按照這幾個部分來講解:APIServer 認證、授權、准入控制等。

我們都知道 kubenetes 預設在兩個埠提供服務:一個是基於 https 安全埠 6443,另一個是基於 http 的非安全埠 8080。其中非安全埠 8080 限制只能本機訪問,即繫結的是 localhost。

對於安全埠來講,一個 API 請求到達 6443 埠後,主要經過以下幾步處理:

  • 認證
  • 授權
  • 准入控制
  • 實際的 API 請求

APIServer 認證

Authentication verifies who you are.

認證的介面為:

// Request attempts to extract authentication information from a request and returns
 // information about the current user and true if successful, false if not successful,
 // or an error if the request could not be checked.
 type Request interface {
 AuthenticateRequest(req *http.Request) (user.Info, bool, error)
 }

// Info describes a user that has been authenticated to the system.
 type Info interface {

GetName() string

GetUID() string

GetGroups() []string

GetExtra() map[string][]string
 }
 也就是說,認證的目的是識別出訪問者是誰,識別出訪問者身份之後,具體有沒有許可權執行某個操作則是由“ 授權模組 ”來完成。

kubernetes 認證主要分為三種:CA 證書認證、Token 認證、Base 認證。可以同時配置多種認證方式,只要其中任意一個方式認證通過即可。

APIServer 授權

Authorization verifies what you are authorized to do.

授權就是授予不同使用者不同的訪問許可權,APIServer 目前支援以下幾種授權策略:

  • AlwaysDeny:表示拒絕所有的請求,該配置一般用於測試
  • AlwaysAllow:表示接收所有請求,如果叢集不需要授權,則可以採取這個策略
  • ABAC:基於屬性的訪問控制,表示基於配置的授權規則去匹配使用者請求,判斷是否有許可權。Beta 版本
  • RBAC:基於角色的訪問控制,允許管理員通過 api 動態配置授權策略。Beta 版本

RBAC 主要還是基於私有云的那種授權思路,網易雲基礎服務(蜂巢)是基於 ABAC 自己開發的一套使用者隔離的授權策略。因此接下來主要講解一下 ABAC。

授權的介面為:

type Authorizer interface {
 Authorize(a Attributes) (err error)
 }
 // Attributes is an interface used by an Authorizer to get information about a request
 // that is used to make an authorization decision.
 type Attributes interface {

GetUserName() string

GetGroups() []string

GetVerb() string

IsReadOnly() bool

// The namespace of the object, if a request is for a REST object.
 GetNamespace() string

// The kind of object, if a request is for a REST object.
 GetResource() string

// GetSubresource returns the subresource being requested, if present
 GetSubresource() string

GetName() string

GetTenantId(tenantId string)

}

其實主要有六個基本屬性:

  • 使用者名稱,代表一個已經被認證的使用者的 id
  • 是否是隻讀請求
  • 請求型別,比如 GET、List、Watch 等
  • 資源型別,比如 pods、nodes 等
  • namespace,被訪問物件所屬的 namespace
  • tenantid,被訪問物件所屬的租戶 id

假如使用者 A 發來請求 /api/v1/namespaces/nsa/pods/pda,那麼我們可以通過這個請求以及 apiserver 的快取,設定好上面的五個基本屬性,為接下來的授權做好準備工作:

  • 使用者名稱:A
  • 只讀:是
  • 請求型別:GET
  • namespace:nsa
  • 資源型別:pods
  • tenantid:一個租戶下面可以由多個 namespace,namespace 的 label 中設定了它屬於哪個租戶

接下來,看一下如何配置授權策略。

比如,我們限制叢集內的使用者只能訪問自己租戶的 persistentvolumes 資源,並且只能執行 get、list 和 watch 請求,那麼對應的授權規則為:

{"ruleName": "kubelet", "resource": "persistentvolumes", "tenantId": "self", "method": "get&list&watch"}

限制叢集內的使用者能訪問叢集內的所有 pods 資源,但是隻有對自己租戶的 pods 資源才具有更改許可權,那麼對應的授權策略為:

{"ruleName": "kubelet", "resource": "pods", "tenantId": "self","method":"*"}
{"ruleName": "kubelet", "resource": "pods", "tenantId":"*","method": "get&list&watch"}

其中“ * ”表示匹配所有。
我們可以定義多條授權策略,只要有一條通過即授權通過。

Admission Control 准入控制

通過了前面的認證和授權之後,還需要經過准入控制處理通過之後,apiserver 才會處理這個請求。Admission Control 有一個准入控制列表,我們可以通過命令列設定選擇執行哪幾個准入控制器。只有所有的准入控制器都檢查通過之後,apiserver 才執行該請求,否則返回拒絕。

當前可配置的准入控制器主要有:

  • AlwaysAdmit:允許所有請求
  • AlwaysDeny:拒絕所有請求
  • AlwaysPullImages:在啟動容器之前總是去下載映象
  • ServiceAccount:將 secret 資訊掛載到 pod 中,比如 service account token,registry key 等
  • ResourceQuota 和 LimitRanger:實現配額控制
  • SecurityContextDeny:禁止建立設定了 Security Context 的 pod

准入控制的介面定義為:

// Interface is an abstract, pluggable interface for Admission Control decisions.
 type Interface interface {
 // Admit makes an admission decision based on the request attributes
 Admit(a Attributes) (err error)

// Handles returns true if this admission controller can handle the given operation
 // where operation can be one of CREATE, UPDATE, DELETE, or CONNECT
 Handles(operation Operation) bool
 }

type Handler struct {
 operations sets.String
 }

// Handles returns true for methods that this handler supports
 func (h *Handler) Handles(operation Operation) bool {
 return h.operations.Has(string(operation))
 }

如果我們想實現自己的准入控制外掛,只要實現這個介面即可,使用起來非常簡單。

參考文獻

https://www.cyberciti.biz/faq/authentication-vs-authorization/
https://kubernetes.io/docs/admin/accessing-the-api/
https://kubernetes.io/docs/admin/authorization/
https://kubernetes.io/docs/admin/admission-controllers/
kubernetes權威指南