Skip to content

Latest commit

 

History

History
 
 

309-deploying-a-chart-repository

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

Deploying a Chart Repository for Helm Charts

You learned about using helm in the module 306 Application Management with Helm this module will teach you how to deploy your own Chart Repository to your Kubernetes cluster so that you can deploy custom applications.

Prerequisites

This chapter uses a cluster with 3 master nodes and 5 worker nodes as described here: multi-master, multi-node gossip based cluster.

All configuration files for this chapter are in the sample directory. Make sure to cd into this directory before running any commands.

This chapter expects that you have gone through 306 Application Management with Helm meaning you should have installed helm.

ChartMuseum

Chart Museum is an Open Source Chart Repository, it helps you to deploy your custom charts to an Amazon S3 bucket and allows you to easily access your charts like you would a stable release from something like Kubeapps.

Installing ChartMuseum

To install chartmuseum you first need to add the incubator helm repo.

$ helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com
"incubator" has been added to your repositories

After you have added the incubator repo, you can install like any other helm package.

helm install incubator/chartmuseum --name chartmuseum \
  --set env.open.DISABLE_API=false \
  --set image.tag=latest

This will deploy the chartmuseum using the standard configuration without long term storage for your charts.

Important
If you do not include --set env.open.DISABLE_API=false the /api/* endpoints won’t be routable meaning you can’t deploy or list charts against the api.

Once you have this installed you can use kubectl port-forward to get access to the service.

$ kubectl port-forward $(kubectl get po -l app=chartmuseum -o jsonpath="{.items..metadata.name}") 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

Now that we have this port-forwarded we can try packaging and pushing our sample project.

$ cd sample/
$ helm package .
Successfully packaged chart and saved it to: /03-path-application-development/309-deploying-a-chart-repository/sample/sample-1.0.0.tgz

Then we can test pushing our first chart to the new repo.

$ curl --data-binary "@sample-1.0.0.tgz" http://localhost:8080/api/charts
{"saved":true}

Now that we have this repo with a chart we can configure out local environment to look through that repo, then we can deploy our chart.

First lets check if the chart is deployed.

$ curl http://localhost:8080/api/charts
{
  "sample": [
    {
      "name": "sample",
      "home": "https://github.com/aws-samples/aws-workshop-for-kubernetes",
      "sources": [
        "https://github.com/aws-samples/aws-workshop-for-kubernetes"
      ],
      "version": "1.0.0",
      "description": "My first Helm chart",
      "keywords": [
        "java",
        "javaee",
        "mysql",
        "wildfly",
        "wildfly swarm"
      ],
      "maintainers": [
        {
          "name": "Arun Gupta",
          "email": "[email protected]"
        }
      ],
      "urls": [
        "charts\/sample-1.0.0.tgz"
      ],
      "created": "2018-03-10T00:20:00Z",
      "digest": "9ee14a033addb5c9b54ae3714bd595fc652a4305535ab643406dfa83a016c9c5"
    }
  ]
}

This output represents the pushed chart from the sample/ repo. Next we’re going to make the storage more reliable by using S3.

Accessing the Charts

To access the repo within the helm cli add it as a repository.

helm repo add chartmuseum http://localhost:8080

Now if you use helm install chartmuseum/sample or helm search chartmuseum/sample you will see the chart you just pushed.

Extending ChartMuseum to be Reliable

Now that you have chartmuseum running in your cluster we need to make a couple edits, first we should use the built in mechanisms for storage, exposing, and authentication. This will help make the service more reliable because the container won’t be bound to a specific host since the storage will be off loaded, and the service will be load balanced meaning we can run multiple copies.

Using S3 for Storage

With the default deploy the charts are stored on a mounted volume, for a Kubernetes deployment where you don’t always run on the same node this can cause issues where the server can’t find the charts. To fix this we need to create an Amazon S3 Bucket for our charts.

$ export CHART_BUCKET=s3://example-chart-store-$(cat /dev/random | LC_ALL=C tr -dc "[:alpha:]" | tr '[:upper:]' '[:lower:]' | head -c 32)
$ aws s3 mb $CHART_BUCKET
make_bucket: example-chart-store-zohaenqynbcctothqpmacoicaytzjach

Now that the bucket has been created we need to edit the node IAM policy to allow access to read, write, delete.

kops edit cluster example.cluster.k8s.local

You will need to add additionalPolicies that will allow all nodes to have access to the bucket, to do so use:

additionalPolicies:
  node: |
    [
      {
        "Sid": "AllowListObjects",
        "Effect": "Allow",
        "Action": [
          "s3:ListBucket"
        ],
        "Resource": "arn:aws:s3:::$BUCKET_NAME"
      },
      {
        "Sid": "AllowObjectsCRUD",
        "Effect": "Allow",
        "Action": [
          "s3:DeleteObject",
          "s3:GetObject",
          "s3:PutObject"
        ],
        "Resource": "arn:aws:s3:::$BUCKET_NAME/*"
      }
    ]
Warning
Make sure to replace $BUCKET_NAME in each of the statements with the $CHART_BUCKET without s3://

After you have saved the file you can update the cluster thus adding the new policies to the nodes.

kops update cluster example.cluster.k8s.local --yes

Then we can upgrade the chart with the updated values helm upgrade cli like so.

helm upgrade chartmuseum incubator/chartmuseum \
  --reuse-values \
  --set env.open.STORAGE=amazon \
  --set env.open.STORAGE_AMAZON_BUCKET=$BUCKET_NAME \
  --set env.open.STORAGE_AMAZON_PREFIX="" \
  --set env.open.STORAGE_AMAZON_REGION=eu-west-1 \

This will deploy a cluster but it won’t be publicly accessible, yet. You will still need to kubectl port-forward to access the repo.

kubectl port-forward $(kubectl get po -l app=chartmuseum -o jsonpath="{.items..metadata.name}") 8080:8080

With port 8080 forwarded you can now open your browser and view the landing page.

# on macOS
open http://localhost:8080

Now that you have access to the server you can add the repo to your local helm client so that you can deploy a repo into it.

helm repo add chartmuseum http://localhost:8080

Then we can test packaging the sample application.

With this packaged chart we then can push it to the port-forwarded repo.

$ curl --data-binary "@sample-1.0.0.tgz" http://localhost:8080/api/charts
{"saved":true}

To verify the package was added properly you can curl the list endpoint.

$ curl http://localhost:8080/api/charts
{
  "sample": [
    {
      "name": "sample",
      "home": "https://github.com/aws-samples/aws-workshop-for-kubernetes",
      "sources": [
        "https://github.com/aws-samples/aws-workshop-for-kubernetes"
      ],
      "version": "1.0.0",
      "description": "My first Helm chart",
      "keywords": [
        "java",
        "javaee",
        "mysql",
        "wildfly",
        "wildfly swarm"
      ],
      "maintainers": [
        {
          "name": "Arun Gupta",
          "email": "[email protected]"
        }
      ],
      "urls": [
        "charts\/sample-1.0.0.tgz"
      ],
      "created": "2018-03-10T00:20:00Z",
      "digest": "9ee14a033addb5c9b54ae3714bd595fc652a4305535ab643406dfa83a016c9c5"
    }
  ]
}
Important
You will notice there is only one chart here even though you’ve deployed the chart twice, this is because the original chart was deployed to the local volume which is unaccessible now.

Accessing the Charts

To access the repo within the helm cli add it as a repository.

helm repo add chartmuseum http://localhost:8080

Now if you use helm install chartmuseum/sample or helm search chartmuseum/sample you will see the chart you just pushed.

Exposing Using a Load Balancer

Up until now we’ve been using port-forwarding to get access to the service running in Kubernetes, by making a couple tweaks we can expose this using an ELB and type LoadBalancer in the helm variables.

Now lets upgrade the chartmuseum adding --set service.type=LoadBalancer and --set service.externalPort=80 to expose using an ELB.

helm upgrade chartmuseum incubator/chartmuseum \
  --reuse-values \
  --set service.type=LoadBalancer \
  --set service.externalPort=80

Once that deploys you can use kubectl get svc to find the exposed Load Balancer.

open http://$(kubectl get svc -l app=chartmuseum -o jsonpath="{.items..status.loadBalancer.ingress..hostname}")

This will open the browser showing the app. We can then test that the API is still configured properly.

$ curl http://$(kubectl get svc -l app=chartmuseum -o jsonpath="{.items..status.loadBalancer.ingress..hostname}")/api/charts
{
  "sample": [
    {
      "name": "sample",
      "home": "https://github.com/aws-samples/aws-workshop-for-kubernetes",
      "sources": [
        "https://github.com/aws-samples/aws-workshop-for-kubernetes"
      ],
      "version": "1.0.0",
      "description": "My first Helm chart",
      "keywords": [
        "java",
        "javaee",
        "mysql",
        "wildfly",
        "wildfly swarm"
      ],
      "maintainers": [
        {
          "name": "Arun Gupta",
          "email": "[email protected]"
        }
      ],
      "urls": [
        "charts\/sample-1.0.0.tgz"
      ],
      "created": "2018-03-10T00:20:00Z",
      "digest": "9ee14a033addb5c9b54ae3714bd595fc652a4305535ab643406dfa83a016c9c5"
    }
  ]
}

Accessing the Charts

To access the repo within the helm cli add it as a repository.

$ helm repo add chartmuseum http://$(kubectl get svc -l app=chartmuseum -o jsonpath="{.items..status.loadBalancer.ingress..hostname}")
"chartmuseum" has been added to your repositories

Now if you use helm install chartmuseum/sample or helm search chartmuseum/sample you will see the chart you just pushed.

Authentication

Now that we have our remote storage in-place and our external routing, we need to lock down who has access to the service. This can be done directly with the helm chart by adding a couple variables.

Warning
The rest of this tutorial expects that you need public access to your helm repo. If you use CI/CD you can use your build pipelines within the cluster to only connect to the internal registry, removing the need for chartmuseum to be public.

Then upgrade the cluster using --set env.secret.BASIC_AUTH_USER and --set env.secret.BASIC_AUTH_PASS

helm upgrade chartmuseum incubator/chartmuseum \
  --reuse-values \
  --set env.secret.BASIC_AUTH_USER=user \
  --set env.secret.BASIC_AUTH_PASS=password

Once this successfully deploys you can use the same command from above to curl the chartmuseum which should error.

$ curl -I http://$(kubectl get svc -l app=chartmuseum -o jsonpath="{.items..status.loadBalancer.ingress..hostname}")/api/charts
HTTP/1.1 404 Not Found
Content-Type: text/plain
X-Request-Id: d254b5d3-5b8a-4e78-9968-1e67434c190a
Date: Fri, 09 Mar 2018 19:54:40 GMT
Content-Length: 18

Resubmitting again using the auth basic header succeeds.

$ curl -H "Authorization:Basic dXNlcjpwYXNzd29yZA==" http://$(kubectl get svc -l app=chartmuseum -o jsonpath="{.items..status.loadBalancer.ingress..hostname}")/api/charts
{
  "sample": [
    {
      "name": "sample",
      "home": "https://github.com/aws-samples/aws-workshop-for-kubernetes",
      "sources": [
        "https://github.com/aws-samples/aws-workshop-for-kubernetes"
      ],
      "version": "1.0.0",
      "description": "My first Helm chart",
      "keywords": [
        "java",
        "javaee",
        "mysql",
        "wildfly",
        "wildfly swarm"
      ],
      "maintainers": [
        {
          "name": "Arun Gupta",
          "email": "[email protected]"
        }
      ],
      "urls": [
        "charts\/sample-1.0.0.tgz"
      ],
      "created": "2018-03-10T00:20:00Z",
      "digest": "9ee14a033addb5c9b54ae3714bd595fc652a4305535ab643406dfa83a016c9c5"
    }
  ]
}

Accessing the Charts

To access the repo within the helm cli add it as a repository.

First lets try adding the repo without the user to verify authentication.

$ helm repo add chartmuseum http://$(kubectl get svc -l app=chartmuseum -o jsonpath="{.items..status.loadBalancer.ingress..hostname}")
Error: Looks like "http://xxx-xxx.us-east-2.elb.amazonaws.com" is not a
valid chart repository or cannot be reached: Failed to fetch
http://xxx-xxx.us-east-2.elb.amazonaws.com/index.yaml : 401 Unauthorized

Next we’ll add the credentials to the url and try again.

$ helm repo add chartmuseum http://user:password@$(kubectl get svc -l app=chartmuseum -o jsonpath="{.items..status.loadBalancer.ingress..hostname}")
"chartmuseum" has been added to your repositories

Now if you use helm install chartmuseum/sample or helm search chartmuseum/sample you will see the chart you just pushed.

Cleanup

To cleanup chartmuseum and the local chart repos you can just use the cli.

helm del chartmuseum --purge
helm del monocular --purge
helm repo rm chartmuseum

You are now ready to continue on with the workshop!

button continue developer

Go to Developer Index