This blog was motivated by a great question on our support forum: "Can I use Shippable with a C# project?". My knee-jerk reaction was to tell him to wait for our imminent support for Windows containers. However, in my previous startup, we had built a cross-platform Xamarin.Forms based mobile app in C# and sheer curiosity provoked me to look at the latest state of Mono.
One of the biggest challenges to implementing an end-to-end Continuous Delivery pipeline is making sure adequate test automation is in place. However, even if you have automated across your entire Test Suite, there is a second challenge: How do you manage Test infrastructure and environments without breaking the bank?
If you want to move towards Continuous Delivery, you need to execute a majority of your tests for each code change in a pristine environment that is as close to your production environment as possible. This ensures that code defects are identified immediately and every code change is therefore 'shippable'. However, creating these environments and updating them with each new application version or every time the config changes adds a lot of overhead. If you're testing an application with many tiers or microservices, the complexity increases since each tier might need to be tested indepedently in its own environment against specific versions of other tiers.
Docker images that comprise a production application are often deployed to private repositories in Docker registries. Kubernetes provides a feature called imagePullSecrets that allows pods to pull private docker images. In this blog, we demonstrate how you can easily hookup imagePullSecrets to your pod using Shippable.
Creating an imagePullSecrets secret
imagePullSecrets is a type of a Kubernete Secret whose sole purpose is to pull private images from a Docker registry. It allows you to specify the Url of the docker registry, credentials for logging in and the image name of your private docker image.
There are two ways an imagePullSecrets can be created.
1. kubectl create secret docker-registry command. We use this approach in our blog.
ambarishs-MacBook-Pro:gke ambarish$ kubectl create secret docker-registry private-registry-key --docker-username="devopsrecipes" --docker-password="xxxxxx" --docker-email="email@example.com" --docker-server="https://index.docker.io/v1/"
secret "private-registry-key" created
2. Creating the secret via a yml.
In this approach, a config.json file is created for the private registry. Its contents are then base64 encoded and specified in the .dockerconfigjson property.
apiVersion: v1 kind: Secret metadata: name: private-registry-key namespace: default data: .dockerconfigjson: UmVhbGx5IHJlYWxseSByZWVlZWVlZWVlZWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGxsbGx5eXl5eXl5eXl5eXl5eXl5eXl5eSBsbGxsbGxsbGxsbGxsbG9vb29vb29vb29vb29vb29vb29vb29vb29vb25ubm5ubm5ubm5ubm5ubm5ubm5ubm5ubmdnZ2dnZ2dnZ2dnZ2dnZ2dnZ2cgYXV0aCBrZXlzCg== type: kubernetes.io/dockerconfigjson
Applications deployed to a Kubernetes cluster often need access to sensitive information such as credentials to access a database and authentication tokens to make authenticated API calls to services. Kubernetes allows you to specify such sensitive information cleanly in an object called a Secret. This avoids putting sensitive data in a Pod defintion or a docker image. In this blog, we demonstrate how you can easily hookup Kubernetes Secrets to your pod using Shippable.
Creating a Kubernetes Secret
Secrets are defined in a yml file in a Secret object. A Secret object can specifiy multiple secrets in name-value pairs. Each secret has to be base64 encoded before specifying it in the yml.
Let's define an API token as a secret for a fake token xxx-xxx-xxx.
1. Base 64 encode the token.
ambarishs-MacBook-Pro:sources ambarish$ echo -n "xxx-xxx-xxx" | base64
2. Create the secrets yml called create-secret.yml.
apiVersion: v1 kind: Secret metadata: name: auth-token-secret type: Opaque data: AUTH_TOKEN_VALUE: eHh4LXh4eC14eHg=
3. Create the secret in the kubernetes cluster using kubectl.
$ kubectl create -f secrets.yml secret "auth-token" created