From d313e5d493f63ecb3842db6a50d07581d3798e57 Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Wed, 10 Aug 2016 17:50:55 -0700 Subject: [PATCH] *: add example for running on kubernetes --- cmd/example-app/main.go | 2 +- cmd/poke/config.go | 22 ++--- example/k8s/.gitignore | 1 + example/k8s/README.md | 19 ++++ example/{ => k8s}/client.yaml | 1 + example/k8s/config-k8s.yaml | 13 +++ example/k8s/deployment.yaml | 38 ++++++++ example/k8s/dex-ingress.yaml | 28 ++++++ example/k8s/gencert.sh | 26 ++++++ example/k8s/nginx-ingress.yaml | 100 +++++++++++++++++++++ example/{ => k8s}/thirdpartyresources.yaml | 0 11 files changed, 239 insertions(+), 11 deletions(-) create mode 100644 example/k8s/.gitignore create mode 100644 example/k8s/README.md rename example/{ => k8s}/client.yaml (99%) create mode 100644 example/k8s/config-k8s.yaml create mode 100644 example/k8s/deployment.yaml create mode 100644 example/k8s/dex-ingress.yaml create mode 100755 example/k8s/gencert.sh create mode 100644 example/k8s/nginx-ingress.yaml rename example/{ => k8s}/thirdpartyresources.yaml (100%) diff --git a/cmd/example-app/main.go b/cmd/example-app/main.go index 60223e4a..56d1a2c8 100644 --- a/cmd/example-app/main.go +++ b/cmd/example-app/main.go @@ -94,7 +94,7 @@ func cmd() *cobra.Command { } // This sets the OAuth2 client and oidc client. - a.ctx = context.WithValue(a.ctx, oauth2.HTTPClient, &client) + a.ctx = context.WithValue(a.ctx, oauth2.HTTPClient, client) } // TODO(ericchiang): Retry with backoff diff --git a/cmd/poke/config.go b/cmd/poke/config.go index 89d1ae21..ed39beb3 100644 --- a/cmd/poke/config.go +++ b/cmd/poke/config.go @@ -47,23 +47,25 @@ func (s *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error { return err } s.Type = storageMeta.Type - var c struct { - Config StorageConfig `yaml:"config"` - } // TODO(ericchiang): replace this with a registration process. + var err error switch storageMeta.Type { case "kubernetes": - c.Config = &kubernetes.Config{} + var config struct { + Config kubernetes.Config `yaml:"config"` + } + err = unmarshal(&config) + s.Config = &config.Config case "memory": - c.Config = &memory.Config{} + var config struct { + Config memory.Config `yaml:"config"` + } + err = unmarshal(&config) + s.Config = &config.Config default: return fmt.Errorf("unknown storage type %q", storageMeta.Type) } - if err := unmarshal(c); err != nil { - return err - } - s.Config = c.Config - return nil + return err } // StorageConfig is a configuration that can create a storage. diff --git a/example/k8s/.gitignore b/example/k8s/.gitignore new file mode 100644 index 00000000..6a0b115e --- /dev/null +++ b/example/k8s/.gitignore @@ -0,0 +1 @@ +ssl/ diff --git a/example/k8s/README.md b/example/k8s/README.md new file mode 100644 index 00000000..28cfe643 --- /dev/null +++ b/example/k8s/README.md @@ -0,0 +1,19 @@ +# Running dex as the Kubernetes + +``` +kubectl create -f thirdpartyresources.yaml +kubectl create configmap dex-config --from-file=config.yaml=config-k8s.yaml +kubectl create -f deployment.yaml +``` + +``` +kubectl create -f https://raw.githubusercontent.com/kubernetes/contrib/master/ingress/controllers/nginx/rc.yaml +./gencert.sh +kubectl create secret tls dex.example.com.tls --cert=ssl/cert.pem --key=ssl/key.pem +kubectl create -f dex-ingress.yaml +``` + +``` +kubectl create -f client.yaml +../../bin/example-app --issuer https://dex.example.com --issuer-root-ca ssl/ca.pem +``` diff --git a/example/client.yaml b/example/k8s/client.yaml similarity index 99% rename from example/client.yaml rename to example/k8s/client.yaml index aa974230..b294c6f9 100644 --- a/example/client.yaml +++ b/example/k8s/client.yaml @@ -3,6 +3,7 @@ apiVersion: oauth2clients.oidc.coreos.com/v1 metadata: name: example-app namespace: default + secret: ZXhhbXBsZS1hcHAtc2VjcmV0 redirectURIs: - http://127.0.0.1:5555/callback diff --git a/example/k8s/config-k8s.yaml b/example/k8s/config-k8s.yaml new file mode 100644 index 00000000..a2720016 --- /dev/null +++ b/example/k8s/config-k8s.yaml @@ -0,0 +1,13 @@ +issuer: https://dex.example.com +storage: + type: kubernetes + config: + inCluster: true + +web: + http: 0.0.0.0:5556 + +connectors: +- type: mock + id: mock + name: Mock diff --git a/example/k8s/deployment.yaml b/example/k8s/deployment.yaml new file mode 100644 index 00000000..c059d59c --- /dev/null +++ b/example/k8s/deployment.yaml @@ -0,0 +1,38 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + labels: + app: dex + name: dex +spec: + replicas: 1 + template: + metadata: + labels: + app: dex + spec: + containers: + - image: quay.io/ericchiang/poke + name: dex + command: + - "/poke" + - "serve" + - "/dex/config.yaml" + env: + # A value required for dex's Kubernetes client. + - name: KUBERNETES_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + + ports: + - containerPort: 5556 + name: worker-port + + volumeMounts: + - name: config-volume + mountPath: /dex + volumes: + - name: config-volume + configMap: + name: dex-config diff --git a/example/k8s/dex-ingress.yaml b/example/k8s/dex-ingress.yaml new file mode 100644 index 00000000..1c52fb09 --- /dev/null +++ b/example/k8s/dex-ingress.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + name: dex +spec: + ports: + - name: dex + port: 5556 + selector: + app: dex +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: dex +spec: + tls: + - secretName: dex.example.com.tls + hosts: + - dex.example.com + rules: + - host: dex.example.com + http: + paths: + - backend: + serviceName: dex + servicePort: 5556 + path: / diff --git a/example/k8s/gencert.sh b/example/k8s/gencert.sh new file mode 100755 index 00000000..77435857 --- /dev/null +++ b/example/k8s/gencert.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +mkdir -p ssl + +cat << EOF > ssl/req.cnf +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name + +[req_distinguished_name] + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = dex.example.com +EOF + +openssl genrsa -out ssl/ca-key.pem 2048 +openssl req -x509 -new -nodes -key ssl/ca-key.pem -days 10 -out ssl/ca.pem -subj "/CN=kube-ca" + +openssl genrsa -out ssl/key.pem 2048 +openssl req -new -key ssl/key.pem -out ssl/csr.pem -subj "/CN=kube-ca" -config ssl/req.cnf +openssl x509 -req -in ssl/csr.pem -CA ssl/ca.pem -CAkey ssl/ca-key.pem -CAcreateserial -out ssl/cert.pem -days 10 -extensions v3_req -extfile ssl/req.cnf diff --git a/example/k8s/nginx-ingress.yaml b/example/k8s/nginx-ingress.yaml new file mode 100644 index 00000000..9740ff5a --- /dev/null +++ b/example/k8s/nginx-ingress.yaml @@ -0,0 +1,100 @@ +apiVersion: v1 +kind: Service +metadata: + name: default-http-backend + labels: + k8s-app: default-http-backend +spec: + ports: + - port: 80 + targetPort: 8080 + protocol: TCP + name: http + selector: + k8s-app: default-http-backend +--- +apiVersion: v1 +kind: ReplicationController +metadata: + name: default-http-backend +spec: + replicas: 1 + selector: + k8s-app: default-http-backend + template: + metadata: + labels: + k8s-app: default-http-backend + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: default-http-backend + # Any image is permissable as long as: + # 1. It serves a 404 page at / + # 2. It serves 200 on a /healthz endpoint + image: gcr.io/google_containers/defaultbackend:1.0 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + ports: + - containerPort: 8080 + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi +--- +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: nginx-ingress-controller + labels: + k8s-app: nginx-ingress-lb +spec: + replicas: 1 + selector: + web-frontend + template: + metadata: + labels: + k8s-app: nginx-ingress-lb + name: nginx-ingress-lb + spec: + terminationGracePeriodSeconds: 60 + containers: + - image: gcr.io/google_containers/nginx-ingress-controller:0.8.2 + name: nginx-ingress-lb + imagePullPolicy: Always + livenessProbe: + httpGet: + path: /healthz + port: 10249 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + # use downward API + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - containerPort: 443 + hostPort: 443 + # we expose 18080 to access nginx stats in url /nginx-status + # this is optional + - containerPort: 18080 + hostPort: 18080 + args: + - /nginx-ingress-controller + - --default-backend-service=default/default-http-backend diff --git a/example/thirdpartyresources.yaml b/example/k8s/thirdpartyresources.yaml similarity index 100% rename from example/thirdpartyresources.yaml rename to example/k8s/thirdpartyresources.yaml