Skip to content

Latest commit

 

History

History
269 lines (192 loc) · 15.9 KB

INSTALL.md

File metadata and controls

269 lines (192 loc) · 15.9 KB

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.

Korifi installation guide

The following lines will guide you through the process of deploying a released version of Korifi.

Prerequisites

  • Tools:
  • Resources:
    • Kubernetes cluster of one of the upstream releases;
    • Container Registry on which you have write permissions.

This document was tested on:

Initial setup

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 is cf.
  • 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.
  • GATEWAY_CLASS_NAME: the name of the Gateway API gatewayclass (see contour section).

Here are the example values we'll use in this guide:

export ROOT_NAMESPACE="cf"
export KORIFI_NAMESPACE="korifi"
export ADMIN_USERNAME="cf-admin"
export BASE_DOMAIN="korifi.example.org"
export GATEWAY_CLASS_NAME="contour"

Free Dockerhub accounts

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.

Dependencies

cert-Manager

cert-Manager allows us to automatically create internal certificates within the cluster. Follow the instructions to install the latest version.

Kpack

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

Contour is our ingress controller. Contour implements the Gateway API. There are two ways to deploy Contour with Gateway API support: static provisioning and dynamic provisioning.

Static Provisioning

Follow the static provisioning instructions from the Gateway API support guide to install the latest version. Note that as part of the Contour installation you have to create a gatewayclass with name $GATEWAY_CLASS_NAME:

kubectl apply -f - <<EOF
kind: GatewayClass
apiVersion: gateway.networking.k8s.io/v1beta1
metadata:
  name: $GATEWAY_CLASS_NAME
spec:
  controllerName: projectcontour.io/gateway-controller
EOF

This gatewayclass name is a parameter of the helm chart installing korifi. The helm chart is going to define a gateway that will be used for all korifi ingress traffic.

Dynamic Provisioning

Follow the dynamic provisioning instructions from the Gateway API support guide to install the latest version.

  • Note that as part of the Contour installation you have to create a gatewayclass with name $GATEWAY_CLASS_NAME:
    kubectl apply -f - <<EOF
    kind: GatewayClass
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: $GATEWAY_CLASS_NAME
    spec:
      controllerName: projectcontour.io/gateway-controller
    EOF
  • You DO NOT need to create a gateway as per the instructions. The Korifi helm chart defines a gateway that will be used for all korifi ingress traffic. The gateway will be created in the korifi-gateway namespace.

Metrics Server

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.

Optional: Service Bindings Controller

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.

Pre-install configuration

Namespace creation

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

Container registry credentials Secret

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.

TLS certificates

Self-signed TLS certificates are generated automatically by the installation if generateIngressCertificates has been set to true.

If you want to generate certificates yourself, you should not set the generateIngressCertificates value, and instead provide your certificates to Korifi by creating two TLS secrets in $KORIFI_NAMESPACE:

  1. korifi-api-ingress-cert;
  2. korifi-workloads-ingress-cert.

Container registry Certificate Authority

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 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.

Install Korifi

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=generateIngressCertificates=true \
    --set=rootNamespace="$ROOT_NAMESPACE" \
    --set=adminUserName="$ADMIN_USERNAME" \
    --set=api.apiServer.url="api.$BASE_DOMAIN" \
    --set=defaultAppDomainName="apps.$BASE_DOMAIN" \
    --set=containerRepositoryPrefix=europe-docker.pkg.dev/my-project/korifi/ \
    --set=kpackImageBuilder.builderRepository=europe-docker.pkg.dev/my-project/korifi/kpack-builder \
    --set=networking.gatewayClass=$GATEWAY_CLASS_NAME \
    --wait

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.

Configure an Authentication Proxy (optional)

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.

Using a Custom Ingress Controller

Korifi leverages the Gateway API for networking. This means that it should be easy to switch to any Gateway API compatible Ingress Controller implementation (e.g. Istio).

Post-install Configuration

DNS

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 be api.korifi.example.org.
  • The apps entry should be a wildcard matching the defaultAppDomainName value. In our example, *.apps.korifi.example.org.

The DNS entries should point to the load balancer endpoint created by Contour when installed.

If you used static provisioning of a Contour gateway, discover your endpoint with:

kubectl get service envoy -n projectcontour -ojsonpath='{.status.loadBalancer.ingress[0]}'

If you used dynamic provisioning of a Contour gateway, discover your endpoint with:

kubectl get service envoy-korifi -n korifi-gateway -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.

Test Korifi

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