You can use the toolkit-maven-plugin to implement a phased release on a Spring Cloud, Dubbo, or High-speed Service Framework (HSF) application that is deployed in Enterprise Distributed Application Service (EDAS).

Automated deployment

To use toolkit-maven-plugin for automated application deployment, add the plug-in dependency, configure the plug-in, and build deployment jobs.

  1. Add the plug-in dependency.

    Add the following plug-in dependency to the pom.xml file:

    <build>
        <plugins>
            <plugin>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>toolkit-maven-plugin</artifactId>
                <version>1.1.9</version>
            </plugin>
        </plugins>
    </build>                            
    Note We recommend that you use the latest toolkit-maven-plugin version.
  2. Configure the plug-in.

    The configurations of the plug-in include account configuration, packaging configuration, and deployment configuration. For information about more custom configuration items, see Specify the packaging parameters and Specify the deployment parameters.

    1. Complete the account configuration.

      In the root directory of your packaged project, create an account configuration file that is in the YAML format. Name the file toolkit_profile.yaml and add the following information to the file:

      regionId:        # The region where the application is deployed. For example, the value cn-beijing indicates the China (Beijing) region, the value cn-shanghai indicates the China (Shanghai) region, and the value cn-hangzhou indicates the China (Hangzhou) region. 
      jarPath:         # The path of the deployment package. If you specify this parameter, you do not need to package the application file in Maven. The package in the specified path is used to deploy the application. You can specify an absolute path or a relative path. 
      accessKeyId:     # The AccessKey ID used to access Alibaba Cloud resources. To reduce security risks, we recommend that you use the AccessKey ID of a RAM user. 
      accessKeySecret: # The AccessKey secret used to access Alibaba Cloud resources. To reduce security risks, we recommend that you use the AccessKey secret of a RAM user. 
    2. Complete the packaging configuration.

      In the root directory of your packaged project, create a package configuration file that is in the YAML format. If the packaged project is created for a Maven submodule, create the file in the directory of the submodule. Name the file toolkit_package.yaml and add the following information to the file:

      apiVersion: V1
      kind: AppPackage
      spec:
       packageType: # The type of the application deployment package. Valid values are War, FatJar, Image, and url. The packageUrl parameter takes effect only if you set this parameter to url. 
       packageUrl:  #  The URL of the package. This parameter takes effect only if you set the packageType parameter to url. If this parameter is left empty, the current Maven build package is used to deploy your application. 
       imageUrl:    #  The URL of the image. This parameter takes effect only if you set the packageType parameter to Image. You can also build a Docker image in your on-premises environment to deploy your application. 
    3. Complete the deployment configuration.

      In the root directory of your packaged project, create a deployment file that is in the YAML format. Name the file toolkit_deploy.yaml and add the following information to the file:

      apiVersion: V1
      kind: AppDeployment
      spec:
        type: kubernetes
        target:
          appId:        # The ID of the application to be deployed. If you specify the appId parameter, you do not need to specify the namespaceId and appName parameters. 
          namespaceId:  # The ID of the microservices namespace where the application is to be deployed. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed. 
          appName:      # The name of the application. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed. 
        updateStrategy:
          type: GrayBatchUpdate    # The phased release mode. 
          grayUpdate:              # The phased release settings. 
            gray: x                 # An integer value, which specifies the number of instances to which the phased release applies. 
          batchUpdate:             # The settings for the batches of the phased release. 
            batch: x                # An integer value, which specifies the number of batches. 
            releaseType: xxx        # The release type. The value auto indicates an automatic release. The value manual indicates a manual release. 
            batchWaitTime: x        # An integer value, which specifies the interval between two consecutive batches. Unit: minutes. 
  3. Build deployment jobs.
    Go to the directory where pom.xml is located. If you want to deploy a Maven submodule, go to the directory where the pom.xml file of the submodule is located. Then, run the following command:
    mvn clean package toolkit:deploy -Dtoolkit_profile=toolkit_profile.yaml -Dtoolkit_package=toolkit_package.yaml -Dtoolkit_deploy=toolkit_deploy.yaml                           
    The following list describes the command parameters:
    • toolkit:deploy: instructs the system to deploy the application after the packaging operation is complete.
    • -Dtoolkit_profile: specifies the account configuration file. If the account configuration file is in the same directory as pom.xml and the file name is .toolkit_profile.yaml, this parameter is not required. In this case, the account configuration file is automatically obtained by the plug-in. Note that a decimal point (.) is required at the beginning of the file name.
    • -Dtoolkit_package: specifies the package file. If the package file is in the same directory as pom.xml and the file name is .toolkit_package.yaml, this parameter is not required. In this case, the package file is automatically obtained by the plug-in. Note that a decimal point (.) is required at the beginning of the file name.
    • -Dtoolkit_deploy: specifies the deployment file. If the deployment file is in the same directory as pom.xml and the file name is .toolkit_deploy.yaml, this parameter is not required. In this case, the deployment file is automatically obtained by the plug-in. Note that a decimal point (.) is required at the beginning of the file name.
    • -Ddeploy_version: specifies the version to be deployed. The specified version has a higher priority than the version specified in the deployment configuration file.
      Note toolkit-maven-plugin 1.0.6 and later support this parameter.

    If "BUILD SUCCESS" appears after you run the packaging command, the deployment is successful.

More configuration items

  1. Specify the packaging parameters.

    The package file supports the following parameters:

    apiVersion: V1
    kind: AppPackage
    spec:
      packageType:  # The type of the application deployment package. Valid values are War, FatJar, Image, and url. The packageUrl parameter takes effect only if you set this parameter to url. 
      imageUrl:     # The URL of the image. This parameter is required if you use an image to deploy your application. 
      packageUrl:   # The URL of the package. This parameter takes effect if you use a WAR or FatJar package to deploy your application. 
    build:
        docker:
           dockerfile:        # The file used to build your Docker image. This parameter is required if you want to build an image in your on-premises environment to deploy the application. 
           imageRepoAddress:  # The address of the Alibaba Cloud image repository that you want to use. This parameter is required if you want to build an image in your on-premises environment to deploy the application. 
           imageTag:          # The image tag. This parameter is required if you want to build an image in your on-premises environment to deploy the application. 
           imageRepoUser:     # The username used to access the Alibaba Cloud image repository. This parameter is required if you want to build an image in your on-premises environment to deploy the application. 
           imageRepoPassword: # The password used to access the Alibaba Cloud image repository. This parameter is required if you want to build an image in your on-premises environment to deploy the application. 
              OSS:
                bucket:          # The name of the destination Object Storage Service (OSS) bucket. This parameter is required if you want to use a custom OSS bucket to store the deployment package. 
                key:             # The path of the OSS bucket. This parameter is required if you want to use a custom OSS bucket to store the deployment package. 
                accessKeyId:     # The AccessKey ID used to access OSS. This parameter is required if you want to use a custom OSS bucket to store the deployment package. 
                accessKeySecret: # The AccessKey secret used to access OSS. This parameter is required if you want to use a custom OSS bucket to store the deployment package. 
  2. Specify the deployment parameters.

    Click here to show the parameters supported by the deployment file.

    apiVersion: V1
    kind: AppDeployment
    spec:
      type: kubernetes
      target:
        appName:     # The name of the application. 
        namespaceId: # The microservices namespace where the application is to be deployed. 
        appId:       # The ID of the application. The plug-in deploys the application identified by the specified ID. If you do not specify this parameter, the values of namespaceId and appName are used to identify the application to be deployed. 
        version:     # The version to be deployed. The default format comprises the values of the day, hour, minute, and second. 
        jdk:         # The Java Development Kit (JDK) version on which the deployed package depends. Open JDK 7 and Open JDK 8 are supported. This parameter is unavailable if you deploy applications by using images. 
        webContainer:  # The Tomcat container version on which the deployed package depends. apache-tomcat-7.0.91 is supported. This parameter is unavailable if you deploy applications by using images. 
        batchWaitTime: # The interval between two consecutive batches. 
        command:       # The command used to start the image. The command must be an existing executable object in the container. For example, you can set the command to sleep. If you specify this parameter, the original startup command of the image becomes invalid. 
        commandArgs:   # The parameters of the image startup command. These parameters are required by the preceding startup command. 
        - 1d
      envs:       # The container environment variables. 
        - name: envtmp0
          value: '0'
        - name: envtmp1
          value: '1'
      liveness:   # Checks the container health status. A container that fails to pass the health check is stopped and then recovered. 
        exec:    # You need to specify one of the exec, tcpSocket, and httpGet parameters.
          command:
            - sleep
            - 1s
        tcpSocket: # You need to specify one of the exec, tcpSocket, and httpGet parameters.
          host: "192.168.1.109"  # Optional. The host IP address. If this parameter is left empty, the default value, which is the IP address of the pod, is used.
          port: "18081"  # The port number. The value must be a string.
        httpGet:  # You need to specify one of the exec, tcpSocket, and httpGet parameters.
          host: "192.168.1.109"  # Optional. The host IP address. If this parameter is left empty, the default value, which is the IP address of the pod, is used.
          port: "18081"  # The port number. The value must be a string.
          path: "/health"
          scheme: "HTTP"  # Valid values are HTTP and HTTPS.
          httpHeaders:
           - name: "color"
             value: "blue"
        initialDelaySeconds: 5
        timeoutSeconds: 11
        periodSeconds: 5
        successThreshold: 1   # The value is fixed to 1 and cannot be changed.
        failureThreshold: 3
      readiness:   # Checks the application startup status. A container that fails to pass this health check multiple times is stopped and then restarted. Containers that fail to pass health checks do not receive traffic from Server Load Balancer (SLB) instances. 
        exec:    # You need to specify one of the exec, tcpSocket, and httpGet parameters.
          command:
            - sleep
            - 1s
        tcpSocket: # You need to specify one of the exec, tcpSocket, and httpGet parameters.
          host: "192.168.1.109"  # Optional. The host IP address. If this parameter is left empty, the default value, which is the IP address of the pod, is used.
          port: "18081"  # The port number. The value must be a string.
        httpGet:  # You need to specify one of the exec, tcpSocket, and httpGet parameters.
          host: "192.168.1.109"  # Optional. The host IP address. If this parameter is left empty, the default value, which is the IP address of the pod, is used.
          port: "18081"  # The port number. The value must be a string.
          path: "/health"
          scheme: "HTTP"  # Valid values are HTTP and HTTPS.
          httpHeaders:
           - name: "color"
             value: "blue"
        initialDelaySeconds: 5
        timeoutSeconds: 11
        periodSeconds: 5
        successThreshold: 2
        failureThreshold: 3
      preStop:   # The lifecycle hook that is triggered when the container is to be deleted.
        exec:
          command:
            - /bin/bash
            - -c
            - ls /tmp
        httpGet:
          host: "192.168.1.109"  # Optional. The host IP address. If this parameter is left empty, the default value, which is the IP address of the pod, is used.
          port: "18081"  # The port number. The value must be a string.
          path: "/health"
          scheme: "HTTP"  # Valid values are HTTP and HTTPS.
          httpHeaders:
           - name: "color"
             value: "blue"
      postStart:   #  The lifecycle hook that is triggered after the container is created.
        exec:
          command:
           - /bin/bash
           - -c
           - ls /tmp
        httpGet:
          host: "192.168.1.109"  # Optional. The host IP address. If this parameter is left empty, the default value, which is the IP address of the pod, is used.
          port: "18081"  # The port number. The value must be a string.
          path: "/health"
          scheme: "HTTP"  # Valid values are HTTP and HTTPS.
          httpHeaders:
           - name: "color"
             value: "blue"
      configMountDescs:   # The configuration resources setting.
        - type: "ConfigMap"  # Valid values are ConfigMap and Secret.
          name: "configtest"
          mountPath: "/home/admin"  # If you specify a directory for this parameter, the mountItems is required to set the mount target to a file.
          mountItems:   # Sets the mount target to a file.
            - key: "test-name"
              path: "test"
          useSubPath: true   # If the mount target is a file, the value true indicates to retain the original file, whereas the value false indicates to overwrite the original file.
      javaStartUpConfig:   # The Java startup parameters. Set the parameters base on your business requirements.
        initialHeapSize:  # The initial size of the heap memory.
          original: 1000
          startup: "-Xms1000m"
        maxHeapSize:  # The maximum size of the heap memory.
          original: 1000
          startup: "-Xmx1000m"
        newSize:   # The initial size of the young generation.
          original: 200
          startup: "-XX:NewSize=200m"
        maxNewSize:  # The maximum size of the young generation.
          original: 200
          startup: "-XX:MaxNewSize=200m"
        survivorRatio:  # The ratio of the Eden space to the Survivor space.
          original: 2
          startup: "-XX:SurvivorRatio=2"
        newRatio:   # The ratio of the old generation to the young generation.
          original: 8
          startup: "-XX:NewRatio=8"
        permSize:  # The size of the permanent generation.
          original: 512
          startup: "-XX:PermSize=512m"
        maxPermSize:  # The maximum size of the permanent generation.
          original: 512
          startup: "-XX:MaxPermSize=200m"
        maxDirectMemorySize:  # The maximum size of the direct memory.
          original: 100
          startup: "-XX:MaxDirectMemorySize=100m"
        threadStackSize:  # The size of the thread stack.
          original: 500
          startup: "-XX:ThreadStackSize=500"
        hsfserverPort:  # The HSF server port.
          original: 12200
          startup: "-Dhsf.server.port=12200"
        hsfserverMinPoolSize:  # The minimum size of the HSF thread pool.
          original: 50
          startup: "-Dhsf.server.min.poolsize=50"
        hsfserverMaxPoolSize:  # The maximum size of the HSF thread pool.
          original: 720
          startup: "-Dhsf.server.max.poolsize=720"
        youngGarbageCollector:   # The garbage collection (GC) policy for the young generation.
          original: "UseSerialGC"  # Valid values are UseSerialGC, UseG1GC, UseParNewGC, and UseParallelGC.
          startup: "-XX:+UseSerialGC"  # If the original parameter is set to UseG1GC, UseParNewGC, or UseParallelGC, the value of this parameter is an empty string.
        oldGarbageCollector:   # The GC policy for the young generation.
          original: "UseConcMarkSweepGC"  # Valid values are UseConcMarkSweepGC, UseSerialGC, UseG1GC, UseConcMarkSweepGC, UseParNewGC, UseParallelOldGC, and UseParallelGC.
          startup: "-XX:+UseConcMarkSweepGC"  # Specify a value in the format of -XX:+<GC policy>.
        concGCThreads:   # The number of concurrent GC threads.
          original: 5
          startup: "-XX:ConcGCThreads=5"
        parallelGCThreads:   # The number of parallel GC threads.
          original: 5
          startup: "-XX:ParallelGCThreads=5"
        g1HeapRegionSize:    # The size of a Garbage-First (G1) region.
          original: 50
          startup: "-XX:G1HeapRegionSize=50m"
        gclogFilePath:  # The directory of GC logs.
          original: "/tmp/"
          startup: "-Xloggc:/tmp/"
        useGCLogFileRotation:  # Specifies whether to enable GC log rotation.
          original: true
          startup: "-XX:+UseGCLogFileRotation"
        numberOfGCLogFiles:  # The number of GC logs.
          original: 5
          startup: "-XX:NumberOfGCLogFiles=5"
        gclogFileSize:  # The size of a GC log.
          original: 100
          startup: "-XX:GCLogFileSize=100m"
        heapDumpOnOutOfMemoryError:  # Specifies whether to enable out-of-memory (OOM) dumps.
          original: true
          startup: "-XX:+HeapDumpOnOutOfMemoryError"
        heapDumpPath: # The file path for OOM dumps.
          original: "/tmp/dumpfile"
          startup: "-XX:HeapDumpPath=/tmp/dumpfile"
        customParams:  # Custom parameters.
          original: "-Dtest=true"
          startup: "-Dtest=true"
      deployAcrossZones: "true"  # Specifies whether to deploy the application across zones. We recommend that you enable this feature. The value must be a Boolean string.
      deployAcrossNodes: "true"  # Specifies whether to deploy the application across nodes. We recommend that you enable this feature. The value must be a Boolean string.
      customTolerations:  # The scheduling toleration settings.
        - key: aa
          operator: Exists
          effect: NoSchedule
        - key: bb
          operator: Equal
          value: "111"
          effect: "NoExecute"
          tolerationSeconds: 111
      customAffinity:  # The custom affinity rule.
        nodeAffinity:  # The node affinity rule.
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: "beta.kubernetes.io/arch"
                operator: "Gt"
                values:
                - "11"
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: "beta.kubernetes.io/arch"
                operator: "Gt"
                values:
                - "11"
        podAffinity:  # The application (node) affinity rule.
          requiredDuringSchedulingIgnoredDuringExecution:
          - namespaces:
            - "default"
            topologyKey: "failure-domain.beta.kubernetes.io/zone"
            labelSelector:
              matchExpressions:
              - key: "beta.kubernetes.io/arch"
                operator: "In"
                values:
                - "11"
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            podAffinityTerm:
              namespaces:
              - "default"
              topologyKey: "failure-domain.beta.kubernetes.io/region"
              labelSelector:
                matchExpressions:
                - key: "beta.kubernetes.io/arch"
                  operator: "Exists"
                  values: []
        podAntiAffinity:   # The application (pod) anti-affinity rule.
          requiredDuringSchedulingIgnoredDuringExecution:
          - namespaces:
            - "default"
            topologyKey: "kubernetes.io/hostname"
            labelSelector:
              matchExpressions:
              - key: "beta.kubernetes.io/arch"
                operator: "In"
                values:
                - "11"
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 2
            podAffinityTerm:
              namespaces:
              - "default"
              topologyKey: "kubernetes.io/hostname"
              labelSelector:
                matchExpressions:
                - key: "beta.kubernetes.io/arch"
                  operator: "In"
                  values:
                  - "11"
    

Typical scenarios

This section describes some typical deployment scenarios and the related configuration examples.
  • Scenario 1: Build a WAR or FatJar package in your on-premises environment to deploy an application
    For example, you have an application that is deployed by using a WAR or FatJar package to EDAS in the China (Beijing) region, and you want to build a WAR or FatJar package in your on-premises environment to redeploy the application. The following list describes the packaging and deployment configurations:
    • Package file:
      apiVersion: V1
      kind: AppPackage
      spec:
        packageType: War                                    
    • Deployment file:
      apiVersion: V1
      kind: AppDeployment
      spec:
        type: kubernetes
        target:
          appId:        # The ID of the application. The plug-in deploys the application identified by the specified ID. If you do not specify this parameter, the values of namespaceId and appName are used to identify the application to be deployed. 
          namespaceId:  # Optional. The microservices namespace where the application is to be deployed. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed. 
          appName:      # Optional. The name of the application. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed. 
  • Scenario 2: Use the URL of an existing image to deploy an application
    For example, you have an application that is deployed by using an image in the China (Beijing) region, and you want to use an existing image (registry.cn-beijing.aliyuncs.com/test/gateway:latest) to redeploy the application. The following list describes the packaging and deployment configurations:
    • Package file:
      apiVersion: V1
      kind: AppPackage
      spec:
        packageType: Image
        imageUrl: registry.cn-beijing.aliyuncs.com/test/gateway:latest                                    
    • Deployment file:
      apiVersion: V1
      kind: AppDeployment
      spec:
        type: kubernetes
        target:
          appId:        # The ID of the application. The plug-in deploys the application identified by the specified ID. If you do not specify this parameter, the values of namespaceId and appName are used to identify the application to be deployed. 
          namespaceId:  # Optional. The microservices namespace where the application is to be deployed. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed. 
          appName:      # Optional. The name of the application. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed. 
  • Scenario 3: Build an image in your on-premises environment and upload the image to a repository to deploy an application
    For example, you have an application that is deployed by using an image in the China (Beijing) region, and you want to compile and build an image in your on-premises environment and then upload the image to your Alibaba Cloud image repository to redeploy the application. The following list describes the packaging and deployment configurations:
    • Package file:
      apiVersion: V1
      kind: AppPackage
      spec:
        packageType: Image
        build:
          docker:
             dockerfile: Dockerfile # The Dockerfile. 
             imageRepoAddress:      # The address of the image repository. 
             imageTag:              # the image tag. 
             imageRepoUser:         # the username used to access the image repository. 
             imageRepoPassword:     # the password used to access the image repository. 
    • Deployment file:
      apiVersion: V1
      kind: AppDeployment
      spec:
        type: kubernetes
        target:
          appId:        # The ID of the application. The plug-in deploys the application identified by the specified ID. If you do not specify this parameter, the values of namespaceId and appName are used to identify the application to be deployed. 
          namespaceId:  # Optional. The microservices namespace where the application is to be deployed. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed. 
          appName:      # Optional. The name of the application. If the value of appId is unavailable, the values of namespaceId and appName can be used to identify the application to be deployed.