Add tutorial doc for how to use Supervisor without Concierge
This commit is contained in:
parent
7bd09ff21d
commit
c08ebc622c
265
site/content/docs/tutorials/supervisor-without-concierge-demo.md
Normal file
265
site/content/docs/tutorials/supervisor-without-concierge-demo.md
Normal file
@ -0,0 +1,265 @@
|
||||
---
|
||||
title: Learn to use the Pinniped Supervisor without the Concierge
|
||||
description: See how the Pinniped Supervisor can work directly with the Kube API server to provide authentication to Kubernetes clusters.
|
||||
cascade:
|
||||
layout: docs
|
||||
menu:
|
||||
docs:
|
||||
name: Supervisor without Concierge
|
||||
parent: tutorials
|
||||
weight: 200
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This tutorial shows how to use the Pinniped Supervisor and Pinniped command-line tool to provide federated identity
|
||||
with a single sign-on user experience on many Kubernetes clusters, without using the Pinniped Concierge.
|
||||
If you would like to learn how to use the Pinniped Supervisor and Concierge together,
|
||||
please instead see this other tutorial:
|
||||
- [Concierge with Supervisor: a complete example of every step, demonstrated using GKE clusters]({{< ref "concierge-and-supervisor-demo" >}})
|
||||
|
||||
The Kubernetes API server can be configured to trust an OIDC identity provider to provide authentication
|
||||
for the cluster. This is done by setting the `--oidc-*` command-line flags of the `kube-apiserver` command-line tool inside
|
||||
the Pod spec of the Kubernetes API server Pods. The details of these command-line flags are described in the
|
||||
[Kubernetes kube-apiserver documentation](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/)
|
||||
and in the
|
||||
[Kubernetes authentication documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens).
|
||||
These flags can be used to configure the Pinniped Supervisor as the OIDC provider for your clusters.
|
||||
|
||||
If your cluster's Kubernetes distribution does not allow you to adjust these command-line flags, then this approach will
|
||||
not work for those clusters. For example, most cloud providers will not allow these flags to be adjusted. In that case,
|
||||
you can use the Pinniped Concierge to provide the equivalent functionality on those clusters.
|
||||
|
||||
Additionally, if you would like to be able to easily change this configuration at any time on your cluster, then
|
||||
you can use the Pinniped Concierge instead of these `kube-apiserver` command-line flags, even on a cluster where you
|
||||
have control over these flags. The Pinniped Concierge offers a custom resource called JWTAuthenticator which can
|
||||
be dynamically configured at any time, which is roughly equivalent to using these `kube-apiserver` command-line flags.
|
||||
|
||||
One Pinniped Supervisor can provide authentication for many Kubernetes clusters. Each cluster can either use
|
||||
the Pinniped Concierge or use the `kube-apiserver` command-line flags, and both approaches can be mixed and matched on different
|
||||
clusters all with a single Pinniped Supervisor.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. A Kubernetes cluster of a type which allows you to adjust the command-line flags of `kube-apiserver`.
|
||||
|
||||
Don't have a cluster handy? Consider using [kind](https://kind.sigs.k8s.io/) on your local machine.
|
||||
See below for an example of using kind.
|
||||
|
||||
1. A kubeconfig where the current context points to the cluster and has administrator-like
|
||||
privileges on that cluster.
|
||||
|
||||
1. A Pinniped Supervisor already installed and running on another cluster, and already configured with
|
||||
a working FederationDomain, TLS certificates, and an external identity provider
|
||||
(e.g. an OIDCIdentityProvider, LDAPIdentityProvider, or ActiveDirectoryIdentityProvider).
|
||||
|
||||
Don't have a Pinniped Supervisor ready? Please refer to the other documents on this site to help you get one up and running
|
||||
and sufficiently configured.
|
||||
This tutorial does not show to install and configure the Pinniped Supervisor. Those steps are
|
||||
shown in the [Concierge with Supervisor tutorial]({{< ref "concierge-and-supervisor-demo" >}}),
|
||||
so if you would like you could follow the steps of that tutorial to install and configure a Pinniped Supervisor
|
||||
before returning to this tutorial.
|
||||
|
||||
## How to configure the kube-apiserver flags
|
||||
|
||||
The `kube-apiserver` command-line flags may be configured on each cluster to trust your Pinniped Supervisor to provide
|
||||
user authentication to that cluster. Add the following flags to the existing list of flags for your cluster:
|
||||
|
||||
```bash
|
||||
# Make this exactly match the spec.issuer of your Supervisor's FederationDomain.
|
||||
# Note: It seems like the kube-apiserver pod cannot resolve `cluster.local`
|
||||
# DNS names, so don't use one of those DNS names as the issuer.
|
||||
--oidc-issuer-url="https://my-supervisor.example.com/my-issuer"
|
||||
|
||||
# This is only required if the kube-apiserver pod is not going to trust your
|
||||
# Supervisor's FederationDomain's TLS certificates, e.g. if you used a
|
||||
# self-signed CA. Make this match where you mounted the CA PEM file into
|
||||
# your control plane node's filesystem, which must be under a directory
|
||||
# that the kube-apiserver container is going to volume mount.
|
||||
--oidc-ca-file="/etc/ca-certificates/supervisor/root-ca.pem"
|
||||
|
||||
# Choose a unique value for each cluster here. By making this unique, the
|
||||
# Supervisor will be able to issue ID tokens for this cluster that cannot
|
||||
# be used on any other cluster, which improves security. Do not use the
|
||||
# special value "pinniped-cli" or any value that contains the substring
|
||||
# ".pinniped.dev", because these special values are reserved for other
|
||||
# purposes.
|
||||
--oidc-client-id="my-cluster-342klb7h"
|
||||
|
||||
# Use these exact values. These are based on how the Supervisor issues ID
|
||||
# tokens. Do not change these values.
|
||||
--oidc-signing-algs="ES256"
|
||||
--oidc-username-claim="username"
|
||||
--oidc-groups-claim="groups"
|
||||
|
||||
# These are optional, use any value you prefer here, or do not set these flags.
|
||||
# These strings will be prepended to the username and group name strings
|
||||
# that were determined by the Supervisor during user authentication to decide
|
||||
# the final username and group names, but only on this cluster. Refer to the
|
||||
# Kubernetes kube-apiserver docs for more information about these flags.
|
||||
--oidc-username-prefix="pinniped:"
|
||||
--oidc-groups-prefix="pinniped:"
|
||||
```
|
||||
|
||||
Use the `--oidc-client-id` to choose a string that is unique for each cluster. This could be a GUID or some other random
|
||||
letters and numbers, and can be combined with a human-readable portion if desired. When a user first authenticates
|
||||
to the Pinniped Supervisor, it will issue an ID token with the `aud` (audience) claim set to the name of the client,
|
||||
which will be either `pinniped-cli` (for the kubectl use case) or will start with `client.oauth.pinniped.dev-`
|
||||
(for a web app client using the OIDCClient CR). Avoid using these names for the `--oidc-client-id` value to ensure
|
||||
that these initial ID tokens cannot be used to authenticate to your cluster. Next, the client will make another call
|
||||
to the Pinniped Supervisor to obtain a new ID token which is scoped to one specific cluster. This new token will have the `aud`
|
||||
claim's value changed to the cluster's unique value. This is the only token that will be sent to that cluster.
|
||||
The `--oidc-client-id` flag of `kube-apiserver` tells it to validate the `aud` claim on the incoming ID tokens.
|
||||
This cluster-scoped ID token will not be accepted by any other cluster, because no other cluster should use the
|
||||
same unique value for this flag. This improves the security of your clusters by making this token only valuable on
|
||||
a single cluster.
|
||||
|
||||
The procedure to add these command-line flags to the `kube-apiserver`'s list of command-line flags depends on
|
||||
the distribution of Kubernetes that you are using. Please refer to the documentation for your distribution.
|
||||
|
||||
Note that you can configure these flags even if the Pinniped Supervisor is not running yet. The Kube API server will
|
||||
continuously try to find the Pinniped Supervisor at the configured URL until it works.
|
||||
|
||||
## How to create a kubeconfig for the cluster
|
||||
|
||||
You can use the Pinniped command-line tool to create a kubeconfig that will work with your Pinniped Supervisor and your cluster.
|
||||
When using the Pinniped Concierge on the cluster, the Pinniped command-line tool will auto-discover many settings for the kubeconfig.
|
||||
However, when configuring the `kube-apiserver` flags instead of using the Pinniped Concierge, then you must give
|
||||
more hints to the Pinniped command-line tool to help it create the kubeconfig.
|
||||
|
||||
Here is how you would create a kubeconfig for the example configuration of the `kube-apiserver` flags shown above:
|
||||
|
||||
```bash
|
||||
pinniped get kubeconfig \
|
||||
--no-concierge \
|
||||
--oidc-issuer "https://my-supervisor.example.com/my-issuer" \
|
||||
--oidc-ca-bundle "supervisor_root_ca_cert.pem" \
|
||||
--oidc-request-audience "my-cluster-342klb7h" \
|
||||
--kubeconfig "my-admin-kubeconfig-for-this-cluster.yaml" \
|
||||
> pinniped-kubeconfig.yaml
|
||||
```
|
||||
|
||||
- Use `--no-concierge` to indicate that you are not using the Pinniped Concierge on this cluster.
|
||||
- The `--oidc-issuer` value should exactly match the issuer URL configured in the `kube-apiserver`'s `--oidc-issuer-url` flag and the `spec.issuer` of your Supervisor's FederationDomain.
|
||||
- The `--oidc-ca-bundle` flag is only required when the machine on which you are running this command is not going to trust your Supervisor's FederationDomain's TLS certificates, e.g. if you used a self-signed CA. This file would have the same content as the file that you provided to `kube-apiserver`'s `--oidc-ca-file` flag.
|
||||
- The `--oidc-request-audience` value should exactly match the value that you chose for the `kube-apiserver`'s `--oidc-client-id` flag.
|
||||
- The `--kubeconfig` value is the admin kubeconfig of the cluster for which you would like to generate a Pinniped-compatible kubeconfig. This is not needed when your current context is already set to the cluster.
|
||||
- The command will output the new Pinniped-compatible kubeconfig to stdout. Optionally redirect this to a file.
|
||||
|
||||
## Example of configuring these kube-apiserver flags on kind
|
||||
|
||||
[kind](https://kind.sigs.k8s.io) is a tool for creating and managing Kubernetes clusters on your local machine
|
||||
which uses Docker containers as the cluster's nodes. This is a convenient way to try out this feature on a local
|
||||
non-production cluster.
|
||||
|
||||
The following steps deploy the latest release of Pinniped on kind using the local-user-authenticator component
|
||||
as the authenticator.
|
||||
|
||||
1. Install the tools required for the following steps.
|
||||
|
||||
- [Install kind](https://kind.sigs.k8s.io/docs/user/quick-start/), if not already installed. For example, `brew install kind` on macOS.
|
||||
|
||||
- kind depends on Docker. If not already installed, [install Docker](https://docs.docker.com/get-docker/), for example `brew cask install docker` on macOS.
|
||||
|
||||
- This demo requires `kubectl`, which comes with Docker, or can be [installed separately](https://kubernetes.io/docs/tasks/tools/install-kubectl/).
|
||||
|
||||
- [Install the Pinniped command-line tool]({{< ref "../howto/install-cli" >}}).
|
||||
|
||||
1. Create a kind configuration yaml file to ask kind to configure the `kube-apiserver` flags. Note that some of these
|
||||
values will need to be adjusted as described in the comments below before using this file in the next step.
|
||||
|
||||
```yaml
|
||||
kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
nodes:
|
||||
- role: control-plane
|
||||
extraMounts:
|
||||
# Adjust this path to your CA PEM file. Use an absolute path.
|
||||
- hostPath: /Users/ryan/supervisor_root_ca_cert.pem
|
||||
# This is under /etc/ca-certificates because the kube-apiserver
|
||||
# pod already mounts the /etc/ca-certificates host path on kind.
|
||||
containerPath: /etc/ca-certificates/supervisor/root-ca.pem
|
||||
readOnly: true
|
||||
kubeadmConfigPatches:
|
||||
- |
|
||||
apiVersion: kubeadm.k8s.io/v1beta3
|
||||
kind: ClusterConfiguration
|
||||
apiServer:
|
||||
extraArgs:
|
||||
# Adjust the values for all these flags as described in the
|
||||
# sections above.
|
||||
oidc-issuer-url: "https://my-supervisor.example.com/my-issuer"
|
||||
oidc-client-id: "my-cluster-342klb7h" # choose a unique value
|
||||
oidc-signing-algs: "ES256"
|
||||
oidc-username-claim: "username"
|
||||
oidc-groups-claim: "groups"
|
||||
oidc-username-prefix: "pinniped:"
|
||||
oidc-groups-prefix: "pinniped:"
|
||||
oidc-ca-file: "/etc/ca-certificates/supervisor/root-ca.pem"
|
||||
```
|
||||
|
||||
Save this as a new yaml file, for example `cluster-config.yaml`.
|
||||
|
||||
1. Create a new Kubernetes cluster using `kind create cluster --config cluster-config.yaml`. Optionally provide a cluster name using the `--name` flag.
|
||||
kind automatically updates your kubeconfig to point to the new cluster as a user with administrator-like permissions.
|
||||
Wait for this command to successfully complete before moving on.
|
||||
|
||||
1. Create a Pinniped-compatible kubeconfig for this new cluster. Note that the previous `kind create cluster` command
|
||||
automatically changed your current kubeconfig context to point at the new cluster.
|
||||
|
||||
```sh
|
||||
pinniped get kubeconfig \
|
||||
--no-concierge \
|
||||
--oidc-issuer "https://my-supervisor.example.com/my-issuer" \
|
||||
--oidc-ca-bundle "supervisor_root_ca_cert.pem" \
|
||||
--oidc-request-audience "my-cluster-342klb7h" \
|
||||
> /tmp/pinniped-kubeconfig.yaml
|
||||
```
|
||||
|
||||
1. Try using the generated kubeconfig to issue arbitrary `kubectl` commands. The first time you run a kubectl command,
|
||||
you will be automatically prompted to authenticate using the external identity provider that is configured in the Pinniped Supervisor.
|
||||
|
||||
```sh
|
||||
kubectl --kubeconfig /tmp/pinniped-kubeconfig.yaml get pods -A
|
||||
```
|
||||
|
||||
Because this user has no RBAC permissions on this cluster, the previous command
|
||||
results in the error `Error from server (Forbidden): pods is forbidden: User "your-username-will-show-here" cannot list resource "pods" in API group "" at the cluster scope`,
|
||||
where `your-username-will-show-here` will be your actual username from the Pinniped Supervisor.
|
||||
However, this error does prove that you are authenticated and acting as that identity from the Pinniped Supervisor on this kind cluster.
|
||||
|
||||
If desired, you can use the administrator kubeconfig to create RBAC RoleBindings and ClusterRoleBindings for
|
||||
that user or for the groups to which that user belongs.
|
||||
|
||||
1. Carry on issuing as many `kubectl` commands as you'd like as that user. You will not be prompted to log in again for 9 hours
|
||||
for this cluster or for any other similarly configured cluster which uses the same Pinniped Supervisor FederationDomain issuer.
|
||||
Each time a few minutes have passed, the next kubectl command will use the Pinniped command-line tool to securely refresh your identity
|
||||
from the external identity provider that is configured in the Pinniped Supervisor without user interaction. During this refresh, your group
|
||||
memberships may be updated from the external identity provider, or you may be prompted to log in again if the Pinniped
|
||||
Supervisor determines that external identity provider does not want your session to continue.
|
||||
|
||||
You may find it convenient to set the `KUBECONFIG` environment variable rather than passing `--kubeconfig` to each invocation.
|
||||
|
||||
```sh
|
||||
export KUBECONFIG=/tmp/pinniped-kubeconfig.yaml
|
||||
kubectl get namespaces
|
||||
kubectl get pods -A
|
||||
```
|
||||
|
||||
Alternatively, you could use the `kubectl config view` command to merge this kubeconfig into another kubeconfig.
|
||||
|
||||
1. Take a look at the contents of the `/tmp/pinniped-kubeconfig.yaml` file. It does not contain any particular
|
||||
user's identity, nor does it contain any credentials. It only contains a recipe for how any user can authenticate.
|
||||
You can safely distribute this file to all users of this cluster. Anyone who uses this kubeconfig will be prompted
|
||||
to authenticate using the external identity provider that is configured in the Pinniped Supervisor. Each user will
|
||||
need to [install the Pinniped command-line tool]({{< ref "../howto/install-cli" >}}) on any machine where they would
|
||||
like to use the kubeconfig.
|
||||
|
||||
## A brief note about the future
|
||||
|
||||
There is an outstanding Kubernetes enhancement proposal to make this Kubernetes API server's OIDC authentication
|
||||
settings configurable using a new Kubernetes API resource. At the time of writing this Pinniped document, the
|
||||
proposal is still under review by the Kubernetes maintainers. If implemented in a future release of Kubernetes,
|
||||
this would remove the need to edit the command-line flags of the `kube-apiserver` binary, making it easier
|
||||
to configure an OIDC provider for your cluster in a standard way. The details and status of this proposal
|
||||
may be found in [KEP-3331](https://github.com/kubernetes/enhancements/pull/3332).
|
Loading…
Reference in New Issue
Block a user