Kyverno外部數(shù)據(jù)源

在 Kyverno 策略中使用來(lái)自 ConfigMap、Kubernetes API Server和 image registry 的數(shù)據(jù)憋槐。

變量部分討論了變量如何幫助創(chuàng)建更智能和可重用的策略定義赚抡,并介紹了存儲(chǔ)所有變量的規(guī)則 context 的概念。

本節(jié)提供關(guān)于在策略中使用來(lái)自 ConfigMap僵刮、Kubernetes API Server和 image registry 的數(shù)據(jù)的詳細(xì)信息。

注意

為了提高安全性和性能鹦牛,Kyverno 被設(shè)計(jì)為不允許連接到集群 Kubernetes API Server和 image registry以外的系統(tǒng)搞糕。使用單獨(dú)的控制器從任何來(lái)源獲取數(shù)據(jù)并將其存儲(chǔ)在可在策略中有效使用的 ConfigMap 中。這種設(shè)計(jì)可以實(shí)現(xiàn)關(guān)注點(diǎn)分離和安全邊界的實(shí)施曼追。

來(lái)自 ConfigMap 的變量

Kubernetes 中的 ConfigMap 資源通常用作應(yīng)用程序可以使用的配置詳細(xì)信息的來(lái)源窍仰。這些數(shù)據(jù)可以以多種格式寫(xiě)入,存儲(chǔ)在命名空間中礼殊,并且可以輕松訪問(wèn)驹吮。 Kyverno 支持使用 ConfigMap 作為變量的數(shù)據(jù)源。評(píng)估引用 ConfigMap 資源的策略時(shí)晶伦,會(huì)檢查 ConfigMap 數(shù)據(jù)碟狞,以確保對(duì) ConfigMap 的引用始終是動(dòng)態(tài)的。如果 ConfigMap 更新婚陪,后續(xù)策略查找將在該時(shí)間點(diǎn)獲取最新數(shù)據(jù)族沃。

為了在 rule 中使用來(lái)自 ConfigMap 的數(shù)據(jù),需要一個(gè)context近忙。對(duì)于您希望使用 ConfigMap 中的數(shù)據(jù)的每個(gè) rule竭业,您必須定義一個(gè) context。然后可以使用 JMESPath 表示法在策略 rule 中引用上下文數(shù)據(jù)及舍。

查找 ConfigMap 值

在規(guī)則的 context 中定義的 ConfigMap 可以使用其在上下文中的唯一名稱來(lái)引用未辆。可以使用 JMESPath 樣式表達(dá)式引用 ConfigMap 值锯玛。

{{ <context-name>.data.<key-name> }}

考慮這樣一個(gè)簡(jiǎn)單的 ConfigMap 定義咐柜。

apiVersion: v1
kind: ConfigMap
metadata:
  name: some-config-map
  namespace: some-namespace
data:
  env: production

要在 rule 內(nèi)引用來(lái)自 ConfigMap 的值兼蜈,請(qǐng)?jiān)?rule 內(nèi)定義一個(gè)使用了一個(gè)或多個(gè) ConfigMap 聲明的 context。使用上面引用的示例 ConfigMap 片段拙友,以下 rule 定義了一個(gè)按名稱引用此特定 ConfigMap 的 context为狸。

rules:
  - name: example-lookup
    # Define a context for the rule
    context:
    # A unique name for the ConfigMap
    - name: dictionary
      configMap:
        # Name of the ConfigMap which will be looked up
        name: some-config-map
        # Namespace in which this ConfigMap is stored
        namespace: some-namespace 

基于上面的示例,我們現(xiàn)在可以使用 {{dictionary.data.env}} 引用 ConfigMap 值遗契。在策略執(zhí)行期間辐棒,該變量將替換為 production。

放入完整 ClusterPolicy 的上下文中牍蜂,將 ConfigMap 作為變量引用如下所示漾根。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: cm-variable-example
  annotations:
    pod-policies.kyverno.io/autogen-controllers: DaemonSet,Deployment,StatefulSet
spec:
    rules:
    - name: example-configmap-lookup
      context:
      - name: dictionary
        configMap:
          name: some-config-map
          namespace: some-namespace
      match:
        any:
        - resources:
            kinds:
            - Pod
      mutate:
        patchStrategicMerge:
          metadata:
            labels:
              my-environment-name: "{{dictionary.data.env}}"

在上面的 ClusterPolicy 中,一個(gè) mutate 規(guī)則匹配所有傳入的 Pod 資源鲫竞,并為其添加一個(gè)名為 my-environment-name 的 label辐怕。因?yàn)槲覀円呀?jīng)定義了一個(gè) context,它指向我們之前名為 some-config-map 的 ConfigMap从绘,所以我們可以使用表達(dá)式 {{dictionary.data.env}} 來(lái)引用該值寄疏。一個(gè)新創(chuàng)建的 Pod 將會(huì)接收到 label my-environment-name=production。

注意:ConfigMap 名稱和鍵可以包含 JMESPath 不支持的字符僵井,例如“-”(減號(hào)或破折號(hào))或“/”(斜杠)陕截。要將這些字符計(jì)算為文字,請(qǐng)?jiān)?JMESPath 表達(dá)式的該部分添加雙引號(hào)批什,如下所示:

{{ "<name>".data."<key>" }}

有關(guān)格式化問(wèn)題的更多信息艘策,請(qǐng)參閱 JMESPath 頁(yè)面

處理 ConfigMap 數(shù)組值

除了簡(jiǎn)單的字符串值之外渊季,Kyverno 還能夠使用 ConfigMap 中的數(shù)組值。

注意:自 Kyverno 1.7.0 起罚渐,將數(shù)組值存儲(chǔ)在 YAML 塊標(biāo)量中已被刪除却汉。請(qǐng)改用 JSON 編碼的字符串?dāng)?shù)組。

例如荷并,假設(shè)您想在 ConfigMap 中定義允許的角色列表合砂。Kyverno 策略可以引用此列表來(lái)拒絕注釋中定義的角色的請(qǐng)求。

假設(shè)一個(gè) ConfigMap源织,其內(nèi)容為 YAML 多行值翩伪。

apiVersion: v1
kind: ConfigMap
metadata:
  name: roles-dictionary
  namespace: default
data:
  allowed-roles: "[\"cluster-admin\", \"cluster-operator\", \"tenant-admin\"]"

注意:如前所述,某些字符必須轉(zhuǎn)義以進(jìn)行 JMESPath 處理谈息。在這種情況下缘屹,反斜杠 ("") 字符用于轉(zhuǎn)義雙引號(hào),這允許將 ConfigMap 數(shù)據(jù)存儲(chǔ)為 JSON 數(shù)組侠仇。

現(xiàn)在數(shù)組數(shù)據(jù)保存在 allowed-roles 鍵中轻姿,下面是一個(gè)示例 ClusterPolicy犁珠,其中包含一個(gè)規(guī)則,如果名為 role 的注解的值不在允許列表中互亮,則該規(guī)則會(huì)阻止部署:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: cm-array-example
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: validate-role-annotation
    context:
      - name: roles-dictionary
        configMap:
          name: roles-dictionary
          namespace: default
    match:
      any:
      - resources:
          kinds:
          - Deployment
    validate:
      message: "The role {{ request.object.metadata.annotations.role }} is not in the allowed list of roles: {{ \"roles-dictionary\".data.\"allowed-roles\" }}."
      deny:
        conditions:
          any:
          - key: "{{ request.object.metadata.annotations.role }}"
            operator: NotIn
            value:  "{{ \"roles-dictionary\".data.\"allowed-roles\" }}"

如果在我們之前定義的名為 roles-dictionary 的 ConfigMap 的數(shù)組中找不到注解 role犁享,則此規(guī)則拒絕新建 Deployment 的請(qǐng)求。

注意:您可能還會(huì)注意到豹休,此示例在單個(gè)規(guī)則中使用了來(lái)自 AdmissionReview 和 ConfigMap 源的變量炊昆。這種組合可以證明在制定有用的策略方面非常強(qiáng)大和靈活。

創(chuàng)建此示例 ClusterPolicy 后威根,嘗試創(chuàng)建注解 role=super-user 的新 Deployment 并測(cè)試結(jié)果凤巨。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: busybox
  annotations:
    role: super-user
  labels:
    app: busybox
spec:
  replicas: 1
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - image: busybox:1.28
        name: busybox
        command: ["sleep", "9999"]

提交清單,看看 Kyverno 的反應(yīng)医窿。

$ kubectl create -f deploy.yaml
Error from server: error when creating "deploy.yaml": admission webhook "validate.kyverno.svc" denied the request:

resource Deployment/default/busybox was blocked due to the following policies

cm-array-example:
  validate-role-annotation: 'The role super-user is not in the allowed list of roles: ["cluster-admin", "cluster-operator", "tenant-admin"].'

將注解 role 更改為 ConfigMap 中存在的值之一磅甩,例如 tenant-admin,允許創(chuàng)建 Deployment 資源姥卢。

來(lái)自 Kubernetes API Server調(diào)用的變量

Kubernetes 由允許查詢和操作資源的聲明性 API 提供支持卷要。Kyverno 策略可以使用 Kubernetes API 來(lái)獲取資源,甚至是資源類型的集合独榴,以在策略中使用僧叉。此外,Kyverno 允許將 JMESPath(JSON 匹配表達(dá)式)應(yīng)用于資源數(shù)據(jù)棺榔,以提取值并將其轉(zhuǎn)換為易于在策略中使用的格式瓶堕。

Kyverno Kubernetes API 調(diào)用與 kubectl 和其他 API 客戶端一樣工作,并且可以使用現(xiàn)有工具進(jìn)行測(cè)試症歇。

例如郎笆,下面是一個(gè)命令行,它使用 kubectl 獲取命名空間中的 Pod 列表忘晤,然后將輸出通過(guò)管道傳輸?shù)?kyverno jp宛蚓,以計(jì)算 Pod 的數(shù)量:

kubectl get --raw /api/v1/namespaces/kyverno/pods | kyverno jp "items | length(@)"

使用 kubectl get --raw 和 kyverno jp 命令來(lái)測(cè)試 API 調(diào)用。

Kyverno 中相應(yīng)的 API 調(diào)用定義如下设塔。使用一個(gè)變量 {{request.namespace}} 來(lái)使用被操作對(duì)象的 Namespace凄吏,然后同樣用 JMESPath 獲取 Namespace 中 Pod 的數(shù)量,并以變量 podCount 的形式存儲(chǔ)到 context 中闰蛔。

rules:
- name: example-api-call
  context:
  - name: podCount
    apiCall:
      urlPath: "/api/v1/namespaces/{{request.namespace}}/pods"
      jmesPath: "items | length(@)"   

URL路徑

Kubernetes API 使用 group 和 version來(lái)組織資源痕钢。例如,資源類型 Deployment 的 API Group 是 apps序六, version 是 v1任连。

API 調(diào)用的 HTTP URL 路徑基于group、version和資源類型难咕,如下所示:

  • /apis/{GROUP}/{VERSION}/{RESOURCETYPE}:獲取一個(gè)資源集合

  • /apis/{GROUP}/{VERSION}/{RESOURCETYPE}/{NAME}:獲取一個(gè)資源

對(duì)于命名空間級(jí)別的資源课梳,要通過(guò)名稱獲取特定資源或獲取命名空間中的所有資源距辆,還必須提供命名空間名稱,如下所示:

  • /apis/{GROUP}/{VERSION}/namespaces/{NAMESPACE}/{RESOURCETYPE}:獲取命名空間中的一組資源集合

  • /apis/{GROUP}/{VERSION}/namespaces/{NAMESPACE}/{RESOURCETYPE}/{NAME}:獲取命名空間中的一個(gè)資源

對(duì)于歷史資源暮刃,Kubernetes 核心 API 都在 /api/v1 下跨算。例如,要查詢所有命名空間資源椭懊,使用路徑 /api/v1/namespaces诸蚕。

v1.22 的 API 參考文檔中定義了 Kubernetes API 組,也可以通過(guò)如下所示的 kubectl api-resources 命令檢索:

$ kubectl api-resources
NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND
bindings                                                                      true         Binding
componentstatuses                 cs                                          false        ComponentStatus
configmaps                        cm                                          true         ConfigMap
endpoints                         ep                                          true         Endpoints
events                            ev                                          true         Event
limitranges                       limits                                      true         LimitRange
namespaces                        ns                                          false        Namespace
nodes                             no                                          false        Node
persistentvolumeclaims            pvc                                         true         PersistentVolumeClaim

...

kubectl api-versions 命令打印出每個(gè) API 組的可用版本氧猬。這是一個(gè)示例:

$ kubectl api-versions
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
batch/v1
...

您可以結(jié)合使用這些命令來(lái)查找資源的 URL 路徑背犯,如下所示:

要查找資源的 API 組和版本,請(qǐng)使用 kubectl api-resources 查找組盅抚,然后使用 kubectl api-versions 查找可用版本漠魏。

本示例查找 Deployment 資源組,然后查詢版本:

kubectl api-resources | grep deploy

API 組顯示在輸出的第三列中妄均。然后柱锹,您可以使用組名來(lái)查找版本:

kubectl api-versions | grep apps

其輸出將是 apps/v1。舊版本的 Kubernetes(1.18 之前)將顯示 apps/v1beta2丰包。

處理集合

請(qǐng)求資源集合的 URL 路徑上的 HTTP GET 的 API 服務(wù)器響應(yīng)將是具有項(xiàng)目(資源)列表的對(duì)象禁熏。

這是一個(gè)獲取所有命名空間資源的示例:

kubectl get --raw /api/v1/namespaces | jq

使用 jq 格式化輸出以提高可讀性。

這將返回一個(gè) NamespaceList 對(duì)象邑彪,其屬性 items 包含命名空間列表:

{
    "kind": "NamespaceList",
    "apiVersion": "v1",
    "metadata": {
      "selfLink": "/api/v1/namespaces",
      "resourceVersion": "2009258"
    },
    "items": [
      {
        "metadata": {
          "name": "default",
          "selfLink": "/api/v1/namespaces/default",
          "uid": "5011b5d5-abb7-4fef-93f9-8b5fa4b2eba9",
          "resourceVersion": "155",
          "creationTimestamp": "2021-01-19T20:20:37Z",
          "managedFields": [
            {
              "manager": "kube-apiserver",
              "operation": "Update",
              "apiVersion": "v1",
              "time": "2021-01-19T20:20:37Z",
              "fieldsType": "FieldsV1",
              "fieldsV1": {
                "f:status": {
                  "f:phase": {}
                }
              }
            }
          ]
        },
        "spec": {
          "finalizers": [
            "kubernetes"
          ]
        },
        "status": {
          "phase": "Active"
        }
      },
      ...

要在 JMESPath 中處理此數(shù)據(jù)瞧毙,請(qǐng)引用items。這是一個(gè)示例寄症,它在所有命名空間資源中提取了一些元數(shù)據(jù)字段:

kubectl get --raw /api/v1/namespaces | kyverno jp "items[*].{name: metadata.name, creationTime: metadata.creationTimestamp}"

這將生成一個(gè)新的 JSON 對(duì)象列表宙彪,其中包含屬性名稱和創(chuàng)建時(shí)間。

[
  {
    "creationTimestamp": "2021-01-19T20:20:37Z",
    "name": "default"
  },
  {
    "creationTimestamp": "2021-01-19T20:20:36Z",
    "name": "kube-node-lease"
  },
  ...

要在列表中查找項(xiàng)目有巧,您可以使用 JMESPath 過(guò)濾器您访。例如,此命令將按名稱匹配命名空間:

kubectl get --raw /api/v1/namespaces | kyverno jp "items[?metadata.name == 'default'].{uid: metadata.uid, creationTimestamp: metadata.creationTimestamp}"

除了通配符和過(guò)濾器之外剪决,JMESPath 還有許多其他強(qiáng)大的、有用的功能檀训。請(qǐng)務(wù)必閱讀 JMESPath 教程并嘗試此處的 Kyverno JMESPath 頁(yè)面之外的交互式示例柑潦。

示例策略:在命名空間中限制 LoadBalancer 類型的服務(wù)

這是一個(gè)完整的示例策略,它將限制每個(gè)命名空間只能有一個(gè) LoadBalancer 類型的服務(wù)峻凫。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: limits
spec:
  validationFailureAction: enforce
  rules:
  - name: limit-lb-svc
    match:
      any:
      - resources:
          kinds:
          - Service
    context:
    - name: serviceCount
      apiCall:
        urlPath: "/api/v1/namespaces/{{ request.namespace }}/services"
        jmesPath: "items[?spec.type == 'LoadBalancer'] | length(@)"    
    preconditions:
      any:
      - key: "{{ request.operation }}"
        operator: Equals
        value: CREATE
    validate:
      message: "Only one LoadBalancer service is allowed per namespace"
      deny:
        conditions:
          any:
          - key: "{{ serviceCount }}"
            operator: GreaterThan
            value: 1

此示例策略檢索命名空間中的 Service列表渗鬼,并將 LoadBalancer 類型的 Service 計(jì)數(shù),并存儲(chǔ)在名為 serviceCount 的變量中荧琼。deny 規(guī)則用于確保計(jì)數(shù)不能超過(guò) 1譬胎。

來(lái)自 Image Registry 的變量

通過(guò)使用 imageRegistry context 類型差牛,context也可以使用 OCI 鏡像上的元數(shù)據(jù)。通過(guò)使用此外部數(shù)據(jù)源堰乔,Kyverno 策略可以根據(jù)作為傳入資源的一部分出現(xiàn)的容器鏡像的詳細(xì)信息做出決策偏化。

例如,如果您使用如下所示的 imageRegistry:

context: 
- name: imageData
  imageRegistry: 
    reference: "ghcr.io/kyverno/kyverno"

輸出 imageData 變量將具有如下結(jié)構(gòu):

{
    "image":         "ghcr.io/kyverno/kyverno",
    "resolvedImage": "ghcr.io/kyverno/kyverno@sha256:17bfcdf276ce2cec0236e069f0ad6b3536c653c73dbeba59405334c0d3b51ecb",
    "registry":      "ghcr.io",
    "repository":    "kyverno/kyverno",
    "identifier":    "latest",
    "manifest":      manifest,
    "configData":    config,
}

注意

imageData 代表了一個(gè)鏡像在 registry 執(zhí)行任何重定向并由 Kyverno 進(jìn)行內(nèi)部修改之后的“歸一化”的視圖(Kyverno 默認(rèn)將一個(gè)空注冊(cè)表設(shè)置為 docker.io 并將一個(gè)空標(biāo)簽設(shè)置為 latest)镐侯。最值得注意的是侦讨,這會(huì)影響托管在 Docker Hub 上的官方鏡像。Docker Hub 上的官方鏡像與其他鏡像的區(qū)別在于它們的存儲(chǔ)庫(kù)以 library/ 為前綴苟翻,即使被拉取的鏡像不包含它韵卤。例如,使用 python:slim 拉取 python 官方圖像會(huì)導(dǎo)致設(shè)置 imageData 的以下字段:

{
    "image":         "docker.io/python:slim",
    "resolvedImage": "index.docker.io/library/python@sha256:43705a7d3a22c5b954ed4bd8db073698522128cf2aaec07690a34aab59c65066",
    "registry":      "index.docker.io",
    "repository":    "library/python",
    "identifier":    "slim"
}

manifest 和 config 分別包含來(lái)自 crane manifest <image> 和 crane config <image> 的輸出崇猫。

例如沈条,可以檢查給定圖像的labels、entrypoint诅炉、volumes蜡歹、history、layers汞扎、etc 等季稳。使用工具 crane,顯示鏡像 ghcr.io/kyverno/kyverno:latest 的配置信息:

$ crane config ghcr.io/kyverno/kyverno:latest | jq
{
  "architecture": "amd64",
  "config": {
    "User": "10001",
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Entrypoint": [
      "./kyverno"
    ],
    "WorkingDir": "/",
    "Labels": {
      "maintainer": "Kyverno"
    },
    "OnBuild": null
  },
  "created": "2022-02-04T08:57:38.818583756Z",
  "history": [
    {
      "created": "2022-02-04T08:57:38.454742161Z",
      "created_by": "LABEL maintainer=Kyverno",
      "comment": "buildkit.dockerfile.v0",
      "empty_layer": true
    },
    {
      "created": "2022-02-04T08:57:38.454742161Z",
      "created_by": "COPY /output/kyverno / # buildkit",
      "comment": "buildkit.dockerfile.v0"
    },
    {
      "created": "2022-02-04T08:57:38.802069102Z",
      "created_by": "COPY /etc/passwd /etc/passwd # buildkit",
      "comment": "buildkit.dockerfile.v0"
    },
    {
      "created": "2022-02-04T08:57:38.818583756Z",
      "created_by": "COPY /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ # buildkit",
      "comment": "buildkit.dockerfile.v0"
    },
    {
      "created": "2022-02-04T08:57:38.818583756Z",
      "created_by": "USER 10001",
      "comment": "buildkit.dockerfile.v0",
      "empty_layer": true
    },
    {
      "created": "2022-02-04T08:57:38.818583756Z",
      "created_by": "ENTRYPOINT [\"./kyverno\"]",
      "comment": "buildkit.dockerfile.v0",
      "empty_layer": true
    }
  ],
  "os": "linux",
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:180b308b8730567d2d06a342148e1e9d274c8db84113077cfd0104a7e68db646",
      "sha256:99187eab8264c714d0c260ae8b727c4d2bda3a9962635aaea67d04d0f8b0f466",
      "sha256:26d825f3d198779c4990007ae907ba21e7c7b6213a7eb78d908122e435ec9958"
    ]
  }
}

在上面的輸出中澈魄,我們可以在 config.User 下看到運(yùn)行這個(gè)容器的 Dockerfile 的 USER 聲明是 10001景鼠。可以編寫(xiě) Kyverno 策略來(lái)利用此信息并執(zhí)行痹扇,例如铛漓,驗(yàn)證鏡像的 USER 是非 root。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: imageref-demo
spec:
  validationFailureAction: enforce
  rules:
  - name: no-root-images
    match:
      any:
      - resources:
          kinds:
          - Pod
    preconditions:
      all:
      - key: "{{request.operation}}"
        operator: NotEquals
        value: DELETE
    validate:
      message: "Images run as root are not allowed."  
      foreach:
      - list: "request.object.spec.containers"
        context: 
        - name: imageData
          imageRegistry: 
            reference: "{{ element.image }}"
        deny:
          conditions:
            any:
              - key: "{{ imageData.configData.config.User || ''}}"
                operator: Equals
                value: ""

在上面的示例策略中鲫构,已經(jīng)編寫(xiě)了一個(gè)名為 imageData 浓恶,類型為 imageRegistry 的新 context。reference 鍵用于指示 Kyverno 存儲(chǔ)鏡像元數(shù)據(jù)的位置结笨。其中 element 是 Pod 內(nèi)的每個(gè)容器包晰,因此 element.image 的容器鏡像。然后可以在表達(dá)式中引用該值炕吸,例如在 deny.conditions 中通過(guò)鍵 {{ imageData.configData.config.User || ''}}伐憾。

使用示例“bad” Pod 來(lái)測(cè)試違反此政策的情況,如下所示赫模,Pod 被阻止树肃。

apiVersion: v1
kind: Pod
metadata:
  name: badpod
spec:
  containers:
  - name: ubuntu
    image: ubuntu:latest
$ kubectl apply -f bad.yaml 
Error from server: error when creating "bad.yaml": admission webhook "validate.kyverno.svc-fail" denied the request: 

resource Pod/default/badpod was blocked due to the following policies

imageref-demo:
  no-root-images: 'validation failure: Images run as root are not allowed.'

相比之下,當(dāng)使用“good”的 Pod 時(shí)瀑罗,例如上面提到的 Kyverno 容器鏡像胸嘴,該資源是允許的雏掠。

apiVersion: v1
kind: Pod
metadata:
  name: goodpod
spec:
  containers:
  - name: kyverno
    image: ghcr.io/kyverno/kyverno:latest
$ kubectl apply -f good.yaml 
pod/goodpod created

imageRegistry 上下文類型還有一個(gè)名為 jmesPath 的可選屬性,能夠應(yīng)用一個(gè) JMESPath 表達(dá)式劣像,事先存儲(chǔ)為 context 的值乡话,并寫(xiě)入 imageRegistry 的返回的內(nèi)容中。例如驾讲,下面的代碼片段通過(guò)疊加其清單報(bào)告的鏡像的所有組成層蚊伞,將鏡像的總大小存儲(chǔ)在名為 imageSize 的 context 中(通過(guò) crane manifest 可以得到各層的信息)。然后可以在稍后的表達(dá)式中評(píng)估 context 變量的值吮铭。

context: 
  - name: imageSize
    imageRegistry: 
      reference: "{{ element.image }}"
      # Note that we need to use `to_string` here to allow kyverno to treat it like a resource quantity of type memory
      # the total size of an image as calculated by docker is the total sum of its layer sizes
      jmesPath: "to_string(sum(manifest.layers[*].size))"

要訪問(wèn)存儲(chǔ)在私有 registry 中的圖像时迫,請(qǐng)參閱使用私有 registry

有關(guān)使用 imageRegistry con text的更多示例谓晌,請(qǐng)參閱示例頁(yè)面掠拳。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市纸肉,隨后出現(xiàn)的幾起案子溺欧,更是在濱河造成了極大的恐慌,老刑警劉巖柏肪,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姐刁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡烦味,警方通過(guò)查閱死者的電腦和手機(jī)聂使,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谬俄,“玉大人柏靶,你說(shuō)我怎么就攤上這事±B郏” “怎么了屎蜓?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)钥勋。 經(jīng)常有香客問(wèn)我炬转,道長(zhǎng),這世上最難降的妖魔是什么算灸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任返吻,我火速辦了婚禮,結(jié)果婚禮上乎婿,老公的妹妹穿的比我還像新娘。我一直安慰自己街佑,他們只是感情好谢翎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布捍靠。 她就那樣靜靜地躺著,像睡著了一般森逮。 火紅的嫁衣襯著肌膚如雪榨婆。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天褒侧,我揣著相機(jī)與錄音良风,去河邊找鬼。 笑死闷供,一個(gè)胖子當(dāng)著我的面吹牛烟央,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歪脏,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼疑俭,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了婿失?” 一聲冷哼從身側(cè)響起钞艇,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎豪硅,沒(méi)想到半個(gè)月后哩照,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡懒浮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年飘弧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嵌溢。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眯牧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赖草,到底是詐尸還是另有隱情学少,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布秧骑,位于F島的核電站版确,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏乎折。R本人自食惡果不足惜绒疗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望骂澄。 院中可真熱鬧吓蘑,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至琳猫,卻和暖如春伟叛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脐嫂。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工统刮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人账千。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓侥蒙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蕊爵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辉哥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容