---
layout: default
title: CAS - Kubernetes Helm Deployment
category: Installation
---
{% include variables.html %}

# Kubernetes Helm Installation

The [CAS WAR Overlay Initializr](WAR-Overlay-Initializr.html) includes a CAS Helm chart that can 
be used to deploy CAS on a Kubernetes cluster. This document won't discuss setting up a production
Kubernetes cluster, but it will walk through setting CAS up using a [Helm](https://helm.sh/) chart 
on a local Kubernetes cluster. This document assumes the [CAS Initializr](WAR-Overlay-Initializr.html) 
has been used to create an overlay since that Initializr project houses the Helm chart and 
the overlay generated by the initializr is needed for building the CAS container image. 

<div class="alert alert-info">:information_source: <strong>Note</strong>
<p>This Helm chart is new and once it stabilizes it may be published to a helm repository. 
For now it is probably best considered as a deployment option for deployers with CAS and Kubernetes experience.</p></div>

You may also be interested to manage [CAS configuration via Kubernetes](../configuration/Configuration-Server-Management-SpringCloud-Kubernetes.html).

# What is Helm?

Helm Charts are a set of templates that are combined with deployment specific values
to generate Kubernetes configuration yaml. The deployer of a Helm chart should be able to 
make their own values file that overrides any default values that the chart defines and install
the application without having to change the templates. If the templates need changing, 
those changes are candidates for contributing back the Helm chart, so it will get more customizable 
and support more deployment options over time.

# CAS Helm Chart Overview

The current helm chart for CAS will deploy CAS with a Spring Boot Admin Server.
Eventually it might be nice to support a config-server and have cas-management or cas-shell available.  
The chart supports mapping in arbitrary volumes and cas config can be specified in values files.
The config could be in cloud config rather than kubernetes config maps, the service registry
could be in a database, git, or a simple json registry in a kubernetes persistent volume. 
The ticket registry could use a standard helm chart for redis, postgresql, or mongo, etc.
Currently, the chart is using SSL between ingress controller and the CAS and Boot Admin servers.
This may be overkill and involves all the pain that comes with SSL (e.g. trust & hostname verification).
This chart uses `StatefulSet` for CAS rather than a `Deployment` but this may change in the future or
become configurable. 

The Spring Boot Admin CAS server discovery method should probably change to "cloud" discovery eventually.

## Installing CAS on local Kubernetes Installation

The following sections provide an overview of the steps for installing Helm and Kubernetes and
getting the CAS Helm chart installed and running locally.

### Install Helm and Kubectl

Helm v3 and Kubectl are just single binary programs. Kubectl may come with the kubernetes
installation, but both should be downloaded and put them in the PATH.

- Install [Helm](https://helm.sh/docs/intro/install/)
- Install [Kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)

### Install Kubernetes

There are multiple options for running a Kubernetes cluster on Mac, Windows or Linux, but
they all require Linux as a VM or as the host OS. The CAS Helm Chart is installed and tested
on a K3S Kubernetes installation as part of the continuous integration scripts of the CAS Initializr 
so that method should always work, but it does require users of Windows and Mac to install
a Linux virtual machine (e.g. running Ubuntu).

### K3S Kubernetes

[k3s](https://k3s.io/) works on linux, very light-weight and easy to install for development. Installing Docker is not required. 
  
```bash
# install k3s, without traefik ingress controller
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server --disable traefik" sh
# the following export is needed for helm, put in profile
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# build a CAS image from the overlay generated from Initializr
./gradlew clean build jibBuildTar --refresh-dependencies
# import the image to k3s (k3s can pull images from registries but can't see local docker images)
k3s ctr images import build/jib-image.tar
# verify the image is loaded
k3s ctr images ls | grep cas
# Go to folder with helm chart
cd helm 
# create secret for tomcat
./create-cas-server-keystore-secret.sh
# create secret for ingress controller to use with CAS ingress (nginx-ingress will use default if not created)
./create-ingress-tls.sh
# create configmap containing SSL trust store
./create-truststore.sh
# install cas-server helm chart
helm upgrade --install cas-server ./cas-server
``` 

#### Other Options 

- [Docker Desktop](https://www.docker.com/products/docker-desktop)
  - Install Docker Desktop
  - Enable Kubernetes in Settings
  - [Helm and Kubectl](#install-helm-and-kubectl) should be installed and added to path of bash terminal 
    (Use Git Bash or Cygwin or Msys2 on Windows)
  - Run shell scripts for installing certs and trust stores (in `helm` sub-directory)
  - Build CAS image via `./gradlew clean build jibBuildTar --refresh-dependencies`
  - Load CAS image locally into Docker `docker load < build/jib-image.tar`
  - Install [Ingress Controller](#install-ingress-controller)
  - Install CAS Helm chart

- [Minikube](https://minikube.sigs.k8s.io/docs/start/)

### Install Ingress Controller

The CAS Helm chart is only tested with Kubernetes ingress-nginx, feel free to add support for other ingress controllers. Kubernetes Nginx 
Ingress Installation Guide can be found [here](https://kubernetes.github.io/ingress-nginx/deploy/).

To install the Ingress controller using Helm and the `ingress-nginx` Helm chart:

```bash
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
kubectl create namespace ingress-nginx
helm install --namespace ingress-nginx ingress-nginx ingress-nginx/ingress-nginx
kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=120s
```

### Install CAS Server Helm Chart

Helm charts consist of templates which are combined with values from one or more values files
(and command line set arguments) to produce kubernetes yaml. The chart folder (containing the `templates` directory)
contains a default values.yaml that is used by default but additional values files should be
specified on the command line to override the default values as appropriate.
The following examples use the `default` namespace but `--namespace cas` can be added to any 
of the following `helm` commands to put CAS in its own kubernetes namespace (The namespace would 
need to be created first, e.g. `kubectl create namespace cas`)

```bash
# delete cas-server helm chart install
helm delete cas-server
# install cas-server chart 
helm install cas-server ./cas-server
# install or update cas-server
helm upgrade --install cas-server ./cas-server
# use local values file to override defaults 
helm upgrade --install cas-server --values values-local.yaml ./cas-server
# see kubernetes yaml without installing  
helm upgrade --install cas-server --values values-local.yaml ./cas-server --dry-run --debug
# sometimes dry-run fails b/c yaml can't convert to json so use template instead to see problem
helm template cas-server --values values-local.yaml ./cas-server --debug
```

### Useful `kubectl` Commands

Don't forget to add `-n` or `--namespace` if using non-default namespace.

```bash
# Look at the pods to see the status
kubectl get pods 
# Describe the CAS pod to see why it isn't starting
kubectl describe pod cas-server-0
# tail the console logs
kubectl logs cas-server-0 -f
# exec into container
kubectl exec -it cas-server-0 sh
# bounce CAS pod
kubectl delete pod cas-server-0
```

### Browse to CAS

Make sure host file entries exist for whatever host is listed in values file for this entry:

```yaml
ingress:
  hosts:
    - host: cas.example.org
      paths: 
        - "/cas"
  tls: 
    - secretName: cas-server-ingress-tls
      hosts:
        - cas.example.org
```

```bash
# host entry
127.0.0.1 cas.example.org 
```

If the CAS pod is running, browse to `https://cas.example.org/cas/login`. 
There is also an ingress for the CAS Spring Boot Admin server that should be accessible
using the host name specified for the Boot Admin's ingress.  
The CAS Spring Boot Admin server has its own ingress since it is meant to be internally accessible 
and CAS is likely external, but both could be internal or external.
