Z.S.K.'s Records

Kubernetes学习(podpreset的平替)

PodPreset是一种K8sAPI资源,用于在创建 Pod 时注入其他运行时需要的信息,这些信息包括 secrets、volume mounts、environment variables等,我们可以使用标签选择器来指定某个或某些 Pod,来将 PodPreset 预设信息应用上去。使用 PodPreset 的好处就是我们可以将一些常用 Pod 预设信息配置为模板,这样就不需要显式为每个 Pod 提供所有信息,简化 Pod 初始化配置,还能起到配置统一的效果.

但是,这么好的功能在kubernetes v1.20的版本中居然给移移了,详情issue,从issue可以看出,大家对社区移除podpreset还是比较可惜的
不过,问题也不大,谁还没有一个平替不是, 官方支持的podpreset被移除,那么就用CRD给补回来,好在,早已有人写了一个可直接使用,这对于在集群中已经使用了podpreset功能,又想把k8s版本升级到v1.20之上的人是个福音.

不多说,上链接

deploy

部署也非常简单, 将代码从github拉取下来之后

1
2
make deploy IMG=quay.io/redhat-cop/podpreset-webhook:latest
# quay.io/redhat-cop/podpreset-webhook:latest是官方编译好的镜像

成功后会将相关的资源发布到集群中.

example

需要对某个namespace中的pod统一挂载多个hostpath对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: redhatcop.redhat.io/vlalphal 
kind: PodPreset
metadata:
name: pp-hostpath-dira-dirb
namespace: test
spec:
volumeMounts
- mountPath: /opt/lib/dira
name: dira-volume
readonly: true
- mountPath: /data/dirb
name: dirb-volume
volumes
- name: dira-volume
hostPath:
path: /opt/lib/dira
- name: dirb-volume
hostPath:
path: /data/dirb

将这个yaml发布到集群中即可
这里要注意,该yaml是对test namespace中的所有pod都生效的,如果需要对该namespace某些pod生效,该如何操作呢?可以使用matchLabels,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: redhatcop.redhat.io/vlalphal 
kind: PodPreset
metadata:
name: pp-hostpath-dira-dirb
namespace: test
spec:
selector:
podpreset: enable
volumeMounts
- mountPath: /opt/lib/dira
name: dira-volume
readonly: true
- mountPath: /data/dirb
name: dirb-volume
volumes
- name: dira-volume
hostPath:
path: /opt/lib/dira
- name: dirb-volume
hostPath:
path: /data/dirb

这样的话,需要挂载hostpath的pod添加podpreset: enable label即可.

fix

不过,对于使用label selector时,podpreset-webhook有个bug会导致label不生效,我这里fix了一下,修改了lable生效逻辑
主要代码调整在filterPodpresets逻辑中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// filterPodPresets returns list of PodPresets which match given Pod.
func filterPodPresets(logger logr.Logger, list redhatcopv1alpha1.PodPresetList, pod *corev1.Pod) ([]*redhatcopv1alpha1.PodPreset, error) {
var matchingPPs []*redhatcopv1alpha1.PodPreset

logger.Info("pod.GetName()=" + pod.GetName())

// fixed this
for i, pp := range list.Items {

selector, err := metav1.LabelSelectorAsSelector(&pp.Spec.Selector)
if err != nil {
return nil, fmt.Errorf("label selector conversion failed: %v for selector: %v", pp.Spec.Selector, err)
}
logger.Info("selector.String()=" + selector.String())
logger.Info("labels.Set(pod.Labels).String()=" + labels.Set(pod.Labels).String())

podnamerequiredvalue, found := selector.RequiresExactMatch("podnamerequired")
logger.Info("checking if found RequiresExactMatch podnamerequired")

if found {
logger.Info("podnamerequiredvalue=" + podnamerequiredvalue)
if podnamerequiredvalue != pod.GetName() {
logger.Info("podnamerequiredvalue not matching the pod name:" + pod.GetName() + "!=" + podnamerequiredvalue + "=====> next loop")
continue
} else {
logger.Info("podnamerequiredvalue matching pod:" + pod.GetName() + "==" + podnamerequiredvalue)
// check if general matching
lbls := pod.Labels
lbls["podnamerequired"] = pod.GetName()
logger.Info("labels.Set(lbls).String()=" + labels.Set(lbls).String())
// check if the pod labels match the selector
if !selector.Matches(labels.Set(lbls)) {
logger.Info("!selector.Matches(labels.Set(lbls)=====> next loop")
continue
}
}
} else {
// check if the pod labels match the selector (generic case, no requirements on pod name)
if !selector.Matches(labels.Set(pod.Labels)) {
logger.Info("!selector.Matches(labels.Set(lbls)=====> next loop")
continue
}
}
// fixed this
matchingPPs = append(matchingPPs, &list.Items[i])
}
if len(matchingPPs) == 0 {
logger.Info("######### no final preset for pod=" + pod.GetName())
} else {
for _, ppr := range matchingPPs {
logger.Info("##############final preset for pod=" + pod.GetName() + " is name=" + ppr.GetName())
}
}
return matchingPPs, nil
}

代码修改后重启make deploy即可
最终的代码repo可见podpreset-webhook

完工.

参考文章:

转载请注明原作者: 周淑科,出处https://izsk.me

 wechat
Scan Me To Read on Phone
I know you won't do this,but what if you did?