This tutorial shows you how to use Kubernetes secrets to deliver credentials to your application. When you’re done, you’ll be able to deploy far more complicated apps to your cluster. Your apps will be able to access the full power of the IBM Cloud catalog, allowing you to extend your Kubernatorial dominance.

Here’s what you’ll do in this tutorial:

  1. Set up — create services, Docker images, Kubernetes clusters, and other useful things.
  2. Create a YAML file that contains the credentials your chatbot app needs.
  3. Create a Kubernetes secret from that YAML file.
  4. Create a YAML file that defines a Kubernetes deployment for your chatbot app.
  5. Deploy your chatbot app to Kubernetes and create a service that exposes your app to the world.

Along the way you’ll also take a look at the Kubernetes dashboard.

As always, we hope you’ll follow along with the exercises here. The goal is for this tutorial to stand on its own, but you can find background on the concepts presented here in the following videos:

Setting up shop

You’ll need to have all of these things created, installed, configured, and running by the end of this section:

  • The source code of the sample app
  • An instance of the Watson conversation service
  • IBM Cloud (bx), Docker, and Kubernetes tools
  • A Docker image built from the code you cloned
  • That Docker image uploaded to the IBM Cloud
  • A Kubernetes cluster running in your IBM Cloud account (or your IBM Cloud Lite account, as the case may be)
  • The kubectl command configured to point to your cluster

It’s entirely possible you have all of these things already. However, we include some basic instructions here if you need them. The starting point is the Rameses II chatbot app built in the chatbot videos mentioned above. If you have some other app that uses an IBM Cloud service that requires credentials, by all means use your app instead.

Getting the source code of the sample app

The first step is to clone the github repo at https://github.com/IBM/conversation-simple-k8s:

Importing the github repo for the simple chatbot application

At a command line, type the following commands:

  1. git clone https://github.com/IBM/conversation-simple-k8s
  2. cd conversation-simple-k8s

This code is based on the conversation-simple app built by the Watson conversation team, with a Dockerfile and some YAML and JSON files added for convenience.

Many thanks to the Watson team for developing, sharing, and maintaining this app.

Creating an instance of the Watson conversation service

To create an instance of the Watson conversation service, go to the IBM Cloud catalog (visit cloud.ibm.com and click “Catalog” at the top of the page). Type conversation in the search bar. You’ll see the Conversation service in the Watson section:

The Watson Conversation service in the IBM Cloud catalog

Click the catalog item to get started. On the next panel you’ll see the name of the new service at the top. You can take the existing name (which will be something like Conversation-n1) or type in something more memorable. Scroll down to the Pricing Plans section and make sure the Lite plan (a.k.a. the “free” plan) is selected:

The Lite pricing plan for the service

Click Create to create your new conversation service. When the service is created, click the Launch tool button to open the workspace:

The management screen for the conversation service

(Notice that the conversation service is named dwtv-convo instead of the far less memorable Conversation-n1.)

You’ll see the Workspaces panel:

The workspaces panel

Now import all of the intents, entities, and dialogs for the chatbot from the file RoyalValet.json in the repo you cloned earlier. In your workspace, click the Import icon:

The import icon in the conversation service workspace

Select the file from your machine, make sure the Import Everything radio button is checked, then click Import:

Importing a workspace

This adds to your workspace a complete chatbot named Royal Valet.

Installing tools

You’ve probably done most of these already, but make sure you go through the following steps:

  • Download and install the Node.js runtime and the NPM package manager from nodejs.org/#download.
  • Install the IBM Cloud (bx) command-line client, then run the following commands to add support for containers: bx plugin install container-registry -r "IBM Cloud" bx plugin install container-service -r "IBM Cloud" Once you’ve installed the plugins, run bx login and bx cr login to log in to the IBM Cloud and its container registry.
  • Run the command bx cr namespace-add [name] to create a namespace. The name you use has to be unique across the IBM Cloud region you’re using. (See the developerWorks Mailbag video on creating a Kubernetes cluster around the 2:40 mark for more information on namespaces.)
  • Visit docker.com/community-edition to download and install the Docker Community Edition for your platform.
  • Finally, install the Kubernetes kubectl command-line tool. You’ll configure the tool once you have a Kubernetes cluster running in the IBM Cloud.

Building and uploading a Docker image

The repo you cloned has a Dockerfile (and a .dockerignore file too, for that matter) to make it easy to create a Docker image from the code. First, make sure the Docker runtime is running on your machine. How you do that depends on your platform, so see the Docker documentation if you need details.

With Docker running, type the following command in the conversation-simple-k8s directory:

docker build -t registry.ng.bluemix.net/[your namespace]/conversation:v1 .

Note that the ng part of the registry name will be different depending IBM Cloud data center you’re using. For example, if your cluster is in Germany, that part of the registry name will be eu-de. (Keep that in mind whenever you see ng in the rest of this article.) The namespace here is the namespace you created with the bx cr namespace-add command earlier.

Finally, be sure to include the period at the end of the command; that tells Docker to look for the Dockerfile in the current directory. The start of the build looks like this:

Starting the Docker build command

When the build finishes, run the following command to push it into your container registry in the IBM Cloud:

docker push registry.ng.bluemix.net/[your namespace]/conversation:v1

You’ll see something like this:

Pushing a Docker image to the IBM Cloud

Now your Docker image is built and uploaded to the IBM Cloud. The next step is to create a Kubernetes cluster for your image.

Creating a Kubernetes cluster in the IBM Cloud

To use a Kubernetes secret, of course, you’ll need a Kubernetes cluster. That’s what you’ll create now. From the IBM Cloud console, go to the menu in the upper left-hand corner and click Containers:

The Containers menu item

Next, click the Create cluster button in the middle of the page:

The 'Create cluster' button

Finally, give your cluster a name (in the example below, the cluster is named “Mailbag”) and make sure you’ve checked the Lite plan (a.k.a. the “free” plan), then click the Create Cluster button on the right-hand side of the panel:

The cluster creation panel

It will take several minutes for the cluster to be provisioned and started. While that’s happening, feel free to stand up and stretch, get a cup of coffee, or visit with your neighbors. When the cluster is up and running, you’ll see it in your IBM Cloud dashboard:

A running Kubernetes cluster in the IBM Cloud dashboard

Configuring kubectl

The last bit of setup work is to configure the kubectl command to point to your Kubernetes cluster in the IBM Cloud. Once configured, anytime you use kubectl, it interacts with your cluster. Run the following two commands to set everything up:

  1. bx cs cluster-config Mailbag
    This uses the IBM Cloud container service plugin to get the configuration details of the Mailbag cluster you created earlier. It returns a command that you can copy and paste to set the KUBECONFIG environment variable.
  2. [Set the KUBECONFIG variable]
    This command is in the output from the previous command. It is an export statement on Linux and the Mac, and a set command in the Windows command line; it returns the information you need for an $env:KUBECONFIG definition in Windows PowerShell.

These two commands look like this on Linux or the Mac:

Defining the KUBECONFIG environment variable

Notice that the export command is merely a cut and paste of the output of the bx cs cluster-config command. Also, be aware that this only configures kubectl for the current command line. If you switch to another window, you’ll need to configure kubectl in that window as well.

Creating the YAML file for your credentials

Okay, enough setup already. Hopefully you had most of those steps done already or knew how to do them without much trouble. Your next task is to create the YAML file for your credentials. Open the file convo-secret.yaml from the repo you cloned:

The initial convo-secret.yaml file

The trick here, as you probably guessed, is to fill in the WORKSPACE_ID, CONVERSATION_USERNAME, and CONVERSATION_PASSWORD values correctly. However, there’s one complication: Those values have to be base64-encoded. And of course, you have to get the values before you can encode them.

To get the WORKSPACE_ID, go back to the conversation workspace, click the three dots icon on the tile for your chatbot, and select View details:

Viewing the details of your chatbot

The tile shows you the workspace ID:

The workspace ID for your chatbot

Click the copy icon to put the value on the clipboard, then use a base64 encoding tool to convert the value. On Linux and the Mac, the command looks like this:

echo -n “c37281df-ea7e-3821-dd7f-c2758fab490c” | base64echo -n "c37281df-ea7e-3821-dd7f-c2758fab490c" | base64

This returns the value you need for the convo-secret.yaml file:

The output of the base64 command

In this example (which is not a valid workspace ID), you would paste the value YzM3MjgxZGYtZWE3ZS0zODIxLWRkN2YtYzI3NThmYWI0OTBj into the convo-secret.yaml file.

Two things to keep in mind: First of all, the -n-n parameter of the echo command is required. This stops echo from adding a newline to the end of the text in double quotes. If you omit this parameter, the encoded value won’t work. Second, if you’re on Windows, use one of the base64 encoding tools that are available on the web. Windows includes certutil, a tool that can do base64 encoding — but it won’t work because it always adds a newline.

That takes care of the first credential you need. Now it’s time to get the CONVERSATION_USERNAME and CONVERSATION_PASSWORD values from the conversation service. Go to the dashboard at cloud.ibm.com, find your conversation service in the list, and click it to open the service’s management page. Click the Service credentials tab on the left:

The service credentials tab

You should see a list of credentials. If you don’t have any credentials, click the New credential button to create one. Next, click View credentials to see the values you need:

The values for a particular credential

Now take those two values, base64 encode them, and paste the encoded values into the YAML file. The final version of convo-secret.yaml should look something like this:

The YAML file with base64-encoded values

With the credentials filled in, it’s time to create the secret.

Creating a Kubernetes secret

Type kubectl create -f convo-secret.yaml at the command line.

Exploring the Kubernetes dashboard

Wait, that was a whole section? That’s all it takes to create the secret?

Well, yes. In retrospect, your author should have put more thought into the outline. But let’s press on.

When you’re working with Kubernetes, the Kubernetes dashboard is an extremely useful tool for figuring out what’s going on in your cluster. (It is also extremely useful for figuring out what’s going wrong in your cluster.) To start it, type:

kubectl proxy

With the proxy running, open localhost:8001/ui in your browser. You’ll most likely see this login prompt:

The Kubernetes dashboard login prompt

Go to the command line and type kubectl config view to get the token you need to log in. The YAML output contains a field named id-token:

The id-token field in the YAML output of kubectl config view

Copy the value of the token to the clipboard. In your browser, click the Token radio button, paste in the token, and click SIGN IN:

Signing in to the Kubernetes dashboard

After you log in, you’ll see a dashboard that looks something like this:

The Kubernetes dashboard

If you scroll to the bottom of the list on the left and click Secrets, you’ll see a list of secrets. Click on the name of the secret you just created:

A secret in the Kubernetes dashboard

You can find the details of the deployments, pods, services, and lots of other things inside your cluster. Get to know the dashboard. The dashboard is your friend.

Creating the YAML file to deploy your app

Continuing its tradition of usefulness, the repo you cloned has a file called convo-deployment.yaml which already has most of the YAML you need. Open it in your favorite editor:

The convo-deployment.yaml file

This defines the Kubernetes deployment that you’ll use to deploy your Docker image. There are a couple of things worth noting here. First of all, this file creates a new deployment named convo and a new container named convo-container, and it is based on the Docker image registry.ng.bluemix.net/mailbag/conversation:v1. You’ll need to change that image name appropriately: ng should be different if you’re not using the US South data center, and mailbag should be replaced with your namespace.

The second thing is that your container exposes port 3000. The node app inside the Docker image listens on this port. If your code does things differently, you’ll need to change this value.

Finally, the env section of the file defines three environment variables that will be available to your app when it starts. The syntax here is pretty straightforward. There are three environment variables (named WORKSPACE_ID, CONVERSATION_USERNAME, and CONVERSATION_PASSWORD, as you’d expect), each one gets its value from a Kubernetes secret named convo-secret and each one is mapped to a particular key in the secret.

Deploying your app to your Kubernetes cluster

You’re almost there! The first thing to do, as you would expect, is to tell kubectl to process the file you just updated:

kubectl create -f convo-deployment

The rest of the work of deploying and exposing your code is done exactly the same way for any app, whether it uses credentials or not. You’ve set up the Kubernetes secret, so deployment is straightforward. Type this exhausting command:

kubectl expose deployment convo --type=NodePort --port=3000 --name=convo-service

This creates a new service (cleverly named convo-service) that your users can use to access your code. The name convo here is the name of the deployment from the YAML file, and 3000 is your app’s port number. We won’t cover what a NodePort is here; suffice to say, it’s your only option with a free cluster in an IBM Cloud Lite account.

When Kubernetes creates your service, it creates a proxy that assigns a randomly generated port number to your app. To find that port number, use kubectl describe service convo-service:

The port number for the service

In this example, Kubernetes has exposed port 31361 to the world, and anything that comes in on that port will be passed on to the service on port 3000. The last thing you need to know is the IP address of the cluster itself. Kubernetes doesn’t know anything about the outside world, so you have to use the bx command for that. bx cs workers Mailbag gives you the information you want:

The IP address of the Kubernetes cluster

The IP address of the cluster is 184.172.247.201. If you open your browser to http://184.172.247.201:31361, you should see your app:

The deployed app running in the Kubernetes cluster

Summary

Using Kubernetes secrets allows you to set up the environment variables your code needs before it starts. Secrets are elegant, straightforward, and easy to create and manage (except for the base64 part, anyway). Now you’re ready to load up your Kubernetes clusters with apps that use any number or combination of services from the IBM Cloud platform. Have fun!