容器镜像部署物

对于使用Docker容器镜像部署的场景,推荐使用容器镜像部署物。计算巢提供了公共的ACR容器镜像实例用来托管保存,一个服务商对应一个命名空间进行多租户隔离。本文为您介绍容器镜像部署物使用场景与原理,以及如何创建和使用容器镜像部署物。

使用场景

通过公网拉取但希望私有化部署的Docker容器镜像,可使用容器镜像部署物通过临时密钥实现服务部署。

重要

容器镜像部署物不支持后续的弹性自动伸缩或动态任务频繁拉取的需求。

如果您的服务场景不适用容器镜像部署物。

  • 无公网访问能力的服务

    对于无法开通公网访问能力的服务,可以通过自建ACR容器镜像仓库的方式,配置容器镜像仓库的内网链接,实现内网拉取。请参见 配置专有网络的访问控制

  • 部署后仍有拉取需求的服务

    私有化部署:需要提供自建的公开ACR容器镜像仓库以保持拉取权限。

    托管版服务:可以创建私有化的ACR容器镜像仓库,并通过ACK集群提供的免密拉取插件进行拉取。

    请参见 使用免密组件拉取容器镜像

  • 公开可拉取的容器镜像

    对于可以公开拉取的容器镜像,没必要使用容器镜像部署物,可以直接使用公开的容器镜像仓库链接进行部署。

实现原理

由于多个服务商的容器镜像存放在一个镜像仓库中,为了实现多租户隔离,目前采用一个服务商对应一个命名空间的方式进行容器镜像存放,在上传和拉取时根据服务商AliUid获取对应命名空间的临时密钥,权限控制以命名空间为维度。

image

详细说明

  1. 上传容器镜像到计算巢ACK仓库

    1. 服务商调用计算巢服务获取临时密钥,计算巢调用ACR服务获取以服务商AliUid为名称的命名空间的临时密钥。

    2. 服务商使用获取的临时密钥,将本地的容器镜像上传到计算巢ACR仓库中,存放在以服务商AliUid为名称的命名空间中。

  2. 部署容器镜像到ACK集群

    1. 计算巢服务获取服务商对应的容器镜像临时密钥,以Secret的方式部署到ACK集群中。

    2. 接着部署容器镜像,将容器镜像部署物替换为计算巢容器镜像仓库中的容器镜像链接,指定拉取密钥为部署的Secret。

    3. ACK集群中会进行对应容器镜像的拉取,完成后续的部署工作。

容器镜像部署物为什么使用托管版方案?

Docker容器镜像可以通过ACR(阿里云容器镜像服务)来保存。服务商可以选择上传镜像到自己的私有仓库并自行管理。然而,考虑到购买ACR实例的成本、方便进行安全扫描的需求以及防止服务商意外删除镜像的问题,计算巢提供一个公共的容器镜像仓库即计算巢ACR仓库,专门用于保存和维护服务商的容器镜像,确保了安全和稳定性。

应用原理

需要在服务的ROS模板中定义以下两个标识,在部署时进行替换。

  • {{ computenest::acrimage::yourimage }} 容器镜像部署物标识位,计算巢会在部署服务模板时进行替换,替换为关联部署物对应的容器镜像地址,如compute-nest-registry.cn-hangzhou.cr.aliyuncs.com/aliUid1/volcanosh/vc-controller-manager:1.0

  • {{ computenest::acr::dockerconfigjson }} 容器镜像仓库拉取密钥标识位,在部署时会替换为容器镜像拉取临时密钥,用来进行私有容器镜像的拉取。

使用容器镜像部署物进行部署的示例YAML如下所示,可以看到拉取密钥{{ computenest::acr::dockerconfigjson }}部署成了Secret computenestrepo,作为容器镜像部署物的imagePullSecret去拉取部署物替换后的容器镜像。

示例代码

Resources:
  ClusterApplication:
    Type: ALIYUN::CS::ClusterApplication
    Properties:
      YamlContent: |
          apiVersion: v1
          data:
            .dockerconfigjson: {{computenest::acr::dockerconfigjson}}
          kind: Secret
          metadata:
            name: computenestrepo
            namespace: nginx
          type: kubernetes.io/dockerconfigjson
          ---
          apiVersion: apps/v1
          kind: Deployment
          spec:
            template:
              spec:
                containers:
                - name: nginx
                  image: {{ computenest::acrimage::nginx }}
                  ports:
                  - containerPort: 80
                imagePullSecrets:
                - name: computenestrepo

创建并使用

前提条件

已安装Docker并制作Docker镜像。如果您没有,请参见Docker的安装与使用

创建容器镜像部署物

  1. 配置部署物的基本信息。

    1. 登录计算巢控制台,在左侧导航栏选择服务部署物,并在部署物区域中单击创建部署物

    2. 部署物信息区域,完成部署物信息填写。

      配置项

      说明

      部署物名称

      由中文、数字、英文及下划线组成,长度在 3~128 个字符之间,一个中文字等于 2 个字符,部署物名称创建后不可修改。

      部署物版本名称

      由中文、数字、英文及下划线组成,长度在 3~50 个字符之间,一个中文字等于 2 个字符。

      部署物描述

      简介长度在10-500个字符之间,一个中文字等于2个字符。

      资源组

      选择创建的部署所归属的资源组名称。

      资源组对您拥有的云资源从用途、权限、归属等维度进行分组,实现企业内部多用户、多项目的资源分级管理。更多信息,请参见资源组

      标签配置

      选择或填写完整的标签键和标签值,为部署物定标签。每个资源最多可绑定20条标签。若无可选的标签键和标签值,可创建自定义标签。创建自定义标签的详细操作,请参见创建并绑定自定义标签

  2. 配置容器镜像部署物。

    本节以上传apache-php5镜像为例。

    1. 部署物内容区块,选择部署物类型容器镜像

    2. 单击获取访问凭证,可以获得上传容器镜像到计算巢仓库的命令。

      image

      1. 登录命令行工具,输入登录命令登录计算巢镜像仓库。

        image

      2. 将您的容器镜像进行计算巢镜像仓库打标。

        image

      3. 推送已打标的容器镜像。

        image

    3. 执行成功后,在选择容器镜像中选取上传的容器镜像,并单击发布部署物

  3. 查看部署物。

    1. 返回服务部署物页面,单击部署物名称,进入部署物详情界面查看部署进度。

    2. 当状态为可用时,表示创建完成。

      image

使用容器镜像部署物

本节以创建私有化部署服务为例,重点介绍在创建服务时使用容器镜像部署物相关配置。

  1. 登录计算巢控制台

  2. 在左侧导航栏中选择我的服务,在我创建的服务区域下单击创建新服务

  3. 在创建新服务页面,创建服务的方式选择为自定义创建服务,服务类型选择为私有部署服务,单击下一步:配置服务

    image

  4. 根据提示填入服务基本信息,根据实际情况进行选择并输入ROS模板。

    在服务ROS模板ALIYUN::CS::ClusterApplication资源中定义访问凭证标识位{{ computenest::acr::dockerconfigjson }} 和容器镜像部署物标识{{ computenest::acrimage::yourimage }}

    示例模板

    说明

    本示例模板仅可用于测试。

    ROSTemplateFormatVersion: '2015-09-01'
    Description:
      en: Application deployed by docker
      zh-cn:  使用docker部署单机应用
    Parameters:
      PayType:
        Type: String
        Label:
          en: ECS Instance Charge Type
          zh-cn: 付费类型
        Default: PostPaid
        AllowedValues:
          - PostPaid
          - PrePaid
        AssociationProperty: ChargeType
        AssociationPropertyMetadata:
          LocaleKey: InstanceChargeType
      PayPeriodUnit:
        Type: String
        Label:
          en: Pay Period Unit
          zh-cn: 购买资源时长周期
        Default: Month
        AllowedValues:
          - Month
          - Year
        AssociationProperty: PayPeriodUnit
        AssociationPropertyMetadata:
          Visible:
            Condition:
              Fn::Not:
                Fn::Equals:
                  - ${PayType}
                  - PostPaid
      PayPeriod:
        Type: Number
        Label:
          en: Period
          zh-cn: 购买资源时长
        Default: 1
        AllowedValues:
          - 1
          - 2
          - 3
          - 4
          - 5
          - 6
          - 7
          - 8
          - 9
        AssociationProperty: PayPeriod
        AssociationPropertyMetadata:
          Visible:
            Condition:
              Fn::Not:
                Fn::Equals:
                  - ${PayType}
                  - PostPaid
      EcsInstanceType:
        Type: String
        Label:
          en: Instance Type
          zh-cn: 实例类型
        AssociationProperty: ALIYUN::ECS::Instance::InstanceType
        AssociationPropertyMetadata:
          InstanceChargeType: ${PayType}
        AllowedValues:
          - ecs.g8i.large
          - ecs.g6.large
        
      InstancePassword:
        NoEcho: true
        Type: String
        Description:
          en: Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
          zh-cn: 服务器登录密码,长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)
        AllowedPattern: '^[a-zA-Z0-9-\(\)\`\~\!\@\#\$\%\^\&\*\_\-\+\=\|\{\}\[\]\:\;\<\>\,\.\?\/]*$'
        Label:
          en: Instance Password
          zh-cn: 实例密码
        ConstraintDescription:
          en: Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)
          zh-cn: 长度8-30,必须包含三项(大写字母、小写字母、数字、 ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ 中的特殊符号)
        MinLength: 8
        MaxLength: 30
        AssociationProperty: ALIYUN::ECS::Instance::Password
      ZoneId:
        Type: String
        Label:
          en: Zone ID
          zh-cn: 可用区ID
        AssociationProperty: ALIYUN::ECS::Instance::ZoneId
      VpcId:
        Type: String
        Label:
          en: VPC ID
          zh-cn: 专有网络VPC实例ID
        Description:
          en: >-
            Please search the ID starting with (vpc-xxx) from console-Virtual
            Private Cloud
          zh-cn: 现有虚拟专有网络的实例ID
        AssociationProperty: 'ALIYUN::ECS::VPC::VPCId'
      VSwitchId:
        Type: String
        Label:
          en: VSwitch ID
          zh-cn: 交换机实例ID
        Description:
          en: >-
            Instance ID of existing business network switches, console-Virtual
            Private Cloud-VSwitches under query
          zh-cn: 现有业务网络交换机的实例ID
        Default: ''
        AssociationProperty: 'ALIYUN::ECS::VSwitch::VSwitchId'
        AssociationPropertyMetadata:
          VpcId: VpcId
          ZoneId: ZoneId
      AdminPassword:
        Type: String
        AssociationProperty: ALIYUN::ECS::Instance::Password
        Label: 管理员密码
        NoEcho: True
    Resources:
      SecurityGroup:
        Type: ALIYUN::ECS::SecurityGroup
        Properties:
          SecurityGroupName:
            Ref: ALIYUN::StackName
          VpcId:
            Ref: VpcId
          SecurityGroupIngress:
            - PortRange: 80/80
              Priority: 1
              SourceCidrIp: 0.0.0.0/0
              IpProtocol: tcp
              NicType: internet
      InstanceGroup:
        Type: ALIYUN::ECS::InstanceGroup
        Properties:
          # 付费类型
          InstanceChargeType:
            Ref: PayType
          PeriodUnit:
            Ref: PayPeriodUnit
          Period:
            Ref: PayPeriod
          VpcId:
            Ref: VpcId
          VSwitchId:
            Ref: VSwitchId
          SecurityGroupId:
            Ref: SecurityGroup
          ZoneId:
            Ref: ZoneId
          ImageId: centos_7
          Password:
            Ref: InstancePassword
          InstanceType:
            Ref: EcsInstanceType
          SystemDiskCategory: cloud_essd
          SystemDiskSize: 200
          InternetMaxBandwidthOut: 5
          IoOptimized: optimized
          MaxAmount: 1
      WaitCondition:
        Type: ALIYUN::ROS::WaitCondition
        Properties:
          Count: 1
          Handle:
            Ref: WaitConditionHandle
          Timeout: 300
      WaitConditionHandle:
        Type: ALIYUN::ROS::WaitConditionHandle
      InstallPackage:
        Type: ALIYUN::ECS::RunCommand
        Properties:
          InstanceIds:
            Fn::GetAtt:
              - InstanceGroup
              - InstanceIds
          Type: RunShellScript
          Sync: true
          Timeout: 300
          CommandContent:
            Fn::Sub:
              - |
                yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
                yum makecache fast
                yum -y install docker-ce jq
                systemctl enable docker
                systemctl start docker
                sleep 10
    
                dockerJson='{{ computenest::acr::dockerconfigjson }}'
                decodeDockerJson=$(echo $dockerJson | base64 -d)
                host=$(echo $decodeDockerJson | jq '.auths' | jq 'keys' | jq .[0])
                username=$(echo $decodeDockerJson | jq ".auths.$host.username" | tr -d '"')
                password=$(echo $decodeDockerJson | jq ".auths.$host.password" | tr -d '"')
                host=$(echo $host | tr -d '"')
                docker login $host --username=$username --password=$password
    
                mkdir -p /home/admin/application
                cat >/home/admin/application/docker-compose.yaml<<EOF
                # docker-compose.yaml中可以引用参数
                # 单个nginx服务实例
                services:
                  # 服务名
                  nginx:
                    # Docker镜像
                    image: {{computenest::acrimage::nginx}}
                    # 端口映射
                    ports:
                      - 80:80
                    volumes:
                      - /home/admin/application/nginx/logs:/var/log/nginx/
                EOF
                
                cat > /etc/systemd/system/docker-compose-app.service <<EOF
                [Unit]
                Description=Docker Compose Application Service
                Requires=docker.service
                After=docker.service
                
                [Service]
                Type=oneshot
                RemainAfterExit=yes
                WorkingDirectory=/home/admin/application
                ExecStart=/usr/bin/docker compose up -d
                ExecStop=/usr/bin/docker compose down
                TimeoutStartSec=0
                
                [Install]
                WantedBy=multi-user.target
                EOF
                
                systemctl enable docker-compose-app
    
                # 在Docker Compose启动前执行此命令片段,命令中可以引用参数
                echo "before docker compose starts"
                mkdir -p /home/admin/application/nginx/logs
                
                systemctl start docker-compose-app
                sleep 10
                # 在Docker Compose启动后执行此命令片段,命令中可以引用参数
                echo "after docker compose starts"
                echo ${AdminPassword}
                
                # 执行成功回调WaitCondition结束waitCondition的等待
                ${CurlCli} -d "{\"Data\" : \"Success\", \"status\" : \"SUCCESS\"}"
              - CurlCli:
                  Fn::GetAtt:
                    - WaitConditionHandle
                    - CurlCli
    Outputs: 
      Endpoint:
        Value:
          Fn::Sub:
            - http://${Address}:80
            - Address:
                Fn::Select:
                - 0
                - Fn::GetAtt:
                  - InstanceGroup
                  - PublicIps
    Metadata:
      ALIYUN::ROS::Interface:
        ParameterGroups:
          - Parameters:
              - PayType
              - PayPeriodUnit
              - PayPeriod
            Label:
              default: 付费类型配置
          - Parameters:
              - EcsInstanceType
              - InstancePassword
            Label:
              default: 资源配置
          
          - Parameters:
              - AdminPassword
            Label:
              en: Software Configuration
              zh-cn: 软件配置
          
          - Parameters:
              - ZoneId
              - VpcId
              - VSwitchId
            Label:
              default: 可用区配置
  5. 部署物关联区块中设置容器镜像关联。单击选择部署物,在弹框中选择部署物和版本,最后单击确定完成容器镜像部署物替换。

    image

  6. 完成服务的创建,并测试通过后, 请根据计算巢服务的发布审核标准进行自检,并提交审核。发布审核标准的详细信息,请参见发布审核标准

  7. 服务创建完成后,可以在服务详情页查看部署物关联关系。

    image

相关文档

  • 关于创建计算巢服务的详细内容,请参见创建服务

  • 当您不再需要部署物或部署物版本时,可删除该部署物或部署物版本,请参见删除部署物

  • 当您需要变更部署物内容等信息时,可通过创建新版本来实现,请参见创建新版本

  • 设置部署物的升级配置,请参见服务升级配置