2020-09-15 19:10:20 +00:00
# Trying Pinniped
## Prerequisites
2020-09-25 00:55:53 +00:00
1. A Kubernetes cluster of a type supported by Pinniped as described in [doc/architecture.md ](../doc/architecture.md ).
2020-09-15 19:10:20 +00:00
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.
2020-09-25 00:55:53 +00:00
1. An identity provider of a type supported by Pinniped as described in [doc/architecture.md ](../doc/architecture.md ).
2020-09-15 19:10:20 +00:00
2020-10-06 23:35:58 +00:00
Don't have an identity provider of a type supported by Pinniped handy? No problem, there is a demo identity provider
available. Start by installing local-user-authenticator on the same cluster where you would like to try Pinniped
2020-10-09 17:00:22 +00:00
by following the directions in [deploy/local-user-authenticator/README.md ](../deploy/local-user-authenticator/README.md ).
2020-09-15 19:10:20 +00:00
See below for an example of deploying this on kind.
2020-09-25 00:55:53 +00:00
1. A kubeconfig where the current context points to the cluster and has admin-like
privileges on that cluster.
2020-10-06 23:35:58 +00:00
## Overview
2020-09-15 19:10:20 +00:00
2020-09-25 00:55:53 +00:00
Installing and trying Pinniped on any cluster will consist of the following general steps. See the next section below
for a more specific example of installing onto a local kind cluster, including the exact commands to use for that case.
2020-10-09 17:00:22 +00:00
1. Install Pinniped. See [deploy/concierge/README.md ](../deploy/concierge/README.md ).
2020-09-17 17:56:54 +00:00
1. Download the Pinniped CLI from [Pinniped's github Releases page ](https://github.com/vmware-tanzu/pinniped/releases/latest ).
2020-09-15 19:10:20 +00:00
1. Generate a kubeconfig using the Pinniped CLI. Run `pinniped get-kubeconfig --help` for more information.
2020-09-25 00:55:53 +00:00
1. Run `kubectl` commands using the generated kubeconfig. Pinniped will automatically be used for authentication during those commands.
2020-09-15 19:10:20 +00:00
2020-10-06 23:35:58 +00:00
## Example of Deploying 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 Pinniped on a local
non-production cluster.
The following steps will deploy the latest release of Pinniped on kind using the local-user-authenticator component
as the identity provider.
<!-- The following image was uploaded to GitHub's CDN using this awesome trick: https://gist.github.com/vinkla/dca76249ba6b73c5dd66a4e986df4c8d -->
< p align = "center" width = "100%" >
2020-10-09 17:00:22 +00:00
< img
2020-10-07 00:11:08 +00:00
src="https://user-images.githubusercontent.com/25013435/95272990-b2ea9780-07f6-11eb-994d-872e3cb68457.gif"
2020-10-09 17:00:22 +00:00
alt="Pinniped Installation Demo"
2020-10-06 23:35:58 +00:00
width="80%"
/>
< / p >
2020-09-15 19:10:20 +00:00
1. Install the tools required for the following steps.
2020-09-25 00:55:53 +00:00
- [Install kind ](https://kind.sigs.k8s.io/docs/user/quick-start/ ), if not already installed. e.g. `brew install kind` on MacOS.
2020-09-15 19:10:20 +00:00
2020-09-25 00:55:53 +00:00
- kind depends on Docker. If not already installed, [install Docker ](https://docs.docker.com/get-docker/ ), e.g. `brew cask install docker` on MacOS.
2020-09-15 19:10:20 +00:00
- This demo requires `kubectl` , which comes with Docker, or can be [installed separately ](https://kubernetes.io/docs/tasks/tools/install-kubectl/ ).
- This demo requires a tool capable of generating a `bcrypt` hash in order to interact with
the webhook. The example below uses `htpasswd` , which is installed on most macOS systems, and can be
installed on some Linux systems via the `apache2-utils` package (e.g., `apt-get install
apache2-utils`).
2020-09-25 00:55:53 +00:00
- One of the steps below optionally uses `jq` to help find the latest release version number. It is not required.
Install `jq` if you would like, e.g. `brew install jq` on MacOS.
2020-09-15 19:10:20 +00:00
1. Create a new Kubernetes cluster using `kind create cluster` . Optionally provide a cluster name using the `--name` flag.
2020-09-25 00:55:53 +00:00
kind will automatically update your kubeconfig to point to the new cluster as a user with admin-like permissions.
2020-09-15 19:10:20 +00:00
2020-09-25 00:55:53 +00:00
1. Query GitHub's API for the git tag of the latest Pinniped
[release ](https://github.com/vmware-tanzu/pinniped/releases/latest ).
2020-09-15 19:10:20 +00:00
2020-09-25 00:55:53 +00:00
```bash
pinniped_version=$(curl https://api.github.com/repos/vmware-tanzu/pinniped/releases/latest -s | jq .name -r)
```
Alternatively, [any release version ](https://github.com/vmware-tanzu/pinniped/releases )
number can be manually selected.
2020-09-15 19:10:20 +00:00
2020-09-25 00:55:53 +00:00
```bash
# Example of manually choosing a release version...
pinniped_version=v0.2.0
```
2020-10-06 23:35:58 +00:00
1. Deploy the local-user-authenticator app. This is a demo identity provider. In production, you would use your
real identity provider, and therefore would not need to deploy or configure local-user-authenticator.
2020-09-15 19:10:20 +00:00
```bash
2020-10-02 23:44:27 +00:00
kubectl apply -f https://github.com/vmware-tanzu/pinniped/releases/download/$pinniped_version/install-local-user-authenticator.yaml
2020-09-15 19:10:20 +00:00
```
2020-09-25 00:55:53 +00:00
The `install-local-user-authenticator.yaml` file includes the default deployment options.
If you would prefer to customize the available options, please
2020-10-09 17:00:22 +00:00
see [deploy/local-user-authenticator/README.md ](../deploy/local-user-authenticator/README.md )
2020-09-25 00:55:53 +00:00
for instructions on how to deploy using `ytt` .
2020-10-06 23:35:58 +00:00
1. Create a test user named `pinny-the-seal` in the local-user-authenticator identity provider.
2020-09-15 19:10:20 +00:00
```bash
kubectl create secret generic pinny-the-seal \
--namespace local-user-authenticator \
--from-literal=groups=group1,group2 \
--from-literal=passwordHash=$(htpasswd -nbBC 10 x password123 | sed -e "s/^x://")
```
2020-10-06 23:35:58 +00:00
1. Fetch the auto-generated CA bundle for the local-user-authenticator's HTTP TLS endpoint.
2020-09-15 19:10:20 +00:00
```bash
Rename many of resources that are created in Kubernetes by Pinniped
New resource naming conventions:
- Do not repeat the Kind in the name,
e.g. do not call it foo-cluster-role-binding, just call it foo
- Names will generally start with a prefix to identify our component,
so when a user lists all objects of that kind, they can tell to which
component it is related,
e.g. `kubectl get configmaps` would list one named "pinniped-config"
- It should be possible for an operator to make the word "pinniped"
mostly disappear if they choose, by specifying the app_name in
values.yaml, to the extent that is practical (but not from APIService
names because those are hardcoded in golang)
- Each role/clusterrole and its corresponding binding have the same name
- Pinniped resource names that must be known by the server golang code
are passed to the code at run time via ConfigMap, rather than
hardcoded in the golang code. This also allows them to be prepended
with the app_name from values.yaml while creating the ConfigMap.
- Since the CLI `get-kubeconfig` command cannot guess the name of the
CredentialIssuerConfig resource in advance anymore, it lists all
CredentialIssuerConfig in the app's namespace and returns an error
if there is not exactly one found, and then uses that one regardless
of its name
2020-09-18 22:56:50 +00:00
kubectl get secret local-user-authenticator-tls-serving-certificate --namespace local-user-authenticator \
2020-09-15 19:10:20 +00:00
-o jsonpath={.data.caCertificate} \
2020-09-17 23:08:45 +00:00
| tee /tmp/local-user-authenticator-ca-base64-encoded
2020-09-15 19:10:20 +00:00
```
2020-09-25 00:55:53 +00:00
2020-09-15 19:10:20 +00:00
1. Deploy Pinniped.
```bash
2020-10-02 23:44:27 +00:00
kubectl apply -f https://github.com/vmware-tanzu/pinniped/releases/download/$pinniped_version/install-pinniped.yaml
2020-09-15 19:10:20 +00:00
```
2020-09-25 00:55:53 +00:00
The `install-pinniped.yaml` file includes the default deployment options.
2020-10-09 17:00:22 +00:00
If you would prefer to customize the available options, please see [deploy/concierge/README.md ](../deploy/concierge/README.md )
2020-09-25 00:55:53 +00:00
for instructions on how to deploy using `ytt` .
2020-10-30 16:39:26 +00:00
1. Create a `WebhookAuthenticator` object to configure Pinniped to authenticate using local-user-authenticator.
2020-09-22 00:55:04 +00:00
```bash
cat < < EOF | kubectl create --namespace pinniped -f -
2020-10-30 16:03:25 +00:00
apiVersion: authentication.concierge.pinniped.dev/v1alpha1
2020-10-30 16:39:26 +00:00
kind: WebhookAuthenticator
2020-09-22 00:55:04 +00:00
metadata:
name: local-user-authenticator
spec:
endpoint: https://local-user-authenticator.local-user-authenticator.svc/authenticate
tls:
certificateAuthorityData: $(cat /tmp/local-user-authenticator-ca-base64-encoded)
EOF
```
2020-09-15 19:10:20 +00:00
1. Download the latest version of the Pinniped CLI binary for your platform
2020-09-25 00:55:53 +00:00
from Pinniped's [latest release ](https://github.com/vmware-tanzu/pinniped/releases/latest ).
2020-09-15 19:10:20 +00:00
2020-09-25 00:55:53 +00:00
1. Move the Pinniped CLI binary to your preferred filename and directory. Add the executable bit,
2020-09-15 19:10:20 +00:00
e.g. `chmod +x /usr/local/bin/pinniped` .
2020-09-17 23:08:45 +00:00
1. Generate a kubeconfig for the current cluster. Use `--token` to include a token which should
allow you to authenticate as the user that you created above.
2020-09-15 19:10:20 +00:00
```bash
2020-10-30 19:02:21 +00:00
pinniped get-kubeconfig --token "pinny-the-seal:password123" --authenticator-type webhook --authenticator-name local-user-authenticator > /tmp/pinniped-kubeconfig
2020-09-15 19:10:20 +00:00
```
Rename many of resources that are created in Kubernetes by Pinniped
New resource naming conventions:
- Do not repeat the Kind in the name,
e.g. do not call it foo-cluster-role-binding, just call it foo
- Names will generally start with a prefix to identify our component,
so when a user lists all objects of that kind, they can tell to which
component it is related,
e.g. `kubectl get configmaps` would list one named "pinniped-config"
- It should be possible for an operator to make the word "pinniped"
mostly disappear if they choose, by specifying the app_name in
values.yaml, to the extent that is practical (but not from APIService
names because those are hardcoded in golang)
- Each role/clusterrole and its corresponding binding have the same name
- Pinniped resource names that must be known by the server golang code
are passed to the code at run time via ConfigMap, rather than
hardcoded in the golang code. This also allows them to be prepended
with the app_name from values.yaml while creating the ConfigMap.
- Since the CLI `get-kubeconfig` command cannot guess the name of the
CredentialIssuerConfig resource in advance anymore, it lists all
CredentialIssuerConfig in the app's namespace and returns an error
if there is not exactly one found, and then uses that one regardless
of its name
2020-09-18 22:56:50 +00:00
2020-09-25 19:56:45 +00:00
If you are using MacOS, you may get an error dialog that says
`“pinniped” cannot be opened because the developer cannot be verified` . Cancel this dialog, open System Preferences,
click on Security & Privacy, and click the Allow Anyway button next to the Pinniped message.
Run the above command again and another dialog will appear saying
`macOS cannot verify the developer of “pinniped”. Are you sure you want to open it?` .
Click Open to allow the command to proceed.
2020-09-18 16:24:04 +00:00
Note that the above command will print a warning to the screen. You can ignore this warning.
Pinniped tries to auto-discover the URL for the Kubernetes API server, but it is not able
to do so on kind clusters. The warning is just letting you know that the Pinniped CLI decided
to ignore the auto-discovery URL and instead use the URL from your existing kubeconfig.
2020-09-15 19:10:20 +00:00
2020-09-17 23:08:45 +00:00
1. Try using the generated kubeconfig to issue arbitrary `kubectl` commands as
the `pinny-the-seal` user.
```bash
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped
```
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 "pinny-the-seal" cannot list resource "pods" in API group "" in the namespace "pinniped"` .
2020-10-06 23:35:58 +00:00
However, this does prove that you are authenticated and acting as the `pinny-the-seal` user.
2020-09-17 23:08:45 +00:00
2020-09-25 00:55:53 +00:00
1. As the admin user, create RBAC rules for the test user to give them permissions to perform actions on the cluster.
2020-09-15 19:10:20 +00:00
For example, grant the test user permission to view all cluster resources.
```bash
kubectl create clusterrolebinding pinny-can-read --clusterrole view --user pinny-the-seal
```
1. Use the generated kubeconfig to issue arbitrary `kubectl` commands as the `pinny-the-seal` user.
```bash
kubectl --kubeconfig /tmp/pinniped-kubeconfig get pods -n pinniped
```
2020-09-17 23:08:45 +00:00
2020-09-25 00:55:53 +00:00
The user has permission to list pods, so the command succeeds this time.
Pinniped has provided authentication into the cluster for your `kubectl` command! 🎉
1. Carry on issuing as many `kubectl` commands as you'd like as the `pinny-the-seal` user.
Each invocation will use Pinniped for authentication.
You may find it convenient to set the `KUBECONFIG` environment variable rather than passing `--kubeconfig` to each invocation.
```bash
export KUBECONFIG=/tmp/pinniped-kubeconfig
kubectl get namespaces
kubectl get pods -A
```
1. Profit! 💰