摘要:介紹干的最重要的三個(gè)事就是認(rèn)證看是否是合法用戶授權(quán)看用戶具備哪些權(quán)限一個(gè)調(diào)用鏈,對請求進(jìn)行控制或修改,比如是否允許這個(gè)請求。把這個(gè)服務(wù)起一個(gè)這樣就可以自動發(fā)現(xiàn)它。是基于開發(fā)平臺的利器更多精彩
Admission Controller介紹
Apiserver干的最重要的三個(gè)事就是:
認(rèn)證 : 看是否是合法用戶
授權(quán) : 看用戶具備哪些權(quán)限
admission controller : 一個(gè)調(diào)用鏈,對請求進(jìn)行控制或修改,比如是否允許這個(gè)請求。
admission controller非常有用,也是經(jīng)常會用到的k8s的一個(gè)擴(kuò)展方式,今天在源碼級別對其做一下介紹,以及如何自己去開發(fā)一個(gè)admission controller.
我們的應(yīng)用場景是:我們希望把所有需要創(chuàng)建的pod都加上一個(gè)注解,因?yàn)槲覀冊缙谑峭ㄟ^podpreset給pod注入lxcfs的配置的,但是用戶在寫yaml文件時(shí)很容易忘記加上,所以需要在apiserver上來個(gè)自動處理
metadata: name: test-net annotations: initializer.kubernetes.io/lxcfs: "true" # 就是在pod的metadata里加上這個(gè)配置默認(rèn)admission controller
已經(jīng)有很多默認(rèn)非常有用的admission插件,這里挑幾個(gè)介紹一下:
名稱 | 作用 |
---|---|
AlwaysPullImages | 把所有鏡像策略都調(diào)整成alwaysPull, 多租戶安全時(shí)比較有用 |
DefaultStorageClass | 默認(rèn)存儲類型 |
DefaultTolerationSeconds | 節(jié)點(diǎn)notready:NoExecute時(shí)的容忍時(shí)間,比如有時(shí)我們升級kubelet,希望升級時(shí)pod不要漂移就會用到 |
DenyEscalatingExec | 拒絕遠(yuǎn)程連接容器 |
ExtendedResourceToleration | 比如我有擴(kuò)展資源,那么我可以通過它來玷污節(jié)點(diǎn),防止不需要該資源的pod到我的機(jī)器上來,如GPU |
LimitRanger | 在多租戶配額時(shí)相當(dāng)有用,如果pod沒配額,那么我可以默認(rèn)給個(gè)很低的配額 |
NamespaceAutoProvision | 這個(gè)也非常有用,資源的namespace不存在時(shí)就創(chuàng)建一個(gè) |
PodPreset | 可以對pod進(jìn)行一些預(yù)處理設(shè)置 |
ResourceQuota | 多租戶配額時(shí)比較重要,看資源是否滿足resource quota中的配置 |
多租戶時(shí)經(jīng)常會開啟這個(gè),強(qiáng)制所有的鏡像必須去拉取,因?yàn)槿绻贿@樣,那么別的租戶如果知道了你的鏡像名就可以寫一個(gè)yaml去啟動你的鏡像,強(qiáng)制拉時(shí)猶豫需要image pull secret所以無法拉取你的鏡像。
所以這個(gè)admission干的事就是把鏡像拉取策略都改成alwaysPull:
代碼位置:
kubernetes/plugin/pkg/admission/alwayspullimages/admission.go func (a *AlwaysPullImages) Admit(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) { // 你可以在attibutes里獲取到對象的一切信息,用戶信息等 if shouldIgnore(attributes) { // 檢查一下是不是你關(guān)注的object, 比如創(chuàng)建的一個(gè)configmap 那么顯然可以忽視 return nil } pod, ok := attributes.GetObject().(*api.Pod) // 這里把initContainer和Container的拉取策略都給改了 for i := range pod.Spec.InitContainers { pod.Spec.InitContainers[i].ImagePullPolicy = api.PullAlways } for i := range pod.Spec.Containers { pod.Spec.Containers[i].ImagePullPolicy = api.PullAlways } return nil } # 還提供一個(gè)校驗(yàn)接口,看是不是真的都已經(jīng)被改了 func (a *AlwaysPullImages) Validate(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) { pod, ok := attributes.GetObject().(*api.Pod) for i := range pod.Spec.InitContainers { if pod.Spec.InitContainers[i].ImagePullPolicy != api.PullAlways { return admission.NewForbidden(attributes, field.NotSupported(field.NewPath("spec", "initContainers").Index(i).Child("imagePullPolicy"), pod.Spec.InitContainers[i].ImagePullPolicy, []string{string(api.PullAlways)}, ), ) } } ... return nil }
然后實(shí)現(xiàn)一個(gè)注冊函數(shù):
func Register(plugins *admission.Plugins) { plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) { return NewAlwaysPullImages(), nil }) } type AlwaysPullImages struct { *admission.Handler }
最后需要在plugin里面把其注冊進(jìn)去:
kubernetes/pkg/kubeapiserver/options/plugins.go func RegisterAllAdmissionPlugins(plugins *admission.Plugins) { imagepolicy.Register(plugins) ... }
所以實(shí)現(xiàn)一個(gè)admission非常簡單,主要就是實(shí)現(xiàn)兩個(gè)接口即可。
admission control webhooks很多情況下我們并不希望大動干戈去改apiserver代碼,所以apiserver提供了一種動態(tài)擴(kuò)展admission的方式,非常推薦。
有兩種類型:
validating admission Webhook 只作校驗(yàn),比如檢測到某個(gè)特殊字段就不讓請求通過
mutating admission webhook 可以對請求體進(jìn)行修改(patch)
比較重要的是這個(gè)AdmissionReview結(jié)構(gòu)體,包含一個(gè)請求一個(gè)響應(yīng)
請求:有Object的詳細(xì)信息,用戶信息
響應(yīng): 最重要的是 1. 是否允許 2. 修改(patch)的類型 3. 修改(patch)的值, 這個(gè)符合json patch標(biāo)準(zhǔn) (kubectl patch)
可在此 找到一個(gè)webhook server的例子
看一個(gè)具體例子,labelpatch,是給對象的元數(shù)據(jù)里加一些label的。
const ( // 特定的json patch格式 addFirstLabelPatch string = `[ { "op": "add", "path": "/metadata/labels", "value": {"added-label": "yes"}} ]` addAdditionalLabelPatch string = `[ { "op": "add", "path": "/metadata/labels/added-label", "value": "yes" } ]` ) // Add a label {"added-label": "yes"} to the object func addLabel(ar v1beta1.AdmissionReview) *v1beta1.AdmissionResponse { obj := struct { metav1.ObjectMeta Data map[string]string }{} raw := ar.Request.Object.Raw err := json.Unmarshal(raw, &obj) if err != nil { klog.Error(err) return toAdmissionResponse(err) } reviewResponse := v1beta1.AdmissionResponse{} reviewResponse.Allowed = true if len(obj.ObjectMeta.Labels) == 0 { reviewResponse.Patch = []byte(addFirstLabelPatch) // 這里最需要注意的就是修改時(shí)是通過patch的方式 } else { reviewResponse.Patch = []byte(addAdditionalLabelPatch) } pt := v1beta1.PatchTypeJSONPatch reviewResponse.PatchType = &pt return &reviewResponse }
把這個(gè)放到http handle里。
把這個(gè)HTTPS服務(wù)起一個(gè)service, 這樣apiserver就可以自動發(fā)現(xiàn)它。
apiVersion: admissionregistration.k8s.io/v1beta1 kind: ValidatingWebhookConfiguration metadata: name:總結(jié)webhooks: - name: rules: # 最好明確一下該hook關(guān)心哪些api,防止帶來不必要的額外開銷。 - apiGroups: - "" apiVersions: - v1 operations: - CREATE resources: - pods scope: "Namespaced" clientConfig: service: namespace: # webhook server的namespace name: # service name caBundle: # 因?yàn)樾枰ㄟ^https訪問,所以要給apiserver配置ca admissionReviewVersions: - v1beta1 timeoutSeconds: 1
adminssion control 是非常重要的APIserver擴(kuò)展的方式,掌握了其開發(fā)很多地方就能以比較優(yōu)雅的方式解決一些實(shí)際問題。是基于k8s開發(fā)PaaS平臺的利器
更多精彩: https://sealyun.com
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/27844.html
摘要:介紹干的最重要的三個(gè)事就是認(rèn)證看是否是合法用戶授權(quán)看用戶具備哪些權(quán)限一個(gè)調(diào)用鏈,對請求進(jìn)行控制或修改,比如是否允許這個(gè)請求。把這個(gè)服務(wù)起一個(gè)這樣就可以自動發(fā)現(xiàn)它。是基于開發(fā)平臺的利器更多精彩 Admission Controller介紹 Apiserver干的最重要的三個(gè)事就是: 認(rèn)證 : 看是否是合法用戶 授權(quán) : 看用戶具備哪些權(quán)限 admission controller : ...
摘要:對應(yīng)的又給新增了配套屬性容忍,用于表示這些可以但不強(qiáng)制要求被調(diào)度到具有相應(yīng)的上。的默認(rèn)值有幾個(gè)特殊情況為空并且等于,表示匹配了所有的,和。用來指定在添加了的后,能容忍該的可停留在上的時(shí)間。目的是確保在出現(xiàn)或的問題時(shí),永遠(yuǎn)不會被驅(qū)逐。 一、概述 前一篇文章講解了 Kubernetes 親和性調(diào)度, 所涉及的內(nèi)容都是描述 pod 的屬性,來聲明此 pod 希望調(diào)度到哪類 nodes。而本文...
摘要:最近被業(yè)務(wù)折騰的死去活來,實(shí)在沒時(shí)間發(fā)帖,花了好多個(gè)晚上才寫好這篇帖子,后續(xù)會加油的利用技術(shù)棧打造個(gè)人私有云系列文章目錄利用技術(shù)棧打造個(gè)人私有云連載之初章利用技術(shù)棧打造個(gè)人私有云連載之集群搭建利用技術(shù)棧打造個(gè)人私有云連載之環(huán)境理解和練手利用 showImg(https://segmentfault.com/img/remote/1460000013077799); 最近被業(yè)務(wù)折騰的死...
摘要:最近被業(yè)務(wù)折騰的死去活來,實(shí)在沒時(shí)間發(fā)帖,花了好多個(gè)晚上才寫好這篇帖子,后續(xù)會加油的利用技術(shù)棧打造個(gè)人私有云系列文章目錄利用技術(shù)棧打造個(gè)人私有云連載之初章利用技術(shù)棧打造個(gè)人私有云連載之集群搭建利用技術(shù)棧打造個(gè)人私有云連載之環(huán)境理解和練手利用 showImg(https://segmentfault.com/img/remote/1460000013077799); 最近被業(yè)務(wù)折騰的死...
摘要:如果有一個(gè)準(zhǔn)入控制拒絕了此次請求,那么整個(gè)請求的結(jié)果將會立即返回,并提示用戶相應(yīng)的信息。 這是啥 準(zhǔn)入控制admission controller本質(zhì)上一段代碼,在對kubernetes api的請求過程中,順序?yàn)?先經(jīng)過 認(rèn)證 & 授權(quán),執(zhí)行準(zhǔn)入操作,在對目標(biāo)對象進(jìn)行操作。這個(gè)準(zhǔn)入代碼在apiserver中,而且必須被編譯到二進(jìn)制文件中才能被執(zhí)行。 在對集群進(jìn)行請求時(shí),每個(gè)準(zhǔn)入控...
閱讀 3023·2021-10-27 14:15
閱讀 3015·2021-09-07 10:18
閱讀 1334·2019-08-30 15:53
閱讀 1584·2019-08-26 18:18
閱讀 3386·2019-08-26 12:15
閱讀 3469·2019-08-26 10:43
閱讀 664·2019-08-23 16:43
閱讀 2219·2019-08-23 15:27