'Create multiple containers with templating

I have a running k8s deployment, with one container.

I want to deploy 10 more containers, with a few differences in the deployment manifest (i.e command launched, container name, ...).

Rather than create 10 more .yml files with the whole deployment, I would prefer use templating. What can I do to achieve this ?

---
apiVersion: v1
kind: CronJob
metadata:
  name: myname
  labels:
    app.kubernetes.io/name: myname
spec:
  schedule: "*/10 * * * *"
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app.kubernetes.io/name: myname
        spec:
          serviceAccountName: myname
          containers:
            - name: myname
              image: 'mynameimage'
              imagePullPolicy: IfNotPresent
              command: ["/my/command/to/launch"]
          restartPolicy: OnFailure


Solution 1:[1]

Kustomize seems to be the go-to tool for templating, composition, multi-environment overriding, etc, in kubernetes configs. And it's built directly into kubectl now as well.

Specifically, I think you can achieve what you want by using the bases and overlays feature. Setup a base which contains the common structure and overlays which contain specific overrides.

Solution 2:[2]

You can either specify a set of containers to be created you can do that like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: container1
        image: your-image
      - name: container2
        image: your-image
      - name: container3
        image: your-image

and you can repeat that container definition as many times as you want.

The other way around is to use a templating engine like helm/kustomize as mentioned above.

Solution 3:[3]

Using helm which is a templating engine for Kubernetes manifests you can create your own template by following me through.

If you have never worked with helm you can check the official docs

In order for you to follow make sure you have helm already installed!

- create a new chart:

helm create cowboy-app

this will generate a new project for you.

- DELETE EVERYTHING WITHING THE templates DIR

- REMOVE ALL values.yaml content

- create a new file deployment.yaml in templates directory and paste this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.appName }}
  labels:
    chart: {{ .Values.appName }}
spec:
  selector:
    matchLabels:
      app: {{ .Values.appName }}
  replicas: 1
  template:
    metadata:
      labels:
        app: {{ .Values.appName }}
    spec:
      containers:
{{ toYaml .Values.images | indent 8 }}     

- in values.yaml paste this:

appName: cowboy-app
images:
  - name: app-1
    image: image-1
  - name: app-2
    image: image-2
  - name: app-3
    image: image-3
  - name: app-4
    image: image-4
  - name: app-5
    image: image-5    
  - name: app-6
    image: image-6
  - name: app-7
    image: image-7
  - name: app-8
    image: image-8
  - name: app-9
    image: image-9
  - name: app-10
    image: image-10                                     

So if you are familiar with helm you can tell that {{ toYaml .Values.images | indent 10 }} in the deployment.yaml is referring to data specified in values.yaml as YAML and by running helm install release-name /path/to/chart will generate and deploy a manifest file which is deployment.yaml that looks like this:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cowboy-app
  labels:
    chart: cowboy-app
spec:
  selector:
    matchLabels:
      app: cowboy-app
  replicas: 1
  template:
    metadata:
      labels:
        app: cowboy-app
    spec:
      containers:
        - image: image-1
          name: app-1
        - image: image-2
          name: app-2
        - image: image-3
          name: app-3
        - image: image-4
          name: app-4
        - image: image-5
          name: app-5
        - image: image-6
          name: app-6
        - image: image-7
          name: app-7
        - image: image-8
          name: app-8
        - image: image-9
          name: app-9
        - image: image-10
          name: app-10

Solution 4:[4]

Either you can use Helm or Kustomize. Both are templating tools and help you to achieve your goal

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Josh Bothun
Solution 2
Solution 3 Affes Salem
Solution 4 Anshuman