简体   繁体   English

带有 bash gcloud 身份令牌、heredoc 和 printf 的 kubectl 补丁秘密

[英]kubectl patch secret with bash gcloud identity-token, heredoc and printf

I want to create a simple k8s cronjob to keep a gcp identity token fresh in a secret.我想创建一个简单的 k8s cronjob 来保持 gcp 身份令牌的新鲜度。

A relatively simple problem that I am not able to solve一个我无法解决的相对简单的问题

Given给定的

kubectl patch secret token-test --type json -p=<< END
[
   {
     "op": "replace",
     "path": "/data/token.jwt",
     "value": "$(gcloud auth print-identity-token | base64 )"
   }
]
END

I want this to be applied with kubectl patch secret token-test --type json -p=$(printf "'%s'" "$json")我希望将其与kubectl patch secret token-test --type json -p=$(printf "'%s'" "$json")

I have tried many variants, the weird thing is that if I paste in the result of the heredoc insted of printf it works.我尝试了很多变体,奇怪的是,如果我粘贴 printf 的 heredoc 插入的结果,它会起作用。 But all my efforts fails with (also tried a json doc on a single line)但是我所有的努力都失败了(也在一行上尝试了一个 json 文档)

$ kubectl patch secret token-test --type json -p=$(printf "'%s'" "$json")
error: unable to parse "'[{": yaml: found unexpected end of stream

Whereas this actually works:而这实际上有效:

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

I cannot understand what is different when it fails.当它失败时,我无法理解有什么不同。 I understand bash is a bit tricky when it comes to string handling, but I am not sure if this is a bash issue or an issue in kubectl.我知道 bash 在处理字符串时有点棘手,但我不确定这是 bash 问题还是 kubectl 中的问题。

$ 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

By appending the string insted of interpolating in the heredoc this was solved.通过在heredoc中附加插入的字符串,这解决了。 Still don't know why the other approach failed though仍然不知道为什么其他方法失败了

It's a slight different approach but, howabout:这是一种稍微不同的方法,但是,怎么样:

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

NOTE it's not a best practice to use your user ( gcloud auth print-identity-token ) credentials in this way.请注意,以这种方式使用您的用户 ( gcloud auth print-identity-token ) 凭据不是最佳做法。 Service Accounts are preferred.首选服务帐户。 Service Accounts are intended for machine (rather than a human) auth and they can be more easily revoked.服务帐户旨在用于机器(而不是人工)身份验证它们可以更轻松地撤销。

User credentials grant the bearer all the powers of the user account (and this is likely extensive).用户凭据授予持有者用户帐户的所有权力(这可能是广泛的)。

There's a portable alternative in which you create a Kubernetes secret from a Service Account key:有一种可移植的替代方法,您可以在其中从服务帐户密钥创建 Kubernetes 机密:

 kubectl create secret generic your-key \\ --from-file=your-key.json=/path/to/your-key.json

There's a cool-kids who use GKE-mostly approach called Workload Identity有一个很酷的孩子,他们主要使用 GKE 方法,称为Workload Identity

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM