[stable/kuberos] (New Chart). Kuberos is a handy ODIC configurator so appropriate others can get kubectl config (#6469)

* Adding Kuberos, a handy ODIC configurator

* [stable/kuberos] updated link in README

* [stable/kuberos] using kuberos-port in service.yaml
This commit is contained in:
Timothy Clarke
2018-07-20 15:58:45 -07:00
committed by k8s-ci-robot
parent c90a85480c
commit 9f78ebf325
11 changed files with 416 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
+11
View File
@@ -0,0 +1,11 @@
apiVersion: v1
appVersion: "2018-07-03"
description: An OIDC authentication helper for Kubernetes
name: kuberos
version: 0.1.0
home: https://github.com/negz/kuberos
sources:
- https://github.com/negz/kuberos
maintainers:
- name: timothyclarke
email: ghtimothy@timothy.fromnz.net
+90
View File
@@ -0,0 +1,90 @@
# Kuberos OIDC Helper
This is a config snippet generator for a k8s cluster
## TL;DR;
Sorry you will need to look at the [configuration](#configuration) values below for this one.
```console
$ helm install incubator/kuberos -f custom-values.yaml
```
## Warning
The config snippets that are generated from this chart include OIDC connection details in clear text.
These include content that would normally be in secrets.
## Introduction
This chart deploys the [kuberos](https://github.com/negz/kuberos) code
snippet generator for clusters using both
* OIDC - OpenID Connect, an authentication layer on top of OAuth 2.0
* RBAC - Role Based Access Controlls (in your k8s cluster)
It provides a quick and easy way for an authenticated user to generate
and download config for kubectl.
This work is [inspired from step 7 of the work](https://medium.com/@noqcks/secure-your-kubernetes-cluster-with-google-oidc-e1905c923522)
@noqcks did using other tooling.
## Prerequisites
- Kubernetes 1.8+ with RBAC enabled
- An OIDC provider eg G Suite
- RBAC on your cluster configured to use OIDC
## Configuration
The following table lists the configurable parameters of the kuberos chart
## Config params which probably need changing
These ones will be site specific and may contain sensitive information
| Parameter | Description | Default |
| --------------------------- | ------------------------------- | ----------------------------------------------------- |
| `kuberos` | App Specific config options | See below |
| `oidcClientURL` | URL of OIDC provider endpoint | `https://accounts.google.com` |
| `oidcClientID` | Your unique client ID | `REDACTED.apps.googleusercontent.com` |
| `oidcSecret` | The password for the Client ID above. | Junk [See Provider below](#oidc-provider-setup) |
| `clusters` | List of clusters to generate config for | See below |
| `name` | The friendly name of the cluster | `dev-cluster` |
| `apiServer` | The endpoint for kubectl to use | `'https://api.dev-cluster.example.com` |
| `caCrt` | The Public CA cert for the cluster | See values.yaml |
| `ingress` | A standard ingress block | See below |
| `enabled` | Enables or Disables the ingress block | `false` |
| `annotations` | Ingress annotations | `{}` |
| `hosts` | List of FQDN's the be browsed to | Not Set |
| `tls` | List of SSL certs to use | Empty list |
| `secretName` | Name of the secret to use | Not Set |
| `hosts` | List of FQDN's the above secret is associated with| Not Set |
### Other Config params can be left alone
In some conditions you might want to set `image.tag` to `latest` and then `image.pullPolicy` to `Always`
this is generally advised against for stability reasons.
In general config params not listed above can be ignored / left alone.
The rest of the params are standard enough the google and other charts will be better at explaining them than me
## OIDC (Provider) Setup
You will need to obtain the OIDC details of the provider you need to use. This will contain the Issuer URL, Client ID and the Client Secret.
In the case of Google (The provider which was used when initially creating this) go to the [Developer / Credentials](https://console.developers.google.com/apis/credentials) console. You will need to add the ingress url to both
* *Authorised JavaScript origins* - https://kuberos.example.com
* *Authorised redirect URIs* - https://kuberos.example.com/ui
If you used kops the credentials you're after are
```
apiVersion: kops/v1alpha2
kind: Cluster
authorization:
rbac: {}
kubeAPIServer:
authorizationRbacSuperUser: admin
oidcClientID: UNIQUE_ID_REDACTED.apps.googleusercontent.com
oidcIssuerURL: https://accounts.google.com
oidcUsernameClaim: email
```
For G Suite :
The redacted part of a ClientID is about 45 alphanumeric characters long (may also contain a hyphen or two)
The client secret will be about 25 alphanumeric chacters (may also contain a hyphen or two)
+19
View File
@@ -0,0 +1,19 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range .Values.ingress.hosts }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ . }}{{ $.Values.ingress.path }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "kuberos.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ template "kuberos.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "kuberos.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "kuberos.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
{{- end }}
+37
View File
@@ -0,0 +1,37 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "kuberos.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "kuberos.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "kuberos.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "kuberos.defaultCluster" -}}
{{- printf "%s" (index .Values.kuberos.clusters 0).name -}}
{{- end -}}
+17
View File
@@ -0,0 +1,17 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "kuberos.fullname" . }}-config
data:
template: |-
apiVersion: v1
kind: Config
current-context: {{ (index .Values.kuberos.clusters 0).name }}
clusters:
{{ range .Values.kuberos.clusters }}
- name: {{ .name }}
cluster:
certificate-authority-data: {{ .caCrt | b64enc | quote }}
server: {{ .apiServer }}
{{- end }}
+70
View File
@@ -0,0 +1,70 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ template "kuberos.fullname" . }}
labels:
app: {{ template "kuberos.name" . }}
chart: {{ template "kuberos.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ template "kuberos.name" . }}
release: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ template "kuberos.name" . }}
release: {{ .Release.Name }}
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["/kuberos", "{{ .Values.kuberos.oidcClientURL }}", "{{ .Values.kuberos.oidcClientID }}", "/cfg/secret", "/cfg/template"]
ports:
- name: kuberos-port
containerPort: 10003
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
port: kuberos-port
readinessProbe:
httpGet:
path: /healthz
port: kuberos-port
resources:
{{ toYaml .Values.resources | indent 12 }}
volumeMounts:
- mountPath: /cfg/template
name: template
subPath: template
- mountPath: /cfg/secret
name: secret
subPath: oidcSecret
volumes:
- name: template
configMap:
name: {{ template "kuberos.fullname" . }}-config
- name: secret
secret:
secretName: {{ template "kuberos.name" . }}-secret
{{- with .Values.nodeSelector }}
nodeSelector:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
+40
View File
@@ -0,0 +1,40 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "kuberos.fullname" . -}}
{{- $servicePort := .Values.service.port -}}
{{- $ingressPath := .Values.ingress.path -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
app: {{ template "kuberos.name" . }}
chart: {{ template "kuberos.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
annotations:
ingress.kubernetes.io/rewrite-target: /
{{- with .Values.ingress.annotations }}
{{ toYaml . | indent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ . }}
http:
paths:
- path: {{ $ingressPath }}
backend:
serviceName: {{ $fullName }}
servicePort: http
{{- end }}
{{- end }}
+10
View File
@@ -0,0 +1,10 @@
---
{{- if .Values.kuberos.oidcSecret -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "kuberos.name" . }}-secret
type: Opaque
data:
oidcSecret: {{ .Values.kuberos.oidcSecret | b64enc | quote }}
{{- end }}
+19
View File
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "kuberos.fullname" . }}
labels:
app: {{ template "kuberos.name" . }}
chart: {{ template "kuberos.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: kuberos-port
protocol: TCP
name: http
selector:
app: {{ template "kuberos.name" . }}
release: {{ .Release.Name }}
+82
View File
@@ -0,0 +1,82 @@
# Default values for kuberos.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
# You probably want to change the values under `kuberos` and `ingress`
# `kuberos` describes the config for the app
kuberos:
oidcClientURL: https://accounts.google.com
# `oidcClientURL` is the endpoint that is used to quesry OIDC info
oidcClientID: REDACTED.apps.googleusercontent.com
# `oidcClientID` is typically a long alpha numeric string.
# For G Suite the 'REDACTED' part is about 45 alphanumeric characters
oidcSecret: super-secret-value-here
# `oidcSecret` is typically a long alpha numeric string.
# For G Suite it's about 25 alphanumeric characters
# For security reasons it's best to set this at deployment time with
# `--set kuberos.oidcSecret=mySuper-secretPassPhrase`
clusters:
# The clusters below must all use the same OIDC details above
# The config snippet that is generated for a user will default
# to the first cluster
- name: dev-cluster
# `name` is a label to apply to the cluster. It would normally be
# the fqdn of the cluster eg dev-cluster.example.com
# it can be something a little more friendly eg dev-cluster
apiServer: https://api.dev-cluster.example.com
# `apiServer` is the url for kubectl
# This is typically https://api.fqdn
caCrt: |-
-----BEGIN CERTIFICATE-----
cert data here
-----END CERTIFICATE-----
# `caCrt` is the public / CA cert for the cluster
ingress:
enabled: false
# Set `enabled` to true to create an ingress and get external traffic to kuberos
annotations: {}
# Add your ingress annotations here. Most common ones are given below
# kubernetes.io/ingress.class: nginx
# certmanager.k8s.io/cluster-issuer: prod-acme
# certmanager.k8s.io/acme-challenge-type: http01
# nginx.ingress.kubernetes.io/force-ssl-redirect: true
path: /
# `path` can stay as-is
hosts:
# Add host headers and cert names below
- chart-example.local
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
image:
repository: negz/kuberos
tag: ede4085
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}