Overview

A pod preset is an object that injects user-specified information into pods as they are created.

Pod presets is a Technology Preview feature only.

Using pod preset objects you can inject:

Developers only need make sure the pod labels match the label selector on the PodPreset in order to add all that information to the pod. The label on a pod associates the pod with one or more pod preset objects that have a matching label selectors.

Using pod presets, a developer can provision pods without needing to know the details about the services the pod will consume. An administrator can keep configuration items of a service invisible from a developer without preventing the developer from deploying pods. For example, an administrator can create a pod preset that provides the name, user name, and password for a database through a secret and the database port through environment variables. The pod developer only needs to know the label to use to include all the information in pods. A developer can also create pod presets and perform all the same tasks. For example, the developer can create a preset that injects environment variable automatically into multiple pods.

When a pod preset is applied to a pod, OpenShift Origin modifies the pod specification, adding the injectable data and annotating the pod spec to show that it was modified by a pod preset. The annotation is of the form:

podpreset.admission.kubernetes.io/<pod-preset name>: `resource version`

In order to use pod presets in your cluster:

  • An administrator must enable the pod preset admission controller plug-in through the /etc/origin/master/master-config.yaml;

  • The pod preset author must enable the API type settings.k8s.io/v1alpha1/podpreset through the pod preset and add injectable information to the pod preset.

If the pod creation encounters an error, the pod is created without any injected resources from the pod preset.

You can exclude specific pods from being altered by any pod preset mutations using the podpreset.admission.kubernetes.io/exclude: "true" parameter in the pod specification. See the example pod specification below.

The Pod Preset feature is available only if the Service Catalog has been installed.

Sample pod preset object
kind: PodPreset
apiVersion: settings.k8s.io/v1alpha1 (1)
metadata:
  name: allow-database (2)
spec:
  selector:
    matchLabels:
      role: frontend (3)
  env:
    - name: DB_PORT (4)
      value: "6379" (4)
  envFrom:
    - configMapRef: (5)
      name: etcd-env-config
    - secretKeyRef: (6)
      name: test-secret
  volumeMounts: (7)
    - mountPath: /cache
      name: cache-volume
  volumes: (8)
    - name: cache-volume
      emptyDir: {}
1 Specify the settings.k8s.io/v1alpha1 API.
2 Name of the pod preset. This name is used in the pod annotation.
3 A label selector that matches the label in the pod specification.
4 Creates an environment variable to pass to the container.
5 Adds a ConfigMap to the pod specification.
6 Adds a secrets object to the pod specification.
7 Specifies where external storage volumes should be mounted within the container.
8 Defines storage volumes that are available to the container(s).
Sample pod specification
apiVersion: v1
kind: Pod
metadata:
  name: website
  labels:
    app: website
    role: frontend (1)
spec:
  containers:
    - name: website
      image: ecorp/website
      ports:
        - containerPort: 80
1 A label to match the label selector in the pod preset.
Sample pod specification after a pod preset
apiVersion: v1
kind: Pod
metadata:
  name: website
  labels:
    app: website
    role: frontend
  annotations:
    podpreset.admission.kubernetes.io/allow-database: "resource version" (1)
spec:
  containers:
    - name: website
      image: ecorp/website
      volumeMounts: (2)
        - mountPath: /cache
          name: cache-volume
      ports:
        - containerPort: 80
      env: (3)
        - name: DB_PORT
          value: "6379"
      envFrom: (4)
        - configMapRef:
          name: etcd-env-config
        - secretKeyRef:
          name: test-secret
  volumes: (5)
    - name: cache-volume
      emptyDir: {}
1 The annotation added to show a pod preset was injected, if the pod specification was not configured to prevent the modification.
2 The volume mount is added to the pod.
3 The environment variable is added to the pod.
4 The ConfigMap and secrets object added to the pod.
5 The volume mount is added to the pod.
Sample pod specification to exclude the pod from pod preset
apiVersion: v1
kind: Pod
metadata:
  name: no-podpreset
  labels:
    app: website
    role: frontend
  annotations:
    podpreset.admission.kubernetes.io/exclude: "true" (1)
spec:
  containers:
    - name: hello-pod
      image: docker.io/ocpqe/hello-pod
1 Add this parameter to prevent this pod from being injected by the pod preset feature.

Creating Pod Presets

The following example demonstrates how to create and use pod presets.

Add the Admission Controller

An administrator can check the /etc/origin/master/master-config.yaml file to make sure the pod preset admission controller plug-in is present. If the admission controller is not present, add the plug-in using the following:

admissionConfig:
  pluginConfig:
    PodPreset:
      configuration:
        kind: DefaultAdmissionConfig
        apiVersion: v1
        disable: false

Then, restart the OpenShift Origin services:

# systemctl restart origin-master-api origin-master-controllers
Create the Pod Preset

An administrator or developer creates the pod preset with the settings.k8s.io/v1alpha1 API, the information to inject, and a label selector to match with the pods:

kind: PodPreset
apiVersion: settings.k8s.io/v1alpha1
metadata:
  name: allow-database
spec:
  selector:
    matchLabels:
      role: frontend
  env:
    - name: DB_PORT
      value: "6379"
  volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
    - name: cache-volume
      emptyDir: {}
Create the Pod

The developer creates the pod with a label that matches the label selector in the pod preset:

For more information on pod creation, see Pods and Services.

  1. Create a standard pod specification with a label that matches the label selector in the pod preset:

    apiVersion: v1
    kind: Pod
    metadata:
      name: website
      labels:
        app: website
        role: frontend
    spec:
      containers:
        - name: website
          image: ecorp/website
          ports:
            - containerPort: 80
  2. Create the pod:

    $ oc create -f pod.yaml
  3. Check the pod spec after creation:

    $ oc get pod website -o yaml
    
    apiVersion: v1
    kind: Pod
    metadata:
      name: website
      labels:
        app: website
        role: frontend
      annotations:
        podpreset.admission.kubernetes.io/allow-database: "resource version" (1)
    spec:
      containers:
        - name: website
          image: ecorp/website
          volumeMounts: (1)
            - mountPath: /cache
              name: cache-volume
          ports:
            - containerPort: 80
          env: (1)
            - name: DB_PORT
              value: "6379"
      volumes:
        - name: cache-volume
          emptyDir: {}
    1 The annotation is present and the container storage and environment variables are injected.

Using Multiple Pod Presets

You can use multiple pod presets to inject multiple pod injection policies.

  • Make sure the pod preset admission controller plug-in is enabled.

  • Create a pod preset, similar to the following, with environment variables, mount points, and/or storage volumes:

    kind: PodPreset
    apiVersion: settings.k8s.io/v1alpha1
    metadata:
      name: allow-database
    spec:
      selector:
        matchLabels:
          role: frontend (1)
      env:
        - name: DB_PORT
          value: "6379"
      volumeMounts:
        - mountPath: /cache
          name: cache-volume
      volumes:
        - name: cache-volume
          emptyDir: {}
    1 Label selector to match the pod labels.
  • Create a second pod preset, similar to the following:

    kind: PodPreset
    apiVersion: settings.k8s.io/v1alpha1
    metadata:
      name: proxy
    spec:
      selector:
        matchLabels:
          role: frontend (1)
      volumeMounts:
        - mountPath: /etc/proxy/configs
          name: proxy-volume
      volumes:
        - name: proxy-volume
          emptyDir: {}
    1 Label selector to match the pod labels.
  • Create a standard pod specification:

    apiVersion: v1
    kind: Pod
    metadata:
      name: website
      labels:
        app: website
        role: frontend (1)
    spec:
      containers:
        - name: website
          image: ecorp/website
          ports:
            - containerPort: 80
    1 Label to match both pod preset label selectors.
  • Create the pod:

    $ oc create -f pod.yaml
  • Check the pod spec after creation:

    apiVersion: v1
    kind: Pod
    metadata:
      name: website
      labels:
        app: website
        role: frontend
      annotations:
        podpreset.admission.kubernetes.io/allow-database: "resource version" (1)
        podpreset.admission.kubernetes.io/proxy: "resource version" (1)
    spec:
      containers:
        - name: website
          image: ecorp/website
          volumeMounts:
            - mountPath: /cache
              name: cache-volume
            - mountPath: /etc/proxy/configs
              name: proxy-volume
          ports:
            - containerPort: 80
          env:
            - name: DB_PORT
              value: "6379"
      volumes:
        - name: cache-volume
          emptyDir: {}
        - name: proxy-volume
          emptyDir: {}
    1 Annotation indicating that multiple pod presets were injected.

Deleting Pod Presets

You can delete a pod preset using the following command:

$ oc delete podpreset <name>

For example:

$ oc delete podpreset allow-database

podpreset "allow-database" deleted