Install Che on Amazon Elastic Kubernetes Service
To provide cloud development environments on AWS, deploy Che on an Amazon EKS cluster by configuring DNS, TLS certificates, and Keycloak as the OIDC identity provider.
-
You have
helminstalled. See Installing Helm. -
You have
chectlinstalled. See Installing the chectl management tool. -
You have the
awsCLI installed. See AWS CLI install and update instructions. -
You have
eksctlinstalled. See Installing eksctl.
Configuring environment variables for Amazon EKS
Follow these instructions to define environment variables and update your kubeconfig to connect to Amazon EKS.
-
Amazon EKS cluster with storage addon. See: Create an Amazon EKS cluster
-
Find the AWS account ID:
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) -
Define the cluster name:
CHE_EKS_CLUSTER_NAME=che -
Define the region:
CHE_EKS_CLUSTER_REGION=eu-central-1 -
Update
kubeconfig:aws eks update-kubeconfig --region $CHE_EKS_CLUSTER_REGION --name $CHE_EKS_CLUSTER_NAME -
Make sure that you have the default storage class set:
kubectl get storageclassThe output should display a storage class with
defaultnext to its name:NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 126m
Installing Ingress-Nginx Controller on Amazon EKS
Follow these instructions to install the Ingress-Nginx Controller on Amazon EKS.
-
Install the
Ingress-Nginx ControllerusingHelm:helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update helm install ingress-nginx ingress-nginx/ingress-nginx \ --wait \ --create-namespace \ --namespace ingress-nginx \ --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-backend-protocol"=tcp \ --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-cross-zone-load-balancing-enabled"="true" \ --set controller.service.annotations."service\.beta\.kubernetes\.io/aws-load-balancer-type"=nlb -
Verify that you can access the load balancer externally. It may take a few minutes for the load balancer to be created:
until curl $(kubectl get service -n ingress-nginx ingress-nginx-controller -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}'); do sleep 5s; doneYou should receive the output similar to:
<html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx</center> </body> </html>
Configuring DNS on Amazon EKS
Follow these instructions to configure DNS on Amazon EKS.
-
A registered domain. See: Registering a new domain on Amazon EKS.
-
Define the registered domain name:
CHE_DOMAIN_NAME=eclipse-che-eks-clould.click -
Define domain name for Keycloak OIDC provider:
KEYCLOAK_DOMAIN_NAME=keycloak.$CHE_DOMAIN_NAME -
Find out the hosted zone ID for the domain:
HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name $CHE_DOMAIN_NAME --query "HostedZones[0].Id" --output text) -
Find out the Canonical Hosted Zone ID for the load balancer:
CANONICAL_HOSTED_ZONE_ID=$(aws elbv2 describe-load-balancers --query "LoadBalancers[0].CanonicalHostedZoneId" --output text) -
Find out the DNS name for the load balancer:
DNS_NAME=$(kubectl get service -n ingress-nginx ingress-nginx-controller -o=jsonpath='{.status.loadBalancer.ingress[0].hostname}') -
Create a DNS record set:
aws route53 change-resource-record-sets \ --hosted-zone-id $HOSTED_ZONE_ID \ --change-batch ' { "Comment": "Ceating a record set", "Changes": [{ "Action" : "CREATE", "ResourceRecordSet" : { "Name" : "'"$CHE_DOMAIN_NAME"'", "Type" : "A", "AliasTarget" : { "HostedZoneId" : "'"$CANONICAL_HOSTED_ZONE_ID"'", "DNSName" : "'"$DNS_NAME"'", "EvaluateTargetHealth" : false } } }] } ' -
Verify that you can access Che domain externally:
until curl $CHE_DOMAIN_NAME; do sleep 5s; done -
Create a DNS record set:
aws route53 change-resource-record-sets \ --hosted-zone-id $HOSTED_ZONE_ID \ --change-batch ' { "Comment": "Ceating a record set", "Changes": [{ "Action" : "CREATE", "ResourceRecordSet" : { "Name" : "'"$KEYCLOAK_DOMAIN_NAME"'", "Type" : "A", "AliasTarget" : { "HostedZoneId" : "'"$CANONICAL_HOSTED_ZONE_ID"'", "DNSName" : "'"$DNS_NAME"'", "EvaluateTargetHealth" : false } } }] } ' -
Verify that you can access the Keycloak domain externally:
until curl $KEYCLOAK_DOMAIN_NAME; do sleep 5s; done
Installing cert-manager on Amazon EKS
Follow these instructions to install the cert-manager on Amazon EKS.
-
Install
cert-managerusingHelm:helm repo add jetstack https://charts.jetstack.io helm repo update helm install cert-manager jetstack/cert-manager \ --wait \ --create-namespace \ --namespace cert-manager \ --set crds.enabled=true
Creating Let’s Encrypt certificate for Che on Amazon EKS
Follow these instructions to create a Let’s Encrypt certificate for Che on Amazon EKS.
-
Create an IAM OIDC provider:
eksctl utils associate-iam-oidc-provider --cluster $CHE_EKS_CLUSTER_NAME --approve -
Create a service principal:
aws iam create-policy \ --policy-name cert-manager-acme-dns01-route53 \ --description "This policy allows cert-manager to manage ACME DNS01 records in Route53 hosted zones. See https://cert-manager.io/docs/configuration/acme/dns01/route53" \ --policy-document file:///dev/stdin <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "route53:GetChange", "Resource": "arn:aws:route53:::change/*" }, { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets", "route53:ListResourceRecordSets" ], "Resource": "arn:aws:route53:::hostedzone/*" }, { "Effect": "Allow", "Action": "route53:ListHostedZonesByName", "Resource": "*" } ] } EOF -
Create an IAM role and associate it with a Kubernetes Service Account:
eksctl create iamserviceaccount \ --name cert-manager-acme-dns01-route53 \ --namespace cert-manager \ --cluster $CHE_EKS_CLUSTER_NAME \ --role-name cert-manager-acme-dns01-route53 \ --attach-policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/cert-manager-acme-dns01-route53 \ --approve -
Grant permission for
cert-managerto create Service Account tokens:kubectl apply -f - << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: cert-manager-acme-dns01-route53-tokenrequest namespace: cert-manager rules: - apiGroups: [''] resources: ['serviceaccounts/token'] resourceNames: ['cert-manager-acme-dns01-route53'] verbs: ['create'] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: cert-manager-acme-dns01-route53-tokenrequest namespace: cert-manager subjects: - kind: ServiceAccount name: cert-manager namespace: cert-manager roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: cert-manager-acme-dns01-route53-tokenrequest EOF -
Create the Issuer:
kubectl apply -f - << EOF apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: che-letsencrypt spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: <email_address> (1) privateKeySecretRef: name: che-letsencrypt-production solvers: - dns01: route53: region: $CHE_EKS_CLUSTER_REGION role: arn:aws:iam::${AWS_ACCOUNT_ID}:role/cert-manager-acme-dns01-route53 auth: kubernetes: serviceAccountRef: name: cert-manager-acme-dns01-route53 EOF1 Replace <email_address>with your email address. -
Create the eclipse-che namespace:
kubectl create namespace eclipse-che -
Create the Certificate:
kubectl apply -f - << EOF apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: che-tls namespace: eclipse-che spec: secretName: che-tls issuerRef: name: che-letsencrypt kind: ClusterIssuer commonName: '$CHE_DOMAIN_NAME' dnsNames: - '$CHE_DOMAIN_NAME' - '*.$CHE_DOMAIN_NAME' usages: - server auth - digital signature - key encipherment - key agreement - data encipherment EOF -
Wait for the
che-tlssecret to be created:until kubectl get secret -n eclipse-che che-tls; do sleep 5s; done
Installing Keycloak on Amazon Elastic Kubernetes Service
Follow these instructions to install Keycloak as the OpenID Connect (OIDC) provider.
-
Install Keycloak:
While this guide provides a development configuration for deploying Keycloak on {kubernetes}, remember that production environments might require different settings, such as external database configuration.kubectl apply -f - <<EOF --- apiVersion: v1 kind: Namespace metadata: name: keycloak --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: keycloak namespace: keycloak labels: app: keycloak spec: secretName: keycloak.tls issuerRef: name: che-letsencrypt kind: ClusterIssuer commonName: '$KEYCLOAK_DOMAIN_NAME' dnsNames: - '$KEYCLOAK_DOMAIN_NAME' usages: - server auth - digital signature - key encipherment - key agreement - data encipherment --- apiVersion: v1 kind: Service metadata: name: keycloak namespace: keycloak labels: app: keycloak spec: ports: - name: http port: 8080 targetPort: 8080 selector: app: keycloak type: LoadBalancer --- apiVersion: apps/v1 kind: Deployment metadata: name: keycloak namespace: keycloak labels: app: keycloak spec: replicas: 1 selector: matchLabels: app: keycloak template: metadata: labels: app: keycloak spec: containers: - name: keycloak image: quay.io/keycloak/keycloak:18.0.2 args: ["start-dev"] env: - name: KEYCLOAK_ADMIN value: "admin" - name: KEYCLOAK_ADMIN_PASSWORD value: "admin" - name: KC_PROXY value: "edge" ports: - name: http containerPort: 8080 readinessProbe: httpGet: path: /realms/master port: 8080 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: keycloak namespace: keycloak annotations: nginx.ingress.kubernetes.io/proxy-connect-timeout: '3600' nginx.ingress.kubernetes.io/proxy-read-timeout: '3600' nginx.ingress.kubernetes.io/ssl-redirect: 'true' spec: ingressClassName: nginx tls: - hosts: - $KEYCLOAK_DOMAIN_NAME secretName: keycloak.tls rules: - host: $KEYCLOAK_DOMAIN_NAME http: paths: - path: / pathType: Prefix backend: service: name: keycloak port: number: 8080 EOF -
Wait until the Keycloak pod is ready:
kubectl wait --for=condition=ready pod -l app=keycloak -n keycloak --timeout=120s -
Wait for the
keycloak.tlssecret to be created:until kubectl get secret -n keycloak keycloak.tls; do sleep 5s; done -
Configure Keycloak to create the realm, client, and user:
kubectl exec deploy/keycloak -n keycloak -- bash -c \ "/opt/keycloak/bin/kcadm.sh config credentials \ --server http://localhost:8080 \ --realm master \ --user admin \ --password admin && \ /opt/keycloak/bin/kcadm.sh create realms \ -s realm='che' \ -s displayName='che' \ -s enabled=true \ -s registrationAllowed=false \ -s resetPasswordAllowed=true && \ /opt/keycloak/bin/kcadm.sh create clients \ -r 'che' \ -s clientId=k8s-client \ -s id=k8s-client \ -s redirectUris='[\"*\"]' \ -s directAccessGrantsEnabled=true \ -s secret=eclipse-che && \ /opt/keycloak/bin/kcadm.sh create users \ -r 'che' \ -s username=test \ -s email=\"test@test.com\" \ -s enabled=true \ -s emailVerified=true && \ /opt/keycloak/bin/kcadm.sh set-password \ -r 'che' \ --username test \ --new-password test"
Associate keycloak as OIDC identity provider on Amazon EKS
Follow these instructions to associate Keycloak an OIDC identity provider on Amazon EKS.
-
Associate Keycloak an identity provider using
eksctl:eksctl associate identityprovider \ --wait \ --config-file - << EOF --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: $CHE_EKS_CLUSTER_NAME region: $CHE_EKS_CLUSTER_REGION identityProviders: - name: keycloak-oidc type: oidc issuerUrl: https://$KEYCLOAK_DOMAIN_NAME/realms/che clientId: k8s-client usernameClaim: email EOF
Installing Che on Amazon EKS
Follow these instructions to install Che on Amazon EKS.
-
Prepare a CheCluster patch YAML file:
cat > che-cluster-patch.yaml << EOF spec: networking: auth: oAuthClientName: k8s-client oAuthSecret: eclipse-che identityProviderURL: "https://$KEYCLOAK_DOMAIN_NAME/realms/che" gateway: oAuthProxy: cookieExpireSeconds: 300 deployment: containers: - env: - name: OAUTH2_PROXY_BACKEND_LOGOUT_URL value: "http://$KEYCLOAK_DOMAIN_NAME/realms/che/protocol/openid-connect/logout?id_token_hint={id_token}" name: oauth-proxy components: cheServer: extraProperties: CHE_OIDC_USERNAME__CLAIM: email EOF -
Deploy Che:
chectl server:deploy \ --platform k8s \ --domain $CHE_DOMAIN_NAME \ --che-operator-cr-patch-yaml che-cluster-patch.yaml \ --skip-cert-manager \ --k8spodreadytimeout 240000 \ --k8spoddownloadimagetimeout 240000 -
Navigate to the Che cluster instance:
chectl dashboard:open