mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
updates docs for running fn on k8s
- removes docker swarm doc
This commit is contained in:
@@ -1,121 +1,66 @@
|
|||||||
# HOWTO run Oracle Functions in Kubernetes at AWS
|
# How to run Fn on Kubernetes
|
||||||
|
|
||||||
*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.*
|
|
||||||
|
|
||||||
|
*Prerequisite 1: working Kubernetes cluster (v1.7+), and a locally configured kubectl.*
|
||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
### Steps
|
### Steps
|
||||||
|
|
||||||
1. Start Oracle Functions in the Kubernetes cluster:
|
1. Deploy Fn to the Kubernetes cluster:
|
||||||
```ShellSession
|
|
||||||
$ cd docs/
|
```bash
|
||||||
$ kubectl create -f kubernetes-quick
|
$ cd docs/operating/
|
||||||
|
$ kubectl create -f fn-service.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Once the daemon is started, check where it is listening for connections:
|
2. Once the Pods have started, check the service for the load balanacer IP:
|
||||||
|
|
||||||
```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: <unset> 8080/TCP
|
|
||||||
NodePort: <unset> 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
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ kubectl get svc --watch
|
||||||
|
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||||
|
fn-mysql-master 10.96.57.185 <none> 3306/TCP 10m
|
||||||
|
fn-redis-master 10.96.127.51 <none> 6379/TCP 10m
|
||||||
|
fn-service 10.96.245.95 <pending> 8080:30768/TCP,80:31921/TCP 10m
|
||||||
|
kubernetes 10.96.0.1 <none> 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:
|
3. Test the cluster:
|
||||||
|
|
||||||
If you are using a Kubernetes setup that can expose a public loadbalancer run:
|
If you are using a Kubernetes setup that can expose a public load balancer, run:
|
||||||
```ShellSession
|
|
||||||
$ export FUNCTIONS=$(kubectl get -o json svc functions | jq -r '.status.loadBalancer.ingress[0].hostname'):8080
|
```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
|
If you are using a Kubernetes setup like minikube, run
|
||||||
```ShellSession
|
```bash
|
||||||
$ 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
|
$ echo $(minikube ip):$(kubectl get svc fn-service -o json | jq -r '.spec.ports[0].nodePort')
|
||||||
$ export FUNCTIONS=localhost:8080
|
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
|
```bash
|
||||||
$ curl -H "Content-Type: application/json" -X POST -d '{ "app": { "name":"myapp" } }' http://$FUNCTIONS/v1/apps
|
$ 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}}
|
{"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
|
$ 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,"type":"sync","config":null}}
|
{"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!
|
Hello Johnny!
|
||||||
```
|
```
|
||||||
|
|
||||||
## Production
|
You can also use the [Fn CLI](https://github.com/fnproject/cli):
|
||||||
|
|
||||||
### Steps
|
```bash
|
||||||
|
$ export API_URL=http://192.168.99.100:30966
|
||||||
1. Start Oracle Functions and its dependencies:
|
$ fn apps list
|
||||||
```ShellSession
|
myapp
|
||||||
$ cd docs/
|
$ fn routes list myapp
|
||||||
$ kubectl create -f kubernetes-production
|
path image endpoint
|
||||||
```
|
/hello-sync fnproject/hello 192.168.99.100:30966/r/myapp/hello-sync
|
||||||
|
```
|
||||||
*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: <unset> 8080/TCP
|
|
||||||
NodePort: <unset> 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!
|
|
||||||
```
|
|
||||||
151
docs/operating/kubernetes/fn-service.yaml
Normal file
151
docs/operating/kubernetes/fn-service.yaml
Normal file
@@ -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
|
||||||
@@ -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
|
|
||||||
@@ -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"
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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"
|
|
||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user