46

我想为我的 kubernetes 集群创建一个秘密。所以我编写了以下dummy-secret.yaml文件:

apiVersion: v1
kind: Secret
metadata:
  name: dummy-secret
type: Opaque
data:
  API_KEY: bWVnYV9zZWNyZXRfa2V5
  API_SECRET: cmVhbGx5X3NlY3JldF92YWx1ZTE=

当我运行时,kubectl create -f dummy-secret.yaml我收到以下消息:

Error from server (BadRequest): error when creating "dummy-secret.yaml": Secret in version "v1" cannot be handled as a Secret: v1.Secret: Data: decode base64: illegal base64 data at input byte 8, error found in #10 byte of ...|Q89_Hj1Aq","API_SECR|..., bigger context ...|sion":"v1","data":{"API_KEY":"af76fsdK_cQ89_Hj1Aq","API_SECRET":"bsdfmkwegwegwe"},"kind":"Secret","m|...

不知道为什么会这样。

据我了解,我需要对datayaml 文件中键下的所有值进行编码。所以我做了base64编码,但是kubernetes仍然没有像我预期的那样处理yaml secret文件。

更新:

我使用此命令data在我的 mac 上对值进行编码:

echo -n 'mega_secret_key' | openssl base64
4

8 回答 8

55

我从您的编码数据中获得了解码值“mega_secret_key”和“really_secret_value1”。似乎它们没有以正确的方式编码。因此,以正确的方式编码您的数据:

$ echo "mega_secret_key" | base64
bWVnYV9zZWNyZXRfa2V5Cg==

$ echo "really_secret_value1" | base64
cmVhbGx5X3NlY3JldF92YWx1ZTEK

然后检查它们是否正确编码:

$ echo "bWVnYV9zZWNyZXRfa2V5Cg==" | base64 -d
mega_secret_key

$ echo "cmVhbGx5X3NlY3JldF92YWx1ZTEK" | base64 -d
really_secret_value1

所以他们没事。现在在你的dummy-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: dummy-secret
type: Opaque
data:
  API_KEY: bWVnYV9zZWNyZXRfa2V5Cg==
  API_SECRET: cmVhbGx5X3NlY3JldF92YWx1ZTEK

并运行$ kubectl create -f dummy-secret.yaml


2022 年 11 月 2 日更新:

较新版本的 Kubernetes 支持可选stringData属性,可以在不解码的情况下针对任何键提供值。

字段中的所有键值对stringData都在内部合并到data字段中。如果键同时出现在datastringData字段中,则字段中指定的值stringData优先。

apiVersion: v1
kind: Secret
metadata:
  name: dummy-secret
type: Opaque
stringData:
  API_KEY: mega_secret_key
  API_SECRET: really_secret_value1

更新:

如果您-n在运行时使用标志$ echo "some_text",它将\n从您正在打印的字符串中修剪尾随(换行符)。

$ echo "some_text"
some_text
$ echo -n "some_text"
some_text⏎

就试一试吧,

# first encode
$ echo -n "mega_secret_key" | base64
bWVnYV9zZWNyZXRfa2V5
$ echo -n "really_secret_value1" | base64
cmVhbGx5X3NlY3JldF92YWx1ZTE=
# then decode and check whether newline is stripped
$ echo "bWVnYV9zZWNyZXRfa2V5" | base64 -d
mega_secret_key⏎
$ echo "cmVhbGx5X3NlY3JldF92YWx1ZTE=" | base64 -d
really_secret_value1⏎

您可以在您的密钥中使用这些新(不带换行符)解码的数据。那也应该没问题。

$ cat - <<-EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: dummy-secret
type: Opaque
data:
  API_KEY: bWVnYV9zZWNyZXRfa2V5
  API_SECRET: cmVhbGx5X3NlY3JldF92YWx1ZTE=
EOF
secret/dummy-secret created

在更新时,我的 kubernetes 版本是,

Minor:"17", GitVersion:"v1.17.3",
GitCommit:"06ad960bfd03b39c8310aaf92d1e7c1 2ce618213",
GitTreeState:"clean", BuildDate:"2020-02-11T18:14:22Z",
GoVersion:"go1.13.6", Compiler:"gc", Platform:"l inux/amd64"} Server
Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3",
GitCommit:"06ad960bfd03b39c8310aaf92d1e7c1 2ce618213",
GitTreeState:"clean", BuildDate:"2020-02-11T18:07:13Z",
GoVersion:"go1.13.6", Compiler:"gc", Platform:"l inux/amd64"} ```
于 2018-11-20T14:32:37.257 回答
43

这已经得到解答,但为了将来参考,无需使用stringData代替data字段来编码字符串,如下所示:

#secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:
  API_KEY: "STRING_IN_CLEAR_TEXT"
  API_SECRET: "STRING_IN_CLEAR_TEXT"
于 2020-03-20T11:29:36.733 回答
13

过了一会儿,我想回到这个问题,并参考官方 kubernetes文档给出答案:

echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm

请特别注意-n,因为它保证您的密钥在解码后不会包含“换行符”。

于 2019-12-12T19:17:31.170 回答
2

看起来您的错误消息发生在不同的dummy-secret.yaml.

apiVersion: v1
kind: Secret
metadata:
  name: dummy-secret
type: Opaque
data:
  API_KEY: af76fsdK_cQ89_Hj1Aq
  API_SECRET: bsdfmkwegwegwe

然后:

$ kubectl create -f s.yaml
Error from server (BadRequest): error when creating "dummy-secret.yaml": Secret in version "v1" cannot be handled as a Secret: v1.Secret.Data: decode base64: illegal base64 data at input byte 8, error found in #10 byte of ...|Q89_Hj1Aq","API_SECR|..., bigger context ...|sion":"v1","data":{"API_KEY":"af76fsdK_cQ89_Hj1Aq","API_SECRET":"bsdfmkwegwegwe"},"kind":"Secret","m|...

如果我使用您的原件,它可以正常工作:

apiVersion: v1
kind: Secret
metadata:
  name: dummy-secret
type: Opaque
data:
  API_KEY: bWVnYV9zZWNyZXRfa2V5
  API_SECRET: cmVhbGx5X3NlY3JldF92YWx1ZTE=

然后:

$ kubectl create -f dummy-secret.yaml
secret/dummy-secret created

我正在使用以下版本:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.2", GitCommit:"17c77c7898218073f14c8d573582e8d2313dc740", GitTreeState:"clean", BuildDate:"2018-10-30T21:39:38Z", GoVersion:"go1.11.1", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.1", GitCommit:"4ed3216f3ec431b140b1d899130a69fc671678f4", GitTreeState:"clean", BuildDate:"2018-10-05T16:36:14Z", GoVersion:"go1.10.4", Compiler:"gc", Platform:"linux/amd64"}
于 2018-11-20T15:56:33.443 回答
0

尝试以错误的方式删除换行符时也可能发生这种情况(正确的方法是删除后缀“Cg==”)。

我使用了 cli 中的 base64,尽管有一些解决方法可以避免使用 NL,比如

https://superuser.com/questions/1225134/why-does-the-base64-of-a-string-contain-n/1225334

它们在 MacOS 中不起作用,我发现像这样使用 python 更简单

import base64

data = "abc123!?$*&()'-=@~"

# Standard Base64 Encoding
encodedBytes = base64.b64encode(data.encode("utf-8"))
encodedStr = str(encodedBytes, "utf-8")

或者仍然使用纯基于 bash 的解决方案:

echo 'secret_to_encode' | tr -d \\n | base64
于 2019-10-17T12:41:49.797 回答
0

就我而言,我忘记转换键的值。它可以是这样的:)。检查你的价值观

于 2020-10-06T10:39:59.250 回答
0

做备份

    sudo mkdir backup 
    sudo cp -R /etc/kubernetes backup/
    sudo tar -cvzf backup/pki_backup_`hostname`-`date +%Y%m%d`.tar.gz backup/kubernetes/

查看目录 /etc/kubernetes/

ls -l

total 80
-rw------- 1 root root 5440 Mar  3 13:21 admin.conf
drwxr-xr-x 2 root root 4096 Aug 17  2020 audit-policy
-rw-r--r-- 1 root root  368 Mar  4  2020 calico-config.yml
-rw-r--r-- 1 root root  270 Mar  4  2020 calico-crb.yml
-rw-r--r-- 1 root root  341 Mar  4  2020 calico-cr.yml
-rw-r--r-- 1 root root  147 Mar  4  2020 calico-node-sa.yml
-rw-r--r-- 1 root root 6363 Mar  4  2020 calico-node.yml
-rw------- 1 root root 5472 Mar  3 13:21 controller-manager.conf
-rw-r--r-- 1 root root 3041 Aug 14  2020 kubeadm-config.v1alpha3.yaml
-rw------- 1 root root 5548 Mar  3 13:21 kubelet.conf
-rw-r--r-- 1 root root 1751 Mar  4  2020 kubelet.env
drwxr-xr-x 2 kube root 4096 Aug 14  2020 manifests
lrwxrwxrwx 1 root root   28 Mar  4  2020 node-kubeconfig.yaml -> /etc/kubernetes/kubelet.conf
-rw------- 1 root root 5420 Mar  3 13:21 scheduler.conf
drwxr-xr-x 3 kube root 4096 Mar  3 10:20 ssl

尝试查找 k8s 集群配置,在我的情况下,这是 kubeadm-config.v1alpha3.yaml 如果没有相同的文件,您可以生成

kubectl get cm kubeadm-config -n kube-system -o yaml > /etc/kubernetes/kubeadm-config.yaml

同样在我的情况下,缺少文件夹 /etc/kubernetes/pki 并且存在 ~/ssl 我从 /etc/kubernetes/ssl 创建符号链接 /etc/kubernetes/pki

ln -s /etc/kubernetes/ssl /etc/kubernetes/pki

让重新生成证书

kubeadm alpha phase certs apiserver  --config /etc/kubernetes/kubeadm-config.v1alpha3.yaml

[certificates] Using the existing apiserver certificate and key.

kubeadm alpha phase certs apiserver-kubelet-client

I0303 13:12:24.543254   40613 version.go:236] remote version is much newer: v1.20.4; falling back to: stable-1.12
[certificates] Using the existing apiserver-kubelet-client certificate and key.

kubeadm alpha phase certs front-proxy-client

I0303 13:12:35.660672   40989 version.go:236] remote version is much newer: v1.20.4; falling back to: stable-1.12
[certificates] Using the existing front-proxy-client certificate and key.

kubeadm alpha phase certs  etcd-server --config /etc/kubernetes/kubeadm-config.v1alpha3.yaml

[certificates] Generated etcd/server certificate and key.
[certificates] etcd/server serving cert is signed for DNS names [prod-uct1-mvp-k8s-0001 localhost] and IPs [127.0.0.1 ::1]

kubeadm alpha phase certs  etcd-server --config /etc/kubernetes/kubeadm-config.v1alpha3.yaml

[certificates] Using the existing etcd/server certificate and key.

kubeadm alpha phase certs  etcd-healthcheck-client --config /etc/kubernetes/kubeadm-config.v1alpha3.yaml

[certificates] Generated etcd/healthcheck-client certificate and key.

kubeadm alpha phase certs  etcd-peer --config /etc/kubernetes/kubeadm-config.v1alpha3.yaml

[certificates] Generated etcd/peer certificate and key.
[certificates] etcd/peer serving cert is signed for DNS names [product1-mvp-k8s-0001 localhost] and IPs [192.168.4.201 127.0.0.1 ::1]

检查实际证书

find /etc/kubernetes/pki/ -name '*.crt' -exec openssl x509 -text -noout -in {} \; | grep -A2 Validity

        Validity
            Not Before: Mar  4 10:29:44 2020 GMT
            Not After : Mar  2 10:29:44 2030 GMT
--
        Validity
            Not Before: Mar  4 10:29:44 2020 GMT
            Not After : Mar  3 10:07:29 2022 GMT
--
        Validity
            Not Before: Mar  4 10:29:44 2020 GMT
            Not After : Mar  3 10:07:52 2022 GMT
--
        Validity
            Not Before: Mar  4 10:29:44 2020 GMT
            Not After : Mar  3 10:06:48 2022 GMT
--
        Validity
            Not Before: Mar  4 10:29:44 2020 GMT
            Not After : Mar  2 10:29:44 2030 GMT
--
        Validity
            Not Before: Mar  4 10:29:44 2020 GMT
            Not After : Mar  2 19:39:56 2022 GMT
--
        Validity
            Not Before: Mar  4 10:29:43 2020 GMT
            Not After : Mar  2 10:29:43 2030 GMT
--
        Validity
            Not Before: Mar  4 10:29:43 2020 GMT
            Not After : Mar  2 19:40:13 2022 GMT
--
        Validity
            Not Before: Mar  4 10:29:44 2020 GMT
            Not After : Mar  2 19:36:38 2022 GMT

下一步生成新配置文件:admin.conf、controller-manager.conf、kubelet.conf、scheduler.conf,第一步将旧文件移动到/tmp

cd /etc/kubernetes/
mv {admin.conf,controller-manager.conf,kubelet.conf,scheduler.conf} /tmp/

kubeadm alpha phase kubeconfig all  --config /etc/kubernetes/kubeadm-config.v1alpha3.yaml 

[kubeconfig] Using existing up-to-date KubeConfig file: "/etc/kubernetes/admin.conf"
[kubeconfig] Using existing up-to-date KubeConfig file: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Using existing up-to-date KubeConfig file: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Using existing up-to-date KubeConfig file: "/etc/kubernetes/scheduler.conf"

重启 master kubelet 并检查重启后的状态

sudo systemctl stop kubelet; sudo docker stop $(docker ps -aq); sudo docker rm $(docker ps -aq); sudo systemctl start kubelet

systemctl status kubelet -l

● kubelet.service - Kubernetes Kubelet Server
   Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-03-03 14:00:22 MSK; 10s ago
     Docs: https://github.com/GoogleCloudPlatform/kubernetes
  Process: 52998 ExecStartPre=/bin/mkdir -p /var/lib/kubelet/volume-plugins (code=exited, status=0/SUCCESS)
 Main PID: 53001 (kubelet)
   Memory: 51.2M
   CGroup: /system.slice/kubelet.service

检查访问主节点

kubectl get nodes

kubectl get ns

NAME                  STATUS   AGE
default               Active   464d
product1-mvp          Active   318d
infra-logging         Active   315d
infra-nginx-ingress   Active   386d
kube-public           Active   464d
kube-system           Active   464d
pg                    Active   318d

检查证书

notAfter=Mar  3 07:40:43 2022 GMT

对所有主节点重复该过程。

现在我们准备更新工作节点的证书。第一步,我们必须删除或移动kubelet.conf

cd /etc/kubernetes/

mv kubelet.conf kubelet.conf_old

更改bootstrap-kubelet.conf后

**apiVersion:v1 集群:

  • 集群:证书授权数据:| LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRFRFD01ETX 服务器 上下文:https ://162.168.4.
  • 上下文:集群:product1 用户:tls-bootstrap-token-user 名称:tls-bootstrap-token-user@product1 当前上下文:tls-bootstrap-token-user@product1 种类:配置首选项:{} 用户:
  • 名称:tls-bootstrap-token-user 用户:令牌:fgz9qz.lujw0bwsdfhdsfjhgds**

其中:certificate-authority-data – 根证书 PKI CA 主节点,可以从主节点上的 /etc/kubernetes/kubelet.conf 获取

  • 服务器:https ://192.168.4.201:6443 - ip api server master node virtual balance ip

令牌:fgz9qz.lujw0bwsdfhdsfjhgds - 令牌,在主节点上生成

kubeadm token create

重启后检查 kubelet 工作节点和工作节点返回集群:

systemctl restart kubelet

systemctl status kubelet -l

● kubelet.service - Kubernetes Kubelet Server
   Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-03-03 14:06:33 MSK; 11s ago
     Docs: https://github.com/GoogleCloudPlatform/kubernetes
  Process: 54615 ExecStartPre=/bin/mkdir -p /var/lib/kubelet/volume-plugins (code=exited, status=0/SUCCESS)
 Main PID: 54621 (kubelet)
   Memory: 52.1M
   CGroup: /system.slice/kubelet.service

检查更新证书可能是目录中的 ls

ls -las /var/lib/kubelet/pki/

total 24
4 -rw-------. 1 root root 1135 Mar  3 14:06 kubelet-client-2021-03-03-14-06-34.pem
0 lrwxrwxrwx. 1 root root   59 Mar  3 14:06 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2021-03-03-14-06-34.pem
4 -rw-r--r--. 1 root root 2267 Mar  2 10:40 kubelet.crt
4 -rw-------. 1 root root 1679 Mar  2 10:40 kubelet.key

在所有工作节点重复此过程后。

于 2021-03-05T16:27:36.827 回答
0

我遇到了同样的问题。
在我的情况下,编码很好 - 我只是复制了没有最后一个字符的输出"="

可能导致相同错误的其他场景:

  1. base64 复制输出中的空格或虚线错误。

  2. 未指定type密钥中的字段。

于 2021-03-10T18:10:26.613 回答