# 使用第三方镜像
第三方镜像是指由除官方镜像仓库和SWR镜像仓库外，其他组织或个人提供的容器镜像。这些镜像通常包含自定义应用程序、工具或特定版本的操作系统，能够满足用户特定的业务需求。在Standard/Turbo集群中，用户可以通过密钥认证的方式拉取第三方镜像，进而创建工作负载，满足业务需要。更多信息，请参见[使用私有仓库](https://kubernetes.io/zh-cn/docs/concepts/containers/images/#using-a-private-registry)。
#### 前提条件
使用第三方镜像时，请确保Standard/Turbo集群可以正常访问其仓库所在的网络环境，具体分为三种情况：
- **内网访问** ：当第三方镜像仓库支持内网访问时，存在以下情况：
  - 当第三方镜像仓库位于集群所在的VPC内时，Pod可以通过内网访问直接拉取镜像，无需额外配置。
  
  - 当第三方镜像仓库与集群处于同一区域的不同VPC时，可以通过对等连接打通两个VPC之间的网络，之后Pod可以通过内网访问直接拉取镜像。关于对等连接的具体操作，请参见[对等连接](https://support.huaweicloud.com/usermanual-vpc/vpc_peering_0009.html)。
   
- **公网访问** ：当第三方镜像仓库支持公网访问时，Pod可以通过公网拉取镜像。此时，需确保**Pod具备访问公网的能力** 。您可以通过以下方式，确保Pod具备访问公网的能力：
  ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
  当使用公网访问方式拉取镜像时，请确保EIP的带宽充足，以避免因带宽不足导致镜像拉取失败或拉取速度过慢。
  - 为集群配置SNAT规则（Standard/Turbo集群）：配置SNAT规则后，集群中的Pod实例都将具备访问公网的能力。此时，创建新的工作负载，可以直接通过公网拉取镜像。具体操作步骤，请参见[从容器访问公网](https://support.huaweicloud.com/usermanual-cce/cce_10_0400.html)。
  
  - 为节点绑定弹性公网IP（Standard集群）：为工作负载运行的节点绑定弹性公网IP（EIP）。绑定EIP后，该节点上所有工作负载都能够访问公网。具体操作步骤，请参见[绑定弹性公网IP](https://support.huaweicloud.com/usermanual-ecs/zh-cn_topic_0174917535.html)。
   
- **云专线或VPN访问** ：当需要使用云下镜像仓库时，您需要通过[云专线](https://support.huaweicloud.com/bestpractice-dc/dc_05_0002.html)或[VPN](https://support.huaweicloud.com/bestpractice-vpn/vpn_best_00019.html)的方式，提前将第三方镜像仓库所在的网络环境与集群所在VPC打通。网络环境打通后，无需额外配置。
 
#### 使用第三方镜像
使用第三方镜像时，需先创建镜像拉取密钥，并在工作负载中引用该密钥以授权访问。本文共提供两种配置方式，即控制台方式和kubectl命令行方式。
- [控制台方式]
  本节将详细介绍如何通过控制台创建密钥，并基于该密钥拉取第三方镜像以创建工作负载。
  1. 如果第三方镜像仓库存在账号和密码，则需要在集群中创建相关密钥，作为拉取镜像的身份凭证。
     
     1. 登录[CCE控制台](https://console.huaweicloud.com/cce2.0/?#/cce/cluster/list)。
     
     2. 单击集群名称进入集群。
     
     3. 在左侧导航栏中，单击"配置与密钥"。在右侧选择"密钥"页签，单击右上角"创建密钥"。
     
     4. 在"创建密钥"页面，配置相关参数，具体请参见[图1 添加密钥]和[表1]。更详细的参数说明，请参见[创建密钥](https://support.huaweicloud.com/usermanual-cce/cce_10_0153.html)。
     
     
     图1添加密钥   
     ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002500304252.png "点击放大")
     
      表1添加密钥 
     | 参数   | 示例                                                                                                                                                        | 参数说明                                                                                                                                                                                                                                                                                                                                                                                                                            |
     |:---|:---|:---|
     | 名称   | test                                                                                                                                                        | 表示新建的密钥名称。 由小写字母、数字、横线（-）和点（.）组成，且以字母或数字开头和结尾，最长支持253个字符。                                                                                                                                                                                                                                                                                                                 |
     | 密钥类型   | kubernetes.io/dockerconfigjson                                                                                                                            | 表示新建的密钥类型。 本处固定为"kubernetes.io/dockerconfigjson"，表示该密钥是拉取第三方镜像时所需要的认证信息。                                                                                                                                                                                                                                                                                           |
     | 密钥数据 | 镜像仓库地址：www.example.com 用户名：ssl 密码：xxx | - 镜像仓库地址：请填入第三镜像仓库的地址。  - 用户名：请填入第三方镜像仓库的账号。  - 密码：请填入第三方镜像仓库的密码。   |
        
     
     
  
  2. 在左侧导航栏中，单击"工作负载"，在右上角单击"创建工作负载"。"创建工作负载"页面中，在"容器配置 \> 容器信息 \> 基本信息 \> 镜像名称"中直接填写第三方镜像地址。并在"镜像访问凭证"中选择[1]中创建的密钥。
     
     ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/caution_3.0-zh-cn.png)
     填写第三方镜像地址时，如果不指定具体域名，例如输入nginx:latest，将默认从docker.io拉取镜像。如果需要指定默认的镜像拉取地址，您可以通过节点池的[容器运行时配置](https://support.huaweicloud.com/usermanual-cce/cce_10_0652.html#cce_10_0652__section942261815116)中的"替代镜像仓库配置"参数进行自定义。
     图2填写第三方镜像地址   
     ![](https://support.huaweicloud.com/usermanual-cce/zh-cn_image_0000002332225269.png "点击放大")
     
     
     
  
  3. 填写其他参数后，单击"创建工作负载"。待工作负载状态变为运行中时，则说明第三方镜像拉取成功。
   
- [kubectl命令行方式]
  1. 请参见[通过kubectl连接集群](https://support.huaweicloud.com/usermanual-cce/cce_10_0107.html)，使用kubectl连接集群。
  
  2. 如果第三方镜像仓库存在账号和密码，则需要在集群中创建相关密钥，作为拉取镜像的身份凭证。 
     1. 执行以下命令，创建认证密钥。该密钥类型默认为kubernetes.io/dockerconfigjson类型，表示该密钥是拉取第三方镜像时所需要的认证信息。
        ```
        kubectl create secret docker-registry test  -n default --docker-server=www.example.com --docker-username=ssl --docker-password=xxx --docker-email=example@123.com
        ```
        其中，*test* 为密钥名称，*default*为密钥所在的命名空间，其余参数如下所示。
        表2密钥参数说明 
        | 参数                 | 示例               | 参数说明                 |
        |:---|:---|:---|
        | docker-server    | www.example.com | 请填入第三镜像仓库的地址。       |
        | docker-username | ssl             | 请填入第三方镜像仓库的账号。     |
        | docker-password     | xxx             | 请填入第三方镜像仓库的密码       |
        | docker-email       | example@123.com | 请填入第三方镜像仓库的邮箱，非必填项。 |
           
        回显结果如下：
        ```
        secret/test created
        ```
        
     
     2. 执行以下命令，检查密钥是否创建成功。
        ```
        kubectl get secret
        ```
        回显结果如下，则说明该密钥已成功创建。
        ```
        NAME             TYPE                             DATA   AGE
        default-secret   kubernetes.io/dockerconfigjson   1      41h
        paas.elb         cfe/secure-opaque                1      41h
        test             kubernetes.io/dockerconfigjson   1      16s
        ```
        
     
     
     
     
  
  3. 使用第三方镜像创建工作负载，具体步骤请参见如下。 
     1. 执行以下命令，创建YAML文件deployment.yaml，用于配置工作负载，文件名称可自定义。
        ```
        vim deployment.yaml
        ```
        文件内容如下：
        ```
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: foo
          namespace: default
        spec:
          replicas: 1
          selector:
            matchLabels:
              app: foo
          strategy:
            type: RollingUpdate
          template:
            metadata:
              labels:
                app: foo
            spec:
              containers:
              - image: www.example.com/janedoe/awesomeapp:v1    # 第三方镜像地址
                imagePullPolicy: Always
                name: foo
              imagePullSecrets:
              - name: test    # 使用上面创建的密钥，作为拉取镜像的身份认证
        ```
        ![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/caution_3.0-zh-cn.png)
        填写第三方镜像地址时，如果不指定具体域名，例如输入nginx:latest，将默认从docker.io拉取镜像。如果需要指定默认的镜像拉取地址，您可以通过节点池的[容器运行时配置](https://support.huaweicloud.com/usermanual-cce/cce_10_0652.html#cce_10_0652__section942261815116)中的"替代镜像仓库配置"参数进行自定义。
        
     
     2. 执行以下命令，创建工作负载。
        ```
        kubectl create -f deployment.yaml
        ```
        回显如下，表示已经开始创建工作负载。
        ```
        deployment.apps/foo created
        ```
        
     
     3. 执行以下命令，查看工作负载状态。
        ```
        kubectl get deployment
        ```
        回显如下，如果工作负载创建的Pod皆为可用状态，则表示创建成功。
        ```
        NAME     READY   UP-TO-DATE   AVAILABLE   AGE
        foo      1/1     1            1           4m59s
        ```
        
     
     
     
     
   
#### 常见问题：远程镜像仓库使用非知名或不安全的证书
从第三方仓库下载镜像时，若第三方仓库使用了非知名或者不安全的证书，节点上会拉取镜像失败，Pod事件列表中有"实例拉取镜像失败"事件，报错原因为"x509: certificate signed by unknown authority"。
![](https://support.huaweicloud.com/usermanual-cce/public_sys-resources/note_3.0-zh-cn.png)
当前EulerOS 2.9镜像中有进行安全增强，移除系统中部分非安全或过期知名证书配置，部分第三方镜像在其他类型节点上未报错，在EulerOS 2.9系统报此错误属正常现象，也可通过下述解决方案进行处理。
**解决方案**：
1. 确认报错unknown authority的第三方镜像服务器地址和端口。 
   从"实例拉取镜像失败"事件信息中能够直接看到报错的第三方镜像服务器地址和端口，错误信息为：
   ```
   Failed to pull image "bitnami/redis-cluster:latest": rpc error: code = Unknown desc = error pulling image configuration: Get https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/e8/e83853f03a2e792614e7c1e6de75d63e2d6d633b4e7c39b9d700792ee50f7b56/data?verify=1636972064-AQbl5RActnudDZV%2F3EShZwnqOe8%3D: x509: certificate signed by unknown authority
   ```
   对应的第三方镜像服务器地址为 *production.cloudflare.docker.com* ，端口为https默认端口*443*。
   
   
2. 在需要下载第三方镜像的节点上加载第三方镜像服务器的根证书。 
   EulerOS, CentOS节点执行如下命令，{server_url}:{server_port}需替换成步骤1中地址和端口，如 production.cloudflare.docker.com:443。
   若节点的容器运行时为containerd，最后一步"systemctl restart docker"命令替换为"systemctl restart containerd"。
   ```
   openssl s_client -showcerts -connect {server_url}:{server_port} < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /etc/pki/ca-trust/source/anchors/tmp_ca.crt
   update-ca-trust
   systemctl restart docker
   ```
   ubuntu节点执行如下命令。
   ```
   openssl s_client -showcerts -connect {server_url}:{server_port} < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /usr/local/share/ca-certificates/tmp_ca.crt
   update-ca-trust
   systemctl restart docker
   ```
   
   
 
