我想創建一個簡單的 k8s cronjob 來保持 gcp 身份令牌的新鮮度。
一個我無法解決的相對簡單的問題
給定的
kubectl patch secret token-test --type json -p=<< END
[
{
"op": "replace",
"path": "/data/token.jwt",
"value": "$(gcloud auth print-identity-token | base64 )"
}
]
END
我希望這適用于 kubectl patch secret token-test --type json -p=$(printf "'%s'" "$json")
我嘗試了很多變體,奇怪的是,如果我粘貼 printf 的 heredoc 插入的結果,它會起作用。但是我所有的努力都失敗了(也在一行上嘗試了一個 json 檔案)
$ kubectl patch secret token-test --type json -p=$(printf "'%s'" "$json")
error: unable to parse "'[{": yaml: found unexpected end of stream
而這實際上有效:
printf "'%s'" "$json"|pbcopy
kubectl patch secret sudo-token-test --type json -p '[{ "op": "replace","path": "/data/token.jwt","value": "ZX...Zwo="}]'
secret/token-test patched
當它失敗時,我無法理解有什么不同。我知道 bash 在處理字串時有點棘手,但我不確定這是 bash 問題還是 kubectl 中的問題。
uj5u.com熱心網友回復:
這是一種稍微不同的方法,但是,怎么樣:
printf "foo" > test
kubectl create secret generic freddie \
--namespace=default \
--from-file=./test
kubectl get secret/freddie \
--namespace=default \
--output=jsonpath="{.data.test}" \
| base64 --decode
foo
X="$(printf "bar" | base64)"
kubectl patch secret/freddie \
--namespace=default \
--patch="{\"data\":{\"test\":\"${X}\"}}"
kubectl get secret/freddie \
--namespace=default \
--output=jsonpath="{.data.test}" \
| base64 --decode
bar
請注意,
gcloud auth print-identity-token以這種方式使用您的用戶 ( ) 憑據不是最佳做法。首選服務帳戶。服務帳戶旨在用于機器(而不是人工)身份驗證,它們可以更輕松地撤銷。用戶憑據授予持有者用戶帳戶的所有權力(這可能是廣泛的)。
有一種可移植的替代方法,您可以在其中從服務帳戶密鑰創建 Kubernetes 機密:
kubectl create secret generic your-key \ --from-file=your-key.json=/path/to/your-key.json有一個很酷的孩子,他們主要使用 GKE 方法,稱為Workload Identity
uj5u.com熱心網友回復:
$ json='[{ "op": "replace","path": "/data/token.jwt","value": "'"$(gcloud auth print-identity-token | base64 )"'"}]'
$ kubectl patch secret token-test --type json -p="$json"
secret/token-test patched
通過在heredoc中附加插入的字串,這解決了。仍然不知道為什么其他方法失敗了。
編輯:
最終結果是洗掉 kubectl 并使用 curl 代替,因為它更適合 docker 鏡像。
# Point to the internal API server hostname
APISERVER=https://kubernetes.default.svc
# Path to ServiceAccount token
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
# Read this Pod's namespace
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
# Read the ServiceAccount bearer token
TOKEN=$(cat ${SERVICEACCOUNT}/token)
# Reference the internal certificate authority (CA)
CACERT=${SERVICEACCOUNT}/ca.crt
SECRET_NAME=$(cat /etc/scripts/secret-name)
# Explore the API with TOKEN
curl --fail --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" --request PATCH ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets/${SECRET_NAME} \
-H 'Accept: application/json' \
-H "Content-Type: application/json-patch json" \
-d '[{ "op": "replace","path": "/data/token.jwt","value": "'"$(gcloud auth print-identity-token | base64 -w0 )"'"}]' \
--output /dev/null
正如我在 DazWilkin 回答中所評論的那樣,呼叫的用戶gcloud auth print-identity-token實際上是 k8s 上的 serviceaccount,通過 GKE 上的作業負載身份驗證到 GCP ServiceAccount。
我需要令牌能夠在不存盤實際憑證的情況下呼叫 AWS,方法是使用它通過 Workload Identity Federation 呼叫 AWS
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/352131.html
標籤:猛击 Kubernetes 云 kubectl
上一篇:將多個變數添加到關聯陣列
