Deploying to Kubernetes in Pipelines

JFrog Pipelines Documentation

ft:sourceType
Paligo

This tutorial demonstrates an example pipeline that uses the HelmPublish and HelmDeploy native steps to deploy a single image from a Docker registry in Artifactory to a Kubernetes cluster using a Helm chart.

Helm is a package manager for Kubernetes applications. Through a Helm chart, you can describe the application structure and manage it using simple commands through the Helm client.

The native steps in Pipelines invoke the Helm client to perform the deployment tasks using the Helm chart.

The example pipeline requires the following integrations:

Create the Helm Chart

To begin, we have created a very simple Helm chart, which we have stored in a GitRepo source repository:

Chart.yml

apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: simplehelm
version: 0.1.0

We use a companion values.yml file to specify the details, including information that identifies which Docker image to deploy.

values.yml

replicaCount: 1
image:
  repository: ${res_simplehelmDockerImage_imageName}
  tag: ${res_simplehelmDockerImage_imageTag}
  pullPolicy: IfNotPresent
  port: 80

....

The repository and tag fields that identify the Docker image name and tag are set to environment variables. These reference the imageName and imageTag properties of the Image resource for the Docker image.

When our pipeline runs, the HelmDeploy step will automatically replace these environment variable reference with their values from the Image resource, so that the correct Docker image is deployed through Helm.

For more information on creating Helm charts, see the Helm Chart Template Guide.

Docker Image

The Helm deploy will pull an image from a Docker registry to orchestrate to a Kubernetes cluster.

You may wish to build the Docker image and push it to the registry as part of your pipeline. If so, you can use the DockerBuildand DockerPushnative steps.

If your image to deploy is already available in the Docker registry, then you can skip this procedure. However, you will still need an Imageresource that specifies the image in the registry.

Ourresourcesdefinitions will specify:

  • simplehelmRepo_docker - The GitRepo source repository where the Dockerfile is storedGitRepo

  • simplehelmDockerImage - An Image resource for the Docker image that will be built and pushed to the Docker registry in Artifactory

resources

 - name: simplehelmRepo_docker
   type: GitRepo
   configuration:
     gitProvider: my_github
     path: myrepo/simplehelm
     files:
       include: "Dockerfile|server.js|package.json"

 - name: simplehelmDockerImage
   type: Image
   configuration:
     registry: myDocker
     imageName: myproject/simplehelm
     imageTag: latest 

Using these resources, the pipeline will build the Docker image and push it to a registry in Artifactory.

steps

pipelines:
   - name: pipelines name
     steps:
      - name: build_image
        type: DockerBuild
        configuration:
          affinityGroup: buildAndPush
          integrations:
            - name: myDocker
          inputResources:
            - name: simplehelmRepo_docker
          dockerFileLocation: .
          dockerFileName: Dockerfile
          dockerImageName: myproject/simplehelm
          dockerImageTag: $run_number

      - name: push_image
        type: DockerPush
        configuration:
          affinityGroup: buildAndPush
          integrations:
            - name: myDocker
          targetRepository: myproject/simplehelm
          inputSteps:
            - name: build_image
          outputResources:
            - name: simplehelmDockerImage  

Publish the Helm Chart

The example pipeline uses the HelmPublish native step to publish the Helm chart and its companion files to a Helm repository in Artifactory.

Our resources definitions will specify:

  • simplehelmRepo_chart - The GitRepo source repository where the Helm chart shown above is stored.GitRepo

  • simpleHelmChart - A HelmChart resource that represents the Helm chart published in Artifactory. It specifies the Artifactory repository, chart name, and version for publishing.

resources

  - name: simplehelmRepo_chart
    type: GitRepo
    configuration:
      gitProvider: my_github
      path: myrepo/simplehelm
      files:
        include: "simplehelm.*"

  - name: simplehelmChart
    type: HelmChart
    configuration:
      sourceArtifactory: art
      repository: simplecharts
      chart: simplehelm
      version: 0.0.0

Using these resources, the HelmPublish native step will publish the Helm chart from the source repository to an Artifactory repository. (Note that this step as configured does not publish the build info.)

step

      - name: publish_helm_chart
        type: HelmPublish
        configuration:
          inputResources:
            - name: simplehelmRepo_chart
          outputResources:
            - name: simplehelmChart
          chartPath: ./simplehelm

The native step uses the helm package command to perform publication, so all chart files (Chart.yml, and values.yml) will be published as a unit.

Deploy With Helm

The example pipeline uses the HelmDeploy native step to deploy the image to Kubernetes.

The HelmDeploy native step will:

  1. Use the simplehelmChart resource to pull the Helm chart from Artifactory

  2. Replace all environment variables in values.yml with their values from the simplehelmDockerImage resource

  3. Perform the helm upgrade command to deploy the simplehelmDockerImage from the Docker repository to a Kubernetes cluster

step

      - name: deploy_helm_chart
        type: HelmDeploy
        configuration:
          integrations:
            - name: tr_kubernetes
          inputResources:
            - name: simplehelmChart
            - name: simplehelmDockerImage
          releaseName: simplehelm
          flags: "--namespace dev"
          valueFilePaths:
            - values.yaml

Note that the Image resource is not required by HelmDeploy to be in its inputresources. The only resource HelmDeploy requires is a HelmChart.

We include simplehelmDockerImage so that its imageName and imageTag properties are available to the step as environment variables. This enables the HelmDeploy step to perform the replacements of those environment variables in the values.yml file of the Helm chart.

After the replacement, the values.yml used by Helm might appear as (if this was run 1):

values.yml (after replacement)

replicaCount: 1
image:
  repository: myproject/simplehelm
  tag: 1
  pullPolicy: IfNotPresent
  port: 80

....

HelmDeploy from a Git Repository

We recommend pushing your Helm charts to Artifactory with traceable metadata,. However, the HelmDeploy step can use a Helm chart directly from a Git source repository instead.

To deploy using the Helm chart in the Git repository without pushing it to Artifactory:

  1. Skip the HelmPublish step

  2. In the Pipelines DSL for the deploy_helm_chart step, in the inputresources section replace the simplehelmChart HelmChart resource with the simplehelmRepo_chart GitRepo resource.

The operation will produce the same result, including the replacement of environment variables in values.yml.

Complete Example

For your reference, here is the complete Pipelines DSL for the example pipeline.

pipelines.resources.yml

  - name: simplehelmRepo_docker
    type: GitRepo
    configuration:
      gitProvider: my_github
      path: myrepo/simplehelm
      files:
        include: "Dockerfile|server.js|package.json"

  - name: simplehelmDockerImage
    type: Image
    configuration:
      registry: myDocker
      imageName: myproject/simplehelm
      imageTag: latest

  - name: simplehelmRepo_chart
    type: GitRepo
    configuration:
      gitProvider: my_github
      path: myrepo/simplehelm
      files:
        include: "simplehelm.*"

  - name: simplehelmChart
    type: HelmChart
    configuration:
      sourceArtifactory: art
      repository: simplecharts
      chart: simplehelm
      version: 0.0.0

pipelines.steps.yml

pipelines:
  - name: helm_full_flow
    steps:
      - name: build_image
        type: DockerBuild
        configuration:
          affinityGroup: buildAndPush
          integrations:
            - name: myDocker
          inputResources:
            - name: simplehelmRepo_docker
          dockerFileLocation: .
          dockerFileName: Dockerfile
          dockerImageName: myproject/simplehelm
          dockerImageTag: $run_number

      - name: push_image
        type: DockerPush
        configuration:
          affinityGroup: buildAndPush
          integrations:
            - name: myDocker
          targetRepository: myproject/simplehelm
          inputSteps:
            - name: build_image
          outputResources:
            - name: simplehelmDockerImage

      - name: publish_helm_chart
        type: HelmPublish
        configuration:
          inputResources:
            - name: simplehelmRepo_chart
          outputResources:
            - name: simplehelmChart
          chartPath: ./simplehelm

      - name: deploy_helm_chart
        type: HelmDeploy
        configuration:
          integrations:
            - name: tr_kubernetes
          inputResources:
            - name: simplehelmChart
            - name: simplehelmDockerImage
          releaseName: simplehelm
          flags: "--namespace dev"
          valueFilePaths:
            - values.yaml