This document contains instructions for deploying the sample service broker to a Kubernetes cluster.
All instructions below assume that the commands are being run from the root of the project repository.
These instructions use the kubectl
CLI to interact with a running Kubernetes cluster.
Follow the kubectl
documentation to install and verify the CLI.
A Kubernetes cluster will be used to deploy the service broker application and register it to the Kubernetes service catalog.
The minikube
project can be used to run a small Kubernetes cluster on a development workstation.
Follow the Kubernetes documentation to install minikube
, start a cluster, and target the cluster with kubectl
.
Pivotal Container Service (PKS) can be used to deploy and manage production-quality Kubernetes clusters on Pivotal Cloud Foundry.
Follow the PKS documentation to install the product, create a cluster, and target the cluster with kubectl
.
Note
|
Ensure that post-deploy scripts have been enabled in PCF Ops Manager as described on the PKS Troubleshooting page. |
Kubernetes support for service brokers via the Open Service Broker API is provided by the Service Catalog project. Follow the project documentation to install the service catalog into your Kubernetes cluster.
An applications deployed to Kubernetes must be packaged into a Docker image using a Docker Engine. Follow the Docker documentation to install Docker and verify the docker
CLI.
The Docker image for the sample service broker must be available in a repository. Public repositories are available from Docker, Google Cloud Platform, Amazon Web Services, and others. If you are using one of these public repositories, use the docker
CLI to log into the repository.
If you are using minikube
to start a Kubernetes cluster, you can use the Docker Engine and repository included with minikube
.
$ eval $(minikube docker-env)
The VMware Harbor product can be used to deploy a Docker registry in the same infrastructure as the Kubernetes clusters deployed by PKS. Follow the product documentation to install Harbor and log in with docker
.
The Gradle build file for the service broker sample project can be used to build a Docker image and push it to a repository.
When using a private Docker repository, the following command can be used to build the image and push it with the default sample
group. This isn’t likely to work with a public Docker repository unless you own the group named sample
in that repository.
$ ./gradlew assemble dockerPush
When using a public Docker repository, provide your repository username to the Gradle command.
$ ./gradlew assemble dockerPush -PdockerGroup=[username]
Create a namespace for the service broker application:
$ kubectl create namespace bookstore-broker namespace "bookstore-broker" created
Deploy the service broker application Docker image and expose the application outside of the container:
$ kubectl create -f deploy/kubernetes/deployment.yml service "bookstore-broker" created deployment "bookstore-broker" created
Show the details of the deployed application:
$ kubectl describe deployment bookstore-broker -n bookstore-broker Name: bookstore-broker Namespace: bookstore-broker Labels: run=bookstore-broker Annotations: deployment.kubernetes.io/revision=1 Selector: run=bookstore-broker Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 1 max unavailable, 1 max surge Pod Template: Labels: run=bookstore-broker Containers: bookstore-broker: Image: sample/bookstore-service-broker:0.0.1.BUILD-SNAPSHOT Port: 8080/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable OldReplicaSets: <none> NewReplicaSet: bookstore-broker-6797f89fcb (1/1 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 48s deployment-controller Scaled up replica set bookstore-broker-6797f89fcb to 1
It may take some time for the application to start. When it has started successfully, the Replicas
row of the output should show 1 available
.
Show the details of the created service:
$ kubectl describe service bookstore-broker -n bookstore-broker Name: bookstore-broker Namespace: bookstore-broker Labels: run=bookstore-broker Annotations: <none> Selector: run=bookstore-broker Type: LoadBalanced IP: 10.107.161.81 LoadBalancer Ingress: 192.168.1.238 Port: <unset> 80/TCP TargetPort: 8080/TCP NodePort: <unset> 32248/TCP Endpoints: 10.8.1.7:8080 Session Affinity: None External Traffic Policy: Cluster Events: <none>
In order to verify that the service broker application is running, you will need some information to construct a URL.
When using minikube
, the following command will show the URL that can be used to access the deployed application:
$ minikube service bookstore-broker -n bookstore-broker --url http://192.168.99.100:31742
Use the provided URL to access the /v2/catalog
endpoint of the service broker application:
$ curl http://192.168.99.100:31742/v2/catalog -u admin:supersecret {"services":[{"id":"bdb1be2e-360b-495c-8115-d7697f9c6a9e","name":"bookstore","description":"A simple book store service","bindable":true,"plan_updateable":false,"plans":[{"id":"b973fb78-82f3-49ef-9b8b-c1876974a6cd","name":"standard","description":"A simple book store plan","free":true}],"tags":["book-store","books","sample"]}]}
Show the details of the service broker application service again:
$ kubectl describe service bookstore-broker -n bookstore-broker Name: bookstore-broker Namespace: bookstore-broker Labels: run=bookstore-broker Annotations: <none> Selector: run=bookstore-broker Type: LoadBalanced IP: 10.107.161.81 LoadBalancer Ingress: 192.168.1.238 Port: <unset> 80/TCP TargetPort: 8080/TCP NodePort: <unset> 32248/TCP Endpoints: 10.8.1.7:8080 Session Affinity: None External Traffic Policy: Cluster Events: <none>
Note the value of the LoadBalancer Ingress
IP address and NodePort
rows. Construct a URL using these two values, and use the this URL to access the /v2/catalog
endpoint of the service broker application:
$ curl http://192.168.1.238:32248/v2/catalog -u admin:supersecret {"services":[{"id":"bdb1be2e-360b-495c-8115-d7697f9c6a9e","name":"bookstore","description":"A simple book store service","bindable":true,"plan_updateable":false,"plans":[{"id":"b973fb78-82f3-49ef-9b8b-c1876974a6cd","name":"standard","description":"A simple book store plan","free":true}],"tags":["book-store","books","sample"]}]}
Now that the application has been deployed and verified, it can be registered to the Service Catalog.
The Open Service Broker API endpoints in the service broker application are secured with a basic auth username and password. Create a Kubernetes secret to store these credentials:
$ kubectl create -f deploy/kubernetes/service-broker-secret.yml secret "bookstore-broker-secret" created
Register the service broker to the Service Catalog:
$ kubectl create -f deploy/kubernetes/service-broker.yml clusterservicebroker "bookstore-broker" created
Show the details of the registration:
$ kubectl describe clusterservicebrokers bookstore-broker Name: bookstore-broker Namespace: Labels: <none> Annotations: <none> API Version: servicecatalog.k8s.io/v1beta1 Kind: ClusterServiceBroker Metadata: Finalizers: kubernetes-incubator/service-catalog Generation: 1 Resource Version: 233 Self Link: /apis/servicecatalog.k8s.io/v1beta1/clusterservicebrokers/bookstore-broker UID: d36778a6-0ab1-11e8-aa16-0242ac110005 Spec: Auth Info: Basic: Secret Ref: Name: bookstore-broker-secret Namespace: bookstore-broker Relist Behavior: Duration Relist Duration: 15m0s Relist Requests: 0 URL: http://bookstore-broker.bookstore-broker.svc.cluster.local Status: Conditions: Message: Successfully fetched catalog entries from broker. Reason: FetchedCatalog Status: "True" Type: Ready Reconciled Generation: 0 Events: <none>
On registration, the Service Catalog will call the service broker application to retrieve the catalog of service provided by the broker. This process might take a while. When this is complete you should see Message: Successfully fetched catalog entries from broker.
in the output from previous command.
Show the list of brokered service offerings advertised by the service broker:
$ kubectl get clusterserviceclasses -o=custom-columns=NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName NAME EXTERNAL NAME bdb1be2e-360b-495c-8115-d7697f9c6a9e bookstore
Show the details of the brokered service offering:
$ kubectl get clusterserviceclasses bdb1be2e-360b-495c-8115-d7697f9c6a9e -o=yaml apiVersion: servicecatalog.k8s.io/v1beta1 kind: ClusterServiceClass metadata: name: bdb1be2e-360b-495c-8115-d7697f9c6a9e resourceVersion: "2147" selfLink: /apis/servicecatalog.k8s.io/v1beta1/clusterserviceclasses/bdb1be2e-360b-495c-8115-d7697f9c6a9e uid: 427af5da-0acb-11e8-aa16-0242ac110005 spec: bindable: true bindingRetrievable: false clusterServiceBrokerName: bookstore-broker description: A simple book store service externalID: bdb1be2e-360b-495c-8115-d7697f9c6a9e externalName: bookstore planUpdatable: false tags: - book-store - books - sample status: removedFromBrokerCatalog: false
Show the list of brokered service plans advertised by the service broker:
$ kubectl get clusterserviceplans -o=custom-columns=NAME:.metadata.name,EXTERNAL\ NAME:.spec.externalName NAME EXTERNAL NAME b973fb78-82f3-49ef-9b8b-c1876974a6cd standard
Show the details of the brokered service plan:
$ kubectl get clusterserviceplans b973fb78-82f3-49ef-9b8b-c1876974a6cd -o yaml apiVersion: servicecatalog.k8s.io/v1beta1 kind: ClusterServicePlan metadata: name: b973fb78-82f3-49ef-9b8b-c1876974a6cd resourceVersion: "2148" selfLink: /apis/servicecatalog.k8s.io/v1beta1/clusterserviceplans/b973fb78-82f3-49ef-9b8b-c1876974a6cd uid: 427ca7e7-0acb-11e8-aa16-0242ac110005 spec: clusterServiceBrokerName: bookstore-broker clusterServiceClassRef: name: bdb1be2e-360b-495c-8115-d7697f9c6a9e description: A simple book store plan externalID: b973fb78-82f3-49ef-9b8b-c1876974a6cd externalName: standard free: true status: removedFromBrokerCatalog: false
Service instances and bindings must be created in a Kubernetes namespace. Create a new namespace for testing:
$ kubectl create namespace test namespace "test" created
Create an instance of a brokered service from the sample service broker:
$ kubectl create -f deploy/kubernetes/service-instance.yml serviceinstance "bookstore-instance" created
Show the details of the created service instance:
$ kubectl describe serviceinstance bookstore-instance -n test Name: bookstore-instance Namespace: test Labels: <none> Annotations: <none> API Version: servicecatalog.k8s.io/v1beta1 Kind: ServiceInstance Metadata: Finalizers: kubernetes-incubator/service-catalog Generation: 1 Resource Version: 2364 Self Link: /apis/servicecatalog.k8s.io/v1beta1/namespaces/test/serviceinstances/bookstore-instance UID: 3f533993-0acd-11e8-aa16-0242ac110005 Spec: Cluster Service Class External Name: bookstore Cluster Service Class Ref: Name: bdb1be2e-360b-495c-8115-d7697f9c6a9e Cluster Service Plan External Name: standard Cluster Service Plan Ref: Name: b973fb78-82f3-49ef-9b8b-c1876974a6cd External ID: b0a7dff9-769f-458c-865f-f8578ad6b740 Parameters: Max: 10 Update Requests: 0 Status: Async Op In Progress: false Conditions: Message: The instance was provisioned successfully Reason: ProvisionedSuccessfully Status: True Type: Ready Deprovision Status: Required External Properties: Cluster Service Plan External ID: b973fb78-82f3-49ef-9b8b-c1876974a6cd Cluster Service Plan External Name: standard Parameter Checksum: 4fa544b50ca7a33fe5e8bc0780f1f36aa0c2c7098242db27bc8a3e21f4b4ab55 Parameters: Max: 10 Orphan Mitigation In Progress: false Reconciled Generation: 1 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ProvisionedSuccessfully 1m service-catalog-controller-manager The instance was provisioned successfully
Create a service binding for the service instance:
$ kubectl create -f deploy/kubernetes/service-binding.yml servicebinding "bookstore-binding" created
Show the details of the created service binding:
$ kubectl describe servicebinding bookstore-binding -n test Name: bookstore-binding Namespace: test Labels: <none> Annotations: <none> API Version: servicecatalog.k8s.io/v1beta1 Kind: ServiceBinding Metadata: Finalizers: kubernetes-incubator/service-catalog Generation: 1 Resource Version: 2427 Self Link: /apis/servicecatalog.k8s.io/v1beta1/namespaces/test/servicebindings/bookstore-binding UID: d2aa53b4-0acd-11e8-aa16-0242ac110005 Spec: External ID: 2464fe07-fc7f-489e-a508-e47370f69eb1 Instance Ref: Name: bookstore-instance Secret Name: bookstore-binding Status: Async Op In Progress: false Conditions: Message: Injected bind result Reason: InjectedBindResult Status: True Type: Ready External Properties: Orphan Mitigation In Progress: false Reconciled Generation: 1 Unbind Status: Required Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal InjectedBindResult 35s service-catalog-controller-manager Injected bind result
Service bindings are exposed via Kubernetes secret objects. Show the details of the secret containing the binding credentials:
$ kubectl get secret bookstore-binding -n test -o yaml apiVersion: v1 data: password: [encoded password] uri: [encoded URI] username: [encoded username] kind: Secret metadata: name: bookstore-binding namespace: test ownerReferences: - apiVersion: servicecatalog.k8s.io/v1beta1 blockOwnerDeletion: true controller: true kind: ServiceBinding name: bookstore-binding uid: 39b3e0c2-2248-11e8-a920-0242ac110002 resourceVersion: "106062" selfLink: /api/v1/namespaces/test/secrets/bookstore-binding uid: 3a4416d8-2248-11e8-95fd-080027d19bb3 type: Opaque
Refer to the Kubernetes documentation to decode the password
, uri
, and username
values.
Note
|
The URI provided in the service binding credentials will only be accessible from within the Kubernetes cluster. |