diff options
26 files changed, 441 insertions, 3 deletions
diff --git a/.dockerignore b/.dockerignore index 9c891de..45bcf26 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,6 +2,10 @@ .*swp __pycache__ +.git + push.sh kubernetes -.git +misc +README + @@ -1 +1,4 @@ Custodia Docker container with Kubernetes example config + +Christian Heimes <cheimes@redhat.com> + diff --git a/kubernetes/custodia-forwarder/README b/kubernetes/custodia-forwarder/README new file mode 100644 index 0000000..7294121 --- /dev/null +++ b/kubernetes/custodia-forwarder/README @@ -0,0 +1,4 @@ +Experimental forwarder pod + +The forwarder needs new features like hostPID and privileged containers +from Kubernetes 1.1, which hasn't been released yet. diff --git a/kubernetes/custodia-forwarder/custodia-forwarder-pod.yaml b/kubernetes/custodia-forwarder/custodia-forwarder-pod.yaml new file mode 100644 index 0000000..59378c9 --- /dev/null +++ b/kubernetes/custodia-forwarder/custodia-forwarder-pod.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Pod +metadata: + name: custodia-forwarder + labels: + role: custodia-forwarder +spec: + containers: + - name: custodia-forwarder + image: 10.34.78.249:5000/custodia-server:latest + securityContext: + privileged: true diff --git a/kubernetes/custodia-server/README b/kubernetes/custodia-server/README new file mode 100644 index 0000000..3241209 --- /dev/null +++ b/kubernetes/custodia-server/README @@ -0,0 +1,2 @@ +Custodia end-user example + diff --git a/kubernetes/custodia-server-claim.yaml b/kubernetes/custodia-server/custodia-server-claim.yaml index ce7fb25..ce7fb25 100644 --- a/kubernetes/custodia-server-claim.yaml +++ b/kubernetes/custodia-server/custodia-server-claim.yaml diff --git a/kubernetes/custodia-server-rc.yaml b/kubernetes/custodia-server/custodia-server-rc.yaml index 2664190..7bf3a90 100644 --- a/kubernetes/custodia-server-rc.yaml +++ b/kubernetes/custodia-server/custodia-server-rc.yaml @@ -23,9 +23,7 @@ spec: - containerPort: 8080 name: custodia-server volumeMounts: - # name must match the volume name below - name: custodia-server-persistent-storage - # mount path within the container mountPath: /custodia-data - name: custodia mountPath: /custodia diff --git a/kubernetes/custodia-server-service.yaml b/kubernetes/custodia-server/custodia-server-service.yaml index 825b53b..65032b1 100644 --- a/kubernetes/custodia-server-service.yaml +++ b/kubernetes/custodia-server/custodia-server-service.yaml @@ -8,5 +8,8 @@ spec: ports: - port: 8080 targetPort: 8080 + nodePort: 30779 selector: name: custodia-server + type: NodePort + diff --git a/kubernetes/pv-nfs-custodia.yaml b/kubernetes/custodia-server/pv-nfs-custodia.yaml index cb36f9d..cb36f9d 100644 --- a/kubernetes/pv-nfs-custodia.yaml +++ b/kubernetes/custodia-server/pv-nfs-custodia.yaml diff --git a/kubernetes/secret-example/README b/kubernetes/secret-example/README new file mode 100644 index 0000000..667d3d8 --- /dev/null +++ b/kubernetes/secret-example/README @@ -0,0 +1,2 @@ +Example pod and secret to demo how secrets can be provided to a k8s pod. + diff --git a/kubernetes/secret-example/secret-example-pod.yaml b/kubernetes/secret-example/secret-example-pod.yaml new file mode 100644 index 0000000..7e0fe25 --- /dev/null +++ b/kubernetes/secret-example/secret-example-pod.yaml @@ -0,0 +1,32 @@ +apiVersion: v1 +kind: Pod +metadata: + name: secretpod + labels: + name: secretpod + secrets_namespace: wordpress +spec: + containers: + - image: fedora + name: secretpod + command: + - sleep + - "86400" + env: + - name: EXAMPLE_PASSWORD + value: mypassword + volumeMounts: + - name: secretvolume + mountPath: /secrets + readOnly: true + - name: custodia + mountPath: /custodia + readOnly: true + volumes: + - name: secretvolume + secret: + secretName: examplesecrets + - name: custodia + hostPath: + path: /var/lib/custodia/client + diff --git a/kubernetes/secret-example/secret-example-secrets.yaml b/kubernetes/secret-example/secret-example-secrets.yaml new file mode 100644 index 0000000..9d08b11 --- /dev/null +++ b/kubernetes/secret-example/secret-example-secrets.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: examplesecrets +type: Opaque +data: + password: c3VwZXIgc2VjcmV0IHBhc3N3b3JkCg== + + diff --git a/kubernetes/wordpress-demo/README b/kubernetes/wordpress-demo/README new file mode 100644 index 0000000..7ab1077 --- /dev/null +++ b/kubernetes/wordpress-demo/README @@ -0,0 +1,29 @@ +Based on http://www.severalnines.com/blog/wordpress-application-clustering-using-kubernetes-haproxy-and-keepalived + +Changes: + + MySQL replication controller instead of plain MySQL pod + NodePort service + Custodia integration + custom entry points for go-secret + +Custodia setup +-------------- + +mkdir -p /var/lib/custodia /var/lib/custodia/client +cp gustodia /var/lib/custodia/client/go-custodia + +modify example "custodia.conf" +set [global] server_socket = /var/lib/custodia/client/server_socket + +curl --unix-socket /var/lib/custodia/client/server_socket \ + -H "REMOTE_USER: curl" \ + -X POST \ + http://localhost/secrets/wordpress/ +curl --unix-socket /var/lib/custodia/client/server_socket \ + -H "REMOTE_USER: curl" \ + -H "Content-Type: application/json" \ + -X PUT \ + -d '{"type": "simple", "value": "yourpassword"}' \ + http://localhost/secrets/wordpress/db_password + diff --git a/kubernetes/wordpress-demo/claim-db.yaml b/kubernetes/wordpress-demo/claim-db.yaml new file mode 100644 index 0000000..a3ffd49 --- /dev/null +++ b/kubernetes/wordpress-demo/claim-db.yaml @@ -0,0 +1,13 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: myclaim-db + labels: + name: myclaim-db +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 5Gi + diff --git a/kubernetes/wordpress-demo/claim-web.yaml b/kubernetes/wordpress-demo/claim-web.yaml new file mode 100644 index 0000000..1a04bec --- /dev/null +++ b/kubernetes/wordpress-demo/claim-web.yaml @@ -0,0 +1,12 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: myclaim-web + labels: + name: myclaim-web +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 3Gi diff --git a/kubernetes/wordpress-demo/mysql-custodia-rc.yaml b/kubernetes/wordpress-demo/mysql-custodia-rc.yaml new file mode 100644 index 0000000..d83dbdd --- /dev/null +++ b/kubernetes/wordpress-demo/mysql-custodia-rc.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: mysql + labels: + name: mysql +spec: + replicas: 1 + selector: + name: mysql + version: v1 + template: + metadata: + labels: + name: mysql + version: v1 + secrets_namespace: wordpress + spec: + containers: + - name: mysql + image: mysql + command: ["/custodia/go-secret"] + args: ["/entrypoint.sh", "mysqld"] + ports: + - containerPort: 3306 + name: mysql + env: + - name: SECRET_MYSQL_ROOT_PASSWORD + value: db_password + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + - name: custodia + mountPath: /custodia + readOnly: true + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: myclaim-db + - name: custodia + hostPath: + path: /var/lib/custodia/client diff --git a/kubernetes/wordpress-demo/mysql-rc.yaml b/kubernetes/wordpress-demo/mysql-rc.yaml new file mode 100644 index 0000000..24448f9 --- /dev/null +++ b/kubernetes/wordpress-demo/mysql-rc.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: mysql + labels: + name: mysql +spec: + replicas: 1 + selector: + name: mysql + version: v1 + template: + metadata: + labels: + name: mysql + version: v1 + spec: + containers: + - name: mysql + image: mysql + ports: + - containerPort: 3306 + name: mysql + env: + - name: MYSQL_ROOT_PASSWORD + value: yourpassword + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: myclaim-db diff --git a/kubernetes/wordpress-demo/mysql-service.yaml b/kubernetes/wordpress-demo/mysql-service.yaml new file mode 100644 index 0000000..2848558 --- /dev/null +++ b/kubernetes/wordpress-demo/mysql-service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + name: mysql + name: mysql +spec: + ports: + - port: 3306 + selector: + name: mysql + diff --git a/kubernetes/wordpress-demo/pv-nfs-db.yaml b/kubernetes/wordpress-demo/pv-nfs-db.yaml new file mode 100644 index 0000000..319b2f4 --- /dev/null +++ b/kubernetes/wordpress-demo/pv-nfs-db.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv5gdb + labels: + name: wordpress-db +spec: + capacity: + storage: 5Gi + accessModes: + - ReadWriteMany + persistentVolumeReclaimPolicy: Recycle + nfs: + path: /srv/kube-vol/wordpress/db + server: 10.34.78.249 + diff --git a/kubernetes/wordpress-demo/pv-nfs-web.yaml b/kubernetes/wordpress-demo/pv-nfs-web.yaml new file mode 100644 index 0000000..b69cd2b --- /dev/null +++ b/kubernetes/wordpress-demo/pv-nfs-web.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv5gweb + labels: + name: wordpress-web +spec: + capacity: + storage: 5Gi + accessModes: + - ReadWriteMany + persistentVolumeReclaimPolicy: Recycle + nfs: + path: /srv/kube-vol/wordpress/web + server: 10.34.78.249 + + diff --git a/kubernetes/wordpress-demo/remove.sh b/kubernetes/wordpress-demo/remove.sh new file mode 100755 index 0000000..00589c7 --- /dev/null +++ b/kubernetes/wordpress-demo/remove.sh @@ -0,0 +1,8 @@ +kubectl delete rc frontend mysql +kubectl delete svc frontend mysql +kubectl delete pvc myclaim-db myclaim-web +kubectl delete pv pv5gdb pv5gweb + +# rm -rf /srv/kube-vol/wordpress/web/* +# rm -rf /srv/kube-vol/wordpress/db/* + diff --git a/kubernetes/wordpress-demo/setup.sh b/kubernetes/wordpress-demo/setup.sh new file mode 100755 index 0000000..84c7ee1 --- /dev/null +++ b/kubernetes/wordpress-demo/setup.sh @@ -0,0 +1,28 @@ +#!/bin/sh +set -e + +# rm -rf /srv/kube-vol/wordpress/web/* +# rm -rf /srv/kube-vol/wordpress/db/* + +mkdir -p /srv/kube-vol/wordpress/web +mkdir -p /srv/kube-vol/wordpress/db + +kubectl create -f pv-nfs-db.yaml +kubectl create -f claim-db.yaml +kubectl create -f mysql-custodia-rc.yaml +kubectl create -f mysql-service.yaml + +sleep 5 + +kubectl create -f pv-nfs-web.yaml +kubectl create -f claim-web.yaml +kubectl create -f wordpress-custodia-rc.yaml +kubectl create -f wordpress-service.yaml + +sleep 5 + +kubectl get pv,pvc +kubectl get rc +kubectl get po +kubectl get svc + diff --git a/kubernetes/wordpress-demo/wordpress-custodia-rc.yaml b/kubernetes/wordpress-demo/wordpress-custodia-rc.yaml new file mode 100644 index 0000000..afb7bf8 --- /dev/null +++ b/kubernetes/wordpress-demo/wordpress-custodia-rc.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: frontend + labels: + name: frontend +spec: + replicas: 1 + selector: + name: frontend + version: v1 + template: + metadata: + labels: + name: frontend + version: v1 + secrets_namespace: wordpress + spec: + containers: + - name: wordpress + image: wordpress + # $ docker pull wordpress + # $ docker inspect --format='{{json .Config.Entrypoint}} {{json .Config.Cmd}}' wordpress + command: ["/custodia/go-secret"] + args: ["/entrypoint.sh", "apache2-foreground"] + ports: + - containerPort: 80 + name: wordpress + env: + - name: SECRET_WORDPRESS_DB_PASSWORD + value: db_password + volumeMounts: + # name must match the volume name below + - name: wordpress-persistent-storage + # mount path within the container + mountPath: /var/www/html + - name: custodia + mountPath: /custodia + readOnly: true + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: myclaim-web + - name: custodia + hostPath: + path: /var/lib/custodia/client + diff --git a/kubernetes/wordpress-demo/wordpress-rc.yaml b/kubernetes/wordpress-demo/wordpress-rc.yaml new file mode 100644 index 0000000..9a64655 --- /dev/null +++ b/kubernetes/wordpress-demo/wordpress-rc.yaml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: ReplicationController +metadata: + name: frontend + labels: + name: frontend +spec: + replicas: 1 + selector: + name: frontend + version: v1 + template: + metadata: + labels: + name: frontend + version: v1 + spec: + containers: + - name: wordpress + image: wordpress + ports: + - containerPort: 80 + name: wordpress + env: + - name: WORDPRESS_DB_PASSWORD + value: yourpassword + volumeMounts: + - name: wordpress-persistent-storage + mountPath: /var/www/html + volumes: + - name: wordpress-persistent-storage + persistentVolumeClaim: + claimName: myclaim-web diff --git a/kubernetes/wordpress-demo/wordpress-service.yaml b/kubernetes/wordpress-demo/wordpress-service.yaml new file mode 100644 index 0000000..beef04e --- /dev/null +++ b/kubernetes/wordpress-demo/wordpress-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + name: frontend + name: frontend +spec: + ports: + - port: 80 + targetPort: 80 + nodePort: 30777 + selector: + name: frontend + type: NodePort + diff --git a/misc/graph.py b/misc/graph.py new file mode 100755 index 0000000..d9deb78 --- /dev/null +++ b/misc/graph.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +from itertools import count + +from pygraphviz import AGraph + +_counter = count(1) +c = lambda: next(_counter) + +graph = AGraph(name='graph', directed=True, strict=False) + +graph.add_node('pod1_app', label='Application 1', sortv=1) +graph.add_node('pod2_app', label='Application 2', sortv=2) + +graph.add_node('node_docker', label='Docker') +graph.add_node('node_custodia', label='Custodia') +graph.add_node('node_proc', label='/proc/PID/cgroup') + +graph.add_node('master_custodia', label='Custodia') +graph.add_node('master_apiserver', label='kube apiserver') +graph.add_node('master_etcd', label='etcd') + +graph.add_node('customer_custodia', label='Custodia') +graph.add_node('customer_sqlite', label='sqlite') + +graph.add_edge('pod1_app', 'node_custodia', label='%i) Ask for secret\n[unix]' % c(), style='bold') +graph.add_edge('pod2_app', 'node_custodia', label='Ask for secret\n[unix]') + +graph.add_edge('node_custodia', 'node_proc', label='%i) Translate PID\nto dockerid' % c(), dir='both') +graph.add_edge('node_custodia', 'node_docker', label='%i) Get k8s namespace/pod\nby docker id' % c(), dir='both') +graph.add_edge('node_custodia', 'master_custodia', label='%i) Ask for secret\n[tcp]' % c(), style='bold') + +graph.add_edge('master_custodia', 'master_etcd', label='%i) Auth' % c()) +graph.add_edge('master_custodia', 'master_apiserver', label='%i) Get secret namespace\nby namespace/pod' % c(), dir='both') +# graph.add_edge('master_apiserver', 'node_docker', dir='both') +graph.add_edge('master_custodia', 'customer_custodia', label='%i) Ask for secret\n[tcp]' % c(), style='bold') + +graph.add_edge('customer_custodia', 'customer_sqlite', 'customer_sqlite_auth', label='%i) Auth' % c()) +graph.add_edge('customer_custodia', 'customer_sqlite', 'customer_sqlite_secret', label='%i) Fetch secret' % c(), style='bold') + +graph.add_edge('customer_custodia', 'master_custodia', 'customer_sqlite_secret', label='%i) Return secret' % c(), style='dashed') +graph.add_edge('master_custodia', 'node_custodia', 'customer_sqlite_secret', label='%i) Return secret' % c(), style='dashed') +graph.add_edge('node_custodia', 'pod1_app', 'customer_sqlite_secret', label='%i) Return secret' % c(), style='dashed') + +SUBGRAPHS = [ + ['node', None, dict(label="Kubernetes Node")], + ['pod2', 'node', dict(label="Pod 2")], + ['pod1', 'node', dict(label="Pod 1")], + ['master', None, dict(label="Kubernetes Master")], + ['customer', None, dict(label="Customer")], +] + +for name, parent, kwargs in SUBGRAPHS: + if parent is None: + parent = graph + else: + parent = graph.get_subgraph("cluster_%s" % parent) + sub = parent.add_subgraph(name="cluster_%s" % name, **kwargs) + sub.add_nodes_from(n for n in graph.nodes() if n.startswith(name)) + + +if __name__ == '__main__': + graph.layout('dot') + print(graph.string()) + graph.draw('graph.svg', format='svg') |