I've been looking into interacting with the secure (tls) ports for the kube-scheduler
and kube-controller-manager
and wanted to share my findings.
Video Walkthrough:
Click here to watch the video version of this content.
Based on the 1.12 changelog, secure serving on 10257
to the kube-controller-manager
is enabled:
Secure serving on port 10257 to kube-controller-manager (configurable via –secure-port) is now enabled. Delegated authentication and authorization are to be configured using the same flags as for aggregated API servers. Without configuration, the secure port will only allow access to /healthz. (#64149, @sttts) Courtesy of SIG API Machinery, SIG Auth, SIG Cloud Provider, SIG Scheduling, and SIG Testing
Based on the 1.13 changelog secure serving on 10259
to the kube-scheduler
is enabled:
Added secure port 10259 to the kube-scheduler (enabled by default) and deprecate old insecure port 10251. Without further flags self-signed certs are created on startup in memory. (#69663, @sttts)
With the kube-controller-manager
running, we can call the pod IP and verify /healthz
is available.
curl https://10.30.0.12:10257/healthz -k
ok
When calling the /metrics
endpoint, you'll get less satisfying results.
curl https://10.30.0.12:10257/metrics -k
Internal Server Error: "/metrics": subjectaccessreviews.authorization.k8s.io is forbidden: User "system:kube-controller-manager" cannot create resource "subjectaccessreviews" in API group "authorization.k8s.io" at the cluster scope
You might wonder why this path/resource is different than /healthz
. It turns out /healthz
is automatically set for authorization to always allow it. By setting --authorization-always-allow-paths=/healthz,/metrics
on the kube-controller-manager
, we can get /metrics
to behave the same. Instead, let's force authorization of the client to ensure not just anyone can scrape these system components.
We want kube-controller-manager
to delegate authorization decisions to kube-apiserver
. It does this by sending a SubjectAccessReview.
kube-controller-manager
must be bound to the existing system:auth-delegator
ClusterRole
.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: system:kube-controller-manager:auth-delegate
subjects:
- kind: User
name: system:kube-controller-manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: system:auth-delegator
apiGroup: rbac.authorization.k8s.io
After applying the ClusterRoleBinding
, request the metrics endpoint. It will now show we cannot access the /metrics
url.
curl https://10.30.0.12:10257/metrics -k
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "forbidden: User \"system:anonymous\" cannot get path \"/metrics\"",
"reason": "Forbidden",
"details": {
},
"code": 403
}
For this example, let's give default:default (<namespace>:<service-account>
) access to the /metrics
nonResourceURLs
. Normally you'd be providing this access to a Prometheus service account.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secure-metrics-scrape
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metrics-endpoint
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: secure-metrics-scrape
subjects:
- kind: ServiceAccount
name: default
namespace: default
Retrieve the default:default token into an environment variable.
TOKEN=$(kubectl describe secret $(kubectl get secrets -n default | grep ^default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d " ")
Request the secure metrics endpoint again.
curl https://10.30.0.12:10257/metrics --header "Authorization: Bearer $TOKEN" -k
...
volumes_work_duration{quantile="0.5"} NaN
volumes_work_duration{quantile="0.9"} NaN
volumes_work_duration{quantile="0.99"} NaN
volumes_work_duration_sum 0
volumes_work_duration_count 0
Hopefully this provides a better idea of how secure port communication and authorization works. You can take these learnings and setup secure interactions from clients like Prometheus.
转载至https://octetz.com/docs/2018/2018-12-05-securing-controller-and-scheduler/