冉冉说
我不认为您可以使用该Update方法更新单个密钥,但您当然可以改为使用Patch。这是一个使用 StrategicMergePatch 的示例;它将val2用值替换秘密中的密钥newval:package mainimport ( "context" "encoding/json" "flag" "fmt" "path/filepath" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir")func main() { var kubeconfig *string var namespace *string var secretname *string namespace = flag.String("namespace", "", "namespace of secret") secretname = flag.String("name", "", "name of secret") if home := homedir.HomeDir(); home != "" { kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") } else { kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") } flag.Parse() if *namespace == "" { panic(fmt.Errorf("you must specify a namespace")) } if *secretname == "" { panic(fmt.Errorf("you must specify a secret name")) } config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) if err != nil { panic(err) } clientset, err := kubernetes.NewForConfig(config) if err != nil { panic(err) } secretClient := clientset.CoreV1().Secrets(*namespace) ctx := context.TODO() updSec := v1.Secret{ Data: map[string][]byte{ "val2": []byte("newval"), }, } payloadBytes, err := json.Marshal(updSec) if err != nil { panic(err) } if _, err = secretClient.Patch(ctx, *secretname, types.StrategicMergePatchType, payloadBytes, metav1.PatchOptions{}); err != nil { panic(err) } // Fetch updated secret sec, err := secretClient.Get(ctx, *secretname, metav1.GetOptions{}) if err != nil { panic(err) } secJson, err := json.MarshalIndent(sec, "", " ") if err != nil { panic(err) } fmt.Print(string(secJson))}例如,如果我创建这样的秘密:kubectl create secret generic \ --from-literal val1=key1 \ --from-literal val2=key2 example然后像这样运行上面的代码:go run main.go -namespace default -name example该代码将输出更新密码。查看该data部分,我们看到: "data": { "val1": "a2V5MQ==", "val2": "bmV3dmFs" },如果我们解码,val2我们会看到:$ kubectl get secret example -o json | jq '.data.val2|@base64d'"newval"使用运营商 SDK如果您使用的是 Operator SDK,则可以Update在第一次读取现有值时使用,如下所示: // Read the existing secret secret := &corev1.Secret{} if err := r.Get(ctx, req.NamespacedName, secret); err != nil { panic(err) } // Check if it needs to be modified val, ok := secret.Data["val2"] // If yes, update the secret with a new value and then write // the entire object back with Update if !ok || !bytes.Equal(val, []byte("val2")) { ctxlog.Info("needs update", "secret", secret) secret.Data["val2"] = []byte("newval") if err := r.Update(ctx, secret); err != nil { panic(err) } }Patch如果您只想提交部分更新,则可以使用该方法: if !ok || !bytes.Equal(val, []byte("val2")) { ctxlog.Info("needs update", "secret", secret) newVal := corev1.Secret{ Data: map[string][]byte{ "val2": []byte("newval"), }, } patch, err := json.Marshal(newVal) if err != nil { panic(err) } if err := r.Client.Patch(ctx, secret, client.RawPatch(types.StrategicMergePatchType, patch)); err != nil { panic(err) } }这与前面的示例几乎相同。文档中有使用 client.Patch 方法的示例,但老实说,我觉得示例不是很清楚。