1
0
mirror of https://github.com/funkypenguin/geek-cookbook/ synced 2025-12-14 10:16:27 +00:00

Add Kubernetes OIDC recipes

Signed-off-by: David Young <davidy@funkypenguin.co.nz>
This commit is contained in:
David Young
2023-11-03 23:04:58 +13:00
parent 6ffd628e58
commit 365cd92dd7
19 changed files with 833 additions and 8 deletions

View File

@@ -0,0 +1,93 @@
---
title: Configure K3s for OIDC authentication with Authentik
description: How to configure your Kubernetes cluster for OIDC authentication with Authentik
---
# Authenticate to Kubernetes with OIDC on K3s
This recipe describes how to configure K3s for OIDC authentication against an [authentik][k8s/authentik] instance.
For details on **why** you'd want to do this, see the [Kubernetes Authentication Guide](/kubernetes/oidc-authentication/).
## Requirements
!!! summary "Ingredients"
* [x] A [Kubernetes cluster](/kubernetes/cluster/) deployed using [K3S](/kubernetes/cluster/k3s)
* [x] [Authentik][k8s/authentik] deployed per the recipe
## Setup authentik for kube-apiserver
Start by logging into your [authentik][k8s/authentik] instance with a superuser account.
### Create provider
Navigate to **Applications** -> **Providers**, and **Create** a new `OAuth2/OpenID Provider`.
![](/images/authentik-kube-apiserver-1.png)
Give your provider a name (*I use `kube-apiserver`*), and set the following:
* Authentication flow: `default-authentication-flow (Welcome to authentik!)`
* Authorization flow: `default-provider-authorization-implicit-consent (Authorize Application)`
* Client type: `Confidential`
![](/images/authentik-kube-apiserver-2.png)
Scroll down, and set:
* Client ID: `kube-apiserver` *take note, this is non-default*
* Client Secret: `<pick a secret, or use the randomly generated one>`
* Redirect URIs/Origins (RegEx): `http://localhost:18000` [^1]
![](/images/authentik-kube-apiserver-3.png)
Under **Advanced Protocol Settings**, below the set the scopes to include the built-in `email` scope, as well as the extra `oidc-groups` scope you added when [initially setting up authentik][k8s/authentik]:
![](/images/authentik-kube-apiserver-4.png)
Finally, enable **Include claims in id_token**, instructing authentik to send the user claims back with the id token:
![](/images/authentik-kube-apiserver-5.png)
..and click **Finish**. On the following summary page, under **OAuth2 Provider**, take note of the **OpenID Configuration** URL (*`/application/o/kube-apiserver/.well-known/openid-configuration` if you followed my conventions above*) - you'll need this when configuring Kubernetes.
!!! question "What's that redirect URI for?"
We'll use [kubelogin](https://github.com/int128/kubelogin) to confirm OIDC login is working, which runs locally on port 18000 to provide a web-based OIDC login flow.
### Create application
authentik requires a one-to-one relationship between applications and providers, so navigate to **Applications** -> **Applications**, and **create** an application for your new provider.
You can name it anything you want (*but it might be more sensible to name it for your provider, rather than a superhero! :superhero:*)
![](/images/authentik-kube-apiserver-6.png)
### Create group
Remember how we setup a groups property-mapper when deploying [authentik][k8s/authentik]? When kube-apiserver requests the `groups` scope from Authentik, the mapper will return all a user's group names.
You can create whatever groups you prefer - later on, you'll configure clusterrolebindings to provide RBAC access to group members. I'd start with a group called `admin-kube-apiserver`, which we'll simply map to the `cluster-admin` clusterrole.
Navigate to **Directory** -> **Groups**, create the necessary groups, and make yourself a member.
## Summary
What have we achieved? We've configured authentik as an OIDC provider, and we've got the details necessary to configure our Kubernetes platform(s) to authenticate against it!
!!! summary "Summary"
Created:
* [X] [authentik][k8s/authentik] configured as an OIDC provider for kube-apiserver
* [X] OIDC parameters, including:
* [X] OIDC Client id (`kube-apiserver`)
* [X] OIDC Client secret (`<your chosen secret>`)
* [X] OIDC Configuration URL (`https://<your-authentic-hosts>/application/o/kube-apiserver/.well-known/openid-configuration`)
What's next?
Return to the [Kubernetes Authentication Guide](/kubernetes/oidc-authentication/) for instructions re configuring your particular Kubernetes platform!
[^1]: Later on, as we add more applications which need kube-apiserver authentication, we'll add more redirect URIs.
{% include 'recipe-footer.md' %}

View File

@@ -0,0 +1,80 @@
---
title: Configure EKS for OIDC authentication with Authentik
description: How to configure your EKS Kubernetes cluster for OIDC authentication with Authentik
---
# Authenticate to Kubernetes with OIDC on EKS
This recipe describes how to configure an EKS cluster for OIDC authentication against an [authentik][k8s/authentik] instance.
For details on **why** you'd want to do this, see the [Kubernetes Authentication Guide](/kubernetes/oidc-authentication/).
## Requirements
!!! summary "Ingredients"
* [x] A [Kubernetes cluster](/kubernetes/cluster/) deployed on Amazon EKS
* [x] [authentik][k8s/authentik] deployed per the recipe, secured with a valid SSL cert (*no self-signed schenanigans will work here!*)
* [x] authentik [configured as an OIDC provider for kube-apiserver](/kubernetes/oidc-authentication/authentik/)
* [x] `eksctl` tool configured and authorized for your IAM account
## Setup EKS for OIDC auth
In order to associate an OIDC provider with your EKS cluster[^1], you'll need (*guess what?*)..
.. some YAML.
Create an EKS magic YAML[^2] like this, and tweak it for your cluster name, region, and issuerUrl:
```yaml title="eks-cluster-setup.yaml"
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: funkypenguin-authentik-test
region: ap-southeast-2
identityProviders:
- name: authentik
type: oidc
issuerUrl: https://authentik.funkypenguin.de/application/o/kube-apiserver/ # (1)!
clientId: kube-apiserver
usernameClaim: email
usernamePrefix: 'oidc:'
groupsClaim: groups
groupsPrefix: 'oidc:'
```
1. Make sure this ends in a `/`, and doesn't include `.well-known/openid-configuration`
Apply the EKS magic by running `eksctl associate identityprovider -f eks-cluster-setup.yaml`
That's it! It may take a few minutes (you can verify it's ready on your EKS console), but once complete, the authentik provider should be visible in your cluster console, under the "Authentication" tab, as illustrated below:
![](/images/eks-authentic-1.png)
{% include 'kubernetes-oidc-setup.md' %}
## Summary
What have we achieved?
We've setup our EKS cluster to authenticate against authentik, running on that same cluster! We can now create multiple users (*with multiple levels of access*) without having to provide them with tricky IAM accounts, and deploy kube-apiserver-integrated tools like Kubernetes Dashboard or Weaveworks GitOps for nice secured UIs.
!!! summary "Summary"
Created:
* [X] EKS cluster with OIDC authentication against [authentik][k8s/authentik]
* [X] Ability to support:
* [X] Kubernetes Dashboard (*coming soon*)
* [X] Weave GitOps (*coming soon*)
* [X] We've also retained our static, IAM-based `kubernetes-admin` credentials in case OIDC auth fails at some point (*keep them safe!*)
What's next?
Deploy Weave GitOps to visualize your Flux / GitOps state, and Kubernetes Dashboard for UI management of your cluster!
[^1]: AWS docs are at https://docs.aws.amazon.com/eks/latest/userguide/authenticate-oidc-identity-provider.html
[^2]: For details on available options, see https://docs.aws.amazon.com/cli/latest/reference/eks/associate-identity-provider-config.html
{% include 'recipe-footer.md' %}

View File

@@ -0,0 +1,37 @@
---
title: Configure Kubernetes for OIDC authentication
description: How to configure your Kubernetes cluster for OIDC authentication, so that you can provide RBAC-protected access to multiple users
---
# Authenticate to Kubernetes with OIDC
So you've got a shiny Kubernetes cluster, and you're probably using the `cluster-admin` config which was created as a result of the initial bootstrap.
While this hard-coded, `cluster-admin` credential is OK while you're bootstrapping, and should be safely stored somewhere as a password-of-last-resort, you'll probably want to secure your cluster with something a little more... secure.
Consider the following downsides to a single, static, long-lived credential:
1. It can get stolen
2. It can't be shared (*you might want to give your team access to the cluster, or even a limited subset of admin access*)
3. It can't be MFA'd
4. Using it for the Kubernetes Dashboard (*copying and pasting into a browser window*) is a huge PITA
True to form, Kubernetes doesn't provide any turnkey access solution, but all the necessary primitives (*RBAC, api-server arguments, etc*) to build your own solution, starting with [authenticating and authorizing access to the apiserver](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#configuring-the-api-server).
## Requirements
Securing access to Kubernetes' API server requires an OIDC provider, be it an external service like Auth0 or Octa, or a self-hosted, open-source IDP like KeyCloak or [authentik][k8s/authentik].
### Setup Provider
1. Setup [Authentik for Kubernetes API authentication](/kubernetes/authentication/authentik/)
2. KeyCloak (*coming soon*)
### Configure Kubernetes for OIDC auth
Once you've configured your OIDC provider, review the following, based on your provider and your Kubernetes platform:
#### Authentik
* [Authenticate K3s with Authentik as an OIDC provider](/kubernetes/oidc-authentication/k3s-authentik/)
* Authenticate EKS with Authentik as an OIDC provider
* Authenticate a kubeadm cluster using Authentik as an OIDC provider

View File

@@ -0,0 +1,199 @@
---
title: Configure K3s for OIDC authentication with Authentik
description: How to configure your K3s Kubernetes cluster for OIDC authentication with Authentik
---
# Authenticate to Kubernetes with OIDC on K3s
This recipe describes how to configure K3s for OIDC authentication against an [authentik][k8s/authentik] instance.
For details on **why** you'd want to do this, see the [Kubernetes Authentication Guide](/kubernetes/oidc-authentication/).
## Requirements
!!! summary "Ingredients"
* [x] A [Kubernetes cluster](/kubernetes/cluster/) deployed using [K3S](/kubernetes/cluster/k3s)
* [x] [authentik][k8s/authentik] deployed per the recipe
* [x] authentik [configured as an OIDC provider for kube-apiserver](/kubernetes/oidc-authentication/authentik/)
## Setup K3s for OIDC auth
If you followed the k3s install guide, you'll have installed K3s with a command something like this:
```bash
MYSECRET=iambatman
curl -fL https://get.k3s.io | K3S_TOKEN=${MYSECRET} \
sh -s - --disable traefik server
```
To configure the apiserver to perform OIDC authentication, you need to add some extra kube-apiserver arguments. There are two ways to do this:
1. Append the arguments to your `curl | bash` command, like a lunatic
2. Add the arguments to a config file which K3s will parse upon start, like a gentleman
Here's the lunatic option:
```bash title="Lunatic curl | bash option"
--kube-apiserver-arg=oidc-issuer-url=https://authentik.example.com/application/o/kube-apiserver/
--kube-apiserver-arg=oidc-client-id=kube-apiserver
--kube-apiserver-arg=oidc-username-claim=email
--kube-apiserver-arg=oidc-groups-claim=groups
--kube-apiserver-arg=oidc-username-prefix='oidc:'
--kube-apiserver-arg=oidc-groups-prefix='oidc:'
```
And here's the gentlemanly option:
Created `/etc/rancher/k3s/config.yaml`, and add:
```yaml title="Gentlemanly YAML config option"
kube-apiserver-arg:
- "oidc-issuer-url=https://authentik.infra.example.com/application/o/kube-apiserver/"
- "oidc-client-id=kube-apiserver"
- "oidc-username-claim=email"
- "oidc-groups-claim=groups"
- "oidc-username-prefix='oidc:'"
- "oidc-groups-prefix='oidc:'"
```
Now restart k3s (*`systemctl restart k3s` on Ubuntu*), and confirm it starts correctly by watching the logs (*`journalctl -u k3s -f` on Ubuntu*)
Assuming nothing explodes, you're good-to-go on attempting to actually connect...
### Install kubelogin
For CLI-based access to your cluster, you'll need a "helper" to perform the OIDC magic on behalf of kubectl. Install [int128/kubelogin](https://github.com/int128/kubelogin), which is design suited to this purpose.
Use kubelogin to test your OIDC parameters, by running:
```bash
kubectl oidc-login setup \
--oidc-issuer-url=ISSUER_URL \
--oidc-client-id=YOUR_CLIENT_ID \
--oidc-client-secret=YOUR_CLIENT_SECRET
```
All going well, your browser will open a new window, logging you into authentik, and on the CLI you should get output something like this:
```
~ kubectl oidc-login setup --oidc-issuer-url=https://authentik.example.com/application/o/kube-apiserver/ --oidc-client-id=kube-apiserver --oidc-client-secret=cVj4YqmB4VPcq6e7 --oidc-extra-scope=groups,email
authentication in progress...
## 2. Verify authentication
You got a token with the following claims:
{
"iss": "https://authentik.example.com/application/o/kube-apiserver/",
"sub": "363d4d0814dbad2d930308dc848342e328b76f925ebba0978a51ddad699022b",
"aud": "kube-apiserver",
"exp": 1701511022,
"iat": 1698919022,
"auth_time": 1698891834,
"acr": "goauthentik.io/providers/oauth2/default",
"nonce": "qgKevTR1gU9Mh14HzOPPCTaP_Mgu9nvY7ZhJkCeFpGY",
"at_hash": "TRZOLHHxFxl9HB7SHCIcMw",
"email": "davidy@example.com",
"email_verified": true,
"groups": [
"authentik Admins",
"admin-kubernetes"
]
}
```
Huzzah, authentication works! :partying_face:
!!! tip
Make sure you see a groups claim in the output above, and if you don't revisit your scope mapper and your claims in the provider under advanced protocol settings!
### Assemble your kubeconfig
Your kubectl access to k3s uses a kubeconfig file at `/etc/rancher/k3s/k3s.yaml`. Treat this file as a root password - it's includes a long-lived token which gives you clusteradmin ("*god mode*" on your cluster.)
Copy the `k3s.yaml` file to your local desktop (*the one with a web browser*), into `$HOME/.kube/config`, and modify it, changing `server: https://127.0.0.1:6443` to match the URL of (*one of*) your control-plane node(*s*).
Test using `kubectl cluster-info` locally, ensuring that you have access.
Amend the kubeconfig file for your OIDC user, by running a variation of:
```bash
kubectl config set-credentials oidc \
--exec-api-version=client.authentication.k8s.io/v1beta1 \
--exec-command=kubectl \
--exec-arg=oidc-login \
--exec-arg=get-token \
--exec-arg=--oidc-issuer-url=https://authentik.example.com/application/o/kube-apiserver/ \
--exec-arg=--oidc-client-id=kube-apiserver \
--exec-arg=--oidc-client-secret=<your client secret> \
--exec-arg=--oidc-extra-scope=groups \
--exec-arg=--oidc-extra-scope=email
```
Test your OIDC powerz by running `kubectl --user=oidc cluster-info`.
Now gasp in dismay as you discover that your request was denied for lack of access! :scream:
```
Error from server (Forbidden): services is forbidden: User "oidc:davidy@funkypenguin.co.nz"
cannot list resource "services" in API group "" in the namespace "kube-system"
```
### Create clusterrolebinding
That's what you wanted, right? Security? Locking out unauthorized users? Ha.
Now that we've confirmed that kube-apiserver knows your **identity** (authn), create a clusterrolebinding to tell it what your identity is **authorized** to do (authz), based on your group membership.
The following is a simple clusterrolebinding which will grant all members of the `admin-kube-apiserver` full access (`cluster-admin`), to get you started:
```yaml title="/authentic/clusterrolebinding-oidc-group-admin-kube-apiserver.yaml"
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: oidc-group-admin-kube-apiserver
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin # (1)!
subjects:
- kind: Group
name: oidc:admin-kube-apiserver # (2)!
```
1. The role to bind
2. The subject (group, in this case) of the binding
Apply your clusterrolebinding using the usual GitOps magic (*I put mine in `/authentic/clusterrolebinding-oidc-group-admin-kube-apiserver.yaml`*).
Run `kubectl --user=oidc cluster-info` again, and confirm you are now authorized to see the cluster details.
If this works, set your user context permanently, using `kubectl config set-context --current --user=oidc`.
!!! tip "whoami?"
Run `kubectl krew install whoami` to install the `whoami` plugin, and then `kubectl whoami` to confirm you're logged in with your OIDC account
You now have OIDC-secured CLI access to your cluster!
## Summary
What have we achieved?
We've setup our K3s cluster to authenticate against authentik, running on that same cluster! We can now create multiple users (*with multiple levels of access*) without having to provide them with tricky IAM accounts, and deploy kube-apiserver-integrated tools like Kubernetes Dashboard or Weaveworks GitOps for nice secured UIs.
!!! summary "Summary"
Created:
* [X] EKS cluster with OIDC authentication against [authentik][k8s/authentik]
* [X] Ability to support:
* [X] Kubernetes Dashboard (*coming soon*)
* [X] Weave GitOps (*coming soon*)
* [X] We've also retained our static, IAM-based `kubernetes-admin` credentials in case OIDC auth fails at some point (*keep them safe!*)
What's next?
Deploy Weave GitOps to visualize your Flux / GitOps state, and Kubernetes Dashboard for UI management of your cluster!
[^1]: Later on, as we add more applications which need kube-apiserver authentication, we'll add more redirect URIs.
{% include 'recipe-footer.md' %}