在Pod创建时可以使用podpreset对象注入某些信息到里面。这个信息可以包含secrets,volumes,voluems mounts和环境变量。
PodPreset概述
Pod Preset是API资源,在Pod创建时可以使用它将额外的运行时需求注入到里面。可以使用标签选择器指定Pod Preset用户相应的Pod。
使用PodPreset允许pod模板不必为每个pod显式的设置信息。这样pod模板的作者不必知道该服务的所有的详细信息。
Admission Control
Admission control是Kubernetes如何对进入Pod的创建请求应用于Pod Presets。当一个Pod创建请求发生,系统发生了如下操作:
1.检索所有可用的PodPresets。
2.pod开始创建检索PodPreset标签选择器。
3.尝试将PodPreset定义的各种资源合并到正在创建的Pod里面。
4.出现错误时,在Pod上抛出一个合并错误的时间记录,并从PodPreset创建一个没有任何注入资源的pod。
表现
当PodPreset被应用于一个或者多个Pod,Kubernetes修改pod的spec。对于Env,EnvFrom和VolumeMounts,Kubernetes修改了Pod里面所有容器的spec;对于Volume Kubernetes修改了Pod Spec。
Kubernetes注解生成修改pod spec,以显示是通过PodPreset修改的。注解如下:
podpreset.admission.kubernetes.io/": ""
开启Pod Preset
为了在集群里面使用Pod Presets必须保证一下几条:
1.开启api类型 settings.k8s.io/v1alpha1/podpreset
2.在admission controller里面开启PodPreset
3.定义自己的pod presets
创建一个Pod Preset
这是一个简单的例子展示了如何通过Pod注入策略修改Pod spec。
用户提交pod spect:
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: ecorp/website
ports:
- containerPort: 80
Pod Preset例子:
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:
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和ConfigMap的例子:
这是一个例子,显示如何通过ConfigMap定义环境变量修改pod spec。
用户提交的pod spec:
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: ecorp/website
ports:
- containerPort: 80
提交的ConfigMap:
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"
Pod Preset例子:
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 spect:
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和Pod Spec例子
下面的例子展示了通过pod注入策略只是修改了pod spec。
用户提交的RelicaSet:
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
提交的Pod Preset:
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:
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: {}
多个PodPreset的例子
这是一个例子展示通过多个pod注入策略修改pod spec.
用户提交pod spec:
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
- name: website
image: ecorp/website
ports:
- containerPort: 80
Pod Preset例子:
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 Preset:
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:
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: {}
Pod和Pod Preset冲突
这是一个例子通过Pod注入策略修改pod spec如果和pod本身冲突则不修改。
提交的pod spec:
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
Pod Preset:
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没有修改因为它们冲突了:
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
删除Pod Preset
如果不需要pod preset可以用kubectl删除它:
$ kubectl delete podpreset allow-database
podpreset "allow-database" deleted