<!-- # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # --> # Deploying OpenWhisk on IBM Cloud Private (ICP) ## Overview IBM Cloud Private (ICP) provides the core infrastructure needed to provision a production-quality OpenWhisk installation. This document outlines ICP-specific steps needed to provision that installation, and calls out shortcuts that could be taken for development-grade installation. ## Initial setup ### Creating the Kubernetes Cluster Follow IBM Cloud Private instructions to provision your cluster. Include GlusterFS provisioning, add [dynamic NFS provisioning](./k8s-nfs-dynamic-storage.md), or be prepared to provision volumes manually for OpenWhisk (see [here](./configurationChoices.md#persistence)). ### Configuring OpenWhisk #### Configuring Image Security IBM Cloud Private includes a provision for filtering the images that are allowed to be deployed into a particular namespace. One _could_ disable this capability for the OpenWhisk namespace, but initally it is best to define a policy for the namespace: (In this case we assume the namespace is `openwhisk`) ```yaml apiVersion: securityenforcement.admission.cloud.ibm.com/v1beta1 kind: ImagePolicy metadata: name: openwhisk-image-policy namespace: openwhisk spec: repositories: - name: docker.io/openwhisk/* policy: va: enabled: false - name: docker.io/apache/couchdb:* policy: va: enabled: false - name: docker.io/nginx:* policy: va: enabled: false - name: docker.io/redis:* policy: va: enabled: false - name: docker.io/zookeeper:* policy: va: enabled: false - name: docker.io/wurstmeister/kafka:* policy: va: enabled: false ``` #### Configuring Ingress An IBM Cloud Private cluster has full support for TLS and can be configured with additional annotations to fine tune ingress performance. A prerequisite for OpenWhisk TLS access via Ingress as currently configured is a Fully Qualified Domain Name (FQDN) that can be resolved correctly from within OpenWhisk and points to the SSL Ingress point, usually your load balancer or proxy node. You will also need to create a TLS certificate to be used by the Ingress controller for your domain. The YAML to create in Kubernetes is (substituting the real values for `<your fqdn>`): ```yaml apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: openwhisk-tls-secret-1 namespace: openwhisk spec: commonName: <your fqdn> dnsNames: - <your fqdn> issuerRef: kind: ClusterIssuer name: icp-ca-issuer secretName: openwhisk-tls-secret-1 ``` #### Putting it all together Now define `mycluster.yaml` as below (substituting the real values for `<your fqdn>`). ```yaml whisk: ingress: apiHostName: <your fqdn> apiHostPort: 443 apiHostProto: https type: Standard domain: <your fqdn> tls: enabled: true secretenabled: true createsecret: false secretname: openwhisk-tls-secret-1 annotations: # A blocking request is held open by the controller for slightly more than 60 seconds # before it is responded to with HTTP status code 202 (accepted) and closed. # Set to 75s to be on the safe side. # See https://console.bluemix.net/docs/containers/cs_annotations.html#proxy-connect-timeout # See http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout nginx.ingress.kubernetes.io/proxy-read-timeout: "75s" # Allow up to 50 MiB body size to support creation of large actions and large # parameter sizes. # See https://console.bluemix.net/docs/containers/cs_annotations.html#client-max-body-size # See http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size nginx.ingress.kubernetes.io/client-max-body-size: "size=50m" # Add the request_id, generated by nginx, to the request against the controllers. This id will be used as tid there. # Note that the serviceName includes the argument to --name from the helm deploy command. (owdev in this example) # https://console.bluemix.net/docs/containers/cs_annotations.html#proxy-add-headers nginx.ingress.kubernetes.io/proxy-add-headers: | serviceName=owdev-controller { 'X-Request-ID' $request_id; } k8s: persistence: hasDefaultStorageClass: false explicitStorageClass: openwhisk ``` ICP does not (by default) provide a properly configured DefaultStorageClass, instead you need to tell the Helm chart to use a storage class you've defined (see Creating the Kubernetes Cluster [above](#creating-the-kubernetes-cluster)). #### Don't want to deal with Ingress (or can't create an FQDN)? An alternative to the Ingress-based access model is to use a NodePort. Use the IP address of any worker node in the cluster to define `mycluster.yaml` as ```yaml whisk: ingress: type: NodePort apiHostName: YOUR_WORKERS_PUBLIC_IP_ADDR apiHostPort: 31001 nginx: httpsNodePort: 31001 k8s: persistence: hasDefaultStorageClass: false explicitStorageClass: openwhisk ``` ICP does not (by default) provide a properly configured DefaultStorageClass, instead you need to tell the Helm chart to use a storage class you've defined (see Creating the Kubernetes Cluster [above](#creating-the-kubernetes-cluster)). ## Hints and Tips On IBM Cloud Private clusters, you can configure OpenWhisk to integrate with platform logging and monitoring services following the general instructions for enabling these services for pods deployed on Kubernetes.