Introduction to Kustomize, Part 2: Overriding values with overlays
Curious about what else is new in Kubernetes 1.14 (besides integration of Kustomize)? Watch our webinar recording.
Changing parameters for a component using Kustomize overlays
Now, we're almost ready, but we do have one more problem. While we're deploying our production system to a cloud provider that supports LoadBalancer, we're developing on our laptop so we need our services to be of type: NodePort. Fortunately, we can solve this problem with Kustomize overlays.
Overlays enable us to take the base YAML and selectively change pieces of it. For example, we're going to create a Kustomize overlay that includes a patch to change the Services to NodePort type services.
It's important that the overlay isn't in the same directory as the base files, so we'll create it in an adjacent directory, then add a dev subdirectory.
OVERLAY_HOME=$BASE/../overlays mkdir $OVERLAY_HOME DEV_HOME=$OVERLAY_HOME/dev mkdir $DEV_HOME cd $DEV_HOMENext we want to create the patch file, $DEV_HOME/localserv.yaml:
apiVersion: v1 kind: Service metadata: name: wordpress spec: type: NodePort --- apiVersion: v1 kind: Service metadata: name: mysql spec: type: NodePortNotice that we've included the bare minimum of information here; just enough to identify each service we want to change, and then specify the change that we want to make -- in this case, the type.
Now we need to create the $DEV_HOME/kustomization.yaml file to tie all of this together:
bases: - ../../base patchesStrategicMerge: - localserv.yamlNotice that this is really very simple; we're pointing at our original base directory, and specifying the Kustomize patch(es) that we want to add.
Now we can go ahead and build the original, and see that it's untouched:
kustomize build $BASE
You can see that we still have LoadBalancer services:... spec: ports: - port: 3306 selector: app: my-wordpress --- apiVersion: v1 kind: Service metadata: labels: app: my-wordpress name: wordpress spec: ports: - port: 80 selector: app: my-wordpress type: LoadBalancer --- apiVersion: apps/v1beta2 kind: Deployment metadata: labels: ...But if we build the overlay instead, we can see that we now have NodePort services:
$ kustomize build $DEV_HOMENotice that everything is unchanged by the patch except the type. Now let's look at making use of these objects in kubectl.
... name: mysql-pass type: Opaque --- apiVersion: v1 kind: Service metadata: labels: app: my-wordpress name: mysql spec: ports: - port: 3306 selector: app: my-wordpress type: NodePort --- apiVersion: v1 kind: Service metadata: labels: app: my-wordpress name: wordpress spec: ports: - port: 80 selector: app: my-wordpress type: NodePort --- apiVersion: apps/v1beta2 kind: Deployment metadata: ...
Using Kustomize with kubectl
Now, all of this is great, but saving it to a file then running the file seems like a little bit of overkill. Fortunately there are two ways we can feed this in directly. One is to simply pipe it in, as you would do with any other Linux program:
kustomize build $DEV_HOME | kubectl apply -f -Or if you're using Kubernetes 1.14 or above, you can simply use the -k parameter:
kubectl apply -k $DEV_HOME secret "mysql-pass" created service "mysql" created service "wordpress" created deployment.apps "mysql" created deployment.apps "wordpress" createdThis may not seem like a big deal, but consider this example from the documentation, showing the old way of doing things:
kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL secret/myregistrykey created.Versus the new way, where we create a kustomization.yaml file:
secretGenerator: - name: myregistrykey type: docker-registry literals: - docker-server=DOCKER_REGISTRY_SERVER - docker-username=DOCKER_USER - docker-password=DOCKER_PASSWORD - docker-email=DOCKER_EMAIL EOF
Then simply reference it using the -k parameter:
$ kubectl apply -k . secret/myregistrykey-66h7d4d986 createdConsidering that kustomization.yaml files can be stored in repos and subject to version control, where they can be tracked and more easily managed, this provides a much cleaner way to manage your infrastructure as code.
There are, of course, other things you can do with Kustomize, including adding name prefixes, generating ConfigMaps, and passing down environment variables, but we'll leave that for another time. (Let us know in the comments if you'd like to see that sooner rather than later.)