From 9734a3cc280de0e3941c7136b5820831c8fb8790 Mon Sep 17 00:00:00 2001 From: Denis Makogon Date: Fri, 18 Jan 2019 20:02:10 +0200 Subject: [PATCH] Updated runner deployment doc Closes: #26 --- fn/operate/runner_pools.md | 195 +++++++++++++++++++++++++++---------- 1 file changed, 141 insertions(+), 54 deletions(-) diff --git a/fn/operate/runner_pools.md b/fn/operate/runner_pools.md index 2bcd546..f91dedf 100644 --- a/fn/operate/runner_pools.md +++ b/fn/operate/runner_pools.md @@ -6,96 +6,183 @@ You can run a load-balanced setup for fn to route requests to a group of one or ## Starting the components (as regular processes) +### Persisted storage + +For the particular example we'd use MySQL 5.7.22: + +```bash +docker run --name fn-mysql \ + -p 3306:3306 \ + -e MYSQL_DATABASE=funcs \ + -e MYSQL_ROOT_PASSWORD=root \ + -d mysql:5.7.22 +``` + +### DNS name requirement + +For the following deployment there's a need in the following DNS names: + + - runner LB node DNS name: `lb.fn.local` + +Please note, this DNS name is an example! + + ### API server ```bash -FN_NODE_TYPE=api ./fnserver +docker run --name fn-api \ + -d \ + -e FN_NODE_TYPE=api \ + -e FN_LOG_LEVEL=DEBUG \ + -e FN_PUBLIC_LB_URL="http://lb.fn.local:8181" \ + -e FN_DB_URL="mysql://root:root@tcp(fn-mysql:3306)/funcs" \ + --link fn-mysql:fn-mysql \ + -p 8080:8080 \ + fnproject/fnserver:latest ``` ### Runners ```bash -mkdir /tmp/runnerdata -# first runner -FN_NODE_TYPE=pure-runner FN_PORT=8082 FN_GRPC_PORT=9190 ./fnserver -# on another terminal, start a second runner -FN_NODE_TYPE=pure-runner FN_PORT=8083 FN_GRPC_PORT=9191 ./fnserver +docker run --name fn-runner-1 \ + --privileged \ + -d \ + -e FN_NODE_TYPE="pure-runner" \ + -e FN_LOG_LEVEL=DEBUG \ + -e FN_IOFS_DOCKER_PATH=${HOME}/.fn/iofs \ + -e FN_IOFS_PATH=/iofs \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v ${HOME}/.fn/iofs:/iofs \ + fnproject/fnserver:latest + +docker run --name fn-runner-2 \ + --privileged \ + -d \ + -e FN_NODE_TYPE="pure-runner" \ + -e FN_LOG_LEVEL=DEBUG \ + -e FN_IOFS_DOCKER_PATH=${HOME}/.fn/iofs \ + -e FN_IOFS_PATH=/iofs \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v ${HOME}/.fn/iofs:/iofs \ + fnproject/fnserver:latest + +docker run --name fn-runner-3 \ + --privileged \ + -d \ + -e FN_NODE_TYPE="pure-runner" \ + -e FN_IOFS_DOCKER_PATH=${HOME}/.fn/iofs \ + -e FN_IOFS_PATH=/iofs \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v ${HOME}/.fn/iofs:/iofs \ + -e FN_LOG_LEVEL=DEBUG \ + fnproject/fnserver:latest ``` -### LB +### Runner load balancer ```bash -mkdir /tmp/lbdata -FN_NODE_TYPE=lb FN_PORT=8081 FN_RUNNER_API_URL=http://localhost:8080 FN_RUNNER_ADDRESSES=localhost:9190,localhost:9191 FN_LOG_LEVEL=DEBUG ./fnserver +docker run --name fn-runner-lb \ + --privileged \ + -d \ + -e FN_NODE_TYPE=lb \ + -e FN_LOG_LEVEL=DEBUG \ + -e FN_RUNNER_API_URL="http://fn-api:8080" \ + -e FN_RUNNER_ADDRESSES="fn-runner-1:9190,fn-runner-2:9190,fn-runner-3:9190" \ + -p 8181:8080 \ + --link fn-runner-1:fn-runner-1 \ + --link fn-runner-2:fn-runner-2 \ + --link fn-runner-3:fn-runner-3 \ + --link fn-api:fn-api \ + fnproject/fnserver:latest ``` -## Starting the components (in Docker containers) +### DNS configuration -### Build the images - -The images don't yet exist in a registry, so they need building first. +As we've mentioned above, we've used the DNS name (`lb.fn.local`) for runner LB node. +At this moment there's a need to figure out how the real IP address of the runner LB node: ```bash -docker build -f images/lb/Dockerfile -t fnproject/lb:latest . -docker build -f images/api/Dockerfile -t fnproject/api:latest . -docker build -f images/runner/Dockerfile -t fnproject/runner:latest . +docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' fn-runner-lb ``` -### Start the containers +With the following IP please update Fn LB DNS resolve: -This mode assumes that LB is started with a static set of runners in a single global pool. Note that this configuration does not support runner certificates and is that the communication between LB and runners is unencrypted. +`xxx.xxx.xxx.xxx lb.fn.local` -### API +But there's also a need to define API DNS name for the sake of simple reference: +```bash +docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' fn-api ``` -docker run -d \ - --name api \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -p 8080:8080 \ - fnproject/api:latest + +With the following IP please update Fn API DNS resolve: + +`xxx.xxx.xxx.xxx api.fn.local` + + +#### Remote Docker + +If you are working with Remote Docker API, the Docker API host is must be used instead: + +```bash +echo ${DOCKER_HOST} +tcp://xxx.xxx.xxx.xxx: ``` -#### First runner +where `xxx.xxx.xxx.xxx` is an IP address that you should use instead of container IP address. + +#### Local docker + +If you run Docker on your machine (docker-4-mac, docker-4-win), +you might use `127.0.0.1` instead of the container IP address. + + +## User-facing services + +In the particular setup we have 3 roles and at least 5 nodes running. +There are only 2 roles that user must interact with: + + - API node (for apps/functions/triggers CRUD operations) + - runner LB node (for triggering/invoking functions) + +## Deploying first app + +In first place please create a new Fn CLI context for the particular deployment: ```bash -docker run -d \ - --name runner \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -p 9190:9190 \ - -e FN_GRPC_PORT=9190 \ - -p 8095:8080 \ - fnproject/runner:latest +fn create context distributed-fn --registry --api-url http://api.fn.local:8080 +fn use context distributed-fn ``` -#### Second runner + ```bash -docker run -d \ - --name runner-2 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -p 9191:9191 \ - -e FN_GRPC_PORT=9191 \ - -p 8096:8080 \ - fnproject/runner:latest +fn init --runtime python3.7 --trigger http pyfn +cd pyfn +fn -v deploy --app testapp ``` -### LB +``` +Successfully created app: testapp +Successfully created function: pyfn with /pyfn:0.0.2 +Successfully created trigger: pyfn-trigger +Trigger Endpoint: http://lb.fn.local:8181/t/testapp/pyfn-trigger +``` -Retrieve the IP addresses for the runners and the API: +Invoke your function: ```bash -export RUNNER1=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' runner` -export RUNNER2=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' runner-2` -export API=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' api` - +fn invoke testapp pyfn +{"message":"Hello World"} ``` -Pass in the static set of runners to _FN\_RUNNER\_ADDRESSES_: +Trigger your function using an HTTP trigger: + +```bash +fn list triggers testapp +FUNCTION NAME ID TYPE SOURCE ENDPOINT +pyfn pyfn-trigger 01D1H0PNWANG8G00RZJ0000003 http /pyfn-trigger http://lb.fn.local:8181/t/testapp/pyfn-trigger +``` ```bash -docker run -d \ - --name lb \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -p 8081:8080 \ - -e FN_RUNNER_API_URL=http://$API:8080 \ - -e FN_RUNNER_ADDRESSES=$RUNNER1:9190,$RUNNER2:9191 \ - fnproject/lb:latest +curl -X POST http://lb.fn.local:8181/t/testapp/pyfn-trigger +{"message":"Hello World"} ```