先说一下背景,生产环境因为有网络隔离,我们一般需要用nginx对k8s api server进行反代,所以就遇到了下面的问题。
闲话少说,直接上报错文本:
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"deployments.apps is
forbidden: User \"system:anonymous\" cannot list resource \"deployments\"
in API group \"apps\" in the namespace \"xxx\"","reason":"Forbidden","details":{"group":"apps","kind":"deployments"},
"code":403}
这里有个小插曲,
你的NGINX中的配置不管是用upstream指令还是直接用proxy_pass指令,都要注意把http改成https,不然k8s api server会报下面的错误:
HTTP response body: Client sent an HTTP request to an https server.
上面的报错在网上一般是直接简单粗暴的给匿名用户加管理员权限,这样子风险太大了,尤其是生产环境不能这样,如下:
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=dont-do-this --user=system:anonymous
下面说说我们怎么样简单的通过正规途径解决这个问题:
[erphpdown]
这里我们以腾讯云的tke为例,先去控制台去下载你的kube config配置,这里我们假定这个配置叫cls-xx9bac.yaml,执行如下命令:
# kubectl --kubeconfig ./cls-xx9bac.yaml config view --minify --raw --output 'jsonpath={..user.client-certificate-data}' | base64 -d | openssl x509 -text -out -
# kubectl --kubeconfig ./cls-xx9bac.yaml config view --minify --raw --output 'jsonpath={..user.client-key-data}' | base64 -d
然后把上述第一条命令输出的结果命名为cert.pem,
注意第二条命令会输出很多无关的东西,你只需要复制其中的证书部分保存下来为private.key即可。
然后就是我们的nginx反代了,这里多说一句nginx必须配置成https访问,否则会报上面提到的那个小插曲中的错误,
反代的其它部分我就不赘述了,大家应该都会的,下面我们来看看核心的部分,
location / {
proxy_ssl_certificate /data/ssl/k8s/cert.pem;
proxy_ssl_certificate_key /data/ssl/k8s/private.key;
proxy_ssl_session_reuse on;
proxy_pass https://192.168.1.1:443;
}
}
上述配置好之后再用k8s的Python sdk去访问就不会报错了。
你可能会说我不需要用nginx反代k8s的api server,但是为了解决问题可以随手用一键脚本编译个nginx进行一下反代。
[/erphpdown]