5

Is it possible to use kustomize to specify a volume hostPath from an env variable?

I have a Kubernetes manifest that describes my deployment consisting of a container. During development, I use a different image (that contains dev tools) and mount code from my host into the container. This way I can make code changes without having to re-deploy.

I'm using a patchStategicMerge to replace the production image, with the one I want to use during dev and mount the code into the container i.e.

kustomization.yaml

kind: Kustomization

bases:
- ../../base

patchesStrategicMerge:
- my-service.yaml

my-service.yaml

---
apiVersion: apps/v1
...
...
    spec:
      containers:
        - name: myservice
          image: myservice-dev-image:1.0.0
          command: ['CompileDaemon',  '--build=make build', '--command=./myservice']
          volumeMounts:
          - name: code
            mountPath: /go/src/app
      volumes:
      - name: code
        hostPath:
          path: /source/mycodepath/github.com/myservice

What I'd like to do is make the path configurable via an environment variable, so that I don't have to check my specific path (/source/mycodepath/) into git, and so that other developers can easily use it in their own environment.

Is it possible to do this with kustomize ?

Coder Jones
  • 93
  • 1
  • 4
  • 1
    I don't know how to do that with an environment variable but it is possible to define an overlay that has a different path. Check out Kustomize overlays. Here's one using overlays https://github.com/kubernetes-sigs/kustomize/tree/master/examples/springboot – Justin Tamblyn Sep 03 '20 at 11:55
  • am I right that your question can be stripped down to "how to mount local path (from my laptop) to the pod?" , additionally, where do you run the pod? do you run it on a standalone k8s , or is ita k8s directly on your host/laptop/PC (minikube, etc) or is it a managed one like GKE, EKS, etc? – Nick Sep 04 '20 at 11:44
  • @Nick not quite. I know how to mount a local path from my laptop. The problem is on my laptop the path could be /users/bob/github/somecode and on a co-workers laptop its on /users/sue/github/mycode. If I use an overlay I can define my path in the overlay. But I don't want to check that into git. In docker-compose we solve this by using a relative path, but that doesn't appear to work with k8s – Coder Jones Sep 04 '20 at 13:08
  • @JustinTamblyn thanks. I am using overlays. The question is how can I create an overlay that different developers can share without having to modify the volume path. Using either a variable or a relative path would help. – Coder Jones Sep 04 '20 at 13:10
  • @CoderJones I think I understand. I'll put something together as an answer – Justin Tamblyn Sep 04 '20 at 15:46

1 Answers1

5

Create following directory structure

  • k8s
  • k8s/base
  • k8s/overlays
  • k8s/overlays/bob
  • k8s/overlays/sue

First we need to create the base. The base is the default template and it provide the bits that apply to both people. In k8s/base create a file called app.yaml and populate with the following (actually paste yours here. You can put other common bits in there too separated by a --- and new line).

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myservice
  namespace: default
spec:
  strategy:
    type: RollingUpdate
  replicas: 1
  template:
    metadata:
      labels:
        name: myservice
        app: myservice
    spec:
      containers:
        - name: myservice
          image: myservice-dev-image:1.0.0
          command: ['CompileDaemon',  '--build=make build', '--command=./myservice']
          volumeMounts:
          - name: code
            mountPath: /go/src/app
      volumes:
      - name: code
        hostPath:
          path: /xxx

Next in the same directory (k8s/base) create another file called kustomization.yaml and populate with:

resources:
 - app.yaml

Next we will create two overlays: one for Bob and one for Sue.

In k8s/overlays/bob let's create Bob's custom changes as app.yaml and populate with the following:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myservice
  namespace: default
spec:
  template:
    spec:
      volumes:
      - name: code
        hostPath:
          path: /users/bob/code

Now also in k8s/overlays/bob create another file called kustomization.yaml with the following:

resources:
  - ../../base
patchesStrategicMerge:
  - app.yaml

We can copy the two files in k8s/overlays/bob into the k8s/overlays/sue directory and just change the path in the volumes: bit.

Next we need to do a kustomize build to generate the resulting versions - bob and sue.

If the k8s directory is in your code directory, open terminal (with Kustomize installed and run:

kustomize build k8s/overlays/bob

That should show you what Bob's kustomization will look like:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myservice
  namespace: default
spec:
  replicas: 1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: myservice
        name: myservice
    spec:
      containers:
      - command:
        - CompileDaemon
        - --build=make build
        - --command=./myservice
        image: myservice-dev-image:1.0.0
        name: myservice
        volumeMounts:
        - mountPath: /go/src/app
          name: code
      volumes:
      - hostPath:
          path: /users/bob/code
        name: code

To apply that you can run:

kustomize build k8s/overlays/bob | kubectl apply -f -

To apply Sue you can run:

kustomize build k8s/overlays/sue| kubectl apply -f -

Yaml is sensitive about spaces and I'm not sure this will sit well in a Stackoverflow answer so I've put on Github as well: https://github.com/just1689/kustomize-local-storage

Justin Tamblyn
  • 719
  • 8
  • 21