注:

使用 Kyverno 将 ImagePullSecrets 属性注入到 Kubernetes 云池中

简介

Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) 是一项完全托管、可扩展且高度可用的服务,您可以使用它将容器化应用程序部署到云中。

Oracle Cloud Infrastructure Registry(也称为容器注册表或 OCIR)是一种由 Oracle 管理的注册表,可用于简化开发到生产工作流的过程。通过容器注册表,开发人员可以轻松存储、共享和管理容器映像。

您可以在 OCIR 中创建公共或专用容器映像资料档案库:

要从 OCIR 专用注册表中提取映像,Kubernetes 需要凭证。Pod 配置文件中的 spec.imagePullSecrets 属性指定 Kubernetes 密钥列表,其中包含 worker 节点应用于从注册表中提取容器映像的身份证明。

要简化应用程序清单和部署,并在与 OCIR 集成时分离某些特定于 OKE 群集的配置,我们可以使用 Kyverno。CNCF 下的这一孵化项目可以使用策略定义来验证、模拟、生成和清理 Kubernetes 资源。在创建新的 pod 并注入 imagePullSecrets 属性(拉取 OCIR 中存储的容器映像时,我们可以利用此产品来修改提交到 Kubernetes API 的清单。

目标

先决条件

任务 1:安装 Kyverno

Kyverno 网页介绍了在 Kubernetes 集群上安装 Kyverno 的两种方法,使用:

在本教程中,我们将重点介绍如何使用 Helm 图表安装 Kyverno。

任务 1.1:安装 helm

  1. 根据您所在的操作系统,浏览本指南并安装 helm

  2. 通过执行以下命令确认安装是否成功。

    helm version
    # version.BuildInfo{Version:"v3.8.1", GitCommit:"5cb9af4b1b271d11d7a97a71df3ac337dd94ad37", GitTreeState:"clean", GoVersion:"go1.17.5"}
    

任务 1.2:在独立模式下安装 Kyverno

  1. 添加 Kyverno Helm 系统信息库。

    helm repo add kyverno https://kyverno.github.io/kyverno/
    # "kyverno" has been added to your repositories
    
  2. 扫描新资料档案库以查找图表。

    helm repo update
    # Hang tight while we grab the latest from your chart repositories...
    # ...Successfully got an update from the "kyverno" chart repository
    # Update Complete. ⎈Happy Helming!⎈
    
  3. kyverno 名称空间中安装 Kyverno。

    helm install kyverno kyverno/kyverno -n kyverno --create-namespace
    # NAME: kyverno
    # LAST DEPLOYED: Fri Aug 30 12:20:33 2023
    # NAMESPACE: kyverno
    # STATUS: deployed
    # REVISION: 1
    # NOTES:
    # Chart version: 3.0.1
    # Kyverno version: v1.10.0
    
    # Thank you for installing kyverno! Your release is named kyverno.
    
    # The following components have been installed in your cluster:
    # - CRDs
    # - Admission controller
    # - Reports controller
    # - Cleanup controller
    # - Background controller
    

任务 2:创建 Kubernetes ImagePull 密钥

  1. 按照此处提供的步骤生成用户 Auth Token获取验证令牌

  2. 确保配置正确的策略以允许用户访问 OCIR:用于控制存储库访问的策略

  3. 确认 OCIR 注册表 URL、用户名和密码:

    注册表 URL 基于 OCI 区域键<region-key>.ocir.io

    示例:对于 OCI 菲尼克斯区域:phx.ocir.io

    用户名基于租户名称空间、oci 用户名和 IDP(如果使用):<tenancy-namespace>/<username><tenancy-namespace>/oracleidentitycloudservice/<username>

    示例:

    axaxnpcrorw5/jdoe@acme.comaxaxnpcrorw5/oracleidentitycloudservice/jdoe@acme.com

  4. 创建名为 ocirsecret 的 Kubernetes 密钥。

    kubectl create secret docker-registry ocirsecret --docker-server='<OCIR registry>' --docker-username='<username>' --docker-password='<auth-token>'
    

    示例:

    kubectl create secret docker-registry ocirsecret --docker-server='phx.ocir.io' --docker-username='axaxnpcrorw5/jdoe@acme.com' --docker-password='cxOY5NL<AnBN}<123{_6'

任务 3:定义必需的 Kyverno ClusterPolicies

  1. 创建名为 add-imagepullsecret.yaml 的文件。

  2. 复制以下文本并将其粘贴在文件中。

    ---
    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: inject-imagepullsecret-to-namespace
      annotations:
        policies.kyverno.io/title: Clone imagePullSecret secret to new namespaces
        policies.kyverno.io/subject: Namespace
        policies.kyverno.io/description: >-
          ImagePullSecrets must be present in the same namespace as the pods using them.
          This policy monitors for new namespaces being created (except kube-system and kyverno),
          and automatically clones into the namespace the `ocirsecret` from the `default` namespace.
    spec:
      generateExisting: true
      rules:
      - name: inject-imagepullsecret-to-namespace
        match:
          any:
          - resources:
              kinds:
              - Namespace
        exclude:
          any:
          - resources:
              namespaces:
              - kube-system
              - kube-node-lease
              - kube-public
              - kyverno
        generate:
          apiVersion: v1
          kind: Secret
          name: ocirsecret
          namespace: "{{ request.object.metadata.name }}"
          synchronize: true
          clone:
            namespace: default
            name: ocirsecret
    ---
    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: add-imagepullsecrets
      annotations:
        policies.kyverno.io/title: Add imagePullSecrets
        policies.kyverno.io/subject: Pod
        policies.kyverno.io/description: >-
          Images coming from certain registries require authentication in order to pull them,
          and the kubelet uses this information in the form of an imagePullSecret to pull
          those images on behalf of your Pod. This policy searches pod spec for images coming from a
          registry which contains `phx.ocir.io/axaxnpcrorw5` and, if found, will mutate the Pod
          to add an imagePullSecret called `ocirsecret`.
    spec:
      rules:
      - name: add-imagepullsecret
        match:
          any:
          - resources:
              kinds:
              - Pod
        context:
        - name: images_in_ocir
          variable:
            jmesPath: "[request.object.spec.containers[*].image.contains(@, 'phx.ocir.io/axaxnpcrorw5'), request.object.spec.initContainers[*].image.contains(@, 'phx.ocir.io/axaxnpcrorw5')][]"
            default: []
        preconditions:
          all:
          - key: true
            operator: In
            value: "{{ images_in_ocir }}"
        mutate:
          patchStrategicMerge:
            spec:
              imagePullSecrets:
              - name: ocirsecret
    
  3. 将默认 OCIR 地址 phx.ocir.io/axaxnpcrorw5 替换为您使用的地址。

  4. 在集群中创建 ClusterPolicy 并执行下面的命令来强制实施策略。

    kubectl apply -f add-imagepullsecret.yaml
    # clusterpolicy.kyverno.io/inject-imagepullsecret-to-namespace created
    # clusterpolicy.kyverno.io/add-imagepullsecrets created
    

任务 4:测试

  1. 创建一个名为 test-pod.yaml 的文件,其中包含以下文本:

    :填写占位符中专用资料档案库中图像的 URL。

    ---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: testns
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        run: testpod
      name: testpod
      namespace: testns
    spec:
      containers:
      - args:
        - /bin/sh
        - -c
        - sleep infinity
        image: <image_from_OCIR> # eg: phx.ocir.io/axaxnpcrorw5/nginx:latest
        name: test
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    
  2. 创建资源

    kubectl apply -f test-pod.yaml
    
  3. 验证 pod 是否已成功创建。

    kubectl get pods -n testns
    # NAME      READY   STATUS    RESTARTS   AGE
    # testpod   1/1     Running   0          2m4s
    
  4. 验证密钥是否已从默认名称空间克隆到新创建的名称空间。

    kubectl get secret -n testns
    # NAME         TYPE                             DATA   AGE
    # ocirsecret   kubernetes.io/dockerconfigjson   1      2m56s
    

任务 5:清除

  1. 删除测试期间创建的负载平衡器。

    kubectl delete -f test-pod.yaml
    
  2. 通过执行命令卸载 Kyverno。

    helm uninstall kyverno -n kyverno
    

确认

更多学习资源

探索 docs.oracle.com/learn 上的其他实验室,或者访问 Oracle Learning YouTube 频道上的更多免费学习内容。此外,请访问 education.oracle.com/learning-explorer 成为 Oracle Learning Explorer。

有关产品文档,请访问 Oracle 帮助中心