Unit #4
Configuration


use ←↑↓→ or <space>

Passing config

Methods

  1. Bake into image
  2. Use environment variables
  3. Mount config files

Bake into image

Limited, can only change by redeploying

Insecure, encourages sharing

Environment vars

Better for individual values, not complex files

Insecure!

Mounting files

Good for simple and complex config

Secure, subject to user permissions

Commonly used by applications already

Sharing config

Only for key values as needed

Write once, use everywhere

Defining config

Secrets

Stores config values, small files

Encrypted

Stored encrypted within k8s

Only decrypted on mounting in pod

Defined separately

Secrets are their own object...

...not part of a Deployment or Statefulset

apiVersion: v1
kind: Secret
metadata:
  name: drupal-db
type: Opaque
data:
  drupal-db-password.txt: YWJldHRlcnBhc3N3b3JkdGhhbnRoaXM=

Data section

Defines one or more individual values

Each mounted as a separate file in pod

base64 encoding

Each data item is base64 encoded

Makes creation clumsy

String Data

Assume values are not base64 encoded

Encoded on save, becomes data afterward

apiVersion: v1
kind: Secret
metadata:
  name: drupal-db
type: Opaque
stringData:
  drupal-db-password.txt: "abetterpasswordthanthis"

Same management

kubectl get secret

kubectl describe secret name

kubectl edit secret name

Encoded on edit

Values aren't base64 decoded

Requires special editor or manual work

Better for values

Okay for small files, but...

...Secret can't be >1MB total!

Bigger config

Configmaps

Use for whole files, sets of files

Much, much larger storage limit

Not encrypted!

Or base64 encoded!

Easier to edit, but less secure

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
data:
  flight-deck-db.yml: |
    mysql_databases:
    - name: "drupal"
    mysql_users:
    - name: "drupal"
      host: "%"
      passwordFile: "/config/drupal-db/drupal-db-password.txt"
      priv: "drupal.*:ALL"
(Scroll down.)
$ kubectl --kubeconfig="/path/to/kubeconfig.yml" apply -f /path/to/configmaps.yml

$ kubectl --kubeconfig="/path/to/kubeconfig.yml" get configmaps

NAME    DATA   AGE
mysql   1      10s

$ kubectl --kubeconfig="/path/to/kubeconfig.yml" edit configmap mysql

Using Secrets, Configmaps

Mounted as volumes

Refer to Secret, Configmap name...

...not volume claim name.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      volumes:                            # Mount disks
        - name: "vol-drupal-db"
          secret:                         # Use Secret...
            secretName: "drupal-db"       # ...with this name.
      containers:
        - image: ten7/flight-deck-drupal:latest
          name: web
          ports:
            - containerPort: 80
          volumeMounts:                   # Mount volume at path.
            -  name: "vol-drupal-db"
               mountPath: "/config/drupal-db"
(Scroll down.)

Volumes section

Tells k8s to treat definition as disk

Defined on Deployment, Statefulset

Volume Mounts section

Specifies where to mount volumes in pod

Used by volume claims, Secrets, and Configmaps

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      volumes:
        - name: "vol-flightdeck-db"          # Volume for ConfigMap
          configMap:
            name: "mysql"
        - name: "vol-drupal-db"              # Volume for Secret
          secret:
            secretName: "drupal-db"
      containers:
        - name: "db"
          image: "ten7/flight-deck-db:develop"
          ports:
            - containerPort: 3306
              name: mysql
              protocol: TCP
          volumeMounts:
            - mountPath: "/var/lib/mysql"    # Mount for claim template...
              name: "vol-mysql"
            - mountPath: "/config/mysql"     # ...for ConfigMap...
              name: "vol-flightdeck-db"
            - mountPath: "/config/drupal-db" # ...and for the Secret.
              name: "vol-drupal-db"
  volumeClaimTemplates:
    - metadata:
        name: vol-mysql
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi
(Scroll down.)

Chaining files

Some config files can include other files

Product and container specific

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
data:
  flight-deck-db.yml: |
    mysql_databases:
    - name: "drupal"
    mysql_users:
    - name: "drupal"
      host: "%"
      passwordFile: "/config/drupal-db/drupal-db-password.txt"
      priv: "drupal.*:ALL"

What about Drupal?

  • Create configmap of settings.local.php
  • Customize container entrypoint

Custom entrypoints

Better, does more startup tasks

Requires deeper Docker knowledge

Example

ten7/flight-deck-drupal

github.com/ten7/flight-deck-drupal

Lab #4

  1. Create Secret, Configmap
  2. Update Deployment, Statefulset
  3. Observe, how changes affect pods