Vault requirements for CI and Kubernetes clusters no longer works with version 1.24 and NEW clusters
Details
- Point of contact for this request: @user
- If a call is needed, what is the proposed date and time of the call: Date and Time
- Additional call details (format, type of call): additional details
SRE Support Needed
Problem Statement
During a recent cluster rebuild, version 1.24 is now our primary version of Kubernetes. This version deprecated Service Accounts creating secret objects or tokens for authentication mechanisms by default.
Functional Example
In a GKE v1.23:
$ kubectl create serviceaccount sa-token-demo
serviceaccount/sa-token-demo created
$ k get secrets
NAME TYPE DATA AGE
default-token-hvs55 kubernetes.io/service-account-token 3 66m
sa-token-demo-token-28rqk kubernetes.io/service-account-token 3 5s
Vs. the new 1.24 cluster:
$ kubectl create serviceaccount sa-token-demo
serviceaccount/sa-token-demo created
$ kubectl get secrets
No resources found in default namespace.
This is problematic as Vault requires some setup that we rely on coming from our service accounts. From our runbook: https://gitlab.com/gitlab-com/runbooks/-/blob/6d5e7441852a4d4d79959d5b425cd9368d695a7e/docs/kube/k8s-cluster-rebuild.md#3d-new-cluster-config-setup and from our Vault documentation: https://gitlab.com/gitlab-com/runbooks/-/blob/master/docs/vault/administration.md#setting-up-the-external-secrets-operator-for-a-namespace-in-a-kubernetes-cluster
CONTEXT_NAME=$(kubectl config current-context)
KUBERNETES_HOST=$(kubectl config view -o jsonpath='{.clusters[?(@.name == "$CONTEXT_NAME")].cluster.server}')
SA_SECRET=$(kubectl --namespace external-secrets get serviceaccount external-secrets-vault-auth -o jsonpath='{.secrets[0].name}')
SA_TOKEN=$(kubectl --namespace external-secrets get secret ${SA_SECRET} -o jsonpath='{.data.token}' | base64 -d)
CA_CERT=$(kubectl --namespace external-secrets get secret ${SA_SECRET} -o jsonpath='{.data.ca\.crt}' | base64 -d)
vault kv put ci/ops-gitlab-net/config-mgmt/vault-production/kubernetes/CLUSTER host="${KUBERNETES_HOST}" ca_cert="${CA_CERT}" token="${SA_TOKEN}"
However, we are unable to populate SA_SECRET
, SA_TOKEN
, nor CA_CERT
as the secret is never created.
Workaround
We can get around this by manually creating a secret and linking it to the service account. This is precisely what was done in a recent cluster rebuild: production#8083 (comment 1189989936)
- Create a secret - we had to do this via a file in order to set the appropriate metadata, there's no secret information in here as Kuberntes creates the token for us:
apiVersion: v1
kind: Secret
metadata:
name: external-secrets-vault-auth-token-1991j
namespace: external-secrets
annotations:
kubernetes.io/service-account.name: "external-secrets-vault-auth"
type: kubernetes.io/service-account-token
data:
foo: YmFyCg==
Kubernetes will create the token
and crt
data objects for us, we're simply left with the data object foo
unnecessarily.
- And then for the service account, edited manually telling SA where to find the secret associated with it. This was effectively:
- `kubectl edit sa -n external-secrets external-secrets-vault-auth
- And adding the below for each of the secrets and SA's we created:
+secrets:
+ - name: external-secrets-vault-auth-token-1991j
This should only be considered temporary as this is not the desired state of service account secrets. Instead, it is desired that secrets are created on an ad-hoc basis, which is why secrets are no longer created by default.
References:
- https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#manual-secret-management-for-serviceaccounts
- https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/token-request-v1/
- https://developer.hashicorp.com/vault/docs/auth/kubernetes
Impact
All NEW clusters created with version 1.24 and later now have a dependency that we need to automate away. Until then, we must rely on a workaround that is currently undocumented, otherwise deployments cannot be completed on a cluster.
Milestones
-
Determine a new or more correct method to apply Kubernetes authentication for Vault -
Update the documentation for Vault -
Update our runbook for cluster rebuilds to point to this refreshed documentation