k8s: admission demo(准入控制)
k8s admission demo,准入控制用例。
1. 背景
k8s中在创建资源前需要校验,修改pod的一些属性,优雅的像java的拦截器,过滤器一样工作,需要加准入控制。概念去官网搜,不占用篇幅。本文主要讲例子,学技术还是脚踏实地作出demo。
2. 资料
本文参考github上demo,可以自己找些例子,我主要讲解:GitHub - stackrox/admission-controller-webhook-demo: Kubernetes admission controller webhook example
3. 项目讲解
项目结构还是很简单
3.1 main.go
cmd/webhook-server/main.go
前两行是密钥对路径。
下面创建server,路径是mutate,端口是8443,加载密钥对。
处理函数是admitFuncHandler参数是applySecurityDefaults这也是个函数,真正的处理在applySecurityDefaults逻辑写在这里,其他都是框架。
看下函数实现
func applySecurityDefaults(req *admission.AdmissionRequest) ([]patchOperation, error) {
// This handler should only get called on Pod objects as per the MutatingWebhookConfiguration in the YAML file.
// However, if (for whatever reason) this gets invoked on an object of a different kind, issue a log message but
// let the object request pass through otherwise.
if req.Resource != podResource {
log.Printf("expect resource to be %s", podResource)
return nil, nil
}
// Parse the Pod object.
raw := req.Object.Raw
pod := corev1.Pod{}
if _, _, err := universalDeserializer.Decode(raw, nil, &pod); err != nil {
return nil, fmt.Errorf("could not deserialize pod object: %v", err)
}
// Retrieve the `runAsNonRoot` and `runAsUser` values.
var runAsNonRoot *bool
var runAsUser *int64
if pod.Spec.SecurityContext != nil {
runAsNonRoot = pod.Spec.SecurityContext.RunAsNonRoot
runAsUser = pod.Spec.SecurityContext.RunAsUser
}
// Create patch operations to apply sensible defaults, if those options are not set explicitly.
var patches []patchOperation
if runAsNonRoot == nil {
patches = append(patches, patchOperation{
Op: "add",
Path: "/spec/securityContext/runAsNonRoot",
// The value must not be true if runAsUser is set to 0, as otherwise we would create a conflicting
// configuration ourselves.
Value: runAsUser == nil || *runAsUser != 0,
})
if runAsUser == nil {
patches = append(patches, patchOperation{
Op: "add",
Path: "/spec/securityContext/runAsUser",
Value: 1234,
})
}
} else if *runAsNonRoot == true && (runAsUser != nil && *runAsUser == 0) {
// Make sure that the settings are not contradictory, and fail the object creation if they are.
return nil, errors.New("runAsNonRoot specified, but runAsUser set to 0 (the root user)")
}
return patches, nil
}
主要业务就是判断pod里面的属性,配置的RunAsNonRoot以及RunAsUser,具体是啥可以不用了解。只要知道这个函数加自己的处理逻辑就好,拿到请求序列化的数据,反序列化成pod对象。然后判断pod里面的属性即可。
里面涉及了创建patches
自己去发现这个path路径的规则。
如果是其他属性自己拼写,假如是容器里面的,就应该是/spec/containers/xxx。这里只是拿pod属性举例,如果是deployment或其他资源,自己加路径,/spec/template/spec/xxx
3.2 deploy.sh
调用generate-keys.sh生成密钥对。
创建webhook-demo命名空间。
根据密钥对创建secret,启动webhook的时候挂载进去。
再看一下deployment.yaml.template
这里会被sed把密钥替换进去。
最终效果
部署好了之后
查询部署的admission的pod log
自己修改代码加一些log,但是要记住,Makefile构建出自己的镜像。
我其实把IMAGE镜像名字换了。可以换成自己的,上面截图没有替换,需要自己换一下。然后在deployment中改一下image
换成自己的。
work了。
说明已经生效了。看看创建的pod,效果。
例子中给了
其实如果你想控制其他的资源,配置这里。例如deploy,sts,vcjob
更多推荐
所有评论(0)