You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 22, 2024. It is now read-only.
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.
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).
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:
## Approach 1: Manually create database service on IBM Cloud console
29
+
## Approach 1: Create a database service using the IBM Cloud console
9
30
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.
12
32
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).
14
34
15
35

16
36
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**.
18
38
19
39

20
40
21
41
### Create a credential for your CloudantDB service
22
42
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
+

46
+
47
+
From the Cloudant DB service, select **Service Credentials** on the left. Then click the blue **New credential** on the right.
24
48
25
49

26
50
27
51
Select the default name and role (should be `manager`) for the credentials, and click **Create**.
28
52
29
53
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.
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:
Once completed, [skip ahead to the next section](##Next-Steps)
65
+
Once completed, [skip ahead to the next section](#Next-Steps)
39
66
40
67
## Approach 2: Use the IBM Cloud Operator to provision a database instance on IBM Cloud
41
68
@@ -45,7 +72,9 @@ With the IBM Cloud Kubernetes Service clusters at version 1.16 and later, the Op
45
72
46
73
### Create an API Key for your Target Account
47
74
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)
49
78
50
79
1. Login to your personal IBM Cloud account. Use `--sso` if using single-sign-on. Select your personal account when asked upon logging in.
51
80
@@ -94,7 +123,7 @@ We will configure the IBM Cloud Operator to maange resources on your personal IB
94
123
ibmcloud iam service-api-key-create apikey-ico serviceid-ico
95
124
```
96
125
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.
98
127
99
128
```
100
129
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
108
137
109
138
### Installing the IBM Cloud operator
110
139
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.
116
141
117
142
1. Target the default resource group that your service ID has privledges to.
118
143
@@ -129,13 +154,13 @@ We will configure the IBM Cloud Operator to maange resources on your personal IB
129
154
Check that the pod for the IBM Cloud operator is running with:
130
155
131
156
```text
132
-
kubectl get pods --namespace ibm-system
157
+
kubectl get pods --namespace ibmcloud-operator-system
133
158
```
134
159
135
160
You should see after a minute or two that the pod for the operator is running:
136
161
137
162
```console
138
-
$ kubectl get pods --all-namespaces
163
+
$ kubectl get pods --namespace ibmcloud-operator-system
@@ -148,7 +173,7 @@ Operators are custom code that uses the Kubernetes API (as a client) to implemen
148
173
149
174
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.
150
175
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).
152
177
153
178
<br>
154
179
@@ -161,7 +186,7 @@ For an application running within a Kubernetes cluster to be able to access an I
161
186
1. Change into the `yaml` directory. apply the `cloudant-ibmcloud.yaml` file.
162
187
163
188
```console
164
-
cd $HOME/kube-storage101/src/yaml
189
+
cd $HOME/guestbook-nodejs-config/src/yaml
165
190
```
166
191
167
192
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
192
217
binding-cloudant Opaque 6 40s
193
218
```
194
219
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
-
197
220
### 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.
### Check the IBM Cloud console - verify the Cloudant DB service
205
228
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
-
208
229
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
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**.
@@ -279,22 +300,21 @@ Remember this name as we will be using it later when we deploy our application.
279
300
280
301
You will have to make minor changes to the Guestbook nodejs application to read from your newly created CloudantDB service.
281
302
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
+
```
287
307
288
308
(Optional) Install the [Loopback connector](https://loopback.io/doc/en/lb2/Cloudant-connector.html) for CloudantDB. This has been done for you already.
289
309
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
+
```
294
314
295
315
The connector provides the boilerplate code to connect to different backends. All we have to do is provide some basic configuration.
296
316
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:
298
318
299
319
```json
300
320
{
@@ -308,89 +328,117 @@ Define the Cloudant as a datasource by installing src/server/datasources.json fi
308
328
"name": "cloudant",
309
329
"connector": "cloudant",
310
330
"url" : "${CLOUDANT_URL}",
311
-
"database" : "${CLOUDANT_DB}
331
+
"database" : "${CLOUDANT_DB}"
312
332
}
313
333
}
314
334
```
315
335
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`.
317
337
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:
319
339
320
340
```json
321
-
"entry": {
341
+
...
342
+
"entry": {
322
343
"dataSource": "cloudant",
323
344
"public": true
324
345
}
346
+
...
325
347
```
326
348
327
349
### Build and push a new docker image
328
350
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.
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.
341
361
342
362
343
363
### Configure Kubernetes yamls
344
364
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.
346
366
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:
352
386
metadata:
353
-
name: guestbook-cloudant
354
387
labels:
355
388
app: guestbook
356
389
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
+
```
384
409
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.
386
413
387
414
### Test your changes by deploying to Kubernetes
388
415
389
416
Deploy to kubernetes using `kubectl apply`:
390
417
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
+

395
440
441
+
From the Cloudant Dashboard, selected `myDatabase` and you should see documents created for the entries you created.
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