"kubectl exec" results in "error: unable to upgrade connection: Unauthorized"

"kubectl exec" results in "error: unable to upgrade connection: Unauthorized"

我在启用了 k8s 1.6.4 RBAC 的集群上尝试了 kubectl exec,返回的错误是:error: unable to upgrade connection: Unauthorizeddocker exec 在同一容器上成功。否则,kubectl 正在工作。 kubectl 通过 SSH 连接建立隧道,但我认为这不是问题所在。

kubelet authn 已启用,但未启用 authz。 docs 说默认情况下 authz 是 AlwaysAllow,所以我就这样保留了。

感觉和差不多。但是错误消息有点不同。

提前致谢!

kubectl exec 命令的详细日志:

I0614 16:50:11.003677   64104 round_trippers.go:398] curl -k -v -XPOST  -H "X-Stream-Protocol-Version: v4.channel.k8s.io" -H "X-Stream-Protocol-Version: v3.channel.k8s.io" -H "X-Stream-Protocol-Version: v2.channel.k8s.io" -H "X-Stream-Protocol-Version: channel.k8s.io" https://localhost:6443/api/v1/namespaces/monitoring/pods/alertmanager-main-0/exec?command=%2Fbin%2Fls&container=alertmanager&container=alertmanager&stderr=true&stdout=true
I0614 16:50:11.003705   64104 round_trippers.go:398] curl -k -v -XPOST  -H "X-Stream-Protocol-Version: v4.channel.k8s.io" -H "X-Stream-Protocol-Version: v3.channel.k8s.io" -H "X-Stream-Protocol-Version: v2.channel.k8s.io" -H "X-Stream-Protocol-Version: channel.k8s.io" -H "User-Agent: kubectl/v1.6.4 (darwin/amd64) kubernetes/d6f4332" https://localhost:6443/api/v1/namespaces/monitoring/pods/alertmanager-main-0/exec?command=%2Fbin%2Fls&container=alertmanager&container=alertmanager&stderr=true&stdout=true
I0614 16:50:11.169474   64104 round_trippers.go:417] POST https://localhost:6443/api/v1/namespaces/monitoring/pods/alertmanager-main-0/exec?command=%2Fbin%2Fls&container=alertmanager&container=alertmanager&stderr=true&stdout=true 401 Unauthorized in 165 milliseconds
I0614 16:50:11.169493   64104 round_trippers.go:423] Response Headers:
I0614 16:50:11.169497   64104 round_trippers.go:426]     Date: Wed, 14 Jun 2017 08:50:11 GMT
I0614 16:50:11.169500   64104 round_trippers.go:426]     Content-Length: 12
I0614 16:50:11.169502   64104 round_trippers.go:426]     Content-Type: text/plain; charset=utf-8
I0614 16:50:11.169506   64104 round_trippers.go:417] POST https://localhost:6443/api/v1/namespaces/monitoring/pods/alertmanager-main-0/exec?command=%2Fbin%2Fls&container=alertmanager&container=alertmanager&stderr=true&stdout=true 401 Unauthorized in 165 milliseconds
I0614 16:50:11.169509   64104 round_trippers.go:423] Response Headers:
I0614 16:50:11.169512   64104 round_trippers.go:426]     Date: Wed, 14 Jun 2017 08:50:11 GMT
I0614 16:50:11.169545   64104 round_trippers.go:426]     Content-Length: 12
I0614 16:50:11.169548   64104 round_trippers.go:426]     Content-Type: text/plain; charset=utf-8
F0614 16:50:11.169635   64104 helpers.go:119] error: unable to upgrade connection: Unauthorized

这是一个 RTFM 时刻...解决方案基本上是按照 this page 上的所有步骤进行 authn、authz 或两者。

我省略了 --kubelet-client-certificate--kubelet-client-key,这导致了错误。如果没有这些标志,kube-apiserver 将无法在您执行 kubectl exec.

时使用 kubelet 进行身份验证

我最初配置 authn 的尝试是阅读 kubelet 守护进程的文档(即不是上面那个)。因此严重遗漏。

以我为例(在学习 Kubernetes The Hard Way 时,我必须配置 RBAC 权限以允许 Kubernetes API 服务器访问 Kubelet API 在每个工作节点上。我创建了一个 ClusterRoleClusterRoleBinding 来访问 Kubelet API

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/proxy
      - nodes/stats
      - nodes/log
      - nodes/spec
      - nodes/metrics
    verbs:
      - "*"

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: kube-apiserver

参考文献:

运行 在我的 minikube 集群版本 1.12.3 上跨越这个
如果您是 运行 minikube 集群,请升级 minikube,它会得到修复。

检查您的 minikube 版本:

$ minikube update-check
CurrentVersion: v1.12.3
LatestVersion: v1.13.0

Minikube docs
升级(Mac OS):

brew upgrade minikube