1 回答

TA貢獻1877條經驗 獲得超1個贊
我不認為您可以使用該Update方法更新單個密鑰,但您當然可以改為使用Patch。這是一個使用 StrategicMergePatch 的示例;它將val2用值替換秘密中的密鑰newval:
package main
import (
"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 方法的示例,但老實說,我覺得示例不是很清楚。
- 1 回答
- 0 關注
- 140 瀏覽
添加回答
舉報