Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 9575546

Browse files
committed
Lab 7 changes from review
1 parent dca50d3 commit 9575546

File tree

5 files changed

+141
-93
lines changed

5 files changed

+141
-93
lines changed
209 KB
Loading
Loading
330 KB
Loading
161 KB
Loading

workshop/Lab7/README.md

Lines changed: 141 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,68 @@
11
# Lab 7. Connecting to External Storage
2-
This lab configures our nodejs guestbook Application to connect to an external database - outside of the kubernetes cluster in which the guestbook app is deployed. We will be using a managed database service offered on IBM Cloud. The advantages of using a database service is that scaling, security, etc are often taken care of for you, but you can apply this lab to any external database service such as a legacy database you might have running on premise.
2+
This lab configures our nodejs guestbook application to connect to an external database, outside of the kubernetes cluster where the guestbook app is deployed. We will be using a managed database service offered on IBM Cloud, but you can apply the concepts in this lab to connect to any external database service such as a legacy database you might have running on premise.
33

4-
Two options to setting up the database service
5-
- [Approach 1](#Approach-1:-Manually-create-database-service-on-IBM-Cloud-console)
4+
With a managed database service, you can take advantage of the provided service's built features for scaling, security, etc. If you'd rather implement your own database service, check out the previous labs in this workshop.
5+
6+
### Prereqs
7+
8+
1. Before you begin, follow the prereqs in [Lab0](../Lab0/README.md).
9+
10+
1. Clone the repos
11+
```
12+
cd $HOME
13+
git clone https://github.com/IBM/guestbook-nodejs.git guestbook-cloudant
14+
git clone --branch storage https://github.com/IBM/guestbook-nodejs-config.git
15+
cd $HOME/guestbook-nodejs-config/storage/lab1
16+
```
17+
18+
1. Create a new Kubernetes namespace. This will help us avoid conflicts with previous labs. Switch to the new namespace so all subsequent commands will run within that namespace:
19+
20+
```
21+
kubectl create namespace cloudant
22+
kubectl config set-context --current --namespace=cloudant
23+
```
24+
25+
Please choose one of the two options for setting up the database service
26+
- [Approach 1](#Approach-1:-Create-a-database-service-using-the-IBM-Cloud-console)
627
- [Approach 2](#-Approach-2:-Use-the-IBM-Cloud-Operator-to-provision-a-database-instance-on-IBM-Cloud)
728
8-
## Approach 1: Manually create database service on IBM Cloud console
29+
## Approach 1: Create a database service using the IBM Cloud console
930
10-
### Create a Cloudant DB service
11-
In these steps will be using a free `lite` CloudantDB on IBM Cloud using your free IBM Cloud account. [Create an account](https://cloud.ibm.com/registration) if you haven't already.
31+
Follow these steps to create a free `lite` CloudantDB on IBM Cloud using a free IBM Cloud account. [Create an account](https://cloud.ibm.com/registration) if you haven't already.
1232
13-
Navigate to the [IBM Cloud Catalog](https://cloud.ibm.com/catalog). Make sure your personal account in selected in the dropdown in the upper right. Select the Cloudant tile.
33+
Navigate to the [IBM Cloud Catalog](https://cloud.ibm.com/catalog). Make sure your personal account in selected in the dropdown in the upper right. Search for **Cloudant** in the search bar and click the **Cloudant** tile. (Click **Log In** in the upper righthand side if you are not logged in).
1434
1535
![CloudantDB in the Catalog](../.gitbook/assets/catalog-cloudant.png)
1636
17-
Set the instance name to "mycloudant". Ensure the "Lite" plan is selected. Then hit create.
37+
Set the instance name to "mycloudant". Select "IAM and legacy credentials" to **Authentication method**. Ensure the "Lite" plan is selected. Then hit **create**.
1838
1939
![Install CloudantDB from console](../.gitbook/assets/install-cloudant-console.png)
2040
2141
### Create a credential for your CloudantDB service
2242
23-
Locate your credentials in your CloudantDB service on IBM Cloud. From the Cloudant DB service, select **Service Credentials** on the left. Then click the blue **New credential** on the right.
43+
Locate your credentials in your CloudantDB service on IBM Cloud. From the IBM Cloud resource page, search for **mycloudant** to find your Cloudant service.
44+
45+
![cloudant in resource list](../.gitbook/assets/cloudant-in-resource-list.png)
46+
47+
From the Cloudant DB service, select **Service Credentials** on the left. Then click the blue **New credential** on the right.
2448
2549
![create new credentials](../.gitbook/assets/cloudant-service-creds.png)
2650
2751
Select the default name and role (should be `manager`) for the credentials, and click **Create**.
2852
2953
Expand the credential and take note of the **url** parameter. We will be using this value to populate a Kubernetes secret in the next step.
3054
55+
![Cloudant URL](../.gitbook/assets/cloudant-url.png)
56+
3157
### Save your credentials in a Kubernetes `secret`
3258
33-
```
34-
kubectl create secret generic cloudant-binding --from-literal=CLOUDANT_URL=[CLOUDANT_URL]
35-
```
59+
From a terminal where you are connected to your kubernetes cluster, run the following command to save the URL to your cloudant service in your cluster as a secret:
3660
61+
```
62+
kubectl create secret generic binding-cloudant --from-literal=url=[CLOUDANT_URL]
63+
```
3764
38-
Once completed, [skip ahead to the next section](##Next-Steps)
65+
Once completed, [skip ahead to the next section](#Next-Steps)
3966
4067
## Approach 2: Use the IBM Cloud Operator to provision a database instance on IBM Cloud
4168
@@ -45,7 +72,9 @@ With the IBM Cloud Kubernetes Service clusters at version 1.16 and later, the Op
4572
4673
### Create an API Key for your Target Account
4774
48-
We will configure the IBM Cloud Operator to maange resources on your personal IBM Cloud Account. You will be able to create and manage a Cloudant DB lite service that only you will have access to.
75+
We will configure the IBM Cloud Operator to manage resources on your personal IBM Cloud Account. You will be able to create and manage a Cloudant DB lite service that only you will have access to.
76+
77+
Note: The account that your Cloudant service will be created on MAY be different than the account where your Kubernetes account, so please keep that in mind. If you are participating in a workshop with the IBM Developer Advocacy team, we do this to avoid creating multiple lite cloudantDB services on the shared account where all the k8s clusters are running (IBM Cloud accounts are limited to 1 lite instance per service)
4978
5079
1. Login to your personal IBM Cloud account. Use `--sso` if using single-sign-on. Select your personal account when asked upon logging in.
5180
@@ -94,7 +123,7 @@ We will configure the IBM Cloud Operator to maange resources on your personal IB
94123
ibmcloud iam service-api-key-create apikey-ico serviceid-ico
95124
```
96125
97-
1. Set the API key of the service ID as your CLI environment variable. Now, when you run the installation script, the script uses the service ID's API key. The following command is an example for macOS.
126+
1. Set the API key of the service ID as your CLI environment variable. Now, when you run the installation script, the script uses the service ID's API key.
98127
99128
```
100129
export IBMCLOUD_API_KEY=<apikey-ico-value>
@@ -108,11 +137,7 @@ We will configure the IBM Cloud Operator to maange resources on your personal IB
108137
109138
### Installing the IBM Cloud operator
110139
111-
1. Follow the setup steps in [Lab0](../Lab0/README.md) if necessary to point your `kubectl` command-line tool to your Kubernetes cluster.
112-
113-
```shell
114-
ibmcloud login
115-
```
140+
1. If you don't already have `kubectl` configured to point to your cluster, follow the setup steps in [Lab0](../Lab0/README.md) to configure.
116141
117142
1. Target the default resource group that your service ID has privledges to.
118143
@@ -129,13 +154,13 @@ We will configure the IBM Cloud Operator to maange resources on your personal IB
129154
Check that the pod for the IBM Cloud operator is running with:
130155
131156
```text
132-
kubectl get pods --namespace ibm-system
157+
kubectl get pods --namespace ibmcloud-operator-system
133158
```
134159
135160
You should see after a minute or two that the pod for the operator is running:
136161
137162
```console
138-
$ kubectl get pods --all-namespaces
163+
$ kubectl get pods --namespace ibmcloud-operator-system
139164
NAMESPACE NAME READY STATUS RESTARTS AGE
140165
ibmcloud-operator-system ibmcloud-operator-controller-manager-56c8548f89-stzdq 2/2 Running 0 14m
141166
```
@@ -148,7 +173,7 @@ Operators are custom code that uses the Kubernetes API (as a client) to implemen
148173
149174
In addition to the IBM Cloud Operator, there are many operators that can manage resources within your cluster available from the [Operator Hub](https://operatorhub.io). The Operator Hub includes many useful operators including operators that implement database installation, monitoring tools, application development frameworks, application runtimes and more.
150175
151-
Your cluster now has the IBM Cloud operator installed. This operator is able to configure two custom resources in the cluster, a **Service** and a **Binding**. The **Service** defines a specific IBM Cloud service instance type to create, and the **Binding** specifies a named binding of a service instance to a secret in the cluster. For more details about the IBM Cloud operator see the [project repository](https://github.com/IBM/cloud-operators)
176+
Your cluster now has the IBM Cloud operator installed. This operator is able to configure two custom resources in the cluster, a **Service** and a **Binding**. The **Service** defines a specific IBM Cloud service instance type to create, and the **Binding** specifies a named binding of a service instance to a secret in the cluster. For more details about the IBM Cloud operator see the [project repository](https://github.com/IBM/cloud-operators).
152177
153178
<br>
154179
@@ -161,7 +186,7 @@ For an application running within a Kubernetes cluster to be able to access an I
161186
1. Change into the `yaml` directory. apply the `cloudant-ibmcloud.yaml` file.
162187
163188
```console
164-
cd $HOME/kube-storage101/src/yaml
189+
cd $HOME/guestbook-nodejs-config/src/yaml
165190
```
166191
167192
1. Apply the `cloudant-ibmcloud.yaml` file using kubectl. This file defines a **Service** and **Binding** resource:
@@ -192,19 +217,15 @@ For an application running within a Kubernetes cluster to be able to access an I
192217
binding-cloudant Opaque 6 40s
193218
```
194219
195-
With the credentials added to the current namespace, you will be able to deploy guestbook application that uses the analyzer microservice. But first, let's do a little checking of the actions by the IBM Cloud operator.
196-
197220
### Debug
198-
If the credentials have not been created after a few moments, check the logs of the kubernetes object you created.
221+
If the credentials have not been created after a few moments, check the logs of the kubernetes object you created.
199222
200-
```
201-
kubectl describe service.ibmcloud.ibm.com/mycloudant
202-
```
223+
```
224+
kubectl describe service.ibmcloud.ibm.com/mycloudant
225+
```
203226
204227
### Check the IBM Cloud console - verify the Cloudant DB service
205228
206-
You can return to your IBM Cloud console and see that the tone analyzer service was created as specified in the `cloudant-ibmcloud.yaml` resource file.
207-
208229
1. Go back to your IBM Cloud tab in the browser and click on the words **IBM Cloud** on the upper left of the top menu. Now your Dashboard view will show a Services item under the **Resource summary**. Click on the **Services** label, and search for `mycloudant` to find your newly created instance
209230
210231
![Updated Cloud Dashboard](../.gitbook/assets/verify-cloudant-on-console.png)
@@ -265,11 +286,11 @@ Regardless of whether you did approach 1 or approach 2, the end result is the sa
265286

266287
### Create a new database on the CloudantDB service
267288

268-
From your newly created Cloudant service on the IBM Cloud console, click "launch dashboard"
289+
From your newly created Cloudant service on the IBM Cloud console, click **Manage** then **Launch Dashboard**.
269290

270291
![launch cloudant dashboard](../.gitbook/assets/cloudant-launch-dashboard.png)
271292

272-
Use your IBM Credentials to login if necessary. From the Cloudant Dashboard screen, click "Create Database" and give it name, such as "mydatabase"
293+
Use your IBM Credentials to login if necessary. From the Cloudant Dashboard screen, click **Create Database** and give it name, such as "mydatabase". Select **Non-partitioned**, then click **Create**.
273294

274295
![launch cloudant dashboard](../.gitbook/assets/cloudant-create-db.png)
275296

@@ -279,22 +300,21 @@ Remember this name as we will be using it later when we deploy our application.
279300

280301
You will have to make minor changes to the Guestbook nodejs application to read from your newly created CloudantDB service.
281302

282-
Download the guestbook application if you haven't already.
283-
284-
```
285-
git clone https://github.com/IBM/guestbook-nodejs
286-
```
303+
Navigate to your guestbook application:
304+
```
305+
cd guestbook-cloudant/src
306+
```
287307

288308
(Optional) Install the [Loopback connector](https://loopback.io/doc/en/lb2/Cloudant-connector.html) for CloudantDB. This has been done for you already.
289309

290-
```
291-
cd guestbook-nodejs/src
292-
npm install loopback-connector-cloudant --save
293-
```
310+
```
311+
cd guestbook-cloudant/src
312+
npm install loopback-connector-cloudant --save
313+
```
294314

295315
The connector provides the boilerplate code to connect to different backends. All we have to do is provide some basic configuration.
296316

297-
Define the Cloudant as a datasource by installing src/server/datasources.json file with the following:
317+
Define the Cloudant as a datasource by replacing `src/server/datasources.json` file with the following:
298318

299319
```json
300320
{
@@ -308,89 +328,117 @@ Define the Cloudant as a datasource by installing src/server/datasources.json fi
308328
"name": "cloudant",
309329
"connector": "cloudant",
310330
"url" : "${CLOUDANT_URL}",
311-
"database" : "${CLOUDANT_DB}
331+
"database" : "${CLOUDANT_DB}"
312332
}
313333
}
314334
```
315335

316-
The environment variables `CLOUDANT_URL` and `CLOUDANT_DB` will be loaded in our environment via our Kubernetes Deployment. You can also hardcode these values if you would like to test locally.
336+
The environment variables `CLOUDANT_URL` and `CLOUDANT_DB` will be loaded in our environment via our Kubernetes `deployment`.
317337

318-
Reference the datasource you just created in `src/server/model-config.json` as seen below:
338+
Modify `src/server/model-config.json` to reference the datasource you just created:
319339

320340
```json
321-
"entry": {
341+
...
342+
"entry": {
322343
"dataSource": "cloudant",
323344
"public": true
324345
}
346+
...
325347
```
326348

327349
### Build and push a new docker image
328350

329-
In order to deploy to kubernetes, we will need a Docker Image saved to a registry somewhere. In this lab, we will build an image locally and push directly to DockerHub. In real-life, we would use CI/CD process to build and push our docker image from source control.
330-
331-
Prereqs: [Create a Docker Hub Account](https://hub.docker.com)
351+
Build a docker images with the changes and push to DockerHub. In this lab, we are building and pushing locally. In real-life, we would use CI/CD process to build and push our docker image from source control.
332352

333353
Build the docker image
334354
```
335-
IMAGE_NAME=[dockerhub username]/guestbook-nodejs:[version tag]
336-
docker build -t $IMAGE_NAME
337-
docker push $IMAGE_NAME
355+
docker build -t $DOCKERUSER/guestbook-nodejs:cloudant .
356+
docker login -u $DOCKERUSER
357+
docker push $DOCKERUSER/guestbook-nodejs:cloudant
338358
```
339359

340360
Your guestbook application is all set to talk to a Cloudant database. Next, we will configure our Kubernetes deployment to use the image you just pushed, and to load the missing environment variables: `CLOUDANT_URL` and `CLOUDANT_DB` from our `binding-cloudant` secret.
341361

342362

343363
### Configure Kubernetes yamls
344364

345-
We have a yaml file create for you, but you will need to enter the location of the Docker Image you built in the previous step.
365+
We have a yaml file created for you, but you will need to enter the location of the Docker Image you built in the previous step.
346366

347-
Replace `[IMAGE_NAME]` in the file [guestbook-deployment-cloudant.yaml](../../src/yaml/guestbook-deployment-cloudant.yaml) with the name of the image you uploaded to Docker Hub. Replace `[DB_NAME]` with the name of the Cloudant Database your created in a previous step. Your final yaml file should look like this:
348-
349-
```
350-
apiVersion: apps/v1
351-
kind: Deployment
367+
Navigate to the location of your yaml deployment files, and inspect.
368+
369+
```
370+
cd $HOME/guestbook-nodejs-config/storage/lab7
371+
cat guestbook-deployment.yaml
372+
```
373+
374+
```
375+
apiVersion: apps/v1
376+
kind: Deployment
377+
metadata:
378+
name: guestbook-cloudant
379+
labels:
380+
app: guestbook
381+
spec:
382+
selector:
383+
matchLabels:
384+
app: guestbook
385+
template:
352386
metadata:
353-
name: guestbook-cloudant
354387
labels:
355388
app: guestbook
356389
spec:
357-
selector:
358-
matchLabels:
359-
app: guestbook
360-
template:
361-
metadata:
362-
labels:
363-
app: guestbook
364-
spec:
365-
containers:
366-
- name: guestbook
367-
image: [IMAGE_NAME]
368-
resources:
369-
requests:
370-
cpu: 100m
371-
memory: 100Mi
372-
ports:
373-
- name: http
374-
containerPort: 3000
375-
env:
376-
- name: CLOUDANT_URL
377-
valueFrom:
378-
secretKeyRef:
379-
name: binding-cloudant
380-
key: url
381-
- name : CLOUDANT_DB
382-
value: "[DB_NAME]"
383-
```
390+
containers:
391+
- name: guestbook
392+
image: [IMAGE_NAME]
393+
resources:
394+
requests:
395+
cpu: 100m
396+
memory: 100Mi
397+
ports:
398+
- name: http
399+
containerPort: 3000
400+
env:
401+
- name: CLOUDANT_URL
402+
valueFrom:
403+
secretKeyRef:
404+
name: binding-cloudant
405+
key: url
406+
- name : CLOUDANT_DB
407+
value: "[DB_NAME]"
408+
```
384409

385-
Notice how we load the environment variable `CLOUDANT_URL` from the `binding-cloudant` secreat that we created for us by the IBM Cloud Operator. This yaml files now defines all the environment variables our guestbook application needs to connect to our Cloudant DB.
410+
Replace `[IMAGE_NAME]` in the file `guestbook-deployment-cloudant.yaml` with the name of the image you uploaded to Docker Hub. Replace `[DB_NAME]` with the name of the Cloudant Database your created in a previous step.
411+
412+
Notice how we load the environment variable `CLOUDANT_URL` from the `binding-cloudant` secret. This yaml files now defines all the environment variables our guestbook application needs to connect to our Cloudant DB.
386413

387414
### Test your changes by deploying to Kubernetes
388415

389416
Deploy to kubernetes using `kubectl apply`:
390417

391-
```
392-
kubectl apply -f [deployment file]
393-
kubectl apply -f [service file]
394-
```
418+
```
419+
kubectl apply -f guestbook-deployment.yaml
420+
kubectl apply -f guestbook-service.yaml
421+
```
422+
423+
Check your pods. If there are any errors, use `kubectl describe pod [POD NAME]` to debug,
424+
```
425+
kubectl get pods
426+
```
427+
428+
429+
Find the URL for the guestbook application by joining the worker node external IP and service node port.
430+
431+
```
432+
HOSTNAME=`kubectl get nodes -ojsonpath='{.items[0].metadata.labels.ibm-cloud\.kubernetes\.io\/external-ip}'`
433+
SERVICEPORT=`kubectl get svc guestbook -o=jsonpath='{.spec.ports[0].nodePort}'`
434+
echo "http://$HOSTNAME:$SERVICEPORT"
435+
```
436+
437+
Navigate to the guestbook in a broswer, and add some entries:
438+
439+
![guestbook](../.gitbook/assets/guestbook.png)
395440

441+
From the Cloudant Dashboard, selected `myDatabase` and you should see documents created for the entries you created.
442+
![guestbook](../.gitbook/assets/cloudant-docs.png)
396443

444+
This Cloudant database service is external to the Kubernetes service and data persists outside of the lifecycle of the container/pod/kubernetes cluster. The Cloudant service is a scalable json document storage solution that can be distributed across regions. For more information, check out the [Cloudant Product Page](https://www.ibm.com/cloud/cloudant).

0 commit comments

Comments
 (0)