github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/docs/site/src/zh/advanced/use-kyverno-baseimage.md (about)

     1  # Kyverno BaseImage
     2  
     3  ## Motivations
     4  
     5  It's common that some k8s clusters have their own private image registry, and they don't want to pull images from other registry for some reasons. This page is about how to integrate kyverno into k8s cluster, which will redirect image pull request to Specified registry.
     6  
     7  ## Uses case
     8  
     9  ### How to use it
    10  
    11  We provide an official BaseImage which integrates kyverno into cluster:`kubernetes-kyverno:v1.19.8`. Note that it contains no docker images other than those necessary to run a k8s cluster, so if you want to use this cloud image, and you also need other docker images(such as `nginx`) to run a container, you need to cache the docker images to your private registry.
    12  
    13  Of course `sealer` can help you do this,use `nginx` as an example.
    14  Firstly include nginx in the file `imageList`.
    15  You can execute `cat imageList` to make sure you have done this, and the result may seem like this:
    16  
    17  ```
    18   [root@ubuntu ~]# cat imageList
    19   nginx:latest
    20  ```
    21  
    22  Secondly edit a Kubefile with the following content:
    23  
    24  ```
    25  FROM kubernetes-kyverno:v1.19.8
    26  COPY imageList manifests
    27  CMD kubectl run nginx --image=nginx:latest
    28  ```
    29  
    30  Thirdly execute `sealer build` to build a new cloud image
    31  
    32  ```
    33   [root@ubuntu ~]# sealer build -t my-nginx-kubernetes:v1.19.8 .
    34  ```
    35  
    36  Just a simple command and let sealer help you cache `nginx:latest` image to private registry. You may doubt whether sealer has successfully cached the image, please execute `sealer inspect my-nginx-kubernetes:v1.19.8` and locate the `layer` attribute of the `spec` section, you will find there are many layers. In this case, the last layer has two `key:value` pairs: `type: BASE`, `value: registry cache`, from which we know it's about images cached to registry. Remembering this layer's id, execute `cd /var/lib/sealer/data/overlay2/{layer-id}/registry/docker/registry/v2/repositories/library`, then you will find the nginx image existing in the directory.
    37  
    38  Now you can use this new cloud image to create k8s cluster. After your cluster startup, there is already a pod running `nginx:latest` image, you can see it by execute `kubectl describe pod nginx`, and you can also create more pods running `nginx:latest` image.
    39  
    40  ### How to build kyverno BaseImage
    41  
    42  The following is a sequence steps of building kyverno build-in cloud image
    43  
    44  #### Step 1: choose a base image
    45  
    46  Choose a base image which can create a k8s cluster with at least one master node and one work node. To demonstrate the workflow, I will use `kubernetes-rawdocker:v1.19.8`. You can get the same image by executing `sealer pull kubernetes-rawdocker:v1.19.8`.
    47  
    48  #### Step 2: get the kyverno install yaml and cache the image
    49  
    50  Download the "install.yaml" of kyverno at `https://raw.githubusercontent.com/kyverno/kyverno/release-1.5/definitions/release/install.yaml`, you can replace the version to what you want. I use 1.5 in this demonstration.
    51  
    52  In order to use kyverno BaseImage in offline environment, you need to cache the image used in `install.yaml`. In this case, there are two docker images need to be cached: `ghcr.io/kyverno/kyverno:v1.5.1` and `ghcr.io/kyverno/kyvernopre:v1.5.1`. So firstly rename them to `sea.hub:5000/kyverno/kyverno:v1.5.1` and `sea.hub:5000/kyverno/kyvernopre:v1.5.1` in the `install.yaml`, where `sea.hub:5000` is the private registry domain in your k8s cluster. Then create a file `imageList` with the following content:
    53  
    54  ```
    55  ghcr.io/kyverno/kyverno:v1.5.1
    56  ghcr.io/kyverno/kyvernopre:v1.5.1
    57  ```
    58  
    59  #### Step 3: create a ClusterPolicy
    60  
    61  Create a yaml with the following content:
    62  
    63  ```yaml
    64  apiVersion : kyverno.io/v1
    65  kind: ClusterPolicy
    66  metadata:
    67    name: redirect-registry
    68  spec:
    69    background: false
    70    rules:
    71    - name: prepend-registry-containers
    72      match:
    73        resources:
    74          kinds:
    75          - Pod
    76      preconditions:
    77        all:
    78        - key: "{{request.operation}}"
    79          operator: In
    80          value:
    81          - CREATE
    82          - UPDATE
    83      mutate:
    84        foreach:
    85        - list: "request.object.spec.containers"
    86          patchStrategicMerge:
    87            spec:
    88              containers:
    89              - name: "{{ element.name }}"
    90                image: "sea.hub:5000/{{ images.containers.{{element.name}}.path}}:{{images.containers.{{element.name}}.tag}}"
    91    - name: prepend-registry-initcontainers
    92      match:
    93        resources:
    94          kinds:
    95          - Pod
    96      preconditions:
    97        all:
    98        - key: "{{request.operation}}"
    99          operator: In
   100          value:
   101          - CREATE
   102          - UPDATE
   103      mutate:
   104        foreach:
   105        - list: "request.object.spec.initContainers"
   106          patchStrategicMerge:
   107            spec:
   108              initContainers:
   109              - name: "{{ element.name }}"
   110                image: "sea.hub:5000/{{ images.initContainers.{{element.name}}.path}}:{{images.initContainers.{{element.name}}.tag}}"
   111  
   112  ```
   113  
   114  This ClusterPolicy will redirect image pull request to private registry `sea.hub:5000`, and I name this file as redirect-registry.yaml
   115  
   116  #### Step 4: create a shell script to monitor kyverno pod
   117  
   118  Because the state of kyverno pod should be running, then the ClusterPolicy will work. It's advised to create and run the following shell script to monitor the state of kyverno pod until it become running.
   119  
   120  ```shell
   121  #!/bin/bash
   122  
   123  echo "[kyverno-start]: Waiting for the kyverno to be ready..."
   124  
   125  while true
   126  do
   127      clusterPolicyStatus=`kubectl get cpol -o go-template --template={{range.items}}{{.status.ready}}{{end}}`;
   128      if [ "$clusterPolicyStatus" == "true" ];then
   129          break;
   130      fi
   131      sleep 1
   132  done
   133  
   134  echo "kyverno is running"
   135  ```
   136  
   137  I named this file `wait-kyverno-ready.sh`.
   138  
   139  #### Step 5: create the build content
   140  
   141  Create a `kyvernoBuild` directory with five files: the etc/install.yaml and imageList in step 2, etc/redirect-registry.yaml in step 3, scripts/wait-kyverno-ready.sh in step 4 and a Kubefile whose content is following:
   142  
   143  ```shell
   144  FROM kubernetes-rawdocker:v1.19.8
   145  COPY imageList manifests
   146  COPY etc .
   147  COPY scripts .
   148  CMD kubectl create -f etc/install.yaml && kubectl create -f etc/redirect-registry.yaml
   149  CMD bash scripts/wait-kyverno-ready.sh
   150  ```
   151  
   152  #### Step 6: build the image
   153  
   154  Supposing you are at the `kyvernoBuild` directory, please execute `sealer build --mode lite -t kubernetes-kyverno:v1.19.8 .`