copyright | lastupdated | keywords | subcollection | ||
---|---|---|---|---|---|
|
2021-03-22 |
kubernetes, iks, helm, integrations, helm chart |
containers |
{:DomainName: data-hd-keyref="APPDomain"} {:DomainName: data-hd-keyref="DomainName"} {:android: data-hd-operatingsystem="android"} {:api: .ph data-hd-interface='api'} {:apikey: data-credential-placeholder='apikey'} {:app_key: data-hd-keyref="app_key"} {:app_name: data-hd-keyref="app_name"} {:app_secret: data-hd-keyref="app_secret"} {:app_url: data-hd-keyref="app_url"} {:authenticated-content: .authenticated-content} {:beta: .beta} {:c#: data-hd-programlang="c#"} {:cli: .ph data-hd-interface='cli'} {:codeblock: .codeblock} {:curl: .ph data-hd-programlang='curl'} {:deprecated: .deprecated} {:dotnet-standard: .ph data-hd-programlang='dotnet-standard'} {:download: .download} {:external: target="_blank" .external} {:faq: data-hd-content-type='faq'} {:fuzzybunny: .ph data-hd-programlang='fuzzybunny'} {:generic: data-hd-operatingsystem="generic"} {:generic: data-hd-programlang="generic"} {:gif: data-image-type='gif'} {:go: .ph data-hd-programlang='go'} {:help: data-hd-content-type='help'} {:hide-dashboard: .hide-dashboard} {:hide-in-docs: .hide-in-docs} {:important: .important} {:ios: data-hd-operatingsystem="ios"} {:java: .ph data-hd-programlang='java'} {:java: data-hd-programlang="java"} {:javascript: .ph data-hd-programlang='javascript'} {:javascript: data-hd-programlang="javascript"} {:new_window: target="_blank"} {:note .note} {:note: .note} {:objectc data-hd-programlang="objectc"} {:org_name: data-hd-keyref="org_name"} {:php: data-hd-programlang="php"} {:pre: .pre} {:preview: .preview} {:python: .ph data-hd-programlang='python'} {:python: data-hd-programlang="python"} {:route: data-hd-keyref="route"} {:row-headers: .row-headers} {:ruby: .ph data-hd-programlang='ruby'} {:ruby: data-hd-programlang="ruby"} {:runtime: architecture="runtime"} {:runtimeIcon: .runtimeIcon} {:runtimeIconList: .runtimeIconList} {:runtimeLink: .runtimeLink} {:runtimeTitle: .runtimeTitle} {:screen: .screen} {:script: data-hd-video='script'} {:service: architecture="service"} {:service_instance_name: data-hd-keyref="service_instance_name"} {:service_name: data-hd-keyref="service_name"} {:shortdesc: .shortdesc} {:space_name: data-hd-keyref="space_name"} {:step: data-tutorial-type='step'} {:subsection: outputclass="subsection"} {:support: data-reuse='support'} {:swift: .ph data-hd-programlang='swift'} {:swift: data-hd-programlang="swift"} {:table: .aria-labeledby="caption"} {:term: .term} {:tip: .tip} {:tooling-url: data-tooling-url-placeholder='tooling-url'} {:troubleshoot: data-hd-content-type='troubleshoot'} {:tsCauses: .tsCauses} {:tsResolve: .tsResolve} {:tsSymptoms: .tsSymptoms} {:tutorial: data-hd-content-type='tutorial'} {:ui: .ph data-hd-interface='ui'} {:unity: .ph data-hd-programlang='unity'} {:url: data-credential-placeholder='url'} {:user_ID: data-hd-keyref="user_ID"} {:vbnet: .ph data-hd-programlang='vb.net'} {:video: .video}
{: #service-binding}
Add {{site.data.keyword.cloud_notm}} services to enhance your Kubernetes cluster with extra capabilities in areas such as {{site.data.keyword.watson}} AI, data, security, and Internet of Things (IoT). {: shortdesc}
What types of services can I bind to my cluster?
When you add {{site.data.keyword.cloud_notm}} services to your cluster, you can choose between services that are enabled for {{site.data.keyword.cloud_notm}} Identity and Access Management (IAM) and services that are based on Cloud Foundry. IAM-enabled services offer more granular access control and can be managed in an {{site.data.keyword.cloud_notm}} resource group. Cloud Foundry services must be added to a Cloud Foundry organization and space, and cannot be added to a resource group. To control access to your Cloud Foundry service instance, you use Cloud Foundry roles. For more information about IAM-enabled services and Cloud Foundry services, see Managing access to resources.
To find a list of supported {{site.data.keyword.cloud_notm}} services, see the {{site.data.keyword.cloud_notm}} catalog.
What is {{site.data.keyword.cloud_notm}} service binding?
Service binding is a quick way to create service credentials for an {{site.data.keyword.cloud_notm}} service by using its public cloud service endpoint and storing these credentials in a Kubernetes secret in your cluster. To bind a service to your cluster, you must provision an instance of the service first. Then, you use the ibmcloud ks cluster service bind
command to create the service credentials and the Kubernetes secret. The Kubernetes secret is automatically encrypted in etcd to protect your data.
Want to make your secrets even more secured? Ask your cluster admin to enable a key management service provider in your cluster to encrypt new and existing secrets, such as the secret that stores the credentials of your {{site.data.keyword.cloud_notm}} service instances. {: tip}
I already have an {{site.data.keyword.cloud_notm}} service. Can I still use {{site.data.keyword.cloud_notm}} service binding?
Yes, you can use services that meet naming requirements and reuse the service credentials.
- Naming: Make sure that the service name is in the following regex format. Example permitted names are
myservice
orexample.com
. Unallowed characters include spaces and underscores.{: screen}[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
- Service credentials: To use your existing service credentials, specify the
--key
flag in theibmcloud ks cluster service bind
command and provide the name of your service credentials. {{site.data.keyword.cloud_notm}} service binding automatically creates a Kubernetes secret with your existing service credentials.
What if I want to use service credentials that use the private cloud service endpoint?
By default, the ibmcloud ks cluster service bind
command creates service credentials with the public cloud service endpoint. To use the private cloud service endpoint, you must manually create service credentials for your service that use the private cloud service endpoint, and then use the --key
option to specify the name of the existing service credentials.
Your service might not yet support private cloud service endpoints. If you have a private-only cluster, you must use service credentials that use the private cloud service endpoint, or open up the public IP address and port to connect to your service.
Can I use all {{site.data.keyword.cloud_notm}} services in my cluster?
You can use service binding only for services that support service keys so that the service credentials can automatically be created and stored in a Kubernetes secret. To find a list of services that support service keys, see Enabling external apps to use {{site.data.keyword.cloud_notm}} services.
Services that do not support service keys usually provide an API that you can use in your app. The service binding method does not automatically set up API access for your app. Make sure to review the API documentation of your service and implement the API interface in your app.
{: #bind-services}
Use {{site.data.keyword.cloud_notm}} service binding to automatically create service credentials for your {{site.data.keyword.cloud_notm}} services and store these credentials in a Kubernetes secret. {: shortdesc}
Before you begin:
- Ensure you have the following roles:
- Editor or Administrator {{site.data.keyword.cloud_notm}} IAM platform access role for the cluster where you want to bind a service
- Writer or Manager {{site.data.keyword.cloud_notm}} IAM service access role for the Kubernetes namespace where you want to bind the service
- For Cloud Foundry services: Developer Cloud Foundry role for the space where you want to provision the service
- Log in to your account. If applicable, target the appropriate resource group. Set the context for your cluster.
To add an {{site.data.keyword.cloud_notm}} service to your cluster:
-
Create an instance of the {{site.data.keyword.cloud_notm}} service.
- Some {{site.data.keyword.cloud_notm}} services are available only in select regions. You can bind a service to your cluster only if the service is available in the same region as your cluster. In addition, if you want to create a service instance in the Washington DC zone, you must use the CLI.
- For IAM-enabled services: You must create the service instance in the same resource group as your cluster. A service can be created in only one resource group that you can't change afterward.
- Make sure that the service name is in the following regex format. Example permitted names are
myservice
orexample.com
. Unallowed characters include spaces and underscores.{: screen}[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
-
Check the type of service that you created and make note of the service instance Name.
-
Cloud Foundry services:
ibmcloud service list
{: pre}
Example output:
name service plan bound apps last operation <cf_service_instance_name> <service_name> spark create succeeded
{: screen}
-
-
{{site.data.keyword.cloud_notm}} IAM-enabled services:
ibmcloud resource service-instances
{: pre}
Example output:
Name Location State Type Tags <iam_service_instance_name> <region> active service_instance
{: screen}
You can also see the different service types in your {{site.data.keyword.cloud_notm}} dashboard as Cloud Foundry Services and Services.
-
Identify the cluster namespace that you want to use to add your service.
kubectl get namespaces
{: pre}
-
Bind the service to your cluster to create service credentials for your service that use the public cloud service endpoint and store the credentials in a Kubernetes secret. If you have existing service credentials, use the
--key
flag to specify the name of the credentials. For IAM-enabled services, the credentials are automatically created with the Writer service access role, but you can use the--role
flag to specify a different service access role. If you use the--key
flag, do not include the--role
flag.If your service supports private cloud service endpoints, you can manually create the service credentials with the private cloud service endpoint, and then use the
--key
flag to specify the name of your credentials. {: tip}ibmcloud ks cluster service bind --cluster <cluster_name_or_ID> --namespace <namespace> --service <service_instance_name> [--key <service_instance_key>] [--role <IAM_service_role>]
{: pre}
When the creation of the service credentials is successful, a Kubernetes secret with the name
binding-<service_instance_name>
is created.Example output:
ibmcloud ks cluster service bind --cluster mycluster --namespace mynamespace --service cleardb Binding service instance to namespace... OK Namespace: mynamespace Secret name: binding-<service_instance_name>
{: screen}
-
Verify the service credentials in your Kubernetes secret.
-
Get the details of the secret and note the binding value. The binding value is base64 encoded and holds the credentials for your service instance in JSON format.
kubectl get secrets binding-<service_instance_name> --namespace=<namespace> -o yaml
{: pre}
Example output:
apiVersion: v1 data: binding: <binding> kind: Secret metadata: annotations: service-instance-id: 1111aaaa-a1aa-1aa1-1a11-111aa111aa11 service-key-id: 2b22bb2b-222b-2bb2-2b22-b22222bb2222 creationTimestamp: 2018-08-07T20:47:14Z name: binding-<service_instance_name> namespace: <namespace> resourceVersion: "6145900" selfLink: /api/v1/namespaces/default/secrets/binding-mycloudant uid: 33333c33-3c33-33c3-cc33-cc33333333c type: Opaque
{: screen}
-
Decode the binding value.
echo "<binding>" | base64 -D
{: pre}
Example output:
{"apikey":"<API_key>","host":"<ID_string>-bluemix.cloudant.com","iam_apikey_description":"Auto generated apikey during resource-key operation for Instance - crn:v1:bluemix:public:cloudantnosqldb:us-south:a/<ID_string>::","iam_apikey_name":"auto-generated-apikey-<ID_string>","iam_role_crn":"crn:v1:bluemix:public:iam::::serviceRole:Writer","iam_serviceid_crn":"crn:v1:bluemix:public:iam-identity::a/1234567890brasge5htn2ec098::serviceid:ServiceId-<ID_string>","password":"<ID_string>","port":443,"url":"https://<ID_string>-bluemix.cloudant.com","username":"123b45da-9ce1-4c24-ab12-rinwnwub1294-bluemix"}
{: screen}
-
Optional: Compare the service credentials that you decoded in the previous step with the service credentials that you find for your service instance in the {{site.data.keyword.cloud_notm}} dashboard.
-
-
Now that your service is bound to your cluster, you must configure your app to access the service credentials in the Kubernetes secret.
{: #adding_app}
To access an {{site.data.keyword.cloud_notm}} service instance from your app, you must make the service credentials that are stored in the Kubernetes secret available to your app. {: shortdesc}
The credentials of a service instance are base64 encoded and stored inside your secret in JSON format. To access the data in your secret, choose among the following options:
Before you begin:
- Ensure you have the Writer or Manager {{site.data.keyword.cloud_notm}} IAM service access role for the
kube-system
namespace. - Log in to your account. If applicable, target the appropriate resource group. Set the context for your cluster.
- Add an {{site.data.keyword.cloud_notm}} service to your cluster.
{: #mount_secret}
When you mount the secret as a volume to your pod, a file that is named binding
is stored in the volume mount directory. The binding
file in JSON format includes all the information and credentials that you need to access the {{site.data.keyword.cloud_notm}} service.
{: shortdesc}
-
List available secrets in your cluster and note the name of your secret. Look for a secret of type Opaque. If multiple secrets exist, contact your cluster administrator to identify the correct service secret.
kubectl get secrets
{: pre}
Example output:
NAME TYPE DATA AGE binding-<service_instance_name> Opaque 1 3m
{: screen}
-
Create a YAML file for your Kubernetes deployment and mount the secret as a volume to your pod.
apiVersion: apps/v1 kind: Deployment metadata: labels: app: secret-test name: secret-test namespace: <my_namespace> spec: selector: matchLabels: app: secret-test replicas: 1 template: metadata: labels: app: secret-test spec: containers: - image: icr.io/ibm/liberty:latest name: secret-test volumeMounts: - mountPath: <mount_path> name: <volume_name> volumes: - name: <volume_name> secret: defaultMode: 420 secretName: binding-<service_instance_name>
{: codeblock}
Understanding the YAML file components Parameter Description volumeMounts.mountPath
The absolute path of the directory to where the volume is mounted inside the container. volumeMounts.name
volumes.name
The name of the volume to mount to your pod. secret.defaultMode
The read and write permissions on the secret. Use `420` to set read-only permissions. secret.secretName
The name of the secret that you noted in the previous step. -
Create the pod and mount the secret as a volume.
kubectl apply -f secret-test.yaml
{: pre}
-
Verify that the pod is created.
kubectl get pods
{: pre}
Example CLI output:
NAME READY STATUS RESTARTS AGE secret-test-1111454598-gfx32 1/1 Running 0 1m
{: screen}
-
Access the service credentials.
-
Log in to your pod.
kubectl exec <pod_name> -it bash
{: pre}
-
Navigate to your volume mount path that you defined earlier and list the files in your volume mount path.
cd <volume_mountpath> && ls
{: pre}
Example output:
binding
{: screen}
The
binding
file includes the service credentials that you stored in the Kubernetes secret. -
View the service credentials. The credentials are stored as key value pairs in JSON format.
cat binding
{: pre}
Example output:
{"apikey":"<API_key>","host":"<ID_string>-bluemix.cloudant.com","iam_apikey_description":"Auto generated apikey during resource-key operation for Instance - crn:v1:bluemix:public:cloudantnosqldb:us-south:a/<ID_string>:<ID_string>::","iam_apikey_name":"auto-generated-apikey-<ID_string>","iam_role_crn":"crn:v1:bluemix:public:iam::::serviceRole:Writer","iam_serviceid_crn":"crn:v1:bluemix:public:iam-identity::a/<ID_string>::serviceid:ServiceId-<ID_string>","password":"<ID_string>","port":443,"url":"https://<ID_string>-bluemix.cloudant.com","username":"123b45da-9ce1-4c24-ab12-rinwnwub1294-bluemix"}
{: screen}
-
Configure your app to parse the JSON content and retrieve the information that you need to access your service.
-
{: #reference_secret}
You can add the service credentials and other key value pairs from your Kubernetes secret as environment variables to your deployment. {: shortdesc}
-
List available secrets in your cluster and note the name of your secret. Look for a secret of type Opaque. If multiple secrets exist, contact your cluster administrator to identify the correct service secret.
kubectl get secrets
{: pre}
Example output:
NAME TYPE DATA AGE binding-<service_instance_name> Opaque 1 3m
{: screen}
-
Get the details of your secret to find potential key value pairs that you can reference as environment variables in your pod. The service credentials are stored in the
binding
key of your secret.kubectl get secrets binding-<service_instance_name> --namespace=<namespace> -o yaml
{: pre}
Example output:
apiVersion: v1 data: binding: <binding> kind: Secret metadata: annotations: service-instance-id: 7123acde-c3ef-4ba2-8c52-439ac007fa70 service-key-id: 9h30dh8a-023f-4cf4-9d96-d12345ec7890 creationTimestamp: 2018-08-07T20:47:14Z name: binding-<service_instance_name> namespace: <namespace> resourceVersion: "6145900" selfLink: /api/v1/namespaces/default/secrets/binding-mycloudant uid: 12345a31-9a83-11e8-ba83-cd49014748f type: Opaque
{: screen}
-
Create a YAML file for your Kubernetes deployment and specify an environment variable that references the
binding
key.apiVersion: apps/v1 kind: Deployment metadata: labels: app: secret-test name: secret-test namespace: <my_namespace> spec: selector: matchLabels: app: secret-test template: metadata: labels: app: secret-test spec: containers: - image: icr.io/ibm/liberty:latest name: secret-test env: - name: BINDING valueFrom: secretKeyRef: name: binding-<service_instance_name> key: binding
{: codeblock}
Understanding the YAML file components Parameter Description containers.env.name
The name of your environment variable. env.valueFrom.secretKeyRef.name
The name of the secret that you noted in the previous step. env.valueFrom.secretKeyRef.key
The key that is part of your secret and that you want to reference in your environment variable. To reference the service credentials, you must use the binding key. -
Create the pod that references the
binding
key of your secret as an environment variable.kubectl apply -f secret-test.yaml
{: pre}
-
Verify that the pod is created.
kubectl get pods
{: pre}
Example CLI output:
NAME READY STATUS RESTARTS AGE secret-test-1111454598-gfx32 1/1 Running 0 1m
{: screen}
-
Verify that the environment variable is set correctly.
-
Log in to your pod.
kubectl exec <pod_name> -it bash
{: pre}
-
List all environment variables in the pod.
env
{: pre}
Example output:
BINDING={"apikey":"<API_key>","host":"<ID_string>-bluemix.cloudant.com","iam_apikey_description":"Auto generated apikey during resource-key operation for Instance - crn:v1:bluemix:public:cloudantnosqldb:us-south:a/<ID_string>::","iam_apikey_name":"auto-generated-apikey-<ID_string>","iam_role_crn":"crn:v1:bluemix:public:iam::::serviceRole:Writer","iam_serviceid_crn":"crn:v1:bluemix:public:iam-identity::a/1234567890brasge5htn2ec098::serviceid:ServiceId-<ID_string>","password":"<password>","port":443,"url":"https://<ID_string>-bluemix.cloudant.com","username":"<ID_string>-bluemix"}
{: screen}
-
-
Configure your app to read the environment variable and to parse the JSON content to retrieve the information that you need to access your service.
Example code in Python:
if os.environ.get('BINDING'): credentials = json.loads(os.environ.get('BINDING'))
{: codeblock}
-
Optional: As a precaution, add error handling to your app in case that the
BINDING
environment variable is not set properly.Example code in Java:
if (System.getenv("BINDING") == null) { throw new RuntimeException("Environment variable 'SECRET' is not set!"); }
{: codeblock}
Example code in Node.js:
if (!process.env.BINDING) { console.error('ENVIRONMENT variable "BINDING" is not set!'); process.exit(1); }
{: codeblock}
{: #unbind-service}
If you do not want to use an {{site.data.keyword.cloud_notm}} service that you bound to your cluster, you can manually remove the Kubernetes secret and the pods that access the secret from your cluster. {: shortdesc}
-
List the services that are bound to your cluster and note the name of your service and the namespace that the service is bound to.
ibmcloud ks cluster service ls --cluster
{: pre}
Example output:
OK Service Instance GUID Key Namespace myservice 12345ab1-1234-1abc-a12b-12abc12a12ab kube-a1a12abcd12a123abc1a12ab1a1234ab7.abcdefg0p1abcd123lgg.default default
{: screen}
-
List the Kubernetes secrets in the namespace that your service is bound to and look for the secret with a name that follows the
binding-<service_name>
format.kubectl get secrets -n <namespace> | grep Opaque
{: pre}
Example output:
binding-myservice Opaque 1 3d23h
{: screen}
-
Retrieve all the pods that access the secret.
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.volumes[*]}{.secret.secretName}{" "}{end}{end}' | grep "<secret_name>"
{: pre}
If your CLI output is empty, no pods exist in your cluster that mount the secret.
-
If you have pods that mount the secret, either remove the pod or the deployment that manages the pod, or update the pod and deployment YAML to use a different secret instead.
-
To remove a pod or deployment:
kubectl delete pod <pod_name> -n <namespace>
{: pre}
kubectl delete deployment <deployment_name> -n <namespace>
{: pre}
-
To update an existing pod or deployment:
-
Get the pod or deployment YAML file.
kubectl get pod <pod_name> -o yaml
{: pre}
kubectl get deployment <deployment_name> -o yaml
{: pre}
-
Copy the YAML file and in the
spec.volumes
section, change the name of the secret that you want to use. -
Apply the change in your cluster.
kubectl apply -f pod.yaml
{: pre}
kubectl apply -f deployment.yaml
{: pre}
-
Verify that a new pod is created with the updated volume specification.
kubectl get pods
{: pre}
kubectl describe pod <pod_name>
{: pre}
-
-
-
Remove the secret.
kubectl delete secret <secret_name> -n <namespace>
{: pre}
-
Verify that your secret is removed.
kubectl get secrets -n <namespace>
{: pre}
-
Optional. Remove the {{site.data.keyword.cloud_notm}} service instance.
-
{{site.data.keyword.cloud_notm}} IAM-enabled services:
ibmcloud resource service-instance-delete <service_name>
{: pre}
-
Cloud Foundry services:
ibmcloud service delete <service_name>
{: pre}
-