# Deploying SAP on Kubernetes: A Practical Guide

###

<figure><img src="https://3977455898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FY7Q4XEDbI8MreYaSbZFG%2Fuploads%2FdBIK483A35kW8iRwfk5r%2Funnamed.jpg?alt=media&#x26;token=fb651d0f-1e92-442a-bdbd-b17c95a1ec57" alt=""><figcaption></figcaption></figure>

### What is Kubernetes Gardener?

Kubernetes Gardener is SAP’s open source managed Kubernetes service. It abstracts environment specifics to deliver a Kubernetes-native experience and enables you to easily create and manage several Kubernetes clusters.&#x20;

Gardener provides a fully-validated extensibility framework that you can adjust to various programmatic cloud and infrastructure providers. It works by implementing Kubernetes’s automated management and operation for clusters as a service.&#x20;

Gardener exposes its Cluster API to create homogeneous clusters on the supported infrastructure. While the SIG Cluster Lifecycle’s Cluster API only harmonizes how to get to clusters, Gardener’s Cluster API also harmonizes the make-up of the clusters. Gardener’s API achieves homogeneous clusters with the same configuration, behavior, and bill of material on all supported infrastructure.

### Setting up Gardener&#x20;

The easiest way to set up Gardner is using the official Helm file (get it [here](https://github.com/gardener/gardener/tree/master/charts/gardener)). Read this blog post to [learn more about Kubernetes Helm](https://komodor.com/learn/kubernetes-helm/).

### Develop your App for Kubernetes with SAP Gardener

The following procedure requires a cluster managed by SAP Gardener and that SAP BTP Service Operator be installed in the cluster. It also requires Docker, a Docker repository with public access, and a Spring Boot application that uses the SAP Cloud SDK. Code examples are adapted from the official Gardener documentation.

#### Containerize Your Application

To ship the application in a container with Docker:

1. Create a Dockerfile in the project’s root folder with the following contents:

`FROM openjdk:8-jdk-alpine`

`ARG JAR_FILE=application/demo-target/demo-*.jar`

`COPY ${JAR_FILE} demoApp.jar`

`ENTRYPOINT ["java","-jar","/demoApp.jar"]`

`EXPOSE 9000`

If required, make the JAR\_FILE point to the .jar file.

2. Use the following commands to compile and push the image:

`docker build -t demo-repo/demo-image-name .`

`docker push demo-repo/demo-image-name`

#### Create a Dedicated Kubernetes Deployment

To create the required Kubernetes deployment for the application:

1. Make a new YAML file and put the following configuration inside it:

\---

`apiVersion: apps/v1`

`kind: Deployment`

`metadata:`

&#x20; `name: demo-deployment`

`spec:`

&#x20; `replicas: 1`

&#x20; `selector:`

&#x20;   `matchLabels:`

&#x20;     `app: demo-app`

&#x20; `template:`

&#x20;   `metadata:`

&#x20;     `labels:`

&#x20;       `app: demo-app`

&#x20;   `spec:`

&#x20;     `containers:`

&#x20;       `- image: demo-repo/demo-image-name`

&#x20;         `name: demo-app`

&#x20;         `imagePullPolicy: Always`

&#x20;         `resources:`

&#x20;           `requests:`

&#x20;             `memory: '1Gi'`

&#x20;             `cpu: '500m'`

&#x20;           limits:

&#x20;             memory: '1.5Gi'

&#x20;             cpu: '750m'

&#x20;         volumeMounts:

&#x20;     imagePullSecrets:

&#x20;       \- name: \<docker-login-secret>

\---

`apiVersion: v1`

`kind: Service`

`metadata:`

&#x20; `labels:`

&#x20;   `app: demo-app`

&#x20; `name: demo-app`

&#x20; `namespace: default`

`spec:`

&#x20;`type: NodePort`

&#x20; `ports:`

&#x20;   `- port: 9000`

&#x20; `selector:`

&#x20;   `app: demo-app`

2. Use the following command to install the configuration:

`kubectl apply -f demo-deployment.yml`

3. Use the following command to monitor the deployment’s status:

`kubectl get deployment demo-app`

#### Create the Required Ingress and Test Application Access

To create an Ingress that makes the application available from outside the cluster:

1. Create a new YAML file and put the following Ingress configuration inside:

\---

`apiVersion: networking.k8s.io/v1`

`kind: Ingress`

`metadata:`

&#x20; `name: demo-ingress`

&#x20; `namespace: default`

&#x20; `annotations:`

`spec:`

&#x20; `tls:`

&#x20;   `- hosts:`

&#x20;     `# - "<demo-cluster-host>"`

&#x20;     `# - "*.ingress.<demo-cluster-host>"`

&#x20;   `# secretName: secret-tls`

&#x20; `rules:`

&#x20;   `- host: 'demo-app.ingress.<demo-cluster-host>'`

&#x20;     `http:`

&#x20;       `paths:`

&#x20;         `- path: /`

&#x20;           `pathType: Prefix`

&#x20;           `backend:`

&#x20;             `service:`

&#x20;               `name: demo-app`

&#x20;               `port:`

&#x20;                `number: 9000`

2. Use the following commands to install the configuration and verify Ingress is functional:

`kubectl apply -f ingress.yml`

`kubectl describe ingress demo-ingress`

3. Visit the host provided in the Ingress specification through a browser or a tool like Postman to check its access.

#### Attach SAP BTP Services

This tutorial will add access to the application for the Destination Service.

To attach SAP BTP services to the application:

1. Create a new YAML file and put in the following configuration:

\---

`apiVersion: services.cloud.sap.com/v1alpha1`

`kind: ServiceInstance`

`metadata:`

&#x20; `name: demo-destination-service`

`spec:`

&#x20; `serviceOfferingName: destination`

&#x20; `servicePlanName: lite`

&#x20; `externalName: default-destination-service`

\---

`apiVersion: services.cloud.sap.com/v1alpha1`

`kind: ServiceBinding`

`metadata:`

&#x20; `name: demo-destination-service-binding`

`spec:`

&#x20; `serviceInstanceName: demo-destination-service`

&#x20; `secretName: demo-destination-service-secret`

&#x20; `secretRootKey: demo-destination-service-key`

2. Use the following command to install the configuration:

`kubectl apply -f destination-service.yml`

3. Use the following command to monitor the installation status:

`kubectl describe ServiceInstance destination-service`

4. Add the following at the end of the deployment.yml file:

\- name: demo-destination-service-binding-volume

&#x20; secret:

&#x20;   secretName: demo-destination-service-secret

5. &#x20;the container section of deployment.yml, add the following in the empty lists of volumeMounts:

\- `name: demo-destination-service-binding-volume`

&#x20; `mountPath: '/etc/secrets/sapcp/destination/demo-destination-service'`

&#x20; `readOnly: true`

&#x20;   Use the following command to update the configuration:

kubectl apply -f deployment.yml

### Conclusion

SAP's Kubernetes Gardener provides a seamless Kubernetes-native experience that abstracts complexities and enables effortless creation and management of Kubernetes clusters across diverse infrastructures.

<br>

By deploying SAP on Kubernetes using Gardener, developers and administrators gain an extensible, uniform, and efficient solution for orchestrating their workloads. This guide has offered a detailed walkthrough on setting up Gardener, developing an application for Kubernetes with SAP Gardener, and leveraging SAP BTP services within a Kubernetes environment. By following these steps, users can fully capitalize on the strengths of Kubernetes while also harnessing the power of SAP's robust cloud offerings.&#x20;

<br>

As cloud-native practices continue to dominate the industry, such integrations provide businesses with a solid foundation to evolve and adapt in a rapidly changing technological landscape.

<br>
