From 2d85b40a4b8cfdca15310d4df12a53808917ee90 Mon Sep 17 00:00:00 2001 From: Erik M Jacobs Date: Thu, 31 May 2018 16:02:34 -0400 Subject: [PATCH 1/5] Fleshing out the EA docs with a big chunk of initial work. --- src/main/asciidoc/index.adoc | 96 ++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index eae4ac5..eee00d5 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -1,12 +1,100 @@ :toc: left -:toclevels: 3 +:toclevels: 2 :sectnums: +:sectnumlevels: 2 :sectanchors: -:source-highlighter: coderay :nofooter: = OpenShift Cloud Functions -== Do this +OpenShift Cloud Functions is a productization of the Apache OpenWhisk project +for use with Red Hat OpenShift. This Early Access (EA) repository provides +some basic getting started instructions for using the EA OpenShift Cloud +Functions bits in an existing OpenShift environment. -== Then Do that. +== Installation +The installation of the OCF EA assumes that one already has an existing +OpenShift environment available and accessible. No special cluster +permissions or settings are required to deploy the OCF infrastructure. + +[NOTE] +==== +Please see the `oc cluster` appendix for information on testing locally. +==== + +=== Installation Prerequisites + +==== Resource Requirements + +The OCF instrastructure has several parts, each with different resource requirements: + +* `controller`` +** 512 Mi of memory +* `couchdb` +** 512 Mi of memory +** 500 milicores of CPU +* `invoker` +** 1 Gi of memory +** 500 milicores of CPU +* `nginx` +** The `nginx` container inherits project defaults +* `strimzi` +** The `strimzi` container inherits project defaults +* `alarmprovider` +** The `alarmprovider` container inherits project defaults + +There are a number of other jobs and activities that will run with project +defaults as well. + +In total, it is recommended that you have a minimum of: + +* 4 GiB of memory +* 4 CPU cores + +available to run the OCF infrastructure. These are the bare minimums for +testing. + +Additionally, you may wish to have a few gigabytes of persistent storage +available. Persistent storage is used so that you can retain the various +settings, function definitions, history and etc. + +==== Disconnected Installations + +If your OpenShift environment is not connected to the internet, you will need +to fetch the following container images in advance of attempting to +install/deploy OCF: + +* image +* image +* image + +=== Deploying OCF + +==== Create a Project +You will want a project to hold the OCF infrastructure. Be sure that it has +sufficient quota, limits, and requests to accommodate the resource +requirements detailed above. + +``` +oc create blah +``` + +==== Process the Template +We have conveniently provided an OpenShift template that will deploy all of the objects required to run the OCF infrastructure. It contains many sensible defaults and aligns with the resource requirements detailed above. To instantiate the OCF infrastructure, simply `process` the template: + +``` +oc process -f https://git.io/openwhisk-template | oc create -f - +``` + +=== Wait for Success ++...+ profit! + +== Initial Configuration + +* users +* things +* stuff + +== `oc cluster` +For local testing purposes, one can use an OpenShift environment provided via +`oc cluster`, a subcommand built into the OpenShift CLI. \ No newline at end of file From b1a482d0e23fed38c2262250771dfdae19fbd1ab Mon Sep 17 00:00:00 2001 From: Erik M Jacobs Date: Thu, 31 May 2018 17:09:55 -0400 Subject: [PATCH 2/5] Added extra content around disconnected installations --- src/main/asciidoc/index.adoc | 88 +++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 12 deletions(-) diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index eee00d5..e40b68e 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -4,6 +4,7 @@ :sectnumlevels: 2 :sectanchors: :nofooter: +:source-highlighter: coderay = OpenShift Cloud Functions @@ -28,7 +29,7 @@ Please see the `oc cluster` appendix for information on testing locally. The OCF instrastructure has several parts, each with different resource requirements: -* `controller`` +* `controller` ** 512 Mi of memory * `couchdb` ** 512 Mi of memory @@ -46,13 +47,9 @@ The OCF instrastructure has several parts, each with different resource requirem There are a number of other jobs and activities that will run with project defaults as well. -In total, it is recommended that you have a minimum of: - -* 4 GiB of memory -* 4 CPU cores - -available to run the OCF infrastructure. These are the bare minimums for -testing. +In total, it is recommended that you have a minimum of **4 GiB of memory** +and **4 CPU cores** available to run the OCF infrastructure. These are the +bare minimums for testing. Additionally, you may wish to have a few gigabytes of persistent storage available. Persistent storage is used so that you can retain the various @@ -61,13 +58,31 @@ settings, function definitions, history and etc. ==== Disconnected Installations If your OpenShift environment is not connected to the internet, you will need -to fetch the following container images in advance of attempting to -install/deploy OCF: +to fetch container images ahead of time and will need to modify the OCF +deployment template. You must download the following container images in +advance of attempting to install/deploy OCF: * image * image * image +The easiest way to do this will be from a RHEL7 or Fedora 27+ host with the +`podman` package installed. You can run this bit of `bash`-fu to make things +work: + +```bash +for image in couchdb foo bar baz +do + podman pull $image + podman save $image -o $image.tar +done +``` + +Once you have all of the tarballs, you can transfer them to a host with +access to your OpenShift cluster. It will also need `podman` installed. See +the additional notes below in the **Deploying OCF** section for what to do in +disconnected environments. + === Deploying OCF ==== Create a Project @@ -76,11 +91,60 @@ sufficient quota, limits, and requests to accommodate the resource requirements detailed above. ``` -oc create blah +oc create project ocf-infra ``` +You will then deploy the OCF infrastructure into this project. + +[NOTE] +==== +In a disconnected environment you will need to load the images into the +OpenShift registry before you can deploy the OCF infrastructure. Now that you +have a project, you also have a place in the registry to push the images. +From the system with the tarballs from earlier, perform the following +commands: + +```bash +podman login ${YOURSPECIALSAUCEHERE} +for image in couchdb foo bar +do + podman something $image + podman push $imageSOMETHING +done +==== + ==== Process the Template -We have conveniently provided an OpenShift template that will deploy all of the objects required to run the OCF infrastructure. It contains many sensible defaults and aligns with the resource requirements detailed above. To instantiate the OCF infrastructure, simply `process` the template: +We have conveniently provided an OpenShift template that will deploy all of +the objects required to run the OCF infrastructure. It contains many sensible +defaults and aligns with the resource requirements detailed above. + +[NOTE] +==== +For disconnected installations, you will need to modify the template to tell +OpenShift to use the images that you just pushed into the registry in the +`ocf-infra` project. + +First, get the template: + + wget https://git.io/openwhisk-template + +Then, you will need to modify the template. Anywhere you see an `ImageStream` +block, you will need to change it to look something like the following: + +```YAML +things + and-stuff: +``` +Once you have appropriately changed all of the `ImageStream` blocks, you can +then `process` the template like so: + + oc process -f ./template.yml | oc create -f - + +Please skip the next step that shows processing the template directly from +the web. +==== + +To instantiate the OCF infrastructure, simply `process` the template: ``` oc process -f https://git.io/openwhisk-template | oc create -f - From 8aa0dca5d2542cffdc87f20dc88378daeb365250 Mon Sep 17 00:00:00 2001 From: Erik M Jacobs Date: Mon, 4 Jun 2018 12:14:10 -0400 Subject: [PATCH 3/5] Completed disconnected setup instructions and supporting scripts. --- image-pull.sh | 38 + image-push.sh | 59 ++ src/main/asciidoc/index.adoc | 85 +- template.yml | 1464 ++++++++++++++++++++++++++++++++++ 4 files changed, 1604 insertions(+), 42 deletions(-) create mode 100644 image-pull.sh create mode 100644 image-push.sh create mode 100644 template.yml diff --git a/image-pull.sh b/image-pull.sh new file mode 100644 index 0000000..8c2554b --- /dev/null +++ b/image-pull.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# temporarily using docker due to podman bugs + +export OPENWHISK_VERSION=rhdemo-9717f07a +export PROJECTODD_VERSION=8ee5579 +export STRIMZI_VERSION="0.3.1" +export ALARMPROVIDER_VERSION="1.9.0" +export NGINX_VERSION="42330f7f29ba1ad67819f4ff3ae2472f62de13a827a74736a5098728462212e7" +for image in \ +action-nodejs-6 \ +action-nodejs-8 \ +action-java-8 \ +action-python-3 \ +action-python-2 \ +action-php-7 \ +dockerskeleton \ +whisk_couchdb \ +whisk_alarms \ +whisk_catalog +do + docker pull docker.io/projectodd/$image:$PROJECTODD_VERSION + docker save -o projectodd-$image.tar docker.io/projectodd/$image:$PROJECTODD_VERSION +done +for image in \ +controller \ +invoker +do + docker pull docker.io/projectodd/$image:$OPENWHISK_VERSION + docker save -o projectodd-$image.tar docker.io/projectodd/$image:$OPENWHISK_VERSION +done +docker pull docker.io/strimzi/cluster-controller:$STRIMZI_VERSION +docker save -o projectodd-strimzi.tar docker.io/strimzi/cluster-controller:$STRIMZI_VERSION +docker pull docker.io/openwhisk/alarmprovider:$ALARMPROVIDER_VERSION +docker save -o projectodd-alarm.tar docker.io/openwhisk/alarmprovider:$ALARMPROVIDER_VERSION +docker pull docker.io/centos/nginx-112-centos7@sha256:$NGINX_VERSION +docker save -o projectodd-nginx.tar docker.io/centos/nginx-112-centos7@sha256:$NGINX_VERSION +docker pull docker.io/busybox +docker save -o projectodd-busybox.tar docker.io/busybox:latest \ No newline at end of file diff --git a/image-push.sh b/image-push.sh new file mode 100644 index 0000000..b64f7e6 --- /dev/null +++ b/image-push.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# using docker due to podman bugs + +export OPENWHISK_VERSION=rhdemo-9717f07a +export PROJECTODD_VERSION=8ee5579 +export STRIMZI_VERSION="0.3.1" +export ALARMPROVIDER_VERSION="1.9.0" +export NGINX_VERSION="42330f7f29ba1ad67819f4ff3ae2472f62de13a827a74736a5098728462212e7" +export REGISTRY="172.30.1.1:5000" + +# create the `ocf-infra` project +oc new-project ocf-infra + +# login to the registry with its builder account +docker login -u serviceaccount -p `oc sa get-token builder -n ocf-infra` $REGISTRY + +# load all the tarballs into the local docker image store +for tarball in `ls projectodd*` +do + docker load -i $tarball +done + +# retag images with `whisky` tag +for image in \ +action-nodejs-6 \ +action-nodejs-8 \ +action-java-8 \ +action-python-3 \ +action-python-2 \ +action-php-7 \ +dockerskeleton +do + docker tag docker.io/projectodd/$image:$PROJECTODD_VERSION $REGISTRY/ocf-infra/$image:whisky +done +for image in \ +controller \ +invoker +do + docker tag docker.io/projectodd/$image:$OPENWHISK_VERSION $REGISTRY/ocf-infra/$image:whisky +done +docker tag docker.io/strimzi/cluster-controller:$STRIMZI_VERSION $REGISTRY/ocf-infra/cluster-controller:whisky +docker tag docker.io/openwhisk/alarmprovider:$ALARMPROVIDER_VERSION $REGISTRY/ocf-infra/alarmprovider:whisky +docker tag docker.io/centos/nginx-112-centos7@sha256:$NGINX_VERSION $REGISTRY/ocf-infra/nginx:whisky +docker tag docker.io/busybox:latest $REGISTRY/ocf-infra/busybox:whisky +docker tag docker.io/projectodd/whisk_couchdb:$PROJECTODD_VERSION $REGISTRY/ocf-infra/couchdb:whisky +docker tag docker.io/projectodd/whisk_alarms:$PROJECTODD_VERSION $REGISTRY/ocf-infra/alarms:whisky +docker tag docker.io/projectodd/whisk_catalog:$PROJECTODD_VERSION $REGISTRY/ocf-infra/catalog:whisky + +# find all the images we re-tagged and then push them into the registry +for image in $(docker images | grep 172 | awk '{print $1":"$2}') +do + docker push $image +done + +# patch the imagestreams to change the lookup policy +for stream in $(oc get is -o name) +do + oc patch $stream -p '{"spec":{"lookupPolicy":{"local":true}}}' +done \ No newline at end of file diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index e40b68e..a673ada 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -62,25 +62,39 @@ to fetch container images ahead of time and will need to modify the OCF deployment template. You must download the following container images in advance of attempting to install/deploy OCF: -* image -* image -* image +* `projectodd/controller` +* `projectodd/invoker` +* `projectodd/action-nodejs-8` +* `projectodd/action-java-8` +* `projectodd/action-python-3` +* `projectodd/action-python-2` +* `projectodd/action-php-7` +* `projectodd/whisk_couchdb` +* `projectodd/whisk_alarms` +* `projectodd/whisk_catalog` +* `projectodd/dockerskeleton` +* `openwhisk/alarmprovider` +* `centos/nginx-112-centos7` +* `strimzi/cluster-controller` +* `busybox` The easiest way to do this will be from a RHEL7 or Fedora 27+ host with the -`podman` package installed. You can run this bit of `bash`-fu to make things -work: +`podman` package installed. In a folder where you want the exported images to +land, you can run the `image-pull.sh` script from this early access repository: ```bash -for image in couchdb foo bar baz -do - podman pull $image - podman save $image -o $image.tar -done +cd +mkdir images +cd images +wget https://raw.githubusercontent.com/openshift-cloud-functions/early-access/master/image-pull.sh +bash image-pull.sh ``` Once you have all of the tarballs, you can transfer them to a host with -access to your OpenShift cluster. It will also need `podman` installed. See -the additional notes below in the **Deploying OCF** section for what to do in +access to your OpenShift cluster. More importantly, it needs to be on the +OpenShift SDN, or you need to have your registry exposed externally so that +images can be pushed into it. It will also need `podman` installed. See the +additional notes below in the **Deploying OCF** section for what to do in disconnected environments. === Deploying OCF @@ -91,7 +105,7 @@ sufficient quota, limits, and requests to accommodate the resource requirements detailed above. ``` -oc create project ocf-infra +oc new-project ocf-infra ``` You will then deploy the OCF infrastructure into this project. @@ -100,17 +114,20 @@ You will then deploy the OCF infrastructure into this project. ==== In a disconnected environment you will need to load the images into the OpenShift registry before you can deploy the OCF infrastructure. Now that you -have a project, you also have a place in the registry to push the images. -From the system with the tarballs from earlier, perform the following -commands: +have a project, you also have a place in the registry to push the images. On +the system with SDN access to your OpenShift environment, and in a folder +with **only** the tarballs from earlier, perform the following commands +logged in to OpenShift with a user account that has at least `cluster-reader` +privileges (you need access to the `openshift` project serviceaccounts and +secrets): ```bash -podman login ${YOURSPECIALSAUCEHERE} -for image in couchdb foo bar -do - podman something $image - podman push $imageSOMETHING -done +cd folder-with-tarballs +wget https://raw.githubusercontent.com/openshift-cloud-functions/early-access/master/image-push.sh +bash image-push.sh +``` + +This script will also create the `ocf-infra` project for you. ==== ==== Process the Template @@ -120,28 +137,12 @@ defaults and aligns with the resource requirements detailed above. [NOTE] ==== -For disconnected installations, you will need to modify the template to tell -OpenShift to use the images that you just pushed into the registry in the -`ocf-infra` project. - -First, get the template: - - wget https://git.io/openwhisk-template - -Then, you will need to modify the template. Anywhere you see an `ImageStream` -block, you will need to change it to look something like the following: - -```YAML -things - and-stuff: -``` -Once you have appropriately changed all of the `ImageStream` blocks, you can -then `process` the template like so: +For disconnected installations, there is a slightly modified template that +you will need to use: - oc process -f ./template.yml | oc create -f - + oc process -f https://raw.githubusercontent.com/openshift-cloud-functions/early-access/master/template.yaml | oc create -f - -Please skip the next step that shows processing the template directly from -the web. +Please skip the next step. ==== To instantiate the OCF infrastructure, simply `process` the template: diff --git a/template.yml b/template.yml new file mode 100644 index 0000000..d9f324f --- /dev/null +++ b/template.yml @@ -0,0 +1,1464 @@ +apiVersion: v1 +kind: Template +metadata: + name: openwhisk-ephemeral + annotations: + openshift.io/display-name: Apache OpenWhisk (Ephemeral) + description: Apache OpenWhisk serverless platform, without persistent storage. You can leave all parameters blank and sensible defaults will be used. + iconClass: icon-apache + tags: serverless, openwhisk + openshift.io/long-description: This template provides a small OpenWhisk installation. Data is not stored on persistent storage, so any restart of the service will result in all data being lost. + openshift.io/provider-display-name: Red Hat, Inc. + openshift.io/documentation-url: https://github.com/projectodd/openwhisk-openshift/ + openshift.io/support-url: https://github.com/projectodd/openwhisk-openshift/issues +message: "To get started download the `wsk` CLI from https://github.com/apache/incubator-openwhisk-cli/releases/\n\nYour OpenWhisk authentication token: ${WHISK_SYSTEM_AUTH}\n\nYour OpenWhisk api endpoint can be found in the console UI after closing the template wizard.\n\nConfigure your `wsk` client with `wsk property set --auth --apihost `" +labels: + template: openwhisk-ephemeral-template + +parameters: +- name: CONTROLLER_INSTANCES + description: The desired number of controllers + value: "1" + required: true +- name: CONTROLLER_MEMORY_REQUEST + description: The minimum container memory for each Controller + value: "512Mi" + required: true +- name: CONTROLLER_MEMORY_LIMIT + description: The maximum container memory for each Controller + value: "512Mi" + required: true +- name: CONTROLLER_JAVA_OPTS + description: JVM options to pass to the Controller - recommended to set at least Xmx here + value: "-Xmx256m" + required: true +- name: CONTROLLER_HA + description: Boolean denoting whether HA mode + value: "FALSE" + required: true +- name: CONTROLLER_LOCALBOOKKEEPING + description: Boolean denoting whether load balancer data is local or shared + value: "TRUE" + required: true +- name: CONTROLLER_INVOKER_BUSYTHRESHOLD + description: Value that controllers when the Controller(s) considers the Invoker(s) to be full. This should be less than or equal to INVOKER_MAX_CONTAINERS. Making them equal will give the highest function density but setting it a bit less than INVOKER_MAX_CONTAINERS can improve overall system throughput and reduce Invoker function container thrashing. + value: "8" + required: true +- name: CONTROLLER_INVOKER_BLACKBOXFRACTION + description: What percent of Invokers should be used for blackbox (user-provider container image) actions. At least one Invoker will be dedicated for blackbox actions as long as 2 or more Invokers are deployed no matter what percentage is set here. + value: "10%" + required: true +- name: AKKA_CLUSTER_SEED_NODES + description: Hostnames of akka seed nodes + value: "controller-0.controller:2551" + required: true +- name: INVOKER_INSTANCES + description: The desired number of invokers + value: "1" + required: true +- name: INVOKER_CPU_REQUEST + description: The minimum cpu cores for each Invoker + value: "500m" + required: true +- name: INVOKER_MEMORY_REQUEST + description: The minimum container memory for each Invoker + value: "1Gi" + required: true +- name: INVOKER_MEMORY_LIMIT + description: The maximum container memory for each Invoker + value: "1Gi" + required: true +- name: INVOKER_JAVA_OPTS + description: JVM options to pass to the Invoker - recommended to set at least Xmx here + value: "-Xmx512m" + required: true +- name: INVOKER_MAX_CONTAINERS + description: Maximum function containers per Invoker + value: "8" + required: true +- name : INVOKER_CONTAINER_TIMEOUT + description: Maximum time an idle function container should stick around before the Invoker deletes it. The longer the timeout, the longer functions stay warm. The shorter the timeout, the less resources consumed by idle function containers. Example values - "5 minutes", "30 seconds", etc. + value: "2 minutes" + required: true +- name: INVOKER_CONTAINER_PAUSE_TIMEOUT + description: Maximum time an idle function container should stick around before the Invoker marks it as paused. Example values - "5 seconds", "500 milliseconds", etc. + value: "5 seconds" + required: true +- name: INVOKER_CONTAINER_CONCURRENT_STARTS + description: Maximum number of action containers each Invoker will attempt to start at once. Raise or lower this number depending on your throughput requirements, cold start rate, number of Invokers you deploy, and how quickly your cluster can spin up new pods. + value: "10" + required: true +- name: INVOKER_LOGSTORE_PROVIDER + description: Apache OpenWhisk LogStoreProvider implementation. Setting this to whisk.core.containerpool.logging.LogDriverLogStoreProvider will increase throughput but users will have to find logs another way, like via Kibana. + value: "whisk.core.containerpool.logging.DockerToActivationLogStoreProvider" + required: true +- name: COUCHDB_INSTANCES + description: The desired number of CouchDB nodes + value: "1" + required: true +- name: COUCHDB_CPU_REQUEST + description: The minimum cpu cores for each CouchDB + value: "500m" + required: true +- name: COUCHDB_MEMORY_REQUEST + description: The minimum container memory for each CouchDB + value: "256Mi" + required: true +- name: COUCHDB_MEMORY_LIMIT + description: The maximum container memory for each CouchDB + value: "512Mi" + required: true +- name: COUCHDB_USER + description: CouchDB Username + generate: expression + from: "user[A-Z0-9]{3}" + required: true +- name: COUCHDB_PASSWORD + description: CouchDB Password + generate: expression + from: "[a-zA-Z0-9]{16}" + required: true +- name: COUCHDB_SECRET + description: CouchDB Replication Secret + generate: expression + from: "[a-zA-Z0-9]{16}" + required: true +- name: ZOOKEEPER_NODE_COUNT + description: Number of Zookeper cluster nodes which will be deployed (odd number of nodes is recomended) + displayName: Number of Zookeper cluster nodes (odd number of nodes is recomended) + required: true + value: "1" +- name: KAFKA_NODE_COUNT + description: Number of Kafka cluster nodes which will be deployed + displayName: Number of Kafka cluster nodes + required: true + value: "1" +- name: WHISK_SYSTEM_AUTH + description: OpenWhisk Auth token for whisk.system account + generate: expression + from: "789c46b1-71f6-4ed5-8c54-816aa4f8c502:[a-zA-Z0-9]{64}" + required: true +- name: WHISK_GUEST_AUTH + description: OpenWhisk Auth token for guest account + generate: expression + from: "23bc46b1-71f6-4ed5-8c54-816aa4f8c502:[a-zA-Z0-9]{64}" + required: true +- name: WHISK_ACTIONS_INVOKES_CONCURRENT + description: Default number of concurrenct actions per user + value: "30" + required: true +- name: WHISK_ACTIONS_INVOKES_CONCURRENT_IN_SYSTEM + description: Number of concurrent actions allowed across the entire system + value: "1000" + required: true +- name: WHISK_ACTIONS_INVOKES_PER_MINUTE + description: Default number of action invocations per minute per user + value: "60" + required: true +- name: WHISK_TRIGGERS_FIRES_PER_MINUTE + description: Default number of triggers that can fire per minute per user + value: "60" + required: true +- name: WHISK_DAYS_TO_KEEP_LOGS + description: Number of days to keep activation logs before pruning them from the database + value: "7" + required: true +- name: WHISK_DAYS_TO_KEEP_ACTIVATIONS + description: Number of days to keep activation records before pruning them from the database + value: "30" + required: true +- name: WHISK_ACTIONS_MEMORY_MAX + description: Maximum memory an action is allowed to request. + value: "1024 m" + required: true +- name: WHISK_ACTIONS_MEMORY_MIN + description: Minimum memory an action is allowed to request. + value: "128 m" + required: true +- name: WHISK_ACTIONS_MEMORY_STD + description: Default memory an action requests if unspecified. + value: "256 m" + required: true +- name: WHISK_KAFKA_REPLICATION_FACTOR + description: Replication factor for all OpenWhisk topics + value: "1" + required: true +- name: WHISK_KAFKA_TOPICS_COMPLETED_RETENTION_BYTES + description: Maximum bytes to retain for the completed activations topic for each Controller. Each kafka node will consume this many bytes times the number of Controllers just for the completed topics. So, if this is set to 1GB and you have 3 Controllers then expect up to 3GB of disk space used by the Controller topics. + value: "268435456" + required: true +- name: WHISK_KAFKA_TOPICS_INVOKER_RETENTION_BYTES + description: Maximum bytes to retain for each Invoker topic. Each Kafka node will consume this many bytes times the number of Invokers just for the Invoker topics. So, if this is set to 1GB and you have 10 Invokers then expect up to 10GB of disk space used by the Invoker topics. + value: "268435456" + required: true +- name: OPENWHISK_VERSION + description: The DockerHub tag for openwhisk/{controller,invoker} + value: "rhdemo-9717f07a" + required: true +- name: PROJECTODD_VERSION + description: The DockerHub tag for projectodd images + value: "8ee5579" + required: true +- name: STRIMZI_VERSION + description: The DockerHub tag for strimzi images + value: "0.3.1" + required: true + +objects: + +- apiVersion: v1 + kind: ConfigMap + metadata: + name: whisk.config + data: + whisk_system_namespace: /whisk.system + whisk_version_date: 2018-01-01T00:00:00Z + whisk_version_name: OpenWhisk + whisk_version_tag: latest +- apiVersion: v1 + kind: ConfigMap + metadata: + creationTimestamp: null + name: whisk.limits + data: + actions_invokes_concurrent: "${WHISK_ACTIONS_INVOKES_CONCURRENT}" + actions_invokes_concurrentInSystem: "${WHISK_ACTIONS_INVOKES_CONCURRENT_IN_SYSTEM}" + actions_invokes_perMinute: "${WHISK_ACTIONS_INVOKES_PER_MINUTE}" + actions_sequence_maxLength: "50" + triggers_fires_perMinute: "${WHISK_TRIGGERS_FIRES_PER_MINUTE}" +- apiVersion: v1 + kind: ConfigMap + metadata: + name: whisk.runtimes + data: + runtimes: | + { + "bypassPullForLocalImages": false, + "defaultImagePrefix": "openwhisk", + "defaultImageTag": "latest", + "runtimes": { + "nodejs": [ + { + "kind": "nodejs", + "image": { + "name": "action-nodejs-6" + }, + "deprecated": true + }, + { + "kind": "nodejs:6", + "default": true, + "image": { + "name": "action-nodejs-6" + }, + "deprecated": false + }, + { + "kind": "nodejs:8", + "default": false, + "image": { + "name": "action-nodejs-8" + }, + "deprecated": false + } + ], + "python": [ + { + "kind": "python", + "image": { + "name": "action-python-2" + }, + "deprecated": false + }, + { + "kind": "python:2", + "default": true, + "image": { + "name": "action-python-2" + }, + "deprecated": false + }, + { + "kind": "python:3", + "image": { + "name": "action-python-3" + }, + "deprecated": false + } + ], + "swift": [ + { + "kind": "swift", + "image": { + "name": "action-swift-3" + }, + "deprecated": true + }, + { + "kind": "swift:3", + "image": { + "name": "action-swift-3" + }, + "deprecated": true + }, + { + "kind": "swift:3.1.1", + "default": true, + "image": { + "name": "action-swift-3" + }, + "deprecated": false + } + ], + "java": [ + { + "kind": "java", + "default": true, + "image": { + "name": "action-java-8" + }, + "deprecated": false, + "attached": { + "attachmentName": "jarfile", + "attachmentType": "application/java-archive" + }, + "sentinelledLogs": false, + "requireMain": true + } + ], + "php": [ + { + "kind": "php:7.1", + "default": true, + "deprecated": false, + "image": { + "name": "action-php-7" + } + } + ] + }, + "blackboxes": [ + { + "name": "dockerskeleton" + } + ] + } +- apiVersion: v1 + kind: ConfigMap + metadata: + name: strimzi-openwhisk + labels: + strimzi.io/type: kafka + strimzi.io/kind: cluster + data: + kafka-nodes: "${KAFKA_NODE_COUNT}" + kafka-image: "strimzi/kafka:${STRIMZI_VERSION}" + kafka-healthcheck-delay: "60" + kafka-healthcheck-timeout: "5" + zookeeper-nodes: "${ZOOKEEPER_NODE_COUNT}" + zookeeper-image: "strimzi/zookeeper:${STRIMZI_VERSION}" + zookeeper-healthcheck-delay: "30" + zookeeper-healthcheck-timeout: "5" + KAFKA_DEFAULT_REPLICATION_FACTOR: "${KAFKA_NODE_COUNT}" + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "${KAFKA_NODE_COUNT}" + KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "${KAFKA_NODE_COUNT}" + kafka-storage: |- + { "type": "ephemeral" } + zookeeper-storage: |- + { "type": "ephemeral" } +- apiVersion: v1 + kind: Service + metadata: + name: controller + labels: + name: controller + spec: + selector: + name: controller + clusterIP: None + ports: + - port: 8080 + targetPort: 8080 + name: http +- apiVersion: v1 + kind: ConfigMap + metadata: + name: controller.config + data: + controller_opts: "-Dwhisk.spi.LoadBalancerProvider=whisk.core.loadBalancer.ShardingContainerPoolBalancer" + java_opts: "${CONTROLLER_JAVA_OPTS}" +- apiVersion: apps/v1beta1 + kind: StatefulSet + metadata: + name: controller + annotations: + template.alpha.openshift.io/wait-for-ready: "true" + labels: + name: controller + spec: + replicas: ${CONTROLLER_INSTANCES} + serviceName: "controller" + template: + metadata: + labels: + name: controller + spec: + restartPolicy: Always + containers: + - name: controller + imagePullPolicy: IfNotPresent + image: controller:whisky + command: ["/bin/bash", "-c", "COMPONENT_NAME=$(hostname | cut -d'-' -f2) CONFIG_akka_remote_netty_tcp_hostname=$(hostname).controller /init.sh `hostname | cut -d'-' -f2`"] + ports: + - name: controller + containerPort: 8080 + - name: akka + containerPort: 2551 + resources: + requests: + memory: ${CONTROLLER_MEMORY_REQUEST} + limits: + memory: ${CONTROLLER_MEMORY_LIMIT} + env: + # Properties for controller HA configuration + # Must change these if changing number of replicas + - name: "CONTROLLER_LOCALBOOKKEEPING" + value: ${CONTROLLER_LOCALBOOKKEEPING} + - name: "CONTROLLER_HA" + value: ${CONTROLLER_HA} + - name: "CONTROLLER_INSTANCES" + value: ${CONTROLLER_INSTANCES} + - name: "AKKA_CLUSTER_SEED_NODES" + value: ${AKKA_CLUSTER_SEED_NODES} + - name: "CONFIG_akka_actor_provider" + value: "cluster" + - name: "CONFIG_akka_remote_netty_tcp_bindPort" + value: "2551" + - name: "CONFIG_akka_remote_netty_tcp_port" + value: "2551" + - name: "CONFIG_whisk_loadbalancer_invokerBusyThreshold" + value: "${CONTROLLER_INVOKER_BUSYTHRESHOLD}" + - name: "CONFIG_whisk_loadbalancer_blackboxFraction" + value: "${CONTROLLER_INVOKER_BLACKBOXFRACTION}" + - name: "CONFIG_whisk_memory_max" + value: "${WHISK_ACTIONS_MEMORY_MAX}" + - name: "CONFIG_whisk_memory_min" + value: "${WHISK_ACTIONS_MEMORY_MIN}" + - name: "CONFIG_whisk_memory_std" + value: "${WHISK_ACTIONS_MEMORY_STD}" + - name: "CONFIG_whisk_kafka_replicationFactor" + value: "${WHISK_KAFKA_REPLICATION_FACTOR}" + - name: "CONFIG_whisk_kafka_topics_completed_retentionBytes" + value: "${WHISK_KAFKA_TOPICS_COMPLETED_RETENTION_BYTES}" + + # extra JVM arguments + - name: "JAVA_OPTS" + valueFrom: + configMapKeyRef: + name: controller.config + key: java_opts + + # extra controller arguments + - name: "CONTROLLER_OPTS" + valueFrom: + configMapKeyRef: + name: controller.config + key: controller_opts + + # action runtimes + - name: "RUNTIMES_MANIFEST" + valueFrom: + configMapKeyRef: + name: whisk.runtimes + key: runtimes + + # deployment version information + - name: "WHISK_VERSION_NAME" + valueFrom: + configMapKeyRef: + name: whisk.config + key: whisk_version_name + - name: "WHISK_VERSION_DATE" + valueFrom: + configMapKeyRef: + name: whisk.config + key: whisk_version_date + - name: "WHISK_VERSION_BUILDNO" + valueFrom: + configMapKeyRef: + name: whisk.config + key: whisk_version_tag + + # specify limits + - name: "LIMITS_ACTIONS_INVOKES_PERMINUTE" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_invokes_perMinute + - name: "LIMITS_ACTIONS_INVOKES_CONCURRENT" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_invokes_concurrent + - name: "LIMITS_ACTIONS_INVOKES_CONCURRENTINSYSTEM" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_invokes_concurrentInSystem + - name: "LIMITS_TRIGGERS_FIRES_PERMINUTE" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: triggers_fires_perMinute + - name: "LIMITS_ACTIONS_SEQUENCE_MAXLENGTH" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_sequence_maxLength + + # properties for Kafka connection + - name: "KAFKA_HOSTS" + value: "$(STRIMZI_OPENWHISK_KAFKA_SERVICE_HOST):$(STRIMZI_OPENWHISK_KAFKA_SERVICE_PORT_CLIENTS)" + + # properties for DB connection + - name: "CONFIG_whisk_couchdb_username" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "CONFIG_whisk_couchdb_password" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "CONFIG_whisk_couchdb_protocol" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "CONFIG_whisk_couchdb_host" + value: "$(COUCHDB_SERVICE_HOST)" + - name: "CONFIG_whisk_couchdb_port" + value: "$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "CONFIG_whisk_couchdb_provider" + valueFrom: + configMapKeyRef: + name: db.config + key: db_provider + - name: "CONFIG_whisk_couchdb_databases_WhiskActivation" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations + - name: "CONFIG_whisk_couchdb_databases_WhiskEntity" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_actions + - name: "CONFIG_whisk_couchdb_databases_WhiskAuth" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_auths + + # must match port used in livenessProbe below + - name: "PORT" + value: "8080" + + livenessProbe: + httpGet: + path: "/ping" + port: 8080 + scheme: "HTTP" + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 10 + failureThreshold: 5 + readinessProbe: + httpGet: + path: "/ping" + port: 8080 + scheme: "HTTP" + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 10 + failureThreshold: 5 + initContainers: + - name: wait-for-services + image: busybox:whisky + command: ['sh', '-cu', 'until nslookup couchdb && nslookup strimzi-openwhisk-kafka; do echo waiting for services; sleep 1; done'] + - name: wait-for-couchdb + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://${COUCHDB_SERVICE_HOST}:${COUCHDB_SERVICE_PORT}/${DB_WHISK_ACTIVATIONS}; do echo waiting for couchdb; sleep 2; done;'] + env: + - name: "DB_WHISK_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations +- apiVersion: batch/v1 + kind: Job + metadata: + name: install-catalog + spec: + activeDeadlineSeconds: 600 + template: + metadata: + name: install-catalog + spec: + containers: + - name: catalog + image: catalog:whisky + env: + - name: "WHISK_AUTH" + valueFrom: + secretKeyRef: + name: whisk.auth + key: system + - name: "WHISK_API_HOST_NAME" + value: "http://controller:8080" + initContainers: + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] + restartPolicy: Never +- apiVersion: v1 + kind: Service + metadata: + name: couchdb + labels: + name: couchdb + spec: + selector: + name: couchdb + ports: + - port: 5984 + targetPort: 5984 + name: couchdb +- apiVersion: v1 + kind: Service + metadata: + name: couchdb-headless + labels: + name: couchdb-headless + spec: + selector: + name: couchdb + ports: + - name: couchdb + port: 5984 + clusterIP: None +- apiVersion: v1 + kind: ConfigMap + metadata: + name: db.config + data: + db_prefix: test_ + db_protocol: http + db_provider: CouchDB + db_whisk_actions: test_whisks + db_whisk_activations: test_activations + db_whisk_auths: test_subjects + db_days_to_keep_logs: "${WHISK_DAYS_TO_KEEP_LOGS}" + db_days_to_keep_activations: "${WHISK_DAYS_TO_KEEP_ACTIVATIONS}" +- apiVersion: apps/v1beta1 + kind: StatefulSet + metadata: + name: couchdb + labels: + name: couchdb + spec: + replicas: ${COUCHDB_INSTANCES} + serviceName: couchdb-headless + template: + metadata: + labels: + name: couchdb + spec: + restartPolicy: Always + volumes: + - name: couchdb-data + emptyDir: {} + containers: + - name: couchdb + imagePullPolicy: IfNotPresent + image: couchdb:whisky + command: ["/init.sh"] + ports: + - name: couchdb + containerPort: 5984 + - name: epmd + containerPort: 4369 + - containerPort: 9100 + resources: + requests: + cpu: "${COUCHDB_CPU_REQUEST}" + memory: ${COUCHDB_MEMORY_REQUEST} + limits: + memory: ${COUCHDB_MEMORY_LIMIT} + env: + - name: "DB_PREFIX" + valueFrom: + configMapKeyRef: + name: db.config + key: db_prefix + - name: "DB_HOST" + value: "127.0.0.1" + - name: "DB_PORT" + value: "$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "COUCHDB_USER" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "COUCHDB_PASSWORD" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "COUCHDB_SECRET" + valueFrom: + secretKeyRef: + name: db.auth + key: db_secret + - name: "NODENAME_HOSTNAME" + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: "NODENAME_SUBDOMAIN" + value: "couchdb-headless" + - name: "COUCHDB_NODE_COUNT" + value: "${COUCHDB_INSTANCES}" + - name: "AUTH_WHISK_SYSTEM" + valueFrom: + secretKeyRef: + name: whisk.auth + key: system + - name: "AUTH_GUEST" + valueFrom: + secretKeyRef: + name: whisk.auth + key: guest + volumeMounts: + - name: couchdb-data + mountPath: "/opt/couchdb/data" + readinessProbe: + httpGet: + port: 5984 + path: "/_utils/" + initialDelaySeconds: 10 + periodSeconds: 15 + failureThreshold: 10 + timeoutSeconds: 3 +- apiVersion: v1 + kind: ConfigMap + metadata: + name: invoker.config + data: + docker_image_prefix: "" + docker_image_tag: whisky + docker_registry: "" + invoker_container_dns: "" + invoker_container_network: bridge + invoker_logs_dir: "" + invoker_opts: "-Dwhisk.spi.ContainerFactoryProvider=whisk.core.containerpool.kubernetes.KubernetesContainerFactoryProvider" + invoker_use_runc: "false" + java_opts: "${INVOKER_JAVA_OPTS}" +- apiVersion: v1 + kind: ConfigMap + metadata: + name: invoker + data: + init: | + export COMPONENT_NAME=$(hostname | cut -d'-' -f2) + # Dynamically determine API gateway host + export TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" + export NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)" + export APIGW_HOST=$(curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer ${TOKEN}" "https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/oapi/v1/namespaces/${NAMESPACE}/routes/openwhisk?pretty=true" | grep '"host":' | head -n 1 | awk -F '"' '{print $4}') + export APIGW_HOST_V2=${APIGW_HOST} + export WHISK_API_HOST_NAME=${APIGW_HOST} + exec /init.sh +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: openwhisk +- apiVersion: v1 + kind: RoleBinding + metadata: + name: openwhisk + roleRef: + name: edit + subjects: + - kind: ServiceAccount + name: openwhisk +- apiVersion: apps/v1beta1 + kind: StatefulSet + metadata: + name: invoker + labels: + name: invoker + spec: + replicas: ${INVOKER_INSTANCES} + serviceName: "invoker" + template: + metadata: + labels: + name: invoker + spec: + restartPolicy: Always + volumes: + - name: invoker-config + configMap: + name: invoker + serviceAccountName: openwhisk + + initContainers: + - name: wait-for-services + image: busybox:whisky + command: ['sh', '-cu', 'until nslookup couchdb && nslookup strimzi-openwhisk-zookeeper && nslookup strimzi-openwhisk-kafka; do echo waiting for services; sleep 1; done'] + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] + + containers: + - name: invoker + imagePullPolicy: IfNotPresent + image: invoker:whisky + command: [ "/bin/bash", "-o", "allexport", "/invoker_config/init" ] + ports: + - name: invoker + containerPort: 8080 + resources: + requests: + cpu: "${INVOKER_CPU_REQUEST}" + memory: ${INVOKER_MEMORY_REQUEST} + limits: + memory: ${INVOKER_MEMORY_LIMIT} + volumeMounts: + - name: invoker-config + mountPath: "/invoker_config" + env: + - name: "PORT" + value: "8080" + + # Generate stable invoker names from the StatefulSet names + - name: "INVOKER_NAME" + valueFrom: + fieldRef: + fieldPath: metadata.name + + # Docker-related options + - name: "INVOKER_CONTAINER_NETWORK" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_container_network + - name: "INVOKER_CONTAINER_DNS" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_container_dns + - name: "INVOKER_USE_RUNC" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_use_runc + - name: "INVOKER_CORESHARE" + value: "1" + - name: "INVOKER_NUMCORE" + value: "${INVOKER_MAX_CONTAINERS}" + - name: "CONFIG_whisk_containerProxy_timeouts_idleContainer" + value: "${INVOKER_CONTAINER_TIMEOUT}" + - name: "CONFIG_whisk_containerProxy_timeouts_pauseGrace" + value: "${INVOKER_CONTAINER_PAUSE_TIMEOUT}" + - name: "CONFIG_whisk_kubernetes_concurrentStarts" + value: "${INVOKER_CONTAINER_CONCURRENT_STARTS}" + - name: "CONFIG_whisk_memory_max" + value: "${WHISK_ACTIONS_MEMORY_MAX}" + - name: "CONFIG_whisk_memory_min" + value: "${WHISK_ACTIONS_MEMORY_MIN}" + - name: "CONFIG_whisk_memory_std" + value: "${WHISK_ACTIONS_MEMORY_STD}" + - name: "CONFIG_whisk_kafka_replicationFactor" + value: "${WHISK_KAFKA_REPLICATION_FACTOR}" + - name: "CONFIG_whisk_kafka_topics_invoker_retentionBytes" + value: "${WHISK_KAFKA_TOPICS_INVOKER_RETENTION_BYTES}" + - name: "DOCKER_IMAGE_PREFIX" + valueFrom: + configMapKeyRef: + name: invoker.config + key: docker_image_prefix + - name: "DOCKER_IMAGE_TAG" + valueFrom: + configMapKeyRef: + name: invoker.config + key: docker_image_tag + - name: "DOCKER_REGISTRY" + valueFrom: + configMapKeyRef: + name: invoker.config + key: docker_registry + + # action runtimes + - name: "RUNTIMES_MANIFEST" + valueFrom: + configMapKeyRef: + name: whisk.runtimes + key: runtimes + + # extra JVM arguments + - name: "JAVA_OPTS" + valueFrom: + configMapKeyRef: + name: invoker.config + key: java_opts + + # extra Invoker arguments + - name: "INVOKER_OPTS" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_opts + + # Recommend using "" because logs should go to stdout on kube + - name: "WHISK_LOGS_DIR" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_logs_dir + + # properties for Kafka connection + - name: "KAFKA_HOSTS" + value: "$(STRIMZI_OPENWHISK_KAFKA_SERVICE_HOST):$(STRIMZI_OPENWHISK_KAFKA_SERVICE_PORT_CLIENTS)" + + # properties for zookeeper connection + - name: "ZOOKEEPER_HOSTS" + value: "$(STRIMZI_OPENWHISK_ZOOKEEPER_SERVICE_HOST):$(STRIMZI_OPENWHISK_ZOOKEEPER_SERVICE_PORT_CLIENTS)" + + # properties for DB connection + - name: "CONFIG_whisk_couchdb_username" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "CONFIG_whisk_couchdb_password" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "CONFIG_whisk_couchdb_protocol" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "CONFIG_whisk_couchdb_host" + value: "$(COUCHDB_SERVICE_HOST)" + - name: "CONFIG_whisk_couchdb_port" + value: "$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "CONFIG_whisk_couchdb_provider" + valueFrom: + configMapKeyRef: + name: db.config + key: db_provider + - name: "CONFIG_whisk_couchdb_databases_WhiskActivation" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations + - name: "CONFIG_whisk_couchdb_databases_WhiskEntity" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_actions + - name: "CONFIG_whisk_couchdb_databases_WhiskAuth" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_auths + - name: CONFIG_whisk_kubernetes_namespace + valueFrom: + fieldRef: + fieldPath: metadata.namespace + + # Increase Kube API timeouts until we handle timeouts nicer + - name: "CONFIG_whisk_kubernetes_timeouts_run" + value: "10 minutes" + - name: "CONFIG_whisk_kubernetes_timeouts_rm" + value: "10 minutes" + - name: "CONFIG_whisk_kubernetes_timeouts_logs" + value: "10 minutes" + - name: "CONFIG_whisk_spi_LogStoreProvider" + value: "${INVOKER_LOGSTORE_PROVIDER}" +- apiVersion: batch/v1 + kind: Job + metadata: + name: preload-openwhisk-runtimes + labels: + name: preload-openwhisk-runtimes + spec: + completions: 1 + serviceAccountName: openwhisk + template: + metadata: + labels: + name: preload-openwhisk-runtimes + spec: + restartPolicy: Never + initContainers: + - name: preload-openwhisk-nodejs6 + image: action-nodejs-6:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-java8 + image: action-java-8:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-python3 + image: action-python-3:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-python2 + image: action-python-2:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-php7 + image: action-php-7:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + containers: + - name: preload-openwhisk-nodejs8 + image: action-nodejs-8:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] +- apiVersion: v1 + kind: Service + metadata: + name: nginx + labels: + name: nginx + spec: + type: NodePort + selector: + name: nginx + ports: + - port: 80 + targetPort: 8080 + name: http + - port: 8443 + targetPort: 8443 + name: https-admin +- apiVersion: v1 + kind: Route + metadata: + name: openwhisk + annotations: + template.openshift.io/expose-apihost: "{.spec.host}" + labels: + name: nginx + spec: + port: + targetPort: http + to: + kind: Service + name: nginx + weight: 100 + wildcardPolicy: None + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect +- apiVersion: v1 + kind: ConfigMap + metadata: + name: nginx + data: + init: | + cp /nginx_config/nginx.conf /tmp/nginx.conf + sed -i "s//$(grep nameserver /etc/resolv.conf | head -1 | awk '{print $2}')/" /tmp/nginx.conf + sed -i "s//${KUBERNETES_NAMESPACE}/" /tmp/nginx.conf + exec nginx -c /tmp/nginx.conf -g "daemon off;" + nginx.conf: | + worker_rlimit_nofile 4096; + + events { + worker_connections 4096; + } + + http { + client_max_body_size 50M; + + rewrite_log on; + log_format combined-upstream '$remote_addr - $remote_user [$time_local] ' + '$request $status $body_bytes_sent ' + '$http_referer $http_user_agent $upstream_addr'; + access_log /logs/nginx_access.log combined-upstream; + error_log /logs/nginx_error.log; + + proxy_http_version 1.1; + proxy_set_header Connection ""; + + server { + listen 8080 default; + + # Make sure nginx dynamically resolves dns entries + # instead of resolving once and caching that result + # forever + resolver ; + set $controller controller..svc.cluster.local; + + # match namespace, note while OpenWhisk allows a richer character set for a + # namespace, not all those characters are permitted in the (sub)domain name; + # if namespace does not match, no vanity URL rewriting takes place. + server_name ~^(?[0-9a-zA-Z-]+)\.localhost$; + + # proxy to the web action path + location / { + if ($namespace) { + rewrite /(.*) /api/v1/web/${namespace}/$1 break; + } + proxy_pass http://$controller:8080; + proxy_read_timeout 75s; # 70+5 additional seconds to allow controller to terminate request + } + + # proxy to 'public/html' web action by convention + location = / { + if ($namespace) { + rewrite ^ /api/v1/web/${namespace}/public/index.html break; + } + proxy_pass http://$controller:8080; + proxy_read_timeout 75s; # 70+5 additional seconds to allow controller to terminate request + } + + location /blackbox.tar.gz { + return 301 https://github.com/apache/incubator-openwhisk-runtime-docker/releases/download/sdk%400.1.0/blackbox-0.1.0.tar.gz; + } + # leaving this for a while for clients out there to update to the new endpoint + location /blackbox-0.1.0.tar.gz { + return 301 /blackbox.tar.gz; + } + + location /OpenWhiskIOSStarterApp.zip { + return 301 https://github.com/openwhisk/openwhisk-client-swift/releases/download/0.2.3/starterapp-0.2.3.zip; + } + + # redirect requests for specific binaries to the matching one from the latest openwhisk-cli release. + location /cli/go/download/linux/amd64 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-linux-amd64.tgz; + } + location /cli/go/download/linux/386 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-linux-386.tgz; + } + location /cli/go/download/mac/amd64 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-mac-amd64.zip; + } + location /cli/go/download/mac/386 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-mac-386.zip; + } + location /cli/go/download/windows/amd64 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-windows-amd64.zip; + } + location /cli/go/download/windows/386 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-windows-386.zip; + } + + # redirect top-level cli downloads to the latest openwhisk-cli release. + location /cli/go/download { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/latest; + } + } + } +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: nginx + annotations: + template.alpha.openshift.io/wait-for-ready: "true" + labels: + name: nginx + spec: + replicas: 1 + template: + metadata: + labels: + name: nginx + spec: + restartPolicy: Always + volumes: + - name: nginx-conf + configMap: + name: nginx + - name: logs + emptyDir: {} + containers: + - name: nginx + imagePullPolicy: IfNotPresent + # Image from Mar 22nd + image: nginx:whisky + command: [ "/bin/bash", "-o", "allexport", "/nginx_config/init" ] + env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 8080 + - name: https-admin + containerPort: 8443 + volumeMounts: + - name: nginx-conf + mountPath: "/nginx_config" + - name: logs + mountPath: "/logs" + initContainers: + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] +- apiVersion: v1 + kind: Secret + metadata: + name: whisk.auth + annotations: + template.openshift.io/expose-auth: "{.data['system']}" + stringData: + guest: "${WHISK_GUEST_AUTH}" + system: "${WHISK_SYSTEM_AUTH}" +- apiVersion: v1 + kind: Secret + metadata: + name: db.auth + stringData: + db_username: "${COUCHDB_USER}" + db_password: "${COUCHDB_PASSWORD}" + db_secret: "${COUCHDB_SECRET}" +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: strimzi-cluster-controller + spec: + replicas: 1 + template: + metadata: + labels: + name: strimzi-cluster-controller + spec: + serviceAccountName: openwhisk + containers: + - name: strimzi-cluster-controller + image: cluster-controller:whisky + env: + - name: STRIMZI_CONFIGMAP_LABELS + value: "strimzi.io/kind=cluster" + - name: STRIMZI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: STRIMZI_OPERATION_TIMEOUT_MS + value: "600000" + livenessProbe: + httpGet: + path: /healthy + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 30 + readinessProbe: + httpGet: + path: /ready + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 30 + initContainers: + - name: preload-strimzi-zookeeper + image: strimzi/zookeeper:${STRIMZI_VERSION} + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-strimzi-kafka + image: strimzi/kafka:${STRIMZI_VERSION} + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] +- apiVersion: v1 + kind: ConfigMap + metadata: + name: alarmprovider + data: + PORT: "8080" + DB_PREFIX: "whisk_alarms_" + CONTROLLER_HOST: "controller" + CONTROLLER_PORT: "8080" + env: | + export TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" + export NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)" + export ROUTER_HOST=$(curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer ${TOKEN}" "https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/oapi/v1/namespaces/${NAMESPACE}/routes/openwhisk?pretty=true" | grep '"host":' | head -n 1 | awk -F '"' '{print $4}') +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: alarmprovider + labels: + name: alarmprovider + spec: + replicas: 1 + template: + metadata: + labels: + name: alarmprovider + spec: + restartPolicy: Always + serviceAccountName: openwhisk + volumes: + - name: alarmprovider-config + configMap: + name: alarmprovider + containers: + - name: alarmprovider + imagePullPolicy: IfNotPresent + image: alarmprovider:whisky + command: [ "/bin/bash", "-c", "source /alarmprovider_config/env; node /alarmsTrigger/app.js" ] + envFrom: + - configMapRef: + name: alarmprovider + env: + - name: "DB_HOST" + value: "$(COUCHDB_SERVICE_HOST):$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "DB_PROTOCOL" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "DB_USERNAME" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "DB_PASSWORD" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + volumeMounts: + - name: alarmprovider-config + mountPath: "/alarmprovider_config" + initContainers: + - name: wait-for-couchdb + image: busybox:whisky + command: ['sh', '-cu', 'echo "$COUCHDB_SERVICE_HOST"'] + - name: install-alarms-catalog + imagePullPolicy: IfNotPresent + image: alarms:whisky + envFrom: + - configMapRef: + name: alarmprovider + env: + - name: "DB_HOST" + value: "$(COUCHDB_SERVICE_HOST):$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "DB_PROTOCOL" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "AUTH_WHISK_SYSTEM" + valueFrom: + secretKeyRef: + name: whisk.auth + key: system + volumeMounts: + - name: alarmprovider-config + mountPath: "/alarmprovider_config" +- apiVersion: batch/v2alpha1 + kind: CronJob + metadata: + name: refresh-activations + labels: + name: refresh-activations + spec: + schedule: "*/5 * * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + metadata: + labels: + parent: "cronjob-refresh-activations" + spec: + serviceAccountName: openwhisk + restartPolicy: Never + containers: + - name: refresh-activations + image: alarms:whisky + command: ["/bin/bash", "-c", "/openwhisk/bin/wsk --auth $AUTH_GUEST --apihost http://controller:8080 -i activation list"] + env: + - name: "AUTH_GUEST" + valueFrom: + secretKeyRef: + name: whisk.auth + key: guest + initContainers: + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] + restartPolicy: Never +- apiVersion: batch/v2alpha1 + kind: CronJob + metadata: + name: prune-activations + labels: + name: prune-activations + spec: + schedule: "0 0 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + metadata: + labels: + parent: "cronjob-prune-activations" + spec: + restartPolicy: Never + containers: + - name: prune-activations + image: couchdb:whisky + command: ["/bin/bash", "-c", "set -x; curl -H \"Content-Type: application/json\" -X PUT -d \"100\" \"http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB/$DB_ACTIONS/_revs_limit\"; curl -H \"Content-Type: application/json\" -X PUT -d \"5\" \"http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB/$DB_ACTIVATIONS/_revs_limit\"; /openwhisk/tools/db/deleteLogsFromActivations.py --dbUrl http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB --dbName $DB_ACTIVATIONS --days $DB_DAYS_TO_KEEP_LOGS; /openwhisk/tools/db/cleanUpActivations.py --dbUrl http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB --dbName $DB_ACTIVATIONS --days $DB_DAYS_TO_KEEP_ACTIVATIONS"] + env: + - name: "DB_USERNAME" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "DB_PASSWORD" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "DB_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations + - name: "DB_ACTIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_actions + - name: "DB_DAYS_TO_KEEP_LOGS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_days_to_keep_logs + - name: "DB_DAYS_TO_KEEP_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_days_to_keep_activations + initContainers: + - name: wait-for-couchdb + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://${COUCHDB_SERVICE_HOST}:${COUCHDB_SERVICE_PORT}/${DB_WHISK_ACTIVATIONS}; do echo waiting for couchdb; sleep 2; done;'] + env: + - name: "DB_WHISK_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations + From 97375763acbddd4cc28edb983dd654abe64fbe51 Mon Sep 17 00:00:00 2001 From: Erik M Jacobs Date: Mon, 4 Jun 2018 12:42:22 -0400 Subject: [PATCH 4/5] Adds wsk CLI configuration --- src/main/asciidoc/index.adoc | 97 ++++++++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 9 deletions(-) diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index a673ada..c1bfca7 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -4,7 +4,7 @@ :sectnumlevels: 2 :sectanchors: :nofooter: -:source-highlighter: coderay +//:source-highlighter: coderay = OpenShift Cloud Functions @@ -64,6 +64,7 @@ advance of attempting to install/deploy OCF: * `projectodd/controller` * `projectodd/invoker` +* `projectodd/action-nodejs-6` * `projectodd/action-nodejs-8` * `projectodd/action-java-8` * `projectodd/action-python-3` @@ -79,8 +80,9 @@ advance of attempting to install/deploy OCF: * `busybox` The easiest way to do this will be from a RHEL7 or Fedora 27+ host with the -`podman` package installed. In a folder where you want the exported images to -land, you can run the `image-pull.sh` script from this early access repository: +`podman` package installed. **As the `root` user** In a folder where you want +the exported images to land, you can run the `image-pull.sh` script from this +early access repository: ```bash cd @@ -119,7 +121,7 @@ the system with SDN access to your OpenShift environment, and in a folder with **only** the tarballs from earlier, perform the following commands logged in to OpenShift with a user account that has at least `cluster-reader` privileges (you need access to the `openshift` project serviceaccounts and -secrets): +secrets) and **as the `root` system user**: ```bash cd folder-with-tarballs @@ -152,14 +154,91 @@ oc process -f https://git.io/openwhisk-template | oc create -f - ``` === Wait for Success -+...+ profit! +Eventually all of the pods will start running. After a few minutes, execute +`oc get pods` and you should see output that looks similar to the following: + +``` +NAME READY STATUS RESTARTS AGE +alarmprovider-574d685789-djfpq 1/1 Running 0 13m +controller-0 1/1 Running 2 13m +couchdb-0 1/1 Running 0 13m +install-catalog-7p8c8 0/1 Completed 0 13m +invoker-0 1/1 Running 0 13m +nginx-648445cbd9-2j2jd 1/1 Running 0 13m +preload-openwhisk-runtimes-z9krn 0/1 Completed 0 13m +refresh-activations-1528129200-697t7 0/1 Completed 0 2m +strimzi-cluster-controller-778d94d86-pxc2c 1/1 Running 0 13m +strimzi-openwhisk-kafka-0 1/1 Running 0 13m +strimzi-openwhisk-zookeeper-0 1/1 Running 0 13m +wskinvoker-00-1-prewarm-nodejs6 1/1 Running 0 10m +wskinvoker-00-2-prewarm-nodejs6 1/1 Running 0 10m +``` + +Notice that all pods are either `Running` and are `1/1` for `READY` or are +`Completed`. If you have any failures or errors you probably need to contact +us so that we can figure out what is wrong. + +==== Install the CLI +OpenShift Cloud Functions still directly uses the `wsk` CLI from the +OpenWhisk project. You can download a CLI for your system from the following +URL: + + https://github.com/projectodd/openwhisk-openshift/releases/tag/latest + +The CLI will talk to OpenShift Cloud Functions' APIs which means that it will +need to be on a host that will have network access to the OpenShift +environment through OpenShift's router. You will also want this host to have +the `oc` binary installed. + +Unpack the `wsk` binary into a folder that is in your path, and then simply +execute `wsk` to validate that it is working. You will see something like the following: + +``` + + ____ ___ _ _ _ _ _ + /\ \ / _ \ _ __ ___ _ __ | | | | |__ (_)___| | __ + /\ /__\ \ | | | | '_ \ / _ \ '_ \| | | | '_ \| / __| |/ / + / \____ \ / | |_| | |_) | __/ | | | |/\| | | | | \__ \ < + \ \ / \/ \___/| .__/ \___|_| |_|__/\__|_| |_|_|___/_|\_\ + \___\/ tm |_| + +Usage: + wsk [command] +... +``` + +TODO: Persistent Storage Stuff == Initial Configuration +Now that OpenShift Cloud Functions is installed, you have to do some basic +configuration before it will be very useful. + +=== Configure CLI +Since you have previously gotten `wsk` working, and you have `oc` installed +and working, first make sure you are logged in to OpenShift with a user that +has `edit` access to the `ocf-infra` project: + + oc login -u someuser + oc project ocf-infra + +You can then run the following two commands to configure the `wsk` CLI to be +able to talk to the OpenShift Cloud Functions API: + + AUTH_SECRET=$(oc get secret whisk.auth -o yaml | grep "system:" | awk '{print $2}' | base64 --decode) + wsk property set --auth $AUTH_SECRET --apihost $(oc get route/openwhisk --template="{{.spec.host}}") + +Now, you can validate that you can correctly talk to OCF. Use the `-i` option +to avoid the validation error triggered by the self-signed cert in the +`nginx` service. + + wsk -i list + wsk -i action invoke /whisk.system/utils/echo -p message hello -b + +If these two commands work, you are up, running, and ready to continue! -* users -* things -* stuff +TODO: People might want to use their own certificates. Do we have a way to do +this? -== `oc cluster` +== Local OpenShift Cluster For local testing purposes, one can use an OpenShift environment provided via `oc cluster`, a subcommand built into the OpenShift CLI. \ No newline at end of file From e8323ff7edadd32e61c5fa4bc0ec4f5d53b13aec Mon Sep 17 00:00:00 2001 From: Erik M Jacobs Date: Mon, 4 Jun 2018 15:30:38 -0400 Subject: [PATCH 5/5] Finalizes base EA instructions and adds persistent storage --- persistent-template.yml | 1484 ++++++++++++++++++++++++++++++++++ src/main/asciidoc/index.adoc | 113 ++- 2 files changed, 1589 insertions(+), 8 deletions(-) create mode 100644 persistent-template.yml diff --git a/persistent-template.yml b/persistent-template.yml new file mode 100644 index 0000000..634700d --- /dev/null +++ b/persistent-template.yml @@ -0,0 +1,1484 @@ +apiVersion: v1 +kind: Template +metadata: + name: openwhisk-persistent + annotations: + openshift.io/display-name: Apache OpenWhisk (Persistent) + description: Apache OpenWhisk serverless platform, with persistent storage. You can leave all parameters blank and sensible defaults will be used. + iconClass: icon-apache + tags: serverless, openwhisk + openshift.io/long-description: This template provides a small OpenWhisk installation. Data is stored on persistent storage. + openshift.io/provider-display-name: Red Hat, Inc. + openshift.io/documentation-url: https://github.com/projectodd/openwhisk-openshift/ + openshift.io/support-url: https://github.com/projectodd/openwhisk-openshift/issues +message: "To get started download the `wsk` CLI from https://github.com/apache/incubator-openwhisk-cli/releases/\n\nYour OpenWhisk authentication token: ${WHISK_SYSTEM_AUTH}\n\nYour OpenWhisk api endpoint can be found in the console UI after closing the template wizard.\n\nConfigure your `wsk` client with `wsk property set --auth --apihost `" +labels: + template: openwhisk-persistent-template + +parameters: +- name: CONTROLLER_INSTANCES + description: The desired number of controllers + value: "1" + required: true +- name: CONTROLLER_MEMORY_REQUEST + description: The minimum container memory for each Controller + value: "512Mi" + required: true +- name: CONTROLLER_MEMORY_LIMIT + description: The maximum container memory for each Controller + value: "512Mi" + required: true +- name: CONTROLLER_JAVA_OPTS + description: JVM options to pass to the Controller - recommended to set at least Xmx here + value: "-Xmx256m" + required: true +- name: CONTROLLER_HA + description: Boolean denoting whether HA mode + value: "FALSE" + required: true +- name: CONTROLLER_LOCALBOOKKEEPING + description: Boolean denoting whether load balancer data is local or shared + value: "TRUE" + required: true +- name: CONTROLLER_INVOKER_BUSYTHRESHOLD + description: Value that controllers when the Controller(s) considers the Invoker(s) to be full. This should be less than or equal to INVOKER_MAX_CONTAINERS. Making them equal will give the highest function density but setting it a bit less than INVOKER_MAX_CONTAINERS can improve overall system throughput and reduce Invoker function container thrashing. + value: "8" + required: true +- name: CONTROLLER_INVOKER_BLACKBOXFRACTION + description: What percent of Invokers should be used for blackbox (user-provider container image) actions. At least one Invoker will be dedicated for blackbox actions as long as 2 or more Invokers are deployed no matter what percentage is set here. + value: "10%" + required: true +- name: AKKA_CLUSTER_SEED_NODES + description: Hostnames of akka seed nodes + value: "controller-0.controller:2551" + required: true +- name: INVOKER_INSTANCES + description: The desired number of invokers + value: "1" + required: true +- name: INVOKER_CPU_REQUEST + description: The minimum cpu cores for each Invoker + value: "500m" + required: true +- name: INVOKER_MEMORY_REQUEST + description: The minimum container memory for each Invoker + value: "1Gi" + required: true +- name: INVOKER_MEMORY_LIMIT + description: The maximum container memory for each Invoker + value: "1Gi" + required: true +- name: INVOKER_JAVA_OPTS + description: JVM options to pass to the Invoker - recommended to set at least Xmx here + value: "-Xmx512m" + required: true +- name: INVOKER_MAX_CONTAINERS + description: Maximum function containers per Invoker + value: "8" + required: true +- name : INVOKER_CONTAINER_TIMEOUT + description: Maximum time an idle function container should stick around before the Invoker deletes it. The longer the timeout, the longer functions stay warm. The shorter the timeout, the less resources consumed by idle function containers. Example values - "5 minutes", "30 seconds", etc. + value: "2 minutes" + required: true +- name: INVOKER_CONTAINER_PAUSE_TIMEOUT + description: Maximum time an idle function container should stick around before the Invoker marks it as paused. Example values - "5 seconds", "500 milliseconds", etc. + value: "5 seconds" + required: true +- name: INVOKER_CONTAINER_CONCURRENT_STARTS + description: Maximum number of action containers each Invoker will attempt to start at once. Raise or lower this number depending on your throughput requirements, cold start rate, number of Invokers you deploy, and how quickly your cluster can spin up new pods. + value: "10" + required: true +- name: INVOKER_LOGSTORE_PROVIDER + description: Apache OpenWhisk LogStoreProvider implementation. Setting this to whisk.core.containerpool.logging.LogDriverLogStoreProvider will increase throughput but users will have to find logs another way, like via Kibana. + value: "whisk.core.containerpool.logging.DockerToActivationLogStoreProvider" + required: true +- name: COUCHDB_INSTANCES + description: The desired number of CouchDB nodes + value: "1" + required: true +- name: COUCHDB_CPU_REQUEST + description: The minimum cpu cores for each CouchDB + value: "500m" + required: true +- name: COUCHDB_MEMORY_REQUEST + description: The minimum container memory for each CouchDB + value: "256Mi" + required: true +- name: COUCHDB_MEMORY_LIMIT + description: The maximum container memory for each CouchDB + value: "512Mi" + required: true +- name: COUCHDB_USER + description: CouchDB Username + generate: expression + from: "user[A-Z0-9]{3}" + required: true +- name: COUCHDB_PASSWORD + description: CouchDB Password + generate: expression + from: "[a-zA-Z0-9]{16}" + required: true +- name: COUCHDB_SECRET + description: CouchDB Replication Secret + generate: expression + from: "[a-zA-Z0-9]{16}" + required: true +- name: COUCHDB_VOLUME_CAPACITY + description: Volume space available for CouchDB data, e.g. 512Mi, 2Gi. + displayName: CouchDB Volume Capacity + required: true + value: 5Gi +- name: ZOOKEEPER_NODE_COUNT + description: Number of Zookeper cluster nodes which will be deployed (odd number of nodes is recomended) + displayName: Number of Zookeper cluster nodes (odd number of nodes is recomended) + required: true + value: "1" +- name: ZOOKEEPER_VOLUME_CAPACITY + description: Volume space available for Zookeeper data, e.g. 512Mi, 2Gi. + displayName: Zookeeper Volume Capacity + required: true + value: 1Gi +- name: KAFKA_NODE_COUNT + description: Number of Kafka cluster nodes which will be deployed + displayName: Number of Kafka cluster nodes + required: true + value: "1" +- name: KAFKA_VOLUME_CAPACITY + description: Volume space available for Kafka data, e.g. 512Mi, 2Gi. + displayName: Kafka Volume Capacity + required: true + value: 1Gi +- name: WHISK_SYSTEM_AUTH + description: OpenWhisk Auth token for whisk.system account + generate: expression + from: "789c46b1-71f6-4ed5-8c54-816aa4f8c502:[a-zA-Z0-9]{64}" + required: true +- name: WHISK_GUEST_AUTH + description: OpenWhisk Auth token for guest account + generate: expression + from: "23bc46b1-71f6-4ed5-8c54-816aa4f8c502:[a-zA-Z0-9]{64}" + required: true +- name: WHISK_ACTIONS_INVOKES_CONCURRENT + description: Default number of concurrenct actions per user + value: "30" + required: true +- name: WHISK_ACTIONS_INVOKES_CONCURRENT_IN_SYSTEM + description: Number of concurrent actions allowed across the entire system + value: "1000" + required: true +- name: WHISK_ACTIONS_INVOKES_PER_MINUTE + description: Default number of action invocations per minute per user + value: "60" + required: true +- name: WHISK_TRIGGERS_FIRES_PER_MINUTE + description: Default number of triggers that can fire per minute per user + value: "60" + required: true +- name: WHISK_DAYS_TO_KEEP_LOGS + description: Number of days to keep activation logs before pruning them from the database + value: "7" + required: true +- name: WHISK_DAYS_TO_KEEP_ACTIVATIONS + description: Number of days to keep activation records before pruning them from the database + value: "30" + required: true +- name: WHISK_ACTIONS_MEMORY_MAX + description: Maximum memory an action is allowed to request. + value: "1024 m" + required: true +- name: WHISK_ACTIONS_MEMORY_MIN + description: Minimum memory an action is allowed to request. + value: "128 m" + required: true +- name: WHISK_ACTIONS_MEMORY_STD + description: Default memory an action requests if unspecified. + value: "256 m" + required: true +- name: WHISK_KAFKA_REPLICATION_FACTOR + description: Replication factor for all OpenWhisk topics + value: "1" + required: true +- name: WHISK_KAFKA_TOPICS_COMPLETED_RETENTION_BYTES + description: Maximum bytes to retain for the completed activations topic for each Controller. Each kafka node will consume this many bytes times the number of Controllers just for the completed topics. So, if this is set to 1GB and you have 3 Controllers then expect up to 3GB of disk space used by the Controller topics. + value: "268435456" + required: true +- name: WHISK_KAFKA_TOPICS_INVOKER_RETENTION_BYTES + description: Maximum bytes to retain for each Invoker topic. Each Kafka node will consume this many bytes times the number of Invokers just for the Invoker topics. So, if this is set to 1GB and you have 10 Invokers then expect up to 10GB of disk space used by the Invoker topics. + value: "268435456" + required: true +- name: OPENWHISK_VERSION + description: The DockerHub tag for openwhisk/{controller,invoker} + value: "rhdemo-9717f07a" + required: true +- name: PROJECTODD_VERSION + description: The DockerHub tag for projectodd images + value: "8ee5579" + required: true +- name: STRIMZI_VERSION + description: The DockerHub tag for strimzi images + value: "0.3.1" + required: true + +objects: + +- apiVersion: v1 + kind: ConfigMap + metadata: + name: whisk.config + data: + whisk_system_namespace: /whisk.system + whisk_version_date: 2018-01-01T00:00:00Z + whisk_version_name: OpenWhisk + whisk_version_tag: latest +- apiVersion: v1 + kind: ConfigMap + metadata: + creationTimestamp: null + name: whisk.limits + data: + actions_invokes_concurrent: "${WHISK_ACTIONS_INVOKES_CONCURRENT}" + actions_invokes_concurrentInSystem: "${WHISK_ACTIONS_INVOKES_CONCURRENT_IN_SYSTEM}" + actions_invokes_perMinute: "${WHISK_ACTIONS_INVOKES_PER_MINUTE}" + actions_sequence_maxLength: "50" + triggers_fires_perMinute: "${WHISK_TRIGGERS_FIRES_PER_MINUTE}" +- apiVersion: v1 + kind: ConfigMap + metadata: + name: whisk.runtimes + data: + runtimes: | + { + "bypassPullForLocalImages": false, + "defaultImagePrefix": "openwhisk", + "defaultImageTag": "latest", + "runtimes": { + "nodejs": [ + { + "kind": "nodejs", + "image": { + "name": "action-nodejs-6" + }, + "deprecated": true + }, + { + "kind": "nodejs:6", + "default": true, + "image": { + "name": "action-nodejs-6" + }, + "deprecated": false + }, + { + "kind": "nodejs:8", + "default": false, + "image": { + "name": "action-nodejs-8" + }, + "deprecated": false + } + ], + "python": [ + { + "kind": "python", + "image": { + "name": "action-python-2" + }, + "deprecated": false + }, + { + "kind": "python:2", + "default": true, + "image": { + "name": "action-python-2" + }, + "deprecated": false + }, + { + "kind": "python:3", + "image": { + "name": "action-python-3" + }, + "deprecated": false + } + ], + "swift": [ + { + "kind": "swift", + "image": { + "name": "action-swift-3" + }, + "deprecated": true + }, + { + "kind": "swift:3", + "image": { + "name": "action-swift-3" + }, + "deprecated": true + }, + { + "kind": "swift:3.1.1", + "default": true, + "image": { + "name": "action-swift-3" + }, + "deprecated": false + } + ], + "java": [ + { + "kind": "java", + "default": true, + "image": { + "name": "action-java-8" + }, + "deprecated": false, + "attached": { + "attachmentName": "jarfile", + "attachmentType": "application/java-archive" + }, + "sentinelledLogs": false, + "requireMain": true + } + ], + "php": [ + { + "kind": "php:7.1", + "default": true, + "deprecated": false, + "image": { + "name": "action-php-7" + } + } + ] + }, + "blackboxes": [ + { + "name": "dockerskeleton" + } + ] + } +- apiVersion: v1 + kind: ConfigMap + metadata: + name: strimzi-openwhisk + labels: + strimzi.io/type: kafka + strimzi.io/kind: cluster + data: + kafka-nodes: "${KAFKA_NODE_COUNT}" + kafka-image: "strimzi/kafka:${STRIMZI_VERSION}" + kafka-healthcheck-delay: "120" + kafka-healthcheck-timeout: "5" + zookeeper-nodes: "${ZOOKEEPER_NODE_COUNT}" + zookeeper-image: "strimzi/zookeeper:${STRIMZI_VERSION}" + zookeeper-healthcheck-delay: "30" + zookeeper-healthcheck-timeout: "5" + KAFKA_DEFAULT_REPLICATION_FACTOR: "${KAFKA_NODE_COUNT}" + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "${KAFKA_NODE_COUNT}" + KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "${KAFKA_NODE_COUNT}" + kafka-storage: |- + { "type": "persistent-claim", "size": "${KAFKA_VOLUME_CAPACITY}", "delete-claim": false } + zookeeper-storage: |- + { "type": "persistent-claim", "size": "${ZOOKEEPER_VOLUME_CAPACITY}", "delete-claim": false } +- apiVersion: v1 + kind: Service + metadata: + name: controller + labels: + name: controller + spec: + selector: + name: controller + clusterIP: None + ports: + - port: 8080 + targetPort: 8080 + name: http +- apiVersion: v1 + kind: ConfigMap + metadata: + name: controller.config + data: + controller_opts: "-Dwhisk.spi.LoadBalancerProvider=whisk.core.loadBalancer.ShardingContainerPoolBalancer" + java_opts: "${CONTROLLER_JAVA_OPTS}" +- apiVersion: apps/v1beta1 + kind: StatefulSet + metadata: + name: controller + annotations: + template.alpha.openshift.io/wait-for-ready: "true" + labels: + name: controller + spec: + replicas: ${CONTROLLER_INSTANCES} + serviceName: "controller" + template: + metadata: + labels: + name: controller + spec: + restartPolicy: Always + containers: + - name: controller + imagePullPolicy: IfNotPresent + image: controller:whisky + command: ["/bin/bash", "-c", "COMPONENT_NAME=$(hostname | cut -d'-' -f2) CONFIG_akka_remote_netty_tcp_hostname=$(hostname).controller /init.sh `hostname | cut -d'-' -f2`"] + ports: + - name: controller + containerPort: 8080 + - name: akka + containerPort: 2551 + resources: + requests: + memory: ${CONTROLLER_MEMORY_REQUEST} + limits: + memory: ${CONTROLLER_MEMORY_LIMIT} + env: + # Properties for controller HA configuration + # Must change these if changing number of replicas + - name: "CONTROLLER_LOCALBOOKKEEPING" + value: ${CONTROLLER_LOCALBOOKKEEPING} + - name: "CONTROLLER_HA" + value: ${CONTROLLER_HA} + - name: "CONTROLLER_INSTANCES" + value: ${CONTROLLER_INSTANCES} + - name: "AKKA_CLUSTER_SEED_NODES" + value: ${AKKA_CLUSTER_SEED_NODES} + - name: "CONFIG_akka_actor_provider" + value: "cluster" + - name: "CONFIG_akka_remote_netty_tcp_bindPort" + value: "2551" + - name: "CONFIG_akka_remote_netty_tcp_port" + value: "2551" + - name: "CONFIG_whisk_loadbalancer_invokerBusyThreshold" + value: "${CONTROLLER_INVOKER_BUSYTHRESHOLD}" + - name: "CONFIG_whisk_loadbalancer_blackboxFraction" + value: "${CONTROLLER_INVOKER_BLACKBOXFRACTION}" + - name: "CONFIG_whisk_memory_max" + value: "${WHISK_ACTIONS_MEMORY_MAX}" + - name: "CONFIG_whisk_memory_min" + value: "${WHISK_ACTIONS_MEMORY_MIN}" + - name: "CONFIG_whisk_memory_std" + value: "${WHISK_ACTIONS_MEMORY_STD}" + - name: "CONFIG_whisk_kafka_replicationFactor" + value: "${WHISK_KAFKA_REPLICATION_FACTOR}" + - name: "CONFIG_whisk_kafka_topics_completed_retentionBytes" + value: "${WHISK_KAFKA_TOPICS_COMPLETED_RETENTION_BYTES}" + + # extra JVM arguments + - name: "JAVA_OPTS" + valueFrom: + configMapKeyRef: + name: controller.config + key: java_opts + + # extra controller arguments + - name: "CONTROLLER_OPTS" + valueFrom: + configMapKeyRef: + name: controller.config + key: controller_opts + + # action runtimes + - name: "RUNTIMES_MANIFEST" + valueFrom: + configMapKeyRef: + name: whisk.runtimes + key: runtimes + + # deployment version information + - name: "WHISK_VERSION_NAME" + valueFrom: + configMapKeyRef: + name: whisk.config + key: whisk_version_name + - name: "WHISK_VERSION_DATE" + valueFrom: + configMapKeyRef: + name: whisk.config + key: whisk_version_date + - name: "WHISK_VERSION_BUILDNO" + valueFrom: + configMapKeyRef: + name: whisk.config + key: whisk_version_tag + + # specify limits + - name: "LIMITS_ACTIONS_INVOKES_PERMINUTE" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_invokes_perMinute + - name: "LIMITS_ACTIONS_INVOKES_CONCURRENT" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_invokes_concurrent + - name: "LIMITS_ACTIONS_INVOKES_CONCURRENTINSYSTEM" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_invokes_concurrentInSystem + - name: "LIMITS_TRIGGERS_FIRES_PERMINUTE" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: triggers_fires_perMinute + - name: "LIMITS_ACTIONS_SEQUENCE_MAXLENGTH" + valueFrom: + configMapKeyRef: + name: whisk.limits + key: actions_sequence_maxLength + + # properties for Kafka connection + - name: "KAFKA_HOSTS" + value: "$(STRIMZI_OPENWHISK_KAFKA_SERVICE_HOST):$(STRIMZI_OPENWHISK_KAFKA_SERVICE_PORT_CLIENTS)" + + # properties for DB connection + - name: "CONFIG_whisk_couchdb_username" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "CONFIG_whisk_couchdb_password" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "CONFIG_whisk_couchdb_protocol" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "CONFIG_whisk_couchdb_host" + value: "$(COUCHDB_SERVICE_HOST)" + - name: "CONFIG_whisk_couchdb_port" + value: "$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "CONFIG_whisk_couchdb_provider" + valueFrom: + configMapKeyRef: + name: db.config + key: db_provider + - name: "CONFIG_whisk_couchdb_databases_WhiskActivation" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations + - name: "CONFIG_whisk_couchdb_databases_WhiskEntity" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_actions + - name: "CONFIG_whisk_couchdb_databases_WhiskAuth" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_auths + + # must match port used in livenessProbe below + - name: "PORT" + value: "8080" + + livenessProbe: + httpGet: + path: "/ping" + port: 8080 + scheme: "HTTP" + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 10 + failureThreshold: 5 + readinessProbe: + httpGet: + path: "/ping" + port: 8080 + scheme: "HTTP" + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 10 + failureThreshold: 5 + initContainers: + - name: wait-for-services + image: busybox:whisky + command: ['sh', '-cu', 'until nslookup couchdb && nslookup strimzi-openwhisk-kafka; do echo waiting for services; sleep 1; done'] + - name: wait-for-couchdb + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://${COUCHDB_SERVICE_HOST}:${COUCHDB_SERVICE_PORT}/${DB_WHISK_ACTIVATIONS}; do echo waiting for couchdb; sleep 2; done;'] + env: + - name: "DB_WHISK_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations +- apiVersion: batch/v1 + kind: Job + metadata: + name: install-catalog + spec: + activeDeadlineSeconds: 600 + template: + metadata: + name: install-catalog + spec: + containers: + - name: catalog + image: catalog:whisky + env: + - name: "WHISK_AUTH" + valueFrom: + secretKeyRef: + name: whisk.auth + key: system + - name: "WHISK_API_HOST_NAME" + value: "http://controller:8080" + initContainers: + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] + restartPolicy: Never +- apiVersion: v1 + kind: Service + metadata: + name: couchdb + labels: + name: couchdb + spec: + selector: + name: couchdb + ports: + - port: 5984 + targetPort: 5984 + name: couchdb +- apiVersion: v1 + kind: Service + metadata: + name: couchdb-headless + labels: + name: couchdb-headless + spec: + selector: + name: couchdb + ports: + - name: couchdb + port: 5984 + clusterIP: None +- apiVersion: v1 + kind: ConfigMap + metadata: + name: db.config + data: + db_prefix: test_ + db_protocol: http + db_provider: CouchDB + db_whisk_actions: test_whisks + db_whisk_activations: test_activations + db_whisk_auths: test_subjects + db_days_to_keep_logs: "${WHISK_DAYS_TO_KEEP_LOGS}" + db_days_to_keep_activations: "${WHISK_DAYS_TO_KEEP_ACTIVATIONS}" +- apiVersion: apps/v1beta1 + kind: StatefulSet + metadata: + name: couchdb + labels: + name: couchdb + spec: + replicas: ${COUCHDB_INSTANCES} + serviceName: couchdb-headless + volumeClaimTemplates: + - metadata: + name: couchdb-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: ${COUCHDB_VOLUME_CAPACITY} + template: + metadata: + labels: + name: couchdb + spec: + restartPolicy: Always + containers: + - name: couchdb + imagePullPolicy: IfNotPresent + image: couchdb:whisky + command: ["/init.sh"] + ports: + - name: couchdb + containerPort: 5984 + - name: epmd + containerPort: 4369 + - containerPort: 9100 + resources: + requests: + cpu: "${COUCHDB_CPU_REQUEST}" + memory: ${COUCHDB_MEMORY_REQUEST} + limits: + memory: ${COUCHDB_MEMORY_LIMIT} + env: + - name: "DB_PREFIX" + valueFrom: + configMapKeyRef: + name: db.config + key: db_prefix + - name: "DB_HOST" + value: "127.0.0.1" + - name: "DB_PORT" + value: "$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "COUCHDB_USER" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "COUCHDB_PASSWORD" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "COUCHDB_SECRET" + valueFrom: + secretKeyRef: + name: db.auth + key: db_secret + - name: "NODENAME_HOSTNAME" + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: "NODENAME_SUBDOMAIN" + value: "couchdb-headless" + - name: "COUCHDB_NODE_COUNT" + value: "${COUCHDB_INSTANCES}" + - name: "AUTH_WHISK_SYSTEM" + valueFrom: + secretKeyRef: + name: whisk.auth + key: system + - name: "AUTH_GUEST" + valueFrom: + secretKeyRef: + name: whisk.auth + key: guest + volumeMounts: + - name: couchdb-data + mountPath: "/opt/couchdb/data" + readinessProbe: + httpGet: + port: 5984 + path: "/_utils/" + initialDelaySeconds: 10 + periodSeconds: 15 + failureThreshold: 10 + timeoutSeconds: 3 +- apiVersion: v1 + kind: ConfigMap + metadata: + name: invoker.config + data: + docker_image_prefix: "" + docker_image_tag: whisky + docker_registry: "" + invoker_container_dns: "" + invoker_container_network: bridge + invoker_logs_dir: "" + invoker_opts: "-Dwhisk.spi.ContainerFactoryProvider=whisk.core.containerpool.kubernetes.KubernetesContainerFactoryProvider" + invoker_use_runc: "false" + java_opts: "${INVOKER_JAVA_OPTS}" +- apiVersion: v1 + kind: ConfigMap + metadata: + name: invoker + data: + init: | + export COMPONENT_NAME=$(hostname | cut -d'-' -f2) + # Dynamically determine API gateway host + export TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" + export NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)" + export APIGW_HOST=$(curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer ${TOKEN}" "https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/oapi/v1/namespaces/${NAMESPACE}/routes/openwhisk?pretty=true" | grep '"host":' | head -n 1 | awk -F '"' '{print $4}') + export APIGW_HOST_V2=${APIGW_HOST} + export WHISK_API_HOST_NAME=${APIGW_HOST} + exec /init.sh +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: openwhisk +- apiVersion: v1 + kind: RoleBinding + metadata: + name: openwhisk + roleRef: + name: edit + subjects: + - kind: ServiceAccount + name: openwhisk +- apiVersion: apps/v1beta1 + kind: StatefulSet + metadata: + name: invoker + labels: + name: invoker + spec: + replicas: ${INVOKER_INSTANCES} + serviceName: "invoker" + template: + metadata: + labels: + name: invoker + spec: + restartPolicy: Always + volumes: + - name: invoker-config + configMap: + name: invoker + serviceAccountName: openwhisk + + initContainers: + - name: wait-for-services + image: busybox:whisky + command: ['sh', '-cu', 'until nslookup couchdb && nslookup strimzi-openwhisk-zookeeper && nslookup strimzi-openwhisk-kafka; do echo waiting for services; sleep 1; done'] + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] + + containers: + - name: invoker + imagePullPolicy: IfNotPresent + image: invoker:whisky + command: [ "/bin/bash", "-o", "allexport", "/invoker_config/init" ] + ports: + - name: invoker + containerPort: 8080 + resources: + requests: + cpu: "${INVOKER_CPU_REQUEST}" + memory: ${INVOKER_MEMORY_REQUEST} + limits: + memory: ${INVOKER_MEMORY_LIMIT} + volumeMounts: + - name: invoker-config + mountPath: "/invoker_config" + env: + - name: "PORT" + value: "8080" + + # Generate stable invoker names from the StatefulSet names + - name: "INVOKER_NAME" + valueFrom: + fieldRef: + fieldPath: metadata.name + + # Docker-related options + - name: "INVOKER_CONTAINER_NETWORK" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_container_network + - name: "INVOKER_CONTAINER_DNS" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_container_dns + - name: "INVOKER_USE_RUNC" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_use_runc + - name: "INVOKER_CORESHARE" + value: "1" + - name: "INVOKER_NUMCORE" + value: "${INVOKER_MAX_CONTAINERS}" + - name: "CONFIG_whisk_containerProxy_timeouts_idleContainer" + value: "${INVOKER_CONTAINER_TIMEOUT}" + - name: "CONFIG_whisk_containerProxy_timeouts_pauseGrace" + value: "${INVOKER_CONTAINER_PAUSE_TIMEOUT}" + - name: "CONFIG_whisk_kubernetes_concurrentStarts" + value: "${INVOKER_CONTAINER_CONCURRENT_STARTS}" + - name: "CONFIG_whisk_memory_max" + value: "${WHISK_ACTIONS_MEMORY_MAX}" + - name: "CONFIG_whisk_memory_min" + value: "${WHISK_ACTIONS_MEMORY_MIN}" + - name: "CONFIG_whisk_memory_std" + value: "${WHISK_ACTIONS_MEMORY_STD}" + - name: "CONFIG_whisk_kafka_replicationFactor" + value: "${WHISK_KAFKA_REPLICATION_FACTOR}" + - name: "CONFIG_whisk_kafka_topics_invoker_retentionBytes" + value: "${WHISK_KAFKA_TOPICS_INVOKER_RETENTION_BYTES}" + - name: "DOCKER_IMAGE_PREFIX" + valueFrom: + configMapKeyRef: + name: invoker.config + key: docker_image_prefix + - name: "DOCKER_IMAGE_TAG" + valueFrom: + configMapKeyRef: + name: invoker.config + key: docker_image_tag + - name: "DOCKER_REGISTRY" + valueFrom: + configMapKeyRef: + name: invoker.config + key: docker_registry + + # action runtimes + - name: "RUNTIMES_MANIFEST" + valueFrom: + configMapKeyRef: + name: whisk.runtimes + key: runtimes + + # extra JVM arguments + - name: "JAVA_OPTS" + valueFrom: + configMapKeyRef: + name: invoker.config + key: java_opts + + # extra Invoker arguments + - name: "INVOKER_OPTS" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_opts + + # Recommend using "" because logs should go to stdout on kube + - name: "WHISK_LOGS_DIR" + valueFrom: + configMapKeyRef: + name: invoker.config + key: invoker_logs_dir + + # properties for Kafka connection + - name: "KAFKA_HOSTS" + value: "$(STRIMZI_OPENWHISK_KAFKA_SERVICE_HOST):$(STRIMZI_OPENWHISK_KAFKA_SERVICE_PORT_CLIENTS)" + + # properties for zookeeper connection + - name: "ZOOKEEPER_HOSTS" + value: "$(STRIMZI_OPENWHISK_ZOOKEEPER_SERVICE_HOST):$(STRIMZI_OPENWHISK_ZOOKEEPER_SERVICE_PORT_CLIENTS)" + + # properties for DB connection + - name: "CONFIG_whisk_couchdb_username" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "CONFIG_whisk_couchdb_password" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "CONFIG_whisk_couchdb_protocol" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "CONFIG_whisk_couchdb_host" + value: "$(COUCHDB_SERVICE_HOST)" + - name: "CONFIG_whisk_couchdb_port" + value: "$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "CONFIG_whisk_couchdb_provider" + valueFrom: + configMapKeyRef: + name: db.config + key: db_provider + - name: "CONFIG_whisk_couchdb_databases_WhiskActivation" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations + - name: "CONFIG_whisk_couchdb_databases_WhiskEntity" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_actions + - name: "CONFIG_whisk_couchdb_databases_WhiskAuth" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_auths + - name: CONFIG_whisk_kubernetes_namespace + valueFrom: + fieldRef: + fieldPath: metadata.namespace + + # Increase Kube API timeouts until we handle timeouts nicer + - name: "CONFIG_whisk_kubernetes_timeouts_run" + value: "10 minutes" + - name: "CONFIG_whisk_kubernetes_timeouts_rm" + value: "10 minutes" + - name: "CONFIG_whisk_kubernetes_timeouts_logs" + value: "10 minutes" + - name: "CONFIG_whisk_spi_LogStoreProvider" + value: "${INVOKER_LOGSTORE_PROVIDER}" +- apiVersion: batch/v1 + kind: Job + metadata: + name: preload-openwhisk-runtimes + labels: + name: preload-openwhisk-runtimes + spec: + completions: 1 + serviceAccountName: openwhisk + template: + metadata: + labels: + name: preload-openwhisk-runtimes + spec: + restartPolicy: Never + initContainers: + - name: preload-openwhisk-nodejs6 + image: action-nodejs-6:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-java8 + image: action-java-8:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-python3 + image: action-python-3:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-python2 + image: action-python-2:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-openwhisk-php7 + image: action-php-7:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + containers: + - name: preload-openwhisk-nodejs8 + image: action-nodejs-8:whisky + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] +- apiVersion: v1 + kind: Service + metadata: + name: nginx + labels: + name: nginx + spec: + type: NodePort + selector: + name: nginx + ports: + - port: 80 + targetPort: 8080 + name: http + - port: 8443 + targetPort: 8443 + name: https-admin +- apiVersion: v1 + kind: Route + metadata: + name: openwhisk + annotations: + template.openshift.io/expose-apihost: "{.spec.host}" + labels: + name: nginx + spec: + port: + targetPort: http + to: + kind: Service + name: nginx + weight: 100 + wildcardPolicy: None + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect +- apiVersion: v1 + kind: ConfigMap + metadata: + name: nginx + data: + init: | + cp /nginx_config/nginx.conf /tmp/nginx.conf + sed -i "s//$(grep nameserver /etc/resolv.conf | head -1 | awk '{print $2}')/" /tmp/nginx.conf + sed -i "s//${KUBERNETES_NAMESPACE}/" /tmp/nginx.conf + exec nginx -c /tmp/nginx.conf -g "daemon off;" + nginx.conf: | + worker_rlimit_nofile 4096; + + events { + worker_connections 4096; + } + + http { + client_max_body_size 50M; + + rewrite_log on; + log_format combined-upstream '$remote_addr - $remote_user [$time_local] ' + '$request $status $body_bytes_sent ' + '$http_referer $http_user_agent $upstream_addr'; + access_log /logs/nginx_access.log combined-upstream; + error_log /logs/nginx_error.log; + + proxy_http_version 1.1; + proxy_set_header Connection ""; + + server { + listen 8080 default; + + # Make sure nginx dynamically resolves dns entries + # instead of resolving once and caching that result + # forever + resolver ; + set $controller controller..svc.cluster.local; + + # match namespace, note while OpenWhisk allows a richer character set for a + # namespace, not all those characters are permitted in the (sub)domain name; + # if namespace does not match, no vanity URL rewriting takes place. + server_name ~^(?[0-9a-zA-Z-]+)\.localhost$; + + # proxy to the web action path + location / { + if ($namespace) { + rewrite /(.*) /api/v1/web/${namespace}/$1 break; + } + proxy_pass http://$controller:8080; + proxy_read_timeout 75s; # 70+5 additional seconds to allow controller to terminate request + } + + # proxy to 'public/html' web action by convention + location = / { + if ($namespace) { + rewrite ^ /api/v1/web/${namespace}/public/index.html break; + } + proxy_pass http://$controller:8080; + proxy_read_timeout 75s; # 70+5 additional seconds to allow controller to terminate request + } + + location /blackbox.tar.gz { + return 301 https://github.com/apache/incubator-openwhisk-runtime-docker/releases/download/sdk%400.1.0/blackbox-0.1.0.tar.gz; + } + # leaving this for a while for clients out there to update to the new endpoint + location /blackbox-0.1.0.tar.gz { + return 301 /blackbox.tar.gz; + } + + location /OpenWhiskIOSStarterApp.zip { + return 301 https://github.com/openwhisk/openwhisk-client-swift/releases/download/0.2.3/starterapp-0.2.3.zip; + } + + # redirect requests for specific binaries to the matching one from the latest openwhisk-cli release. + location /cli/go/download/linux/amd64 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-linux-amd64.tgz; + } + location /cli/go/download/linux/386 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-linux-386.tgz; + } + location /cli/go/download/mac/amd64 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-mac-amd64.zip; + } + location /cli/go/download/mac/386 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-mac-386.zip; + } + location /cli/go/download/windows/amd64 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-windows-amd64.zip; + } + location /cli/go/download/windows/386 { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/download/latest/OpenWhisk_CLI-latest-windows-386.zip; + } + + # redirect top-level cli downloads to the latest openwhisk-cli release. + location /cli/go/download { + return 301 https://github.com/projectodd/openwhisk-openshift/releases/latest; + } + } + } +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: nginx + annotations: + template.alpha.openshift.io/wait-for-ready: "true" + labels: + name: nginx + spec: + replicas: 1 + template: + metadata: + labels: + name: nginx + spec: + restartPolicy: Always + volumes: + - name: nginx-conf + configMap: + name: nginx + - name: logs + emptyDir: {} + containers: + - name: nginx + imagePullPolicy: IfNotPresent + # Image from Mar 22nd + image: nginx:whisky + command: [ "/bin/bash", "-o", "allexport", "/nginx_config/init" ] + env: + - name: KUBERNETES_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 8080 + - name: https-admin + containerPort: 8443 + volumeMounts: + - name: nginx-conf + mountPath: "/nginx_config" + - name: logs + mountPath: "/logs" + initContainers: + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] +- apiVersion: v1 + kind: Secret + metadata: + name: whisk.auth + annotations: + template.openshift.io/expose-auth: "{.data['system']}" + stringData: + guest: "${WHISK_GUEST_AUTH}" + system: "${WHISK_SYSTEM_AUTH}" +- apiVersion: v1 + kind: Secret + metadata: + name: db.auth + stringData: + db_username: "${COUCHDB_USER}" + db_password: "${COUCHDB_PASSWORD}" + db_secret: "${COUCHDB_SECRET}" +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: strimzi-cluster-controller + spec: + replicas: 1 + template: + metadata: + labels: + name: strimzi-cluster-controller + spec: + serviceAccountName: openwhisk + containers: + - name: strimzi-cluster-controller + image: cluster-controller:whisky + env: + - name: STRIMZI_CONFIGMAP_LABELS + value: "strimzi.io/kind=cluster" + - name: STRIMZI_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: STRIMZI_OPERATION_TIMEOUT_MS + value: "600000" + livenessProbe: + httpGet: + path: /healthy + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 30 + readinessProbe: + httpGet: + path: /ready + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 30 + initContainers: + - name: preload-strimzi-zookeeper + image: strimzi/zookeeper:${STRIMZI_VERSION} + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] + - name: preload-strimzi-kafka + image: strimzi/kafka:${STRIMZI_VERSION} + imagePullPolicy: IfNotPresent + command: ["/bin/sh", "-c", "echo", "success"] +- apiVersion: v1 + kind: ConfigMap + metadata: + name: alarmprovider + data: + PORT: "8080" + DB_PREFIX: "whisk_alarms_" + CONTROLLER_HOST: "controller" + CONTROLLER_PORT: "8080" + env: | + export TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" + export NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)" + export ROUTER_HOST=$(curl -s --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer ${TOKEN}" "https://${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT}/oapi/v1/namespaces/${NAMESPACE}/routes/openwhisk?pretty=true" | grep '"host":' | head -n 1 | awk -F '"' '{print $4}') +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + name: alarmprovider + labels: + name: alarmprovider + spec: + replicas: 1 + template: + metadata: + labels: + name: alarmprovider + spec: + restartPolicy: Always + serviceAccountName: openwhisk + volumes: + - name: alarmprovider-config + configMap: + name: alarmprovider + containers: + - name: alarmprovider + imagePullPolicy: IfNotPresent + image: alarmprovider:whisky + command: [ "/bin/bash", "-c", "source /alarmprovider_config/env; node /alarmsTrigger/app.js" ] + envFrom: + - configMapRef: + name: alarmprovider + env: + - name: "DB_HOST" + value: "$(COUCHDB_SERVICE_HOST):$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "DB_PROTOCOL" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "DB_USERNAME" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "DB_PASSWORD" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + volumeMounts: + - name: alarmprovider-config + mountPath: "/alarmprovider_config" + initContainers: + - name: wait-for-couchdb + image: busybox:whisky + command: ['sh', '-cu', 'echo "$COUCHDB_SERVICE_HOST"'] + - name: install-alarms-catalog + imagePullPolicy: IfNotPresent + image: alarms:whisky + envFrom: + - configMapRef: + name: alarmprovider + env: + - name: "DB_HOST" + value: "$(COUCHDB_SERVICE_HOST):$(COUCHDB_SERVICE_PORT_COUCHDB)" + - name: "DB_PROTOCOL" + valueFrom: + configMapKeyRef: + name: db.config + key: db_protocol + - name: "AUTH_WHISK_SYSTEM" + valueFrom: + secretKeyRef: + name: whisk.auth + key: system + volumeMounts: + - name: alarmprovider-config + mountPath: "/alarmprovider_config" +- apiVersion: batch/v2alpha1 + kind: CronJob + metadata: + name: refresh-activations + labels: + name: refresh-activations + spec: + schedule: "*/5 * * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + metadata: + labels: + parent: "cronjob-refresh-activations" + spec: + serviceAccountName: openwhisk + restartPolicy: Never + containers: + - name: refresh-activations + image: alarms:whisky + command: ["/bin/bash", "-c", "/openwhisk/bin/wsk --auth $AUTH_GUEST --apihost http://controller:8080 -i activation list"] + env: + - name: "AUTH_GUEST" + valueFrom: + secretKeyRef: + name: whisk.auth + key: guest + initContainers: + - name: wait-for-controller + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://controller:8080/ping; do echo waiting for controller; sleep 2; done;'] + restartPolicy: Never +- apiVersion: batch/v2alpha1 + kind: CronJob + metadata: + name: prune-activations + labels: + name: prune-activations + spec: + schedule: "0 0 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 1 + jobTemplate: + spec: + template: + metadata: + labels: + parent: "cronjob-prune-activations" + spec: + restartPolicy: Never + containers: + - name: prune-activations + image: couchdb:whisky + command: ["/bin/bash", "-c", "set -x; curl -H \"Content-Type: application/json\" -X PUT -d \"100\" \"http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB/$DB_ACTIONS/_revs_limit\"; curl -H \"Content-Type: application/json\" -X PUT -d \"5\" \"http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB/$DB_ACTIVATIONS/_revs_limit\"; /openwhisk/tools/db/deleteLogsFromActivations.py --dbUrl http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB --dbName $DB_ACTIVATIONS --days $DB_DAYS_TO_KEEP_LOGS; /openwhisk/tools/db/cleanUpActivations.py --dbUrl http://$DB_USERNAME:$DB_PASSWORD@$COUCHDB_SERVICE_HOST:$COUCHDB_SERVICE_PORT_COUCHDB --dbName $DB_ACTIVATIONS --days $DB_DAYS_TO_KEEP_ACTIVATIONS"] + env: + - name: "DB_USERNAME" + valueFrom: + secretKeyRef: + name: db.auth + key: db_username + - name: "DB_PASSWORD" + valueFrom: + secretKeyRef: + name: db.auth + key: db_password + - name: "DB_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations + - name: "DB_ACTIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_actions + - name: "DB_DAYS_TO_KEEP_LOGS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_days_to_keep_logs + - name: "DB_DAYS_TO_KEEP_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_days_to_keep_activations + initContainers: + - name: wait-for-couchdb + image: busybox:whisky + command: ['sh', '-c', 'until wget -T 5 --spider http://${COUCHDB_SERVICE_HOST}:${COUCHDB_SERVICE_PORT}/${DB_WHISK_ACTIVATIONS}; do echo waiting for couchdb; sleep 2; done;'] + env: + - name: "DB_WHISK_ACTIVATIONS" + valueFrom: + configMapKeyRef: + name: db.config + key: db_whisk_activations diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index c1bfca7..1f8973e 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -4,7 +4,7 @@ :sectnumlevels: 2 :sectanchors: :nofooter: -//:source-highlighter: coderay +:source-highlighter: coderay = OpenShift Cloud Functions @@ -53,7 +53,10 @@ bare minimums for testing. Additionally, you may wish to have a few gigabytes of persistent storage available. Persistent storage is used so that you can retain the various -settings, function definitions, history and etc. +settings, function definitions, history and etc. In the case of crashes or +other malfunctions, having persistent storage is going to make things much +easier, so it is strongly encouraged to follow the notes below regarding +provisioning an environment that can use it. ==== Disconnected Installations @@ -144,7 +147,13 @@ you will need to use: oc process -f https://raw.githubusercontent.com/openshift-cloud-functions/early-access/master/template.yaml | oc create -f - +If you would like to use persistent storage with your OCF installation, use +the following template which includes PersistentVolumeClaims: + + oc process -f https://raw.githubusercontent.com/openshift-cloud-functions/early-access/master/persistent-template.yaml | oc create -f - + Please skip the next step. + ==== To instantiate the OCF infrastructure, simply `process` the template: @@ -153,6 +162,34 @@ To instantiate the OCF infrastructure, simply `process` the template: oc process -f https://git.io/openwhisk-template | oc create -f - ``` +Or, alternatively, if you want to use persistent storage (with PersistentVolumeClaims) you can do the following: + +``` +oc process -f https://raw.githubusercontent.com/projectodd/openwhisk-openshift/master/persistent-template.yml | oc create -f - +``` + +[NOTE] +==== +If you want a more heavy-duty and higher-powered OCF deployment, there is an +environment file that can be used with either template (disconnected or +otherwise). It increases the resources of individual components (CPU/memory) +and also increases the count of some components (eg: couchdb). First, fetch +the file: + + https://raw.githubusercontent.com/projectodd/openwhisk-openshift/master/larger.env + +If you don't want to use persistent storage, you will need to remove the +lines in `larger.env` that have `_VOLUME_CAPACITY`. + +Then, you can use this file with `process`: + + oc process -f ... --param-file=larger.env ... + +Using the larger environment will consume significantly more resources. You +will need at least **20Gi of memory** and **8 CPUs** across your OpenShift +infrastructure. +==== + === Wait for Success Eventually all of the pods will start running. After a few minutes, execute `oc get pods` and you should see output that looks similar to the following: @@ -174,11 +211,17 @@ wskinvoker-00-1-prewarm-nodejs6 1/1 Running 0 10 wskinvoker-00-2-prewarm-nodejs6 1/1 Running 0 10m ``` +[NOTE] +==== +If you are using the "larger" environment files then you will likely see a +larger quantity of pods in the output. +==== + Notice that all pods are either `Running` and are `1/1` for `READY` or are `Completed`. If you have any failures or errors you probably need to contact us so that we can figure out what is wrong. -==== Install the CLI +==== Install the OpenWhisk CLI OpenShift Cloud Functions still directly uses the `wsk` CLI from the OpenWhisk project. You can download a CLI for your system from the following URL: @@ -207,8 +250,6 @@ Usage: ... ``` -TODO: Persistent Storage Stuff - == Initial Configuration Now that OpenShift Cloud Functions is installed, you have to do some basic configuration before it will be very useful. @@ -227,6 +268,7 @@ able to talk to the OpenShift Cloud Functions API: AUTH_SECRET=$(oc get secret whisk.auth -o yaml | grep "system:" | awk '{print $2}' | base64 --decode) wsk property set --auth $AUTH_SECRET --apihost $(oc get route/openwhisk --template="{{.spec.host}}") +=== Validate CLI Now, you can validate that you can correctly talk to OCF. Use the `-i` option to avoid the validation error triggered by the self-signed cert in the `nginx` service. @@ -236,9 +278,64 @@ to avoid the validation error triggered by the self-signed cert in the If these two commands work, you are up, running, and ready to continue! -TODO: People might want to use their own certificates. Do we have a way to do -this? +// TODO: People might want to use their own certificates. Do we have a way to do this? + +== Getting Started +There are many existing exercises and examples in the OpenShift Cloud +Functions scenarios that can be found here: + + https://learn.openshift.com/serverless/ + +You should take some time to go through these scenarios but, instead of +executing them in your browser, run the commands locally against your +OpenShift Cloud Functions environment. + +If you have any problems, please make sure to contact us. + +== Now What? +Now that you have a general understanding of how OpenWhisk / OpenShift Cloud +Functions works, go ahead and try to come up with your own scenarios and +integrate it into your applications and workflows. == Local OpenShift Cluster For local testing purposes, one can use an OpenShift environment provided via -`oc cluster`, a subcommand built into the OpenShift CLI. \ No newline at end of file +`oc cluster`, a subcommand built into the OpenShift CLI. However, with +OpenShift 3.9 there is an issue regarding using ImageStreams for the source +of Kubernetes resources (Deployments and others). + +You will need to make sure you are persisting your `oc cluster` config and +data somewhere, and then stop your cluster, and edit the `master-config.yaml` +to have the following stanza in the `admissionConfig` section: + +```YAML +admissionConfig: + pluginConfig: + GenericAdmissionWebhook: + configuration: + apiVersion: v1 + disable: false + kind: DefaultAdmissionConfig + location: "" + openshift.io/ImagePolicy: + configuration: + apiVersion: v1 + executionRules: + - matchImageAnnotations: + - key: images.openshift.io/deny-execution + value: "true" + name: execution-denied + onResources: + - resource: pods + - resource: builds + reject: true + skipOnResolutionFailure: true + kind: ImagePolicyConfig + location: "" +``` + +There are actually two `admissionConfig` sections. You want the one at the +top of the config file and not the one that is nested under +`kubernetesMasterConfig`. + +Once this change is made, you can restart your cluster and then follow the +installation/configuration instructions for OpenShift Cloud Functions. \ No newline at end of file