From e87b393ba3302241d887980d145e8e1595aa0ff6 Mon Sep 17 00:00:00 2001 From: Jess Frazelle Date: Tue, 14 Mar 2017 10:54:21 -0700 Subject: [PATCH] Add pod preset docs Signed-off-by: Jess Frazelle --- _data/reference.yml | 1 + docs/user-guide/pod-preset/OWNERS | 2 + docs/user-guide/pod-preset/index.md | 544 ++++++++++++++++++++++++++++ 3 files changed, 547 insertions(+) create mode 100644 docs/user-guide/pod-preset/OWNERS create mode 100644 docs/user-guide/pod-preset/index.md diff --git a/_data/reference.yml b/_data/reference.yml index 0d7dc82db6..41ee51ff92 100644 --- a/_data/reference.yml +++ b/_data/reference.yml @@ -174,6 +174,7 @@ toc: - docs/user-guide/petset.md - docs/user-guide/pods/index.md - docs/user-guide/pod-security-policy/index.md + - docs/user-guide/pod-preset/index.md - docs/user-guide/replicasets.md - docs/user-guide/replication-controller/index.md - docs/admin/resourcequota/index.md diff --git a/docs/user-guide/pod-preset/OWNERS b/docs/user-guide/pod-preset/OWNERS new file mode 100644 index 0000000000..14223284cb --- /dev/null +++ b/docs/user-guide/pod-preset/OWNERS @@ -0,0 +1,2 @@ +assignees: +- jessfraz diff --git a/docs/user-guide/pod-preset/index.md b/docs/user-guide/pod-preset/index.md new file mode 100644 index 0000000000..75e8ab2c50 --- /dev/null +++ b/docs/user-guide/pod-preset/index.md @@ -0,0 +1,544 @@ +--- +assignees: +- jessfraz +title: Pod Preset +--- + +You can use a `podpreset` object to inject certain information into pods at creation +time. This information can include secrets, volumes, volume mounts, and environment +variables. + +See [PodPreset proposal](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/pod-preset.md) for more information. + +* TOC +{:toc} + +## What is a Pod Preset? + +A _Pod Preset_ is an API resource that you can use to inject additional runtime +requirements into a Pod at creation time. You use label selectors to specify +the Pods to which a given Pod Preset applies. Check out more information on [label +selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). + +Using a Pod Preset allows pod template authors to not have to explicitly set +information for every pod. This way, authors of pod templates consuming a +specific service do not need to know all the details about that service. + +## Admission Control + +_Admission control_ is how Kubernetes applies Pod Presets to incoming pod +creation requests. When a pod creation request occurs, the system does the +following: + +1. Retrieve all `PodPresets` available for use. +1. Match the label selector of the `PodPreset` to the pod being created. +1. Attempt to merge the various defined resources for the `PodPreset` into the + Pod being created. +1. On error, throw an event documenting the merge error on the pod, and create + the pod _without_ any injected resources from the `PodPreset`. + +### Behavior + +When a `PodPreset` is applied to one or more Pods, Kubernetes modifies the pod +spec. For changes to `Env`, `EnvFrom`, and `VolumeMounts`, Kubernetes modifies +the container spec for all containers in the Pod; for changes to Volume, +Kubernetes modifies the Pod Spec. + +Kubernetes annotates the resulting modified pod spec to show that it was +modified by a `PodPreset`. The annotation is of the form +`podpreset.admission.kubernetes.io/": ""`. + + +## Enabling Pod Preset + +In order to use Pod Presets in your cluster you must ensure the +following + +1. You have enabled the api type `settings.k8s.io/v1alpha1/podpreset` +1. You have enabled the admission controller `PodPreset` +1. You have defined your pod presets + +## Creating a Pod Preset + +### Simple Pod Spec Example + +This is a simple example to show how a Pod spec is modified by the Pod +Injection Policy. + +**User submitted pod spec:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend +spec: + containers: + - name: website + image: ecorp/website + ports: + - containerPort: 80 +``` + +**Example Pod Preset:** + +```yaml +kind: PodPreset +apiVersion: settings.k8s.io/v1alpha1 +metadata: + name: allow-database + namespace: myns +spec: + selector: + matchLabels: + role: frontend + env: + - name: DB_PORT + value: "6379" + volumeMounts: + - mountPath: /cache + name: cache-volume + volumes: + - name: cache-volume + emptyDir: {} +``` + +**Pod spec after admission controller:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend + annotations: + podpreset.admission.kubernetes.io/allow-database: "resource version" +spec: + containers: + - name: website + image: ecorp/website + volumeMounts: + - mountPath: /cache + name: cache-volume + ports: + - containerPort: 80 + env: + - name: DB_PORT + value: "6379" + volumes: + - name: cache-volume + emptyDir: {} +``` + +### Pod Spec with `ConfigMap` Example + +This is an example to show how a Pod spec is modified by the Pod Injection +Policy that defines a `ConfigMap` for Environment Variables. + +**User submitted pod spec:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend +spec: + containers: + - name: website + image: ecorp/website + ports: + - containerPort: 80 +``` + +**User submitted `ConfigMap`:** + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: etcd-env-config +data: + number_of_members: "1" + initial_cluster_state: new + initial_cluster_token: DUMMY_ETCD_INITIAL_CLUSTER_TOKEN + discovery_token: DUMMY_ETCD_DISCOVERY_TOKEN + discovery_url: http://etcd_discovery:2379 + etcdctl_peers: http://etcd:2379 + duplicate_key: FROM_CONFIG_MAP + REPLACE_ME: "a value" +``` + +**Example Pod Preset:** + +```yaml +kind: PodPreset +apiVersion: settings.k8s.io/v1alpha1 +metadata: + name: allow-database + namespace: myns +spec: + selector: + matchLabels: + role: frontend + env: + - name: DB_PORT + value: 6379 + - name: duplicate_key + value: FROM_ENV + - name: expansion + value: $(REPLACE_ME) + envFrom: + - configMapRef: + name: etcd-env-config + volumeMounts: + - mountPath: /cache + name: cache-volume + - mountPath: /etc/app/config.json + readOnly: true + name: secret-volume + volumes: + - name: cache-volume + emptyDir: {} + - name: secret-volume + secretName: config-details +``` + +**Pod spec after admission controller:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend + annotations: + podpreset.admission.kubernetes.io/allow-database: "resource version" +spec: + containers: + - name: website + image: ecorp/website + volumeMounts: + - mountPath: /cache + name: cache-volume + - mountPath: /etc/app/config.json + readOnly: true + name: secret-volume + ports: + - containerPort: 80 + env: + - name: DB_PORT + value: "6379" + - name: duplicate_key + value: FROM_ENV + - name: expansion + value: $(REPLACE_ME) + envFrom: + - configMapRef: + name: etcd-env-config + volumes: + - name: cache-volume + emptyDir: {} + - name: secret-volume + secretName: config-details +``` + +### ReplicaSet with Pod Spec Example + +The following example shows that only the pod spec is modified by the Pod +Injection Policy. + +**User submitted ReplicaSet:** + +```yaml +apiVersion: settings.k8s.io/v1alpha1 +kind: ReplicaSet +metadata: + name: frontend +spec: + replicas: 3 + selector: + matchLabels: + tier: frontend + matchExpressions: + - {key: tier, operator: In, values: [frontend]} + template: + metadata: + labels: + app: guestbook + tier: frontend + spec: + containers: + - name: php-redis + image: gcr.io/google_samples/gb-frontend:v3 + resources: + requests: + cpu: 100m + memory: 100Mi + env: + - name: GET_HOSTS_FROM + value: dns + ports: + - containerPort: 80 +``` + +**Example Pod Preset:** + +```yaml +kind: PodPreset +apiVersion: settings.k8s.io/v1alpha1 +metadata: + name: allow-database + namespace: myns +spec: + selector: + matchLabels: + tier: frontend + env: + - name: DB_PORT + value: "6379" + volumeMounts: + - mountPath: /cache + name: cache-volume + volumes: + - name: cache-volume + emptyDir: {} +``` + +**Pod spec after admission controller:** + +```yaml +kind: Pod + metadata: + labels: + app: guestbook + tier: frontend + annotations: + podpreset.admission.kubernetes.io/allow-database: "resource version" + spec: + containers: + - name: php-redis + image: gcr.io/google_samples/gb-frontend:v3 + resources: + requests: + cpu: 100m + memory: 100Mi + volumeMounts: + - mountPath: /cache + name: cache-volume + env: + - name: GET_HOSTS_FROM + value: dns + - name: DB_PORT + value: "6379" + ports: + - containerPort: 80 + volumes: + - name: cache-volume + emptyDir: {} +``` + +### Multiple PodPreset Example + +This is an example to show how a Pod spec is modified by multiple Pod +Injection Policies. + +**User submitted pod spec:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend +spec: + containers: + - name: website + image: ecorp/website + ports: + - containerPort: 80 +``` + +**Example Pod Preset:** + +```yaml +kind: PodPreset +apiVersion: settings.k8s.io/v1alpha1 +metadata: + name: allow-database + namespace: myns +spec: + selector: + matchLabels: + role: frontend + env: + - name: DB_PORT + value: "6379" + volumeMounts: + - mountPath: /cache + name: cache-volume + volumes: + - name: cache-volume + emptyDir: {} +``` + +**Another Pod Preset:** + +```yaml +kind: PodPreset +apiVersion: settings.k8s.io/v1alpha1 +metadata: + name: proxy + namespace: myns +spec: + selector: + matchLabels: + role: frontend + volumeMounts: + - mountPath: /etc/proxy/configs + name: proxy-volume + volumes: + - name: proxy-volume + emptyDir: {} +``` + +**Pod spec after admission controller:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend + annotations: + podpreset.admission.kubernetes.io/allow-database: "resource version" + podpreset.admission.kubernetes.io/proxy: "resource version" +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: {} +``` + +### Conflict Example + +This is a example to show how a Pod spec is not modified by the Pod Injection +Policy when there is a conflict. + +**User submitted pod spec:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend +spec: + containers: + - name: website + image: ecorp/website + volumeMounts: + - mountPath: /cache + name: cache-volume + ports: + volumes: + - name: cache-volume + emptyDir: {} + - containerPort: 80 +``` + +**Example Pod Preset:** + +```yaml +kind: PodPreset +apiVersion: settings.k8s.io/v1alpha1 +metadata: + name: allow-database + namespace: myns +spec: + selector: + matchLabels: + role: frontend + env: + - name: DB_PORT + value: "6379" + volumeMounts: + - mountPath: /cache + name: other-volume + volumes: + - name: other-volume + emptyDir: {} +``` + +**Pod spec after admission controller will not change because of the conflict:** + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: website + labels: + app: website + role: frontend +spec: + containers: + - name: website + image: ecorp/website + volumeMounts: + - mountPath: /cache + name: cache-volume + ports: + volumes: + - name: cache-volume + emptyDir: {} + - containerPort: 80 +``` + +**If we run `kubectl describe...` we can see the event:** + +``` +$ kubectl describe ... +.... +Events: + FirstSeen LastSeen Count From SubobjectPath Reason Message + Tue, 07 Feb 2017 16:56:12 -0700 Tue, 07 Feb 2017 16:56:12 -0700 1 {podpreset.admission.kubernetes.io/allow-database } conflict Conflict on pod preset. Duplicate mountPath /cache. +``` + +## Deleting a Pod Preset + +Once you don't need a pod preset anymore, you can delete it with `kubectl`: + +```shell +$ kubectl delete podpreset allow-database +podpreset "allow-database" deleted +``` +