如何解决使用 Mutate 准入控制器修改 deploymnet 中的 ImagePullPolicy
我正在构建一个用于部署的 Mutate 准入控制器,以确保将 Pod 上的 imagePullPolicy 设置为始终使用相应的验证准入控制器。 我注意到我可以在部署(创建时)或副本集上设置它。
代码如下:
package main
import (
"net/http"
"fmt"
"io/ioutil"
"encoding/json"
"os"
// "github.com/golang/glog"
"strconv"
"k8s.io/api/admission/v1"
// corev1 "k8s.io/api/core/v1"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
admissionv1 "k8s.io/api/admission/v1"
)
func isKubeNamespace(ns string) bool {
return ns == metav1.NamespacePublic || ns == metav1.NamespaceSystem
}
type patchOperation struct {
Op string `json:"op"`
Path string `json:"path"`
Value interface{} `json:"value,omitempty"`
}
func (mr *myServerHandler) mutserve(w http.ResponseWriter,r *http.Request) {
var Body []byte
if r.Body != nil {
if data,err := ioutil.ReadAll(r.Body); err == nil {
Body = data
}
}
if len(Body) == 0 {
fmt.Fprintf(os.Stderr,"Unable to retrieve Body from API")
http.Error(w,"Empty Body",http.StatusBadRequest)
}
fmt.Fprintf(os.Stdout,"Received Request")
if r.URL.Path != "/mutate" {
fmt.Fprintf(os.Stderr,"Not a Validate URL Path")
http.Error(w,"Not A Validate URL Path",http.StatusBadRequest)
}
// Read the Response from the Kubernetes API and place it in the Request
arRequest := &v1.AdmissionReview{}
if err := json.Unmarshal(Body,arRequest); err != nil {
fmt.Fprintf(os.Stderr,"Error Unmarsheling the Body request")
http.Error(w,"Error Unmarsheling the Body request",http.StatusBadRequest)
return
}
// if arRequest.Request.Resource.Resource != "pods" {
// fmt.Fprintf(os.Stderr,"Handling the wrong resource")
// http.Error(w,"Handling the wrong resource",http.StatusBadRequest)
// return
// }
raw := arRequest.Request.Object.Raw
replicaset := appsv1.ReplicaSet{}
if !isKubeNamespace(arRequest.Request.Namespace) {
if err := json.Unmarshal(raw,&replicaset); err != nil {
fmt.Fprintf(os.Stderr,"Error,unable to Deserializing Pod")
http.Error(w,unable to Deserializing Pod",http.StatusBadRequest)
return
}
} else {
fmt.Fprintf(os.Stderr,unauthorized Namespace")
http.Error(w,unauthorized Namespace",http.StatusBadRequest)
return
}
containers := replicaset.Spec.Template.Spec.Containers
arResponse := v1.AdmissionReview{
Response: &v1.AdmissionResponse{
UID: arRequest.Request.UID,},}
var patches []patchOperation
for i,container := range containers {
fmt.Fprintf(os.Stdout,"container[%d]= %s imagePullPolicy=%s",i,container.Name,container.ImagePullPolicy)
if containers[i].ImagePullPolicy != "Always" {
if containers[i].ImagePullPolicy == "Never" || containers[i].ImagePullPolicy == "IfNotPresent" {
patches = append(patches,patchOperation{
Op: "replace",Path: "spec/template/spec/containers/[" + strconv.Itoa(i) + "]/ImagePullPolicy",Value: "Always",})
} else {
patches = append(patches,patchOperation{
Op: "Add",Path: "/spec/template/spec/containers/[" + strconv.Itoa(i) + "]/ImagePullPolicy",})
arResponse.Response.Allowed = true
}
}
}
// if pullPolicy != "Always" {
patchBytes,err := json.Marshal(patches)
if err != nil {
fmt.Fprintf(os.Stderr,"Can't encode Patches: %v",err)
http.Error(w,fmt.Sprintf("couldn't encode Patches: %v",err),http.StatusInternalServerError)
return
}
v1JSONPatch := admissionv1.PatchTypeJSONPatch
arResponse.APIVersion = "admission.k8s.io/v1"
arResponse.Kind = arRequest.Kind
arResponse.Response.Allowed = true
arResponse.Response.Patch = patchBytes
arResponse.Response.PatchType = &v1JSONPatch
resp,rErr := json.Marshal(arResponse)
if rErr != nil {
fmt.Fprintf(os.Stderr,"Can't encode response: %v",rErr)
http.Error(w,fmt.Sprintf("couldn't encode response: %v",rErr),http.StatusInternalServerError)
}
if _,wErr := w.Write(resp); wErr != nil {
fmt.Fprintf(os.Stderr,"Can't write response: %v",wErr)
http.Error(w,fmt.Sprintf("cloud not write response: %v",wErr),http.StatusInternalServerError)
}
}
如果我运行“添加”补丁,它最终会将 imagePullPolicy 添加到 always 但如果我想替换它,我会收到以下错误:
“无法创建新的副本集“ubi-kuku-547654586”:发生内部错误:替换操作不适用:文档丢失路径:/spec/template/spec/containers/[0]/ImagePullPolicy:缺少值"
我在创建部署的时候试过了,还是一样的错误
我尝试使用 core/v1 包为单个 pod (/spec/containers/[0]/ImagePullPolicy) 使用相同的结构(不同的路径),并且成功了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。