
# 使用OpenKruise预热镜像
在节点上启动容器的时长受镜像拉取速度影响较大，在需要快速启动应用的场景下，长时间拉取镜像会拖慢容器启动。通过预热镜像的方法，提前在节点上拉取镜像，容器启动时直接使用节点上已预热的镜像，加速容器启动。
在集群中部署OpenKruise插件，利用其镜像预热能力，在集群中创建ImagePullJob或ImageListPullJob CRD资源，自动化地在节点上预热指定镜像。Kruise会自动为每个Node创建一个NodeImage，记录该节点上需要预热的镜像。用户创建ImagePullJob对象，指定一个镜像要在哪些Node上做预热。
#### 前提条件
- 已创建CCE集群，并安装了Openkruise插件。插件详情请参见[OpenKruise](https://support.huaweicloud.com/usermanual-cce/cce_10_0915.html)。
- 已在CCE集群的节点上配置好kubeconfig，详情请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html#section6)。
 
#### 操作步骤
#### 步骤一：预热镜像
根据需要选择以下方式：
- **预热单个镜像**：使用ImagePullJob
- **预热多个镜像**：使用ImageListPullJob
 
- [方式一：使用ImagePullJob预热单个镜像]
- [方式二：使用ImageListPullJob预热多个镜像]
ImagePullJob可以在指定节点上预热单个镜像。
1. 登录配置好kubeconfig的节点。
2. 创建文件image-pull.yaml，写入如下内容。
   ```
   apiVersion: apps.kruise.io/v1beta1
   kind: ImagePullJob
   metadata:
     name: image-pull-demo
     namespace: default
   spec:
     image: nginx:1.9.1   # [required] 完整的镜像名name:tag
     parallelism: 10      # [optional] 最大并发拉取的节点梳理, 默认为 1
     selector:            # [optional] 指定节点的名字列表或标签选择器 (只能设置其中一种)
       names:
         - node-1
         - node-2
       matchLabels:
         node-type: xxx
   # podSelector:         # [optional] 通过podSelector匹配Pod，在这些Pod所在节点上拉取镜像, 与selector不能同时设置。
   #   matchLabels:
   #     pod-label: xxx
   #   matchExpressions:
   #   - key: pod-label
   #     operator: In
   #     values:
   #       - xxx
     completionPolicy:
       type: Always                  # [optional] 默认为Always
       activeDeadlineSeconds: 1200   # [optional] 无默认值, 只对Always类型生效
       ttlSecondsAfterFinished: 300  # [optional] 无默认值, 只对Always类型生效
     pullPolicy:                     # [optional] 默认backoffLimit=3, timeoutSeconds=600
       backoffLimit: 3
       timeoutSeconds: 300
   ```
   涉及参数信息如下表所示。
   
   | 参数                                       | 说明                                                                                                                                                                                                                                                                                                                                                 |
   |:---|:---|
   | image                                    | 完整的镜像名（name:tag），必填。                                                                                                                                                                                                                                                                                                                               |
   | parallelism                              | 拉取镜像的并发节点数，默认为1。                                                                                                                                                                                                                                                                                                                                   |
   | selector                                 | 指定节点的名称或者标签，两种方式不可同时选择。如果不填写selector字段则会选择所有节点。                                                                                                                                                                                                                                                                                                    |
   | selector.names                           | 节点名称列表，不与matchLabels同时生效。                                                                                                                                                                                                                                                                                                                          |
   | selector.matchLabels                     | 节点标签，可填多个标签，需所有标签同时匹配。                                                                                                                                                                                                                                                                                                                             |
   | selector.podSelector                     | 在匹配的Pod所在节点上预热镜像，与selector不可同时配置。                                                                                                                                                                                                                                                                                                                  |
   | completionPolicy                         | 镜像预热方案。                                                                                                                                                                                                                                                                                                                                            |
   | completionPolicy.type                    | 预热策略，可选值： - "Always"表示一次性预热，不论结果是否成功拉取到镜像预热任务总会结束。  - "Never"表示长期运行，每天都会在匹配到的节点上重新预热一次镜像   |
   | completionPolicy.activeDeadlineSeconds   | 仅在"Always"类型下生效，整个任务的超时时间，超时后任务会被强制结束                                                                                                                                                                                                                                                                                                              |
   | completionPolicy.ttlSecondsAfterFinished | 仅在"Always"类型下生效，任务结束后自动删除本ImagePullJob的时间。                                                                                                                                                                                                                                                                                                         |
   | pullPolicy                               | 拉取策略。                                                                                                                                                                                                                                                                                                                                              |
   | pullPolicy.backoffLimit                  | 拉取失败后的重试次数，默认为3。                                                                                                                                                                                                                                                                                                                                   |
   | pullPolicy.timeoutSeconds                | 单次拉取的超时时间，默认为600秒。                                                                                                                                                                                                                                                                                                                                 |
      
   
3. （可选）仅镜像类型为私有时需配置镜像拉取凭证。在spec字段下配置pullSecrets字段。
   ```
   spec:
     pullSecrets:
       - secret-name1
       - secret-name2
   ```
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   由于ImagePullJob是命名空间级别的资源，需要将资源创建到镜像拉取凭证Secret所在的命名空间下。
   
4. （可选）配置镜像拉取策略。
   ```
   spec:
     imagePullPolicy: Always
   ```
   
   | 策略           | 说明                           |
   |:---|:---|
   | Always       | 每次都尝试从镜像仓库拉取镜像，无论节点上是否有同名镜像。 |
   | IfNotPresent | 仅在本地节点不存在该镜像时才拉取镜像。          |
      
   
5. 部署资源。
   ```
   kubectl apply -f image-pull.yaml
   ```
   
 
ImageListPullJob可以在指定节点上预热多个镜像，字段与ImagePullJob基本相同。
1. 登录配置好kubeconfig的节点。
2. 创建文件image-list-pull.yaml，写入如下内容。
   ```
   apiVersion: apps.kruise.io/v1beta1
   kind: ImageListPullJob
   metadata:
     name: image-list-pull-demo
     namespace: default
   spec:
     images:
     - nginx:1.9.1   # [required] 完整的镜像名，列表
     - busybox:1.29.2
     parallelism: 10      # [optional] 最大并发拉取的节点梳理, 默认为1
     selector:            # [optional] 指定节点的名字列表或标签选择器 (只能设置其中一种)
       names:
       - node-1
       - node-2
       matchLabels:
         node-type: xxx
   # podSelector:         # [optional] 通过podSelector匹配Pod，在这些Pod所在节点上拉取镜像, 与selector不能同时设置。
   #   matchLabels:
   #     pod-label: xxx
   #   matchExpressions:
   #   - key: pod-label
   #     operator: In
   #     values:
   #       - xxx
     completionPolicy:
       type: Always                  # [optional] 默认 Always
       activeDeadlineSeconds: 1200   # [optional] 无默认值, 只对Always类型生效
       ttlSecondsAfterFinished: 300  # [optional] 无默认值, 只对Always类型生效
     pullPolicy:                     # [optional] 默认backoffLimit=3, timeoutSeconds=600
       backoffLimit: 3
       timeoutSeconds: 300
   ```
   
   涉及参数信息如下表所示。
   
   | 参数                                       | 说明                                                                                                |
   |:---|:---|
   | images                                   | 完整的镜像名列表，必填。                                                                                      |
   | parallelism                              | 拉取镜像的并发节点数，默认为1。                                                                                  |
   | selector                                 | 指定节点的名称或者标签，两种方式不可同时选择。如果不填写selector字段则会选择所有节点。                                                   |
   | selector.names                           | 节点名称列表，不与matchLabels同时生效。                                                                         |
   | selector.matchLabels                     | 节点标签，可填多个标签，需所有标签同时匹配。                                                                            |
   | selector.podSelector                     | 在匹配的Pod所在节点上预热镜像，与selector不可同时配置。                                                                 |
   | completionPolicy                         | 镜像预热方案。                                                                                           |
   | completionPolicy.type                    | 预热策略，可选值"Always"、"Never"。"Always"表示一次性预热，不论结果是否成功拉取到镜像预热任务总会结束；"Never"表示长期运行，每天都会在匹配到的节点上重新预热一次镜像 |
   | completionPolicy.activeDeadlineSeconds   | 仅在"Always"类型下生效，整个任务的超时时间，超时后任务会被强制结束                                                             |
   | completionPolicy.ttlSecondsAfterFinished | 仅在"Always"类型下生效，任务结束后自动删除本ImagePullJob的时间。                                                        |
   | pullPolicy                               | 拉取策略。                                                                                             |
   | pullPolicy.backoffLimit                  | 拉取失败后的重试次数，默认为3。                                                                                  |
   | pullPolicy.timeoutSeconds                | 单次拉取的超时时间，默认为600秒。                                                                                |
      
   
3. （可选）仅镜像类型为私有时需配置镜像拉取凭证。在spec字段下配置pullSecrets字段。
   ```
   spec:
     pullSecrets:
       - secret-name1
       - secret-name2
   ```
   ![](https://support.huaweicloud.com/bestpractice-cce/public_sys-resources/note_3.0-zh-cn.png)
   由于ImageListPullJob是命名空间级别的资源，需要将资源创建到镜像拉取凭证Secret所在的命名空间下。
   
4. （可选）配置镜像拉取策略。
   ```
   spec:
     imagePullPolicy: Always
   ```
   
   | 策略           | 说明                           |
   |:---|:---|
   | Always       | 每次都尝试从镜像仓库拉取镜像，无论节点上是否有同名镜像。 |
   | IfNotPresent | 仅在本地节点不存在该镜像时才拉取镜像。          |
      
   
5. 部署资源。
   ```
   kubectl apply -f image-list-pull.yaml
   ```
   
 
#### 步骤二：查看预热镜像情况
1. 查看镜像预热任务概览。 
   ```
   kubectl get imagepulljob
   ```
   回显如下：
   ```
   NAME              TOTAL   ACTIVE   SUCCEED   FAILED   AGE     MESSAGE
   image-pull-demo   4       0        4         0        9m49s   job has completed
   ```
   
   
2. 查看镜像预热任务的具体信息，在status字段中可看到成功数、失败数等。如果有失败的镜像，可以在status中看到失败的节点。 
   ```
   kubectl get imagepulljob image-pull-demo -o yaml
   ```
   
   
3. 通过NodeImage资源查看镜像预热失败的具体信息。 
   ```
   kubectl get nodeimage <node-name> -o yaml
   ```
   
   
 
