-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updates to service injection policy proposal
Signed-off-by: Jess Frazelle <acidburn@google.com>
- Loading branch information
Showing
2 changed files
with
279 additions
and
65 deletions.
There are no files selected for viewing
279 changes: 279 additions & 0 deletions
279
contributors/design-proposals/service-injection-policy.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
# Service Injection Policy | ||
|
||
## Abstract | ||
|
||
Describes a policy resource that allows loose coupling from services to the pods | ||
that consume them. | ||
|
||
## Motivation | ||
|
||
Consuming a service involves more than just connectivity. In addition to | ||
coordinates to reach the service, credentials and non-secret configuration | ||
parameters are typically needed to use the service. The primitives for this | ||
already exist, but a gap exists where loose coupling is desired: it should be | ||
possible to inject pods with the information they need to use a service on a | ||
service-by-service basis, without the pod authors having to incorporate the | ||
information into every pod spec where it is needed. | ||
|
||
## Constraints and Assumptions | ||
|
||
1. New mechanisms must be made to work with controllers such as deployments and | ||
replicasets that create pods. Existing controllers that create pods should | ||
recreate their pods when a new Service Injection Policy is added that would | ||
effect them. | ||
|
||
## Use Cases | ||
|
||
1. As a user, I want to be able to describe a way that pods should be injected | ||
with the information to consume a particular service in a loosely-coupled | ||
way, so that I can concisely model the information about how the service | ||
should be consumed without altering every consuming pod spec. | ||
|
||
### Loose coupling between services and their consumers | ||
|
||
Using a Service Injection Policy allows pod authors to not have to explicitly | ||
set information for every pod. The information will be injected based off the | ||
policy's `Selector`. | ||
|
||
## Proposed Changes | ||
|
||
### ServiceInjectionPolicy API object | ||
|
||
```go | ||
type ServiceInjectionPolicy struct { | ||
unversioned.TypeMeta | ||
ObjectMeta | ||
|
||
Spec ServiceInjectionPolicySpec | ||
} | ||
|
||
type ServiceInjectionPolicySpec struct { | ||
// Service is a reference to the service being injected (optional, immutable). | ||
Service string | ||
// Selector defines which Pods should be modified (required, immutable). | ||
Selector *unversioned.LabelSelector | ||
// Env defines the collection of EnvVar to inject (optional, mutable). | ||
Env []EnvVar | ||
// EnvFrom defines the collection of EnvVarFrom to inject (optional, mutable). | ||
EnvFrom []EnvVarFrom | ||
// Volumes defines the collection of Volume to inject (optional, mutable). | ||
Volumes []Volume | ||
// VolumeMounts defines the collection of VolumeMount to inject (optional, mutable). | ||
VolumeMounts []VolumeMount | ||
} | ||
``` | ||
|
||
### AdmissionControl Plugin: ServiceInjectionPolicy | ||
|
||
The **ServiceInjectionPolicy** plugin introspects all incoming pod creation | ||
requests and injects the pod based off a `LabelSelector` with the desired | ||
attributes. | ||
|
||
#### Behavior | ||
|
||
This will modify the containers in the pod spec. The supported changes to | ||
`Env`, `EnvFrom`, and `VolumeMounts` apply to the container spec for | ||
all containers in the pod with the specified matching `Selector`. The | ||
changes to `Volumes` apply to the pod spec for all pods matching `Selector`. | ||
|
||
*Why modify all containers in a pod?* | ||
|
||
Currently there is no concept of labels on specific containers in a pod which | ||
would be necessary for per-container service injections. We could add labels | ||
for specific containers which would allow this and be the best solution to not | ||
injecting all. Container labels have been discussed various times through | ||
multiple issues and proposals, which all congregate to this thread on the | ||
[kubernetes-sig-node mailing | ||
list](https://groups.google.com/forum/#!topic/kubernetes-sig-node/gijxbYC7HT8). | ||
|
||
Other solutions include basing the container to inject based off | ||
matching its name to another field in the `ServiceInjectionPolicy` spec, but | ||
this would not scale well and would cause annoyance with configuration | ||
management. | ||
|
||
The resultant modified pod spec will be annotated to show that it was modified by | ||
the `ServiceInjectionPolicy`. | ||
|
||
#### Optional Behavior with implicit injections | ||
|
||
The above described the behavior for explicitly defining what should be | ||
injected into a pod. | ||
|
||
But a helper has been discussed to automatically fill in the | ||
`ServiceInjectionSpec` values based off annotations on a service defining the | ||
resources you need. This would be similar to the functionality ConfigMaps and | ||
Secrets. | ||
|
||
## Examples | ||
|
||
### Simple Pod Spec Example | ||
|
||
This is a simple example to show how a Pod spec is modified by the Service | ||
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 service injection policy:** | ||
```yaml | ||
kind: ServiceInjectionPolicy | ||
apiVersion: extensions/v1beta1 | ||
metadata: | ||
name: allow-database | ||
namespace: myns | ||
spec: | ||
service: db | ||
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: | ||
serviceinjectionpolicy.k8s.io/db: allow-database | ||
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: {} | ||
``` | ||
### ReplicaSet with Pod Spec Example | ||
The following example shows that only the pod spec is modified by the Service | ||
Injection Policy. | ||
**User submitted ReplicaSet:** | ||
```yaml | ||
apiVersion: extensions/v1beta1 | ||
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 service injection policy:** | ||
```yaml | ||
kind: ServiceInjectionPolicy | ||
apiVersion: extensions/v1beta1 | ||
metadata: | ||
name: allow-database | ||
namespace: myns | ||
spec: | ||
service: db | ||
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: | ||
serviceinjectionpolicy.k8s.io/db: allow-database | ||
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: {} | ||
``` |
This file was deleted.
Oops, something went wrong.