我已经完全复制了你的场景,我会尝试解释我是如何修复它的
重现相同的场景
- 在
/home/koopakiller/secrets.yaml上创建加密文件:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: r48bixfj02BvhhnVktmJJiuxmQZp6c0R60ZQBFE7558=
- identity: {}
编辑文件/etc/kubernetes/manifests/kube-apiserver.yaml 并设置--encryption-provider-config 标志:
- --encryption-provider-config=/home/koopakiller/encryption.yaml
保存文件并退出。
当我检查 pods 状态时得到了同样的错误:
$ kubectl get pods -A
The connection to the server 10.128.0.62:6443 was refused - did you specify the right host or port?
疑难解答
由于 kubectl 不再工作,我尝试使用 docker 命令直接查看正在运行的容器,然后我看到 kube-apiserver 容器最近重新创建:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
54203ea95e39 k8s.gcr.io/pause:3.1 "/pause" 1 minutes ago Up 1 minutes k8s_POD_kube-apiserver-lab-1_kube-system_015d9709c9881516d6ecf861945f6a10_0
...
Kubernetes 将创建的 pod 的日志存储在 /var/log/pods 目录中,我查看了 kube-apiserver 日志文件,发现了一个有价值的信息:
{"log":"Error: error opening encryption provider configuration file "/home/koopakiller/encryption.yaml": open /home/koopakiller/encryption.yaml: no such file or directory \n","stream":"stderr","time":"2020-01-22T13:28:46.772768108Z"}
说明
查看清单文件kube-apiserver.yaml 可以看到命令kube-apiserver,它运行到容器中,所以他们需要将encryption.yaml 文件挂载到容器中。
如果您检查此文件中的volumeMounts,您会看到默认情况下只有以下路径安装在容器中:
- /etc/ssl/certs
- /etc/ca-certificates
- /etc/kubernetes/pki
- /usr/local/share/ca-certificates
- /usr/share/ca-certificates
...
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/ca-certificates
name: etc-ca-certificates
readOnly: true
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
- mountPath: /usr/local/share/ca-certificates
name: usr-local-share-ca-certificates
readOnly: true
- mountPath: /usr/share/ca-certificates
name: usr-share-ca-certificates
readOnly: true
...
基于以上事实,我们可以假设 apiserver 启动失败是因为/home/koopakiller/encryption.yaml 实际上并没有挂载到容器中。
如何解决
我可以看到解决此问题的两种方法:
1st - 将加密文件复制到/etc/kubernetes/pki(或上述任何路径)并更改/etc/kubernetes/kube-apiserver.yaml中的路径:
- --encryption-provider-config=/etc/kubernetes/encryption.yaml
保存文件并等待 apiserver 重启。
2nd - 在 kube-apiserver.yaml 清单中创建一个新的 volumeMounts 以将自定义目录从节点挂载到容器中。
让我们在/etc/kubernetes/secret 中创建一个新目录(主文件夹不是放置配置文件的好位置 =))。
编辑/etc/kubernetes/manifests/kube-apiserver.yaml:
...
- --encryption-provider-config=/etc/kubernetes/secret/encryption.yaml
...
volumeMounts:
- mountPath: /etc/kubernetes/secret
name: secret
readOnly: true
...
volumes:
- hostPath:
path: /etc/kubernetes/secret
type: DirectoryOrCreate
name: secret
...
保存文件后kubernetes会将节点路径/etc/kubernetes/secret挂载到apiserver容器的同一路径中,等待完全启动,再次尝试列出你的节点。
如果有帮助,请告知!