New to AppsCode Service Broker? Please start here.
This tutorial will show you how to use AppsCode Service Broker to provision and deprovision an Elasticsearch cluster and bind to the Elasticsearch service.
Before we start, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using Minikube. Then install Service Catalog onto your cluster. If you haven’t, please see the installation instructions for Service Catalog. Optionally you may install the Service Catalog CLI, svcat
. Examples for both svcat
and kubectl
are provided so that you may follow this walk-through using svcat
or using only kubectl
.
If you’ve AppsCode Service Broker installed, then we are ready for the next step. If not, follow the instructions to install KubeDB and AppsCode Service Broker.
To keep things isolated, we are going to use a separate namespace called demo
throughout this tutorial.
$ kubectl create ns demo
namespace/demo created
All commands in this document assume that you’re operating out of the root of this repository.
First, list the available ClusterServiceClass
resources:
$ kubectl get clusterserviceclasses
NAME EXTERNAL-NAME BROKER AGE
2010d83f-d908-4d9f-879c-ce8f5f527f2a postgresql appscode-service-broker 1h
315fc21c-829e-4aa1-8c16-f7921c33550d elasticsearch appscode-service-broker 1h
938a70c5-f2bc-4658-82dd-566bed7797e9 mysql appscode-service-broker 1h
ccfd1c81-e59f-4875-a39f-75ba55320ce0 redis appscode-service-broker 1h
d690058d-666c-45d8-ba98-fcb9fb47742e mongodb appscode-service-broker 1h
d88856cb-fe3f-4473-ba8b-641480da810f memcached appscode-service-broker 1h
$ svcat get classes
NAME NAMESPACE DESCRIPTION
+---------------+-----------+------------------------------+
postgresql KubeDB managed PostgreSQL
elasticsearch KubeDB managed ElasticSearch
mysql KubeDB managed MySQL
redis KubeDB managed Redis
mongodb KubeDB managed MongoDB
memcached KubeDB managed Memcached
Now, describe the elasticsearch
class from the Service Broker
.
$ svcat describe class elasticsearch
Name: elasticsearch
Scope: cluster
Description: KubeDB managed ElasticSearch
Kubernetes Name: 315fc21c-829e-4aa1-8c16-f7921c33550d
Status: Active
Tags:
Broker: appscode-service-broker
Plans:
NAME DESCRIPTION
+----------------------------+--------------------------------+
demo-elasticsearch-cluster Demo Elasticsearch cluster
elasticsearch Elasticsearch cluster with
custom specification
demo-elasticsearch Demo Standalone Elasticsearch
database
To view the details of any plan in this class use command $ svcat describe plan <class_name>/<plan_name>
. For example:
$ svcat describe plan elasticsearch/elasticsearch --scope cluster
Name: elasticsearch
Description: Elasticsearch cluster with custom specification
Kubernetes Name: 6fa212e2-e043-4ae9-91c2-8e5c4403d894
Status: Active
Free: true
Class: elasticsearch
Instances:
No instances defined
Here we,ve used
--scope
flag to specify that ourClusterServiceBroker
,ClusterServiceClass
andClusterServiceBroker
resources are cluster scoped (not namespaced scope)
AppsCode Service Broker currently supports three plans for elasticsearch
class as we can see above. Using demo-elasticsearch
plan we can provision a demo Elasticsearch database. Using demo-elasticsearch-cluster
plan we can provision a demo Elasticsearch database with clustering support. And using elasticsearch
plan we can provision a custom Elasticsearch cluster with the full functionality of an Elasticsearch CRD.
AppsCode Service Broker accepts only metadata and Elasticsearch Spec as parameters for the plans of elasticsearch
class. The metadata and spec should be provided with key "metadata"
and "spec"
respectively. The metadata is optional for all of the plans available. But the spec is required for the custom plan and it must be valid.
Since a ClusterServiceClass
named elasticsearch
exists in the cluster with a ClusterServicePlan
named elasticsearch
, we can create a ServiceInstance
pointing to them with custom specification as parameters.
Unlike
ClusterServiceBroker
,ClusterServiceClass
andClusterServicePlan
resources,ServiceInstance
resources must be namespaced. The latest version of .service catalog supportsServiceBroker
,ServiceClass
andServicePlan
resources that are namespace scoped and alternative toClusterServiceBroker
,ClusterServiceClass
andClusterServicePlan
resources.
Create the ServiceInstance
:
$ kubectl create -f docs/examples/elasticsearch-instance.yaml
serviceinstance.servicecatalog.k8s.io/elasticsearchdb created
After it is created, the service catalog controller will communicate with the service broker server to initiate provisioning. Now, see the details:
$ svcat describe instance elasticsearchdb --namespace demo
Name: elasticsearchdb
Namespace: demo
Status: Ready - The instance was provisioned successfully @ 2018-12-26 11:16:56 +0000 UTC
Class: elasticsearch
Plan: elasticsearch
Parameters:
metadata:
labels:
app: my-elasticsearch
spec:
enableSSL: true
storage:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
storageType: Durable
terminationPolicy: WipeOut
version: 6.3-v1
Bindings:
No bindings defined
The yaml configuration of this ServiceInstance
:
kubectl get serviceinstance elasticsearchdb --namespace demo -o yaml
Output:
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
creationTimestamp: "2018-12-26T11:16:55Z"
finalizers:
- kubernetes-incubator/service-catalog
generation: 1
labels:
app: appscode-service-broker
name: elasticsearchdb
namespace: demo
resourceVersion: "240"
selfLink: /apis/servicecatalog.k8s.io/v1beta1/namespaces/demo/serviceinstances/elasticsearchdb
uid: c07af740-08ff-11e9-9fa4-0242ac110006
spec:
clusterServiceClassExternalName: elasticsearch
clusterServiceClassRef:
name: 315fc21c-829e-4aa1-8c16-f7921c33550d
clusterServicePlanExternalName: elasticsearch
clusterServicePlanRef:
name: 6fa212e2-e043-4ae9-91c2-8e5c4403d894
externalID: c07af6f6-08ff-11e9-9fa4-0242ac110006
parameters:
metadata:
labels:
app: my-elasticsearch
spec:
enableSSL: true
storage:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
storageType: Durable
terminationPolicy: WipeOut
version: 6.3-v1
updateRequests: 0
userInfo:
groups:
- system:masters
- system:authenticated
uid: ""
username: minikube-user
status:
asyncOpInProgress: false
conditions:
- lastTransitionTime: "2018-12-26T11:16:56Z"
message: The instance was provisioned successfully
reason: ProvisionedSuccessfully
status: "True"
type: Ready
deprovisionStatus: Required
externalProperties:
clusterServicePlanExternalID: 6fa212e2-e043-4ae9-91c2-8e5c4403d894
clusterServicePlanExternalName: elasticsearch
parameterChecksum: b3e231fcc94d12101a01ce801019f64d3d47ca03c25fc198dc6a1c224e64c166
parameters:
metadata:
labels:
app: my-elasticsearch
spec:
enableSSL: true
storage:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
storageType: Durable
terminationPolicy: WipeOut
version: 6.3-v1
userInfo:
groups:
- system:masters
- system:authenticated
uid: ""
username: minikube-user
observedGeneration: 1
orphanMitigationInProgress: false
provisionStatus: Provisioned
reconciledGeneration: 1
We have a ready ServiceInstance
. To use this service, we can bind to it. AppsCode Service Broker currently supports no parameter for binding. Now, create a ServiceBinding
resource:
$ kubectl create -f docs/examples/elasticsearch-binding.yaml
servicebinding.servicecatalog.k8s.io/elasticsearchdb created
Once the ServiceBinding
resource is created, the service catalog controller initiates binding process by communicating with the service broker server. In general, the broker server returns the necessary credentials in this step. Then the service catalog controller will insert them into a Kubernetes Secret
object.
$ kubectl get servicebindings elasticsearchdb --namespace demo
NAME SERVICE-INSTANCE SECRET-NAME STATUS AGE
elasticsearchdb elasticsearchdb elasticsearchdb Ready 57s
$ svcat get bindings --namespace demo
NAME NAMESPACE INSTANCE STATUS
+-----------------+-----------+-----------------+--------+
elasticsearchdb demo elasticsearchdb Ready
$ svcat describe bindings elasticsearchdb --namespace demo
Name: elasticsearchdb
Namespace: demo
Status: Ready - Injected bind result @ 2018-12-26 11:23:04 +0000 UTC
Secret: elasticsearchdb
Instance: elasticsearchdb
Parameters:
No parameters defined
Secret Data:
Host 24 bytes
Password 8 bytes
Port 4 bytes
Protocol 5 bytes
RootCert 1520 bytes
URI 37 bytes
Username 5 bytes
You can see the secret data by passing --show-secrets
flag to the above command. The yaml configuration of this ServiceBinding
resource is as follows:
kubectl get servicebindings elasticsearchdb --namespace demo -o yaml
Output:
apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
creationTimestamp: "2018-12-26T11:23:04Z"
finalizers:
- kubernetes-incubator/service-catalog
generation: 1
labels:
app: appscode-service-broker
name: elasticsearchdb
namespace: demo
resourceVersion: "250"
selfLink: /apis/servicecatalog.k8s.io/v1beta1/namespaces/demo/servicebindings/elasticsearchdb
uid: 9ca83d72-0900-11e9-9fa4-0242ac110006
spec:
externalID: 9ca83d35-0900-11e9-9fa4-0242ac110006
instanceRef:
name: elasticsearchdb
secretName: elasticsearchdb
userInfo:
groups:
- system:masters
- system:authenticated
uid: ""
username: minikube-user
status:
asyncOpInProgress: false
conditions:
- lastTransitionTime: "2018-12-26T11:23:04Z"
message: Injected bind result
reason: InjectedBindResult
status: "True"
type: Ready
externalProperties:
userInfo:
groups:
- system:masters
- system:authenticated
uid: ""
username: minikube-user
orphanMitigationInProgress: false
reconciledGeneration: 1
unbindStatus: Required
Here, the status has Ready
condition which means the binding is now ready for use. This binding operation creates a Secret
named elasticsearchdb
in namespace demo
.
$ kubectl get secrets --namespace demo
NAME TYPE DATA AGE
default-token-2qbzg kubernetes.io/service-account-token 3 6h58m
elasticsearchdb Opaque 7 4m14s
elasticsearchdb-auth Opaque 9 8m50s
elasticsearchdb-cert Opaque 6 8m50s
We can now delete the ServiceBinding
resource we created in the Binding
step (it is called Unbinding
the ServiceInstance
)
$ kubectl delete servicebinding elasticsearchdb --namespace demo
servicebinding.servicecatalog.k8s.io "elasticsearchdb" deleted
$ svcat unbind elasticsearchdb --namespace demo
deleted elasticsearchdb
After completion of unbinding, the Secret
named elasticsearchdb
should be deleted.
$ kubectl get secrets --namespace demo
NAME TYPE DATA AGE
default-token-2qbzg kubernetes.io/service-account-token 3 6h59m
elasticsearchdb-auth Opaque 9 10m
elasticsearchdb-cert Opaque 6 10m
After unbinding the ServiceInstance
, our next step is deleting the ServiceInstance
resource we provisioned before. It is called Deprovisioning
.
$ kubectl delete serviceinstance elasticsearchdb --namespace demo
serviceinstance.servicecatalog.k8s.io "elasticsearchdb" deleted
$ svcat deprovision elasticsearchdb --namespace demo
deleted elasticsearchdb
To cleanup the cluster, just uninstall the broker. It’ll delete the ClusterServiceBroker
resource. Then service catalog controller automatically deletes all ClusterServiceClass
and ClusterServicePlan
resources that came from that broker.
$ kubectl get clusterserviceclasses
No resources found.
$ svcat get classes
NAME NAMESPACE DESCRIPTION
+------+-----------+-------------+