contrib/k8s: update to use 1.2 features

- Consolidate files
- Update to Deployments
- Use Ingress, add ingress controller help in README
- Remove hardcoded namespace in postgres URI
- Remove hardcoded IP addresses
- Add readinessProbes
This commit is contained in:
Andrew Stuart 2016-04-09 00:28:03 -07:00
parent c2c7f03f47
commit 64eeececde
No known key found for this signature in database
GPG key ID: D409317C5B5ACD4D
11 changed files with 263 additions and 193 deletions

View file

@ -6,19 +6,29 @@ This document will allow you to set up dex in your Kubernetes cluster; the examp
The document assumes that you already have a cluster with at least one worker up and running. The easiest way to bring up a small cluster for experimentation is the [coreos-kubernetes single node](coreos-kubernetes-single-node) Vagrant installer.
The other assumption is that your Kubernetes cluster will be routable on `172.17.4.99` (which is what it will be if you use [coreos-kubernetes single node][coreos-kubernetes-single-node], and the issuer URL for your dex installation is `http://172.17.4.99:30556`; in production installations you will need to make sure that you are serving on https and you will likely want to use a hostname rather than an IP address.
The other assumption is that your Kubernetes cluster will be running an appropriate Ingress controller for your environment (see below, or for more advanced or cloud-specific options, see [the Kubernetes Ingress Docs](http://kubernetes.io/docs/user-guide/ingress/#ingress-controllers)).
Additionally, make sure that a `dex.example.com` DNS or `/etc/hosts` entry has been made pointing to the ingress controller Node IP(s).
[coreos-kubernetes-single-node](https://github.com/coreos/coreos-kubernetes/blob/master/single-node/README.md)
## Create Ingress Controller
If you do not already have an ingress controller in place, and if you'd like to use the latest kubernetes/contrib nginx ingress controller, simply run the following:
```bash
kubectl apply -f https://raw.githubusercontent.com/kubernetes/contrib/master/ingress/controllers/nginx/rc.yaml
```
## Start Postgres
Dex needs a database to store information; these commands will create a Postgres service that dex can use. Note that this configuration is not suitable for production - if the container is destroyed, the data is gone forever.
In production you should have a sufficiently fault-tolerant Postgres deployment on a persistent volume with backup.
In production you should have a sufficiently fault-tolerant and secure (TLS enabled) Postgres deployment on a persistent volume with backup.
```
kubectl create -f postgres-rc.yaml
kubectl create -f postgres-service.yaml
```bash
kubectl apply -f postgres.yaml
```
## Create your secrets.
@ -27,17 +37,23 @@ dex needs a secret key for encrypting private keys in the database. These can be
[k8s-secrets]: http://kubernetes.io/v1.0/docs/user-guide/secrets.html
```
kubectl create -f dex-secrets.yaml
The secret will be created as part of the next command, from `dex-overlord.yaml`
If you would like to set up your own secret, you can do the following:
```bash
# For a real secret (i.e. not checked into this public repo), run the following
# and comment out the secret in the dex-overlord.yaml file.
dd if=/dev/random bs=1 count=32 2>/dev/null | base64 | tr -d '\n' | \
kubectl create secret generic dex --from-file=key-secrets=/dev/stdin
```
## Start the Overlord
Start the overlord. This will also initialize your database the first time it's run, and perform migrations when new versions are installed.
```
kubectl create -f dex-overlord-rc.yaml
kubectl create -f dex-overlord-service.yaml
```bash
kubectl apply -f dex-overlord.yaml
```
Note: this will make the admin API available to any pod in the cluster. This API is very powerful, and allows the creation of admin users who can perform any action in dex, including creating, modifying and deleting other users. This will be fixed soon by requirng some sort of authentication.
@ -52,72 +68,54 @@ inside a pod via `kubectl exec`. (note that if your DB is not running on the clu
The other hacky thing is that this needs to happen before the workers start because workers do not (yet!) respond dynamically to connector configuration changes.
First, start a shell session on the overlord pod.
```
DEX_OVERLORD_POD=$(kubectl get pod -l=app=dex,role=overlord -o template --template "{{ (index .items 0).metadata.name }}")
kubectl exec -ti $DEX_OVERLORD_POD -- sh
```
Once we're on the pod, we create a connectors file and upload it to dex.
```bash
DEX_OVERLORD_POD=$(kubectl get pod -l=app=dex,role=overlord -o template --template "{{ (index .items 0).metadata.name }}")
```
DEX_CONNECTORS_FILE=$(mktemp /tmp/dex-conn.XXXXXX)
cat << EOF > $DEX_CONNECTORS_FILE
[
{
"type": "local",
"id": "local"
}
]
EOF
/opt/dex/bin/dexctl --db-url=postgres://postgres@dex-postgres.default:5432/postgres?sslmode=disable set-connector-configs $DEX_CONNECTORS_FILE
exit
kubectl exec $DEX_OVERLORD_POD -- /opt/dex/bin/dexctl --db-url='postgres://postgres@dex-postgres:5432/postgres?sslmode=disable' set-connector-configs '/etc/dex-connectors/connector.json'
```
## Start the Worker
Start the worker. The worker is exposed as an external service so that end-users can access it.
```
kubectl create -f dex-worker-rc.yaml
kubectl create -f dex-worker-service.yaml
```bash
kubectl apply -f dex-worker.yaml
```
## [Create a client](https://github.com/coreos/dex#registering-clients)
We then `eval` that which creates the shell variables `DEX_APP_CLIENT_ID` and `DEX_APP_CLIENT_SECRET`
```
eval "$(kubectl exec $DEX_OVERLORD_POD -- /opt/dex/bin/dexctl --db-url=postgres://postgres@dex-postgres.default:5432/postgres?sslmode=disable new-client http://127.0.0.1:5555/callback )"
```bash
CALLBACK_URL='http://127.0.0.1:5555/callback'
eval "$(kubectl exec $DEX_OVERLORD_POD -- /opt/dex/bin/dexctl --db-url='postgres://postgres@dex-postgres:5432/postgres?sslmode=disable' new-client $CALLBACK_URL )"
```
## Build and Run the Example App
First, go to the root of the dex repo:
```
cd ../..
```bash
cd $GOPATH/src/github.com/coreos/dex
```
Now, build and run the example app.
```
```bash
./build
./bin/example-app --client-id=$DEX_APP_CLIENT_ID --client-secret=$DEX_APP_CLIENT_SECRET --discovery=http://172.17.4.99:30556
./bin/example-app --client-id=$DEX_APP_CLIENT_ID --client-secret=$DEX_APP_CLIENT_SECRET --discovery=http://dex.example.com
```
Now you can register and log-in to your example app: Go to http://127.0.0.1:5555
## Debugging
### psql
Here's how to get psql session.
```
```bash
DEX_PSQL_POD=$(kubectl get pod -l=app=postgres -o template --template "{{ (index .items 0).metadata.name }}")
kubectl exec $DEX_PSQL_POD -ti -- psql postgres://postgres@dex-postgres.default:5432/postgres?sslmode=disable
kubectl exec $DEX_PSQL_POD -ti -- psql 'postgres://postgres@dex-postgres:5432/postgres?sslmode=disable'
```

View file

@ -1,47 +0,0 @@
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: dex
role: overlord
name: dex-overlord
spec:
replicas: 1
selector:
app: dex
role: overlord
template:
metadata:
labels:
app: dex
role: overlord
spec:
containers:
- image: quay.io/coreos/dex
name: dex-overlord
env:
- name: DEX_OVERLORD_DB_URL
value: postgres://postgres@dex-postgres.default:5432/postgres?sslmode=disable
- name: DEX_OVERLORD_ADMIN_LISTEN
value: http://0.0.0.0:5557
command:
- "sh"
- "-c"
- "/opt/dex/bin/dex-overlord --key-secrets=$(cat /etc/dex/key-secrets)"
ports:
- containerPort: 5557
name: overlord-port
livenessProbe:
httpGet:
path: /health
port: 5557
initialDelaySeconds: 15
timeoutSeconds: 1
volumeMounts:
- name: dex
mountPath: "/etc/dex"
readOnly: true
volumes:
- name: dex
secret:
secretName: "dex"

View file

@ -1,13 +0,0 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: dex
role: overlord
name: dex-overlord
spec:
ports:
- port: 5557
selector:
app: dex
role: overlord

View file

@ -0,0 +1,104 @@
apiVersion: v1
kind: Secret
metadata:
name: dex
type: Opaque
data:
key-secrets: ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIZz0= # 32 x's base64 encoded twice.
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: dex
role: overlord
name: dex-overlord
spec:
replicas: 1
template:
metadata:
labels:
app: dex
role: overlord
spec:
containers:
- image: quay.io/coreos/dex
name: dex-overlord
env:
- name: DEX_OVERLORD_DB_URL
value: postgres://postgres@dex-postgres:5432/postgres?sslmode=disable
- name: DEX_OVERLORD_ADMIN_LISTEN
value: http://0.0.0.0:5557
- name: DEX_OVERLORD_KEY_SECRETS
valueFrom:
secretKeyRef:
name: dex
key: key-secrets
command:
- "/opt/dex/bin/dex-overlord"
ports:
- containerPort: 5557
name: overlord-port
livenessProbe:
httpGet:
path: /health
port: 5557
initialDelaySeconds: 16
timeoutSeconds: 1
volumeMounts:
- name: connectors
mountPath: /etc/dex-connectors
# In production, you will likely want to include your own trusted
# /etc/ca-certificates and /etc/ssl in your container.
- name: ca
mountPath: /etc/ca-certificates
readOnly: true
- name: ssl
mountPath: /etc/ssl
readOnly: true
volumes:
- name: connectors
configMap:
name: dex-connectors
- name: ca
hostPath:
path: /etc/ca-certificates
- name: ssl
hostPath:
path: /etc/ssl
---
apiVersion: v1
kind: Service
metadata:
labels:
app: dex
role: overlord
name: dex-overlord
spec:
ports:
- port: 5557
selector:
app: dex
role: overlord
---
apiVersion: v1
kind: ConfigMap
metadata:
name: dex-connectors
data:
connector.json: |
[
{
"id": "local",
"type": "local"
}
]
# google-connector.json: |
# [{
# "id": "google",
# "type": "oidc",
# "issuerURL": "https://accounts.google.com",
# "clientID": "<your id here>",
# "clientSecret": "<your secret here>",
# "trustedEmailProvider": true
# }]

View file

@ -1,7 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: dex
type: Opaque
data:
key-secrets: ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIaDRlSGg0ZUhoNGVIZz0= # 32 x's base64 encoded twice.

View file

@ -1,51 +0,0 @@
apiVersion: v1
kind: ReplicationController
metadata:
labels:
app: dex
role: worker
name: dex-worker
spec:
replicas: 1
selector:
app: dex
role: worker
template:
metadata:
labels:
app: dex
role: worker
spec:
containers:
- image: quay.io/coreos/dex
name: dex-worker
env:
- name: DEX_WORKER_ISSUER
value: http://172.17.4.99:30556
- name: DEX_WORKER_DB_URL
value: postgres://postgres@dex-postgres.default:5432/postgres?sslmode=disable
- name: DEX_WORKER_EMAIL_CFG
value: /opt/dex/email/emailer.json
- name: DEX_WORKER_LISTEN
value: http://0.0.0.0:5556
command:
- "sh"
- "-c"
- "/opt/dex/bin/dex-worker --key-secrets=$(cat /etc/dex/key-secrets)"
ports:
- containerPort: 5556
name: worker-port
livenessProbe:
httpGet:
path: /health
port: 5556
initialDelaySeconds: 15
timeoutSeconds: 1
volumeMounts:
- name: dex
mountPath: "/etc/dex"
readOnly: true
volumes:
- name: dex
secret:
secretName: "dex"

View file

@ -1,17 +0,0 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: dex
role: worker
name: dex-worker
spec:
type: "NodePort"
ports:
- name: "worker"
port: 5556
nodePort: 30556
selector:
app: dex
role: worker

104
contrib/k8s/dex-worker.yaml Normal file
View file

@ -0,0 +1,104 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: dex
role: worker
name: dex-worker
spec:
replicas: 1
template:
metadata:
labels:
app: dex
role: worker
spec:
containers:
- image: quay.io/coreos/dex
name: dex-worker
env:
- name: DEX_WORKER_ISSUER
value: http://dex.example.com
# enable https if you have configured your Ingress with TLS
# value: https://dex.example.com
- name: DEX_WORKER_DB_URL
value: postgres://postgres@dex-postgres:5432/postgres?sslmode=disable
- name: DEX_WORKER_EMAIL_CFG
value: /opt/dex/email/emailer.json
- name: DEX_WORKER_LISTEN
value: http://0.0.0.0:5556
- name: DEX_WORKER_KEY_SECRETS
valueFrom:
secretKeyRef:
name: dex
key: key-secrets
- name: DEX_WORKER_ENABLE_REGISTRATION
value: "true"
command:
- "/opt/dex/bin/dex-worker"
ports:
- containerPort: 5556
name: worker-port
readinessProbe:
httpGet:
path: /health
port: 5556
timeoutSeconds: 1
periodSeconds: 2
livenessProbe:
httpGet:
path: /health
port: 5556
initialDelaySeconds: 15
timeoutSeconds: 1
# In production, you will likely want to include your own trusted
# /etc/ca-certificates and /etc/ssl in your container.
volumeMounts:
- name: ca
mountPath: /etc/ca-certificates
readOnly: true
- name: ssl
mountPath: /etc/ssl
readOnly: true
volumes:
- name: ca
hostPath:
path: /etc/ca-certificates
- name: ssl
hostPath:
path: /etc/ssl
---
apiVersion: v1
kind: Service
metadata:
name: dex-worker
spec:
ports:
- name: worker
port: 5556
selector:
app: dex
role: worker
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dex-worker
spec:
# Uncomment this section to enable tls, after creating a [tls
# secret](http://kubernetes.io/docs/user-guide/ingress/#tls) with the
# appropriate name.
# tls:
# - secretName: dex.example.com.tls
# hosts:
# - dex.example.com
rules:
# Make sure to add dex.example.com to your /etc/hosts or DNS server if you
# run one locally.
- host: dex.example.com
http:
paths:
- path: /
backend:
serviceName: dex-worker
servicePort: 5556

View file

@ -1,11 +0,0 @@
apiVersion: v1
kind: Service
metadata:
labels:
app: postgres
name: dex-postgres
spec:
ports:
- port: 5432
selector:
app: postgres

View file

@ -1,13 +1,11 @@
apiVersion: v1
kind: ReplicationController
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: postgres
name: dex-postgres
spec:
replicas: 1
selector:
app: postgres
template:
metadata:
labels:
@ -19,3 +17,15 @@ spec:
ports:
- containerPort: 5432
name: postgres-port
---
apiVersion: v1
kind: Service
metadata:
labels:
app: postgres
name: dex-postgres
spec:
ports:
- port: 5432
selector:
app: postgres

2
env
View file

@ -16,7 +16,7 @@ done
for V in "${KNOWN_INSECURE[@]}"; do
if [ "$V" = "$FULL_GOVERSION" ]; then
echo "Go version ${V} has known security vulnerabilities which impact dex. Plesae update your Go verison."
echo "Go version ${V} has known security vulnerabilities which impact dex. Please update your Go verison."
exit 2
fi
done