-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
dev-docs: howto generate kubeconfigs (#3047)
- Loading branch information
Showing
1 changed file
with
88 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# How to create kubeconfigs for users | ||
|
||
One of the first things to do after setting up a Constellation cluster is to hand out kubeconfig files to its prospective users. | ||
Adhering to the *principle of least privilege*, it is not advisable to share the admin config with all cluster users. | ||
Instead, users should authenticate individually to the API server, and permissions should be controlled by [RBAC]. | ||
|
||
Constellation users authenticate to the API server with a client TLS certificate, signed by the Kubernetes CA. | ||
The user's identity and group memberships are taken from the certificates common name and organizations, respectively. | ||
Details can be found in the upstream [authn documentation]. | ||
|
||
The [`kubeadm` documentation] describes a process for creating new kubeconfigs, but the instructions requires access to a control-plane node, or at least the Kubernetes CA certificate and key. | ||
While the certificates can be extracted, e.g. by spawning a [node debugger pod], we can take a safer road that only requires `kubectl`. | ||
The example script below creates a new kubeconfig for a user and optional group memberships. | ||
It uses the [Kubernetes certificate API] to obtain a user certificate signed by the cluster CA. | ||
|
||
[RBAC]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/ | ||
[authn documentation]: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#users-in-kubernetes | ||
[`kubeadm` documentation]: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#kubeconfig-additional-users | ||
[node debugger pod]: https://kubernetes.io/docs/tasks/debug/debug-cluster/kubectl-node-debug/ | ||
[Kubernetes certificate API]: https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/ | ||
|
||
```sh | ||
#!/bin/sh | ||
set -eu | ||
|
||
if [ $# -lt 2 ]; then | ||
echo "Usage: $0 username [groupname...]" >&2 | ||
exit 1 | ||
fi | ||
|
||
user=$1 | ||
shift | ||
|
||
subj="/CN=${user}" | ||
for g in "$@"; do | ||
subj="${subj}/O=$g" | ||
done | ||
|
||
openssl req -newkey rsa:4096 -out ${user}.csr -keyout ${user}.key -nodes -subj "${subj}" | ||
|
||
kubectl apply -f - <<EOF | ||
apiVersion: certificates.k8s.io/v1 | ||
kind: CertificateSigningRequest | ||
metadata: | ||
name: ${user} | ||
spec: | ||
request: $(base64 -w0 ${user}.csr) | ||
signerName: kubernetes.io/kube-apiserver-client | ||
usages: | ||
- digital signature | ||
- key encipherment | ||
- client auth | ||
EOF | ||
kubectl certificate approve ${user} | ||
kubectl wait --for=jsonpath='{.status.certificate}' csr/${user} | ||
kubectl get csr ${user} -o jsonpath='{.status.certificate}' | base64 -d >${user}.pem | ||
kubectl delete csr ${user} | ||
|
||
kubectl get cm kube-root-ca.crt -o go-template='{{ index .data "ca.crt" }}' >ca.pem | ||
kubectl get cm kubeadm-config -n kube-system -o=jsonpath="{.data.ClusterConfiguration}" >clusterconfig.yaml | ||
cluster=$(yq .clusterName clusterconfig.yaml) | ||
endpoint=$(yq .controlPlaneEndpoint clusterconfig.yaml) | ||
|
||
cat >${user}.conf <<EOF | ||
apiVersion: v1 | ||
kind: Config | ||
clusters: | ||
- cluster: | ||
certificate-authority-data: $(base64 -w0 ca.pem) | ||
server: https://${endpoint} | ||
name: ${cluster} | ||
contexts: | ||
- context: | ||
cluster: ${cluster} | ||
user: ${user} | ||
name: ${user}@${cluster} | ||
current-context: ${user}@${cluster} | ||
users: | ||
- name: ${user} | ||
user: | ||
client-certificate-data: $(base64 -w0 ${user}.pem) | ||
client-key-data: $(base64 -w0 ${user}.key) | ||
EOF | ||
|
||
env KUBECONFIG=./${user}.conf kubectl auth whoami | ||
|
||
rm ca.pem clusterconfig.yaml ${user}.csr ${user}.pem ${user}.key | ||
``` |