Introduction to Kubernetes Service Catalog
Service Catalog is what allows Kubernetes to provision and connect to resources in the cloud. Let me explain through a demo.
In Kubernetes, we can deploy ‘almost’ anything. Anything that is a container. We can deploy SQL/NoSQL Databases, API Gateways, Queueing systems, monitoring tools, etc… But, it is still hard manage them. For example, running a database server in a container in Kubernetes is not always the best option. Because, if we will need a High Availability (HA), SLA of 99.99%, Failover plans… then we will need to do a lot of work. It is doable, for sure. But we still need to have a dedicated team with deep knowledge about k8s, working only on this.
On the other side, the Cloud providers have some nice managed PaaS offers. They have HA, SLA of four or five nines, failover plans…
Why not using PaaS offerings to complete apps running on Kubernetes ? Well, that is the idea behind a Service Catalog.
1. What is Service Catalog ?
Service Catalog is an extension to the Kubernetes API. It enables k8s to provision and connect to external managed services like databases and messaging systems.
We know that a managed Kubernetes cluster have some extension API to create resources in the cloud like a managed storage disk/file, Load Balancer, or even a Node/VM. These resources are vital and essential for k8s. Each cloud provider implements this API into its managed k8s offering. If we are using AKS, we would benefit from this API to use an Azure Disk or Azure Load Balancer. The same applies for EKS, GKE, etc…
Service Catalog, however, extends even more these capabilities. It can create and connect to ‘almost’ any service on the cloud. We said ‘almost’, because it is up to the cloud provider to implement the API that enable this integration.
How Service Catalog works ?
To provision and connect to a cloud service, Kubernetes should talk to Service Catalog which in its turn should talk to Open Service Broker specific implementation for Azure or AWS or GCP etc…
2. What is Open Service Broker API (OSBA)
Open Service Broker API defines a specification for listing, provisioning, accessing and deprovisioning cloud services. It have implementations for many cloud providers. Each implemenetation have a list of services that can be managed:
OSBA for Azure: Azure SQL Database, Azure Database for PostgresSQL / for MySQL, Azure CosmosDB, Azure Redis Cache, Azure Service Bus, Azure Storage, Azure Event Hubs, Azure Key Vault.
Service Broker for AWS: Amazon Relational Database Service (Amazon RDS), Amazon EMR, Amazon DynamoDB, Amazon Simple Storage Service (Amazon S3), and Amazon Simple Queue Service (Amazon SQS).
GCP Service Broker: BigQuery, Cloud Bigtable, Pub/Sub, Cloud Spanner, Cloud SQL, Cloud Storage.
3. Deploying Service Catalog into Kubernetes
Service Catalog is an extension API. This means that is not installed by default in Kubernetes. And because it depends on the OSBA, we need to deploy both. We will use an AKS cluster with Azure’s OSBA implementation.
3.1. Deploying the Service Catalog with Helm
The easisest way to deploy into k8s is using Helm. Lets first install Helm into k8s, then add Helm repository for Service Catalog:
$ helm init
$ helm repo add svc-cat https://svc-catalog-charts.storage.googleapis.com
Now, we can deploy the Service Catalog from the Helm repo:
$ helm install svc-cat/catalog
--name catalog
--namespace catalog
--set rbacEnable=false
--set apiserver.storage.etcd.persistence.enabled=true
--set apiserver.healthcheck.enabled=false
--set controllerManager.healthcheck.enabled=false
--set apiserver.verbosity=2
--set controllerManager.verbosity=2
One of the objects created is the APIService (v1beta1.servicecatalog.k8s.io). We can check if it was successfully created:
$ kubectl get apiservices
3.2 Deploying Open Service Broker for Azure with Helm
Now we need to install OSBA into Kubernetes. Again, we’ll be using Helm charts from the Azure repository.
$ helm repo add azure https://kubernetescharts.blob.core.windows.net/azure
Then, we’ll proceed to the deployment. But, before that, we need to understand that OSBA will communicate to Azure API, thus it needs authentication and authorisation. For that, we need to create a Service Principal to get the access right.
$ az ad sp create-for-rbac
$ helm install azure/open-service-broker-azure
--name osba
--namespace osba
--set azure.subscriptionId=$AZURE_SUBSCRIPTION_ID
--set azure.tenantId=$AZURE_TENANT_ID # tenant
--set azure.clientId=$AZURE_CLIENT_ID # appId
--set azure.clientSecret=$AZURE_CLIENT_SECRET # password
It will take a few minutes before the service broker gets ready. We can check its status here:
$ kubectl get ClusterServiceBrokers
3.3 Exploring Service Catalog CLI: svcat
Kubectl is what we typically use to interact with Kubernetes cluster including some Service Catalog API. But, for even more flexibility, Service Catalog had created its own CLI tool, that is svcat. We can install it using this link.
Lets explore the available commands with svcat:
$ svcat --help
To get the list of different brokers, as we have done before with command: kubectl get ClusterServiceBrokers
$ svcat get brokers
The broker defines the list of cloud services we can create through the command marketplace. Note here the services mentioned earlier like SQL databases, CosmosDB, etc.
$ svcat marketplace # or svcat get classes
Note that each offer have different plans like Basic, Standard, Premium, etc. We can get the list of all these plans with the command svcat get plans.
Later, we will be using the class ‘azure-sql-12–0’.
4. Provisioning SQL Azure Database with Service Catalog
The goal here is to use Service Catalog to create an Azure SQL database then connect it to a web app. We’ll be using yaml files with app’s source code which are available here: github.com/HoussemDellai/OSBA-Azure-AKS
4.1 Provisioning SQL Azure Server and Database
Service Catalog API uses the same structure of Kubernetes manifest files. We need to use the object type ServiceInstance and specify the class name with clusterServiceClassExternalName with the plan through clusterServicePlanExternalName. Note how we could specify the resource location and the resource group name.
To deploy this object, we’ll use the command:
$ kubectl create -f sql-instance.yaml
Then we can check if the creation was successful:
$ svcat get instances -n osba
$ kubectl get ServiceInstances -n osba
Now if we go to the Azure portal, we can see that there is a new resource group created with the two resources: Azure SQL server and database, great!
Now we want to connect to this database from the app. We can go to the database properties to retrieve the connection string from Azure portal. This is bad from a security perspective. Because we will be sharing sensitive data across email, slack, postit, etc. Fortunately, there is a another better solution. Service Catalog solves this prolem.
4.2 Binding Database secrets with the cluster
Service Catalog can get the Database information like name, username, password, host URL and port number. Then it will share these information in a Secret object in Kubernetes. To ask it to do that, we create a ServiceBinding object.
$ kubectl create -f sql-binding.yaml
The database credentials will be saved into a secret file called ‘my-sql-secret’. Lets view its content:
$ kubectl describe secret my-sql-secret -n osba
We can also view these credentials within the k8s dashboard:
5. Connecting a sample web app to the database instance
Now that the credentials are exposed through a Secret object, we can use it to connect a web app. We have a sample .NET Core web app configured to read the connection string different parts from environment variables.
And we need to pass these environment variables through the Deployment file.
$ kubectl create -f app-deploy-svc.yaml
If all works fine, we should be able to open the web app URL on a browser and navigate to web-app-url/Products to see an empty table for products. That means the web app successfully connected to the SQL database.
5. Deleting the created resources
To delete all the created resources:
$ helm delete osba --purge
$ helm delete catalog --purge
$ svcat delete instance my-sql-instance -n osba
$ svcat delete binding my-sql-binding -n osba
To learn more
I run a youtube channel where I post videos about DevOps, Docker and Azure.
Take a look at Kubernetes Operator.