From 232069cbca06485dbd40313434142b496d6779ac Mon Sep 17 00:00:00 2001 From: Derek Schultz Date: Thu, 28 Sep 2017 12:59:21 -0600 Subject: [PATCH] updates docs for running fn on k8s - removes docker swarm doc --- docs/operating/kubernetes/README.md | 135 +++++----------- docs/operating/kubernetes/fn-service.yaml | 151 ++++++++++++++++++ .../functions-config.yaml | 7 - .../functions-deployment.yaml | 43 ----- .../functions-service.yaml | 14 -- .../postgresql-deployment.yaml | 17 -- .../postgresql-service.yaml | 14 -- .../redis-deployment.yaml | 17 -- .../kubernetes-production/redis-service.yaml | 14 -- .../kubernetes-quick/deployment.yaml | 33 ---- .../kubernetes/kubernetes-quick/service.yaml | 14 -- 11 files changed, 191 insertions(+), 268 deletions(-) create mode 100644 docs/operating/kubernetes/fn-service.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-production/functions-config.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-production/functions-deployment.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-production/functions-service.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-production/postgresql-deployment.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-production/postgresql-service.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-production/redis-deployment.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-production/redis-service.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-quick/deployment.yaml delete mode 100644 docs/operating/kubernetes/kubernetes-quick/service.yaml diff --git a/docs/operating/kubernetes/README.md b/docs/operating/kubernetes/README.md index a2b30781b..523a50b2b 100644 --- a/docs/operating/kubernetes/README.md +++ b/docs/operating/kubernetes/README.md @@ -1,121 +1,66 @@ -# HOWTO run Oracle Functions in Kubernetes at AWS - -*Prerequisite 1: it assumes you have a working Kubernetes, and a locally configured kubectl.* - -*Prerequisite 2: It assumes you are using Kubernetes 1.4 or newer.* +# How to run Fn on Kubernetes +*Prerequisite 1: working Kubernetes cluster (v1.7+), and a locally configured kubectl.* ## Quickstart ### Steps -1. Start Oracle Functions in the Kubernetes cluster: -```ShellSession -$ cd docs/ -$ kubectl create -f kubernetes-quick +1. Deploy Fn to the Kubernetes cluster: + +```bash +$ cd docs/operating/ +$ kubectl create -f fn-service.yaml ``` -2. Once the daemon is started, check where it is listening for connections: - -```ShellSession -# kubectl describe svc functions - -Name: functions -Namespace: default -Labels: app=functions -Selector: app=functions -Type: LoadBalancer -IP: 10.0.116.122 -LoadBalancer Ingress: a23122e39900111e681ba0e29b70bb46-630391493.us-east-1.elb.amazonaws.com -Port: 8080/TCP -NodePort: 30802/TCP -Endpoints: 10.244.1.12:8080 -Session Affinity: None -Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 22m 22m 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer - 22m 22m 1 {service-controller } Normal CreatedLoadBalancer Created load balancer +2. Once the Pods have started, check the service for the load balanacer IP: +```bash +$ kubectl get svc --watch +NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE +fn-mysql-master 10.96.57.185 3306/TCP 10m +fn-redis-master 10.96.127.51 6379/TCP 10m +fn-service 10.96.245.95 8080:30768/TCP,80:31921/TCP 10m +kubernetes 10.96.0.1 443/TCP 15d ``` -Note `a23122e39900111e681ba0e29b70bb46-630391493.us-east-1.elb.amazonaws.com` in `LoadBalancer Ingress` line, this is where the service is listening. +Note that `fn-service` is initially pending on allocating an external IP. The `kubectl get svc --watch` command will update this once an IP has been assigned. 3. Test the cluster: -If you are using a Kubernetes setup that can expose a public loadbalancer run: -```ShellSession -$ export FUNCTIONS=$(kubectl get -o json svc functions | jq -r '.status.loadBalancer.ingress[0].hostname'):8080 +If you are using a Kubernetes setup that can expose a public load balancer, run: + +```bash +$ export FUNCTIONS=$(kubectl get -o json svc fn-service | jq -r '.status.loadBalancer.ingress[0].ip'):8080 ``` -If you are using a Kubernetes setup like minikube run -```ShellSession -$ export ns=default ; export label='app=functions'; kubectl -n $ns get pod -l $label -o jsonpath='{.items[0].metadata.name}' | xargs -I{} kubectl -n $ns port-forward {} 8080:8080 -$ export FUNCTIONS=localhost:8080 +If you are using a Kubernetes setup like minikube, run +```bash +$ echo $(minikube ip):$(kubectl get svc fn-service -o json | jq -r '.spec.ports[0].nodePort') +192.168.99.100:30966 +$ export API_URL=http://192.168.99.100:30966 ``` -Now setup the functions: +Now, test by creating a function via curl: -```ShellSession -$ curl -H "Content-Type: application/json" -X POST -d '{ "app": { "name":"myapp" } }' http://$FUNCTIONS/v1/apps +```bash +$ curl -H "Content-Type: application/json" -X POST -d '{ "app": { "name":"myapp" } }' http://$API_URL/v1/apps {"message":"App successfully created","app":{"name":"myapp","config":null}} -$ curl -H "Content-Type: application/json" -X POST -d '{ "route": { "type": "sync", "path":"/hello-sync", "image":"fnproject/hello" } }' http://$FUNCTIONS/v1/apps/myapp/routes -{"message":"Route successfully created","route":{"app_name":"myapp","path":"/hello-sync","image":"fnproject/hello","memory":128,"type":"sync","config":null}} +$ curl -H "Content-Type: application/json" -X POST -d '{ "route": { "type": "sync", "path":"/hello-sync", "image":"fnproject/hello" } }' http://$API_URL/v1/apps/myapp/routes +{"message":"Route successfully created","route":{"app_name":"myapp","path":"/hello-sync","image":"fnproject/hello","memory":128,"headers":{},"type":"sync","format":"default","timeout":30,"idle_timeout":30,"config":{}}} -$ curl -H "Content-Type: application/json" -X POST -d '{ "name":"Johnny" }' http://$FUNCTIONS/r/myapp/hello-sync +$ curl -H "Content-Type: application/json" -X POST -d '{ "name":"Johnny" }' http://$API_URL/r/myapp/hello-sync Hello Johnny! ``` -## Production +You can also use the [Fn CLI](https://github.com/fnproject/cli): -### Steps - -1. Start Oracle Functions and its dependencies: -```ShellSession -$ cd docs/ -$ kubectl create -f kubernetes-production -``` - -*Optionally, you might have both Redis and PostgreSQL started somewhere else, in this case, remember to update kubernetes-production/functions-config.yaml with the appropriate configuration.* - -2. Once the daemon is started, check where it is listening for connections: - -```ShellSession -# kubectl describe svc functions - -Name: functions -Namespace: default -Labels: app=functions -Selector: app=functions -Type: LoadBalancer -IP: 10.0.116.122 -LoadBalancer Ingress: a23122e39900111e681ba0e29b70bb46-630391493.us-east-1.elb.amazonaws.com -Port: 8080/TCP -NodePort: 30802/TCP -Endpoints: 10.244.1.12:8080 -Session Affinity: None -Events: - FirstSeen LastSeen Count From SubobjectPath Type Reason Message - --------- -------- ----- ---- ------------- -------- ------ ------- - 22m 22m 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer - 22m 22m 1 {service-controller } Normal CreatedLoadBalancer Created load balancer - -``` - -Note `a23122e39900111e681ba0e29b70bb46-630391493.us-east-1.elb.amazonaws.com` in `LoadBalancer Ingress` line, this is where the service is listening. - -3. Test the cluster: - -```ShellSession -$ export FUNCTIONS=$(kubectl get -o json svc functions | jq -r '.status.loadBalancer.ingress[0].hostname'):8080 - -$ curl -H "Content-Type: application/json" -X POST -d '{ "app": { "name":"myapp" } }' http://$FUNCTIONS/v1/apps -{"message":"App successfully created","app":{"name":"myapp","config":null}} - -$ curl -H "Content-Type: application/json" -X POST -d '{ "route": { "type": "sync", "path":"/hello-sync", "image":"fnproject/hello" } }' http://$FUNCTIONS/v1/apps/myapp/routes -{"message":"Route successfully created","route":{"app_name":"myapp","path":"/hello-sync","image":"fnproject/hello","memory":128,"type":"sync","config":null}} - -$ curl -H "Content-Type: application/json" -X POST -d '{ "name":"Johnny" }' http://$FUNCTIONS/r/myapp/hello-sync -Hello Johnny! -``` +```bash +$ export API_URL=http://192.168.99.100:30966 +$ fn apps list +myapp +$ fn routes list myapp +path image endpoint +/hello-sync fnproject/hello 192.168.99.100:30966/r/myapp/hello-sync +``` \ No newline at end of file diff --git a/docs/operating/kubernetes/fn-service.yaml b/docs/operating/kubernetes/fn-service.yaml new file mode 100644 index 000000000..ecf97e566 --- /dev/null +++ b/docs/operating/kubernetes/fn-service.yaml @@ -0,0 +1,151 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: fn-service-config + namespace: default +data: + MQ_URL: redis://fn-redis-master.default + DB_URL: mysql://root:fnsecretpassword@tcp(fn-mysql-master:3306)/fn + API_URL: http://fn-service:8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: fn-service + labels: + app: fn + role: fn-service +spec: + type: LoadBalancer + ports: + - name: fn-service + port: 8080 + targetPort: 8080 + - name: fn-ui + port: 80 + targetPort: 80 + selector: + app: fn + role: fn-service +--- +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: fn-service +spec: + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + minReadySeconds: 30 + template: + metadata: + labels: + app: fn + role: fn-service + spec: + containers: + - name: fn-service + image: fnproject/functions:latest + securityContext: + privileged: true + ports: + - containerPort: 8080 + env: + - name: MQ_URL + valueFrom: + configMapKeyRef: + name: fn-service-config + key: MQ_URL + - name: DB_URL + valueFrom: + configMapKeyRef: + name: fn-service-config + key: DB_URL + - name: fn-ui + image: fnproject/ui:latest + ports: + - containerPort: 80 + env: + - name: PORT + value: "80" + - name: API_URL + valueFrom: + configMapKeyRef: + name: fn-service-config + key: API_URL +--- +apiVersion: v1 +kind: Service +metadata: + name: fn-mysql-master + labels: + app: mysql + role: datastore +spec: + ports: + - port: 3306 + targetPort: 3306 + selector: + app: mysql + role: datastore +--- +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: fn-mysql-master +spec: + replicas: 1 + template: + metadata: + labels: + app: mysql + role: datastore + spec: + containers: + - name: fn-mysql + image: mysql:5.7 + args: + - "--max-connections=500" + - "--wait-timeout=300" + ports: + - containerPort: 3306 + env: + - name: MYSQL_ROOT_PASSWORD + value: fnsecretpassword + - name: MYSQL_DATABASE + value: fn +--- +apiVersion: v1 +kind: Service +metadata: + name: fn-redis-master + labels: + app: redis + role: mq +spec: + ports: + - port: 6379 + targetPort: 6379 + selector: + app: redis + role: mq +--- +apiVersion: apps/v1beta1 +kind: Deployment +metadata: + name: fn-redis-master +spec: + replicas: 1 + template: + metadata: + labels: + app: redis + role: mq + spec: + terminationGracePeriodSeconds: 1 + containers: + - name: fn-redis + image: redis:4.0 + ports: + - containerPort: 6379 \ No newline at end of file diff --git a/docs/operating/kubernetes/kubernetes-production/functions-config.yaml b/docs/operating/kubernetes/kubernetes-production/functions-config.yaml deleted file mode 100644 index 485e04bf8..000000000 --- a/docs/operating/kubernetes/kubernetes-production/functions-config.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: ConfigMap -apiVersion: v1 -metadata: - name: functions-config -data: - MQ_URL: redis://redis-master.default - DB_URL: postgres://postgres:mysecretpassword@postgresql-master.default/?sslmode=disable diff --git a/docs/operating/kubernetes/kubernetes-production/functions-deployment.yaml b/docs/operating/kubernetes/kubernetes-production/functions-deployment.yaml deleted file mode 100644 index 8caaa7bfa..000000000 --- a/docs/operating/kubernetes/kubernetes-production/functions-deployment.yaml +++ /dev/null @@ -1,43 +0,0 @@ ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: functions - labels: - app: functions -spec: - replicas: 1 - template: - metadata: - labels: - app: functions - spec: - containers: - - name: functions - image: treeder/functions - securityContext: - privileged: true - env: - - name: DOCKER_HOST - value: unix:///var/run/docker.sock - - name: MQ_URL - valueFrom: - configMapKeyRef: - name: functions-config - key: MQ_URL - - name: DB_URL - valueFrom: - configMapKeyRef: - name: functions-config - key: DB_URL - volumeMounts: - - mountPath: "/var/run/docker.sock" - name: docker-socket - readOnly: false - ports: - - name: http-server - containerPort: 8080 - volumes: - - name: docker-socket - hostPath: - path: "/var/run/docker.sock" diff --git a/docs/operating/kubernetes/kubernetes-production/functions-service.yaml b/docs/operating/kubernetes/kubernetes-production/functions-service.yaml deleted file mode 100644 index 7a4c8b31f..000000000 --- a/docs/operating/kubernetes/kubernetes-production/functions-service.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -kind: Service -apiVersion: v1 -metadata: - name: functions - labels: - app: functions -spec: - ports: - - port: 8080 - targetPort: http-server - selector: - app: functions - type: LoadBalancer diff --git a/docs/operating/kubernetes/kubernetes-production/postgresql-deployment.yaml b/docs/operating/kubernetes/kubernetes-production/postgresql-deployment.yaml deleted file mode 100644 index dabe22d71..000000000 --- a/docs/operating/kubernetes/kubernetes-production/postgresql-deployment.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: postgresql-master -spec: - replicas: 1 - template: - metadata: - labels: - app: postgresql - role: datastore - spec: - containers: - - name: functions-postgresql - image: postgres - ports: - - containerPort: 5432 \ No newline at end of file diff --git a/docs/operating/kubernetes/kubernetes-production/postgresql-service.yaml b/docs/operating/kubernetes/kubernetes-production/postgresql-service.yaml deleted file mode 100644 index 861287d84..000000000 --- a/docs/operating/kubernetes/kubernetes-production/postgresql-service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: postgresql-master - labels: - app: postgresql - role: datastore -spec: - ports: - - port: 5432 - targetPort: 5432 - selector: - app: postgresql - role: datastore \ No newline at end of file diff --git a/docs/operating/kubernetes/kubernetes-production/redis-deployment.yaml b/docs/operating/kubernetes/kubernetes-production/redis-deployment.yaml deleted file mode 100644 index 3538603e3..000000000 --- a/docs/operating/kubernetes/kubernetes-production/redis-deployment.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: redis-master -spec: - replicas: 1 - template: - metadata: - labels: - app: redis - role: mq - spec: - containers: - - name: functions-redis - image: redis - ports: - - containerPort: 6379 \ No newline at end of file diff --git a/docs/operating/kubernetes/kubernetes-production/redis-service.yaml b/docs/operating/kubernetes/kubernetes-production/redis-service.yaml deleted file mode 100644 index be92ba845..000000000 --- a/docs/operating/kubernetes/kubernetes-production/redis-service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: redis-master - labels: - app: redis - role: mq -spec: - ports: - - port: 6379 - targetPort: 6379 - selector: - app: redis - role: mq \ No newline at end of file diff --git a/docs/operating/kubernetes/kubernetes-quick/deployment.yaml b/docs/operating/kubernetes/kubernetes-quick/deployment.yaml deleted file mode 100644 index 83766ca49..000000000 --- a/docs/operating/kubernetes/kubernetes-quick/deployment.yaml +++ /dev/null @@ -1,33 +0,0 @@ ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: functions - labels: - app: functions -spec: - replicas: 1 - template: - metadata: - labels: - app: functions - spec: - containers: - - name: functions - image: treeder/functions - securityContext: - privileged: true - env: - - name: DOCKER_HOST - value: unix:///var/run/docker.sock - volumeMounts: - - mountPath: "/var/run/docker.sock" - name: docker-socket - readOnly: false - ports: - - name: http-server - containerPort: 8080 - volumes: - - name: docker-socket - hostPath: - path: "/var/run/docker.sock" diff --git a/docs/operating/kubernetes/kubernetes-quick/service.yaml b/docs/operating/kubernetes/kubernetes-quick/service.yaml deleted file mode 100644 index 7a4c8b31f..000000000 --- a/docs/operating/kubernetes/kubernetes-quick/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -kind: Service -apiVersion: v1 -metadata: - name: functions - labels: - app: functions -spec: - ports: - - port: 8080 - targetPort: http-server - selector: - app: functions - type: LoadBalancer