In addition to the REST API of the OpenFaaS gateway, the Function Custom Resource Definition can be used to manage functions.
Q: What's the difference between a Custom Resource Definition (CRD) and a Custom Resource (CR)?
A: The CRD is the definition of a Function, which is installed to the cluster once via helm when OpenFaaS is installed The CR is an instance of a Function.
Q: Do you still need stack.yml, if we want to adopt the Function CRD?
A: We recommend using either stack.yml on its own, along with IAM for OpenFaaS. However, if you want to use Helm, ArgoCD or Flux for GitOps-style deployments, then we would recommend using stack.yml for local development and for building images during CI, and the Function CRD for deployment.
Q: Can GitOps be used with Functions CRs?
A: You can use Helm, ArgoCD, or FluxCD to template, update and deploy functions. The Function CRD is a native Kubernetes resource, so it can be managed in the same way as Deployments, Services, and other resources.
Q: Can I still use kubectl if I deploy functions via REST or faas-cli?
A: Yes, the REST API accepts JSON deployment requests and then creates and manages a Function CR behind the scenes for you. That means you can explore, backup and inspect Functions using kubectl, even if you are not deploying via kubectl directly.
Do not remove the Custom Resource Definition from the cluster.
If you remove the Function CRD, then all instances of the CRD (known as CRs) will be removed from the cluster, meaning all your functions will be deleted immediately.
Here is an example of a function, written out in long form:
---apiVersion:openfaas.com/v1kind:Functionmetadata:name:nodeinfonamespace:openfaas-fnspec:name:nodeinfohandler:node main.jsimage:ghcr.io/openfaas/nodeinfo:latestlabels:com.openfaas.scale.min:"2"com.openfaas.scale.max:"15"annotations:current-time:Mon 6 Aug 23:42:00 BST 2018next-time:Mon 6 Aug 23:42:00 BST 2019environment:write_debug:"true"limits:cpu:"200m"memory:"256Mi"requests:cpu:"10m"memory:"128Mi"constraints:-"cloud.google.com/gke-nodepool=default-pool"secrets:-nodeinfo-secret1
Replicas represents the desired state, this starts as either 1 or the value of the com.openfaas.min.scale label. This value may also be changed by the autoscaler.
Available represents the actual number of Pods that are ready to serve traffic, that have passed their readiness check.
The OpenFaaS REST API contains readiness information in the form of available replicas being > 0. The faas-cli also has a describe command which queries the amount of available replicas and will report Ready or Not Ready.
That said, the Custom Resource now has a .status field with a number of conditions.
Reconciling is True - the operator has discovered the Function CR and is working on creating child resources in Kubernetes
Stalled is True - the operator cannot create the function, check the reason, perhaps some secrets are missing?
Ready condition is True - the operator was able to create the required Deployment, all required secrets exist, and it has no more work to do. The Reconciling condition is removed
Healthy condition is True - there is at least one ready Pod available to serve traffic
What about scaling to zero? When a Function is scaled to zero, the Ready state will be True and the Healthy state will be False. Invoke the function via its URL on the gateway to have it scale up from zero, you'll see it progress and gain a Healthy condition of True.
If you change a Function once it has passed into the Ready=true state, then the Ready condition will change to Unknown, and the Reconciling condition will be added again.
If you're an ArgoCD user, then you can define a custom health check at deployment time to integrate with the Custom Resource: ArgoCD: Custom Health Checks
To check that all secrets existed, and that the function could be applied correctly, then look for a Ready condition with a status of True for the current generation of the object. If you want to know if the function's code was valid, and was able to start, and that its image could be pulled, look for the Healthy condition instead. Bear in mind that any functions scaled to zero may have the Healthy condition removed, or set to False.
What happens when auto-scaling? When a Function is scaling from at least one replica to some higher number, the Healthy condition will continue to be set to True. The same applies when scaling down, so long as the target number of replicas is greater than zero.
Helm does not currently support readiness or waiting for Custom Resources, however, you can do this via kubectl if you wish:
# Wait until "env" is reconciled:
$kubectlgetfunction/env-nopenfaas-fn-ojsonpath="{.status.conditions[?(@.type == 'Ready')].status}"# Wait until "env" has at least one ready Pod:
$kubectlgetfunction/env-nopenfaas-fn-ojsonpath="{.status.conditions[?(@.type == 'Healthy')].status}"
Edit ArgoCD's configmap to add a custom health check for the Function CRD:
kubectleditconfigmapargocd-cm-nargocd
data:resource.customizations:|openfaas.com/Function:health.lua: |hs = {}if obj.status ~= nil thenif obj.status.conditions ~= nil thenfor i, condition in ipairs(obj.status.conditions) doif condition.type == "Ready" and condition.status == "False" thenhs.status = "Degraded"hs.message = condition.messagereturn hsendif condition.type == "Stalled" and condition.status == "True" thenhs.status = "Degraded"hs.message = condition.messagereturn hsendif condition.type == "Ready" and condition.status == "True" thenif obj.status.replicas ~= nil and obj.status.replicas > 0 thenhs.status = "Healthy"hs.message = condition.messageelsehs.status = "Suspended"hs.message = "No replicas available"endreturn hsendendendendhs.status = "Progressing"hs.message = "Waiting for Function"return hs
ArgoCD health status:
Function can't become ready due to a missing secret => Argo status: degraded
Function is ready and can serve traffic to at least one Pod => Argo status: healthy
Function is ready (no changes need to be applied), but has been scaled down to zero replicas => Argo status: suspended
Note: A pull request was sent to the ArgoCD project, so in a future version of ArgoCD, you won't need to create the above ConfigMap manually. However if you do want to override the behaviour of the health status, then you can still create a ConfigMap with the above content.
You can template and deploy functions via Helm, ArgoCD and Flux by including the Function's CR YAML in the same way you would for any other native Kubernetes resource.