Warning Make sure you are using the correct version of these instructions by using the link in the release notes for the version you're trying to install. If you're not sure, check our latest release.
The following lines will guide you through the process of deploying a released version of Korifi.
- Tools:
- Resources:
- Kubernetes cluster of one of the upstream releases;
- Container Registry on which you have write permissions.
This document was tested on:
- EKS, using AWS' Elastic Container Registry (ECR) (see Install Korifi on EKS);
- GKE, using GCP's Artifact Registry;
- kind, using DockerHub (see Install Korifi on kind).
The following environment variables will be needed throughout this guide:
ROOT_NAMESPACE
: the namespace at the root of the Korifi org and space hierarchy. The default value iscf
.KORIFI_NAMESPACE
: the namespace in which Korifi will be installed.ADMIN_USERNAME
: the name of the Kubernetes user who will have CF admin privileges on the Korifi installation. For security reasons, you should choose or create a user that is different from your cluster admin user. To provision new users, follow the user management instructions specific for your cluster's authentication configuration or create a new (short-lived) client certificate for user authentication.BASE_DOMAIN
: the base domain used by both the Korifi API and, by default, all apps running on Korifi.
Here are the example values we'll use in this guide:
ROOT_NAMESPACE="cf"
KORIFI_NAMESPACE="korifi"
ADMIN_USERNAME="cf-admin"
BASE_DOMAIN="korifi.example.org"
DockerHub allows only one private repository per free account. In case the DockerHub account you configure Korifi with has the private
default repository privacy enabled, then Korifi would only be able to create a single repository and would get UNAUTHORIZED: authentication required
error when trying to push to a subsequent repository. This could either cause build errors during cf push
, or the Kpack cluster builder may never become ready. Therefore you should either set the default repository privacy to public
, or upgrade your DockerHub subscription plan. As of today, the Pro
subscription plan provides unlimited private repositories.
cert-Manager allows us to automatically create internal certificates within the cluster. Follow the instructions to install the latest version.
Kpack is used to build runnable applications from source code using Cloud Native Buildpacks. Follow the instructions to install the latest version.
The Helm chart will create an example Kpack ClusterBuilder
(with the associated ClusterStore
and ClusterStack
) by default. To use your own ClusterBuilder
, specify the kpackImageBuilder.clusterBuilderName
value. See the Kpack documentation for details on how to set up your own ClusterBuilder
.
Contour is our ingress controller. Follow the instructions from the getting started guide to install the latest version.
We use the Kubernetes Metrics Server to implement process stats.
Most Kubernetes distributions will come with metrics-server
already installed. If yours does not, you should follow the instructions to install it.
We use the Service Binding Specification for Kubernetes and its controller reference implementation to implement Cloud Foundry service bindings (see this issue). Follow the instructions to install the latest version.
Create the root and korifi namespaces:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: $ROOT_NAMESPACE
labels:
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/enforce: restricted
EOF
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: $KORIFI_NAMESPACE
labels:
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/enforce: restricted
EOF
Warning This is not required when using ECR on an EKS deployment.
Use the following command to create a Secret
that Korifi and Kpack will use to connect to your container registry:
kubectl --namespace "$ROOT_NAMESPACE" create secret docker-registry image-registry-credentials \
--docker-username="<your-container-registry-username>" \
--docker-password="<your-container-registry-password>" \
--docker-server="<your-container-registry-hostname-and-port>"
Make sure the value of --docker-server
is a valid URI authority.
- If using DockerHub:
--docker-server
should be omitted;--docker-username
should be your DockerHub user;--docker-password
can be either your DockerHub password or a generated personal access token.
- If using Google Artifact Registry:
--docker-server
should be<region>-docker.pkg.dev
;--docker-username
should be_json_key
;--docker-password
should be the JSON-formatted access token for a service account that has permission to manage images in Google Artifact Registry.
Self-signed TLS certificates are generated automatically by the installation if global.generateIngressCertificates
has been set to true
.
If you want to generate certificates yourself, you should not set the global.generateIngressCertificates
value, and instead provide your certificates to Korifi by creating two TLS secrets in $KORIFI_NAMESPACE
:
korifi-api-ingress-cert
;korifi-workloads-ingress-cert
.
Korifi can be configured to use a custom Certificate Authority when contacting the container registry. To do so, first create a Secret
containing the CA certificate:
kubectl --namespace "$KORIFI_NAMESPACE" create secret generic <registry-ca-secret-name> \
--from-file=ca.crt=</path/to/ca-certificate>
You can then specify the <registry-ca-secret-name>
using the global.containerRegistryCACertSecret
.
Warning Kpack does not support self-signed/internal CA configuration out of the box (see pivotal/kpack#207). In order to make Kpack trust your CA certificate, you will have to inject it in both the Kpack controller and the Kpack build pods.
- The
kpack-controller
Deployment
can be modified to mount aSecret
similar to the one created above: see the Korifi APIDeployment
for an example of how to do this.- For the build pods you can use the cert-injection-webhook, configured on the
kpack.io/build
label.
Korifi is distributed as a Helm chart. See Customizing the Chart Before Installing for details on how to specify values when installing a Helm chart.
For example:
helm install korifi https://github.com/cloudfoundry/korifi/releases/download/v<VERSION>/korifi-<VERSION>.tgz \
--namespace="$KORIFI_NAMESPACE" \
--set=global.generateIngressCertificates=true \
--set=global.rootNamespace="$ROOT_NAMESPACE" \
--set=adminUserName="$ADMIN_USERNAME" \
--set=api.apiServer.url="api.$BASE_DOMAIN" \
--set=global.defaultAppDomainName="apps.$BASE_DOMAIN" \
--set=global.containerRepositoryPrefix=europe-west1-docker.pkg.dev/my-project/korifi/ \
--set=kpackImageBuilder.builderRepository=europe-west1-docker.pkg.dev/my-project/korifi/kpack-builder \
--wait
global.containerRepositoryPrefix
is used to determine the container repository for the package and droplet images produced by Korifi.
In particular, the app GUID and image type (packages
or droplets
) are appended to form the name of the repository.
For example:
Registry | containerRepositoryPrefix | Resultant Image Ref | Notes |
---|---|---|---|
Azure Container Registry | <projectID>.azurecr.io/foo/bar/korifi- |
<projectID>.azurecr.io/foo/bar/korifi-<appGUID>-packages |
Repositories are created dynamically during push by ACR |
DockerHub | index.docker.io/<dockerOrganisation>/ |
index.docker.io/<dockerOrganisation>/<appGUID>-packages |
Docker does not support nested repositories |
Amazon Elastic Container Registry | <projectID>.dkr.ecr.<region>.amazonaws.com/foo/bar/korifi- |
<projectID>.dkr.ecr.<region>.amazonaws.com/foo/bar/korifi-<appGUID>-packages |
Korifi will create the repository before pushing, as dynamic repository creation is not posssible on ECR |
Google Artifact Registry | <region>-docker.pkg.dev/<projectID>/foo/bar/korifi- |
<region>-docker.pkg.dev/<projectID>/foo/bar/korifi-<appGUID>-packages |
The foo repository must already exist in GAR |
Google Container Registry | gcr.io/<projectID>/foo/bar/korifi- |
gcr.io/<projectID>/foo/bar/korifi-<appGUID>-packages |
Repositories are created dynamically during push by GCR |
GitHub Container Registry | ghcr.io/<githubUserName>/foo/bar/korifi- |
ghcr.io/<githubUserName>/foo/bar/korifi-<appGUID>-package |
Repositories are created dynamically during push by GHCR |
The chart provides various other values that can be set. See README.helm.md
for details.
If you are using an authentication proxy with your cluster to enable SSO, you must set the following chart values:
api.authProxy.host
: IP address of your cluster's auth proxy;api.authProxy.caCert
: CA certificate of your cluster's auth proxy.
If you want to expose the API server using a means other than Contour, you can switch off the default API server ingress by setting the api.expose
value to false
.
Make sure your ingress targets a service with name korifi-api-svc
and port 443
.
Create DNS entries for the Korifi API and for the apps running on Korifi. They should match the Helm values used to deploy Korifi:
- The Korifi API entry should match the
api.apiServer.url
value. In our example, that would beapi.korifi.example.org
. - The apps entry should be a wildcard matching the
global.defaultAppDomainName
value. In our example,*.apps.korifi.example.org
.
The DNS entries should point to the load balancer endpoint created by Contour when installed. To discover your endpoint, run:
kubectl get service envoy -n projectcontour -ojsonpath='{.status.loadBalancer.ingress[0]}'
It may take some time before the address is available. Retry this until you see a result.
The type of DNS records to create will differ based on the type of the endpoint: ip
endpoints (e.g. the ones created by GKE) will need an A
record, while hostname
endpoints (e.g. on EKS) a CNAME
record.
cf api https://api.$BASE_DOMAIN --skip-ssl-validation
cf login # choose the entry in the list associated to $ADMIN_USERNAME
cf create-org org1
cf create-space -o org1 space1
cf target -o org1
cd <directory of a test cf app>
cf push test-app