How To’s

High-level diagram

Steps

Required tools:

  • go
  • docker
  • kubectl
  • minikube

Docker registry

The custom microservices docker image needs to be built on a registry. For development, the host docker runtime can be used instead, so that any docker command that’s running will be ran againts minikube runtime

  • Current $ docker ps

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ docker ps
CONTAINER ID   IMAGE                                 COMMAND                  CREATED             STATUS             PORTS                                                                                                                                  NAMES
8d80ac3e5fe4   gcr.io/k8s-minikube/kicbase:v0.0.28   "/usr/local/bin/entr…"   About an hour ago   Up About an hour   127.0.0.1:49157->22/tcp, 127.0.0.1:49156->2376/tcp, 127.0.0.1:49155->5000/tcp, 127.0.0.1:49154->8443/tcp, 127.0.0.1:49153->32443/tcp   minikube
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 
  • After $ eval $(minikube docker-env)

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ eval $(minikube docker-env)
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED             STATUS             PORTS     NAMES
e6adc4978fb5   nginx                  "/docker-entrypoint.…"   44 minutes ago      Up 44 minutes                k8s_nginx-pod_nginx-rc-rl7hb_default_36dbe609-2e70-457a-9e57-feed9e411d75_0
63c9e671637f   nginx                  "/docker-entrypoint.…"   44 minutes ago      Up 44 minutes                k8s_nginx-pod_nginx-rc-62lhm_default_e687fac3-6248-4cf0-a463-b2cec918a24d_0
a367331facec   nginx                  "/docker-entrypoint.…"   44 minutes ago      Up 44 minutes                k8s_nginx-pod_nginx-rc-b5jch_default_43d0b81f-bca1-4fc5-a2d0-91e15048c7ae_0
# ...
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

Minikube

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ minikube start
😄  minikube v1.24.0 on Ubuntu 20.04
✨  Automatically selected the docker driver
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.22.3 on Docker 20.10.8 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$

Storage services

PostgreSQL

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f ./storage/postgres.yaml
service/postgres-service created
pod/postgres created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME       READY   STATUS              RESTARTS   AGE
postgres   0/1     ContainerCreating   0          5s
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$

PostgreSQL data

You can execute the SQL on storage/postgres-migrations via admin/tools UI, or with something like

# For every SQL on migrations directory, run it against the postgres pod
for FILE in ./storage/postgres-migrations/*; do
    kubectl exec -it pods/postgres -- psql postgres://[email protected]:5432 < $FILE
done

After first migrations:

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl exec -it pods/postgres -- psql postgres://[email protected]:5432
psql (14.1 (Debian 14.1-1.pgdg110+1))
Type "help" for help.

postgres=# SELECT id, stock FROM product;
                  id                  |        stock         
--------------------------------------+----------------------
 52a1356b-24eb-4675-af0b-a6aa8cd3722b | (OK,100)
 5adb6b31-25f8-4cc1-86aa-a07cea266bb6 | (ALWAYS_AVAILABLE,0)
 35ffc992-bd05-479e-a089-f082d2daefa9 | (OK,0)
(3 rows)

postgres=# 

Elasticsearch

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f ./storage/elasticsearch.yaml
service/elasticsearch-service created
pod/elasticsearch created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME            READY   STATUS              RESTARTS   AGE
elasticsearch   0/1     ContainerCreating   0          31s
postgres        1/1     Running             0          3m51s
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$

Elasticsearch data

First-time data can be imported from product table via search-import service. The dependencies include the product service, which needs to be started first

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ docker build -t ecommerce-product ./services/product/
Sending build context to Docker daemon    7.2MB
Step 1/7 : FROM golang:1.18beta1-alpine3.15
 ---> 80848e6ab8b2
# ...
Successfully built ed092fbf310e
Successfully tagged ecommerce-product:latest
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f ./services/product/resources/ecommerce-product.yaml
service/ecommerce-product-service created
replicationcontroller/ecommerce-product-rc created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
ecommerce-product-rc-8fbs6   1/1     Running   0          30s
ecommerce-product-rc-hkhwx   1/1     Running   0          30s
ecommerce-product-rc-kg8mh   1/1     Running   0          30s
elasticsearch                1/1     Running   0          5m5s
postgres                     1/1     Running   0          8m25s
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

Then we build the search service image & run the importer

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ docker build -t ecommerce-search ./services/search/
Sending build context to Docker daemon  16.38kB
Step 1/7 : FROM golang:1.18beta1-alpine3.15
 ---> 80848e6ab8b2
# ...
Successfully built 0c9375e7bae6
Successfully tagged ecommerce-search:latest
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f ./services/search/resources/ecommerce-search-import.yaml
job.batch/ecommerce-search created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME                         READY   STATUS      RESTARTS   AGE
ecommerce-product-rc-8fbs6   1/1     Running     0          2m25s
ecommerce-product-rc-hkhwx   1/1     Running     0          2m25s
ecommerce-product-rc-kg8mh   1/1     Running     0          2m25s
ecommerce-search--1-dl9wg    0/1     Completed   0          6s
elasticsearch                1/1     Running     0          7m
postgres                     1/1     Running     0          10m
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

We can then confirm it by accessing the ES instance

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl port-forward svc/elasticsearch-service 9200
Forwarding from 127.0.0.1:9200 -> 9200
Forwarding from [::1]:9200 -> 9200
Handling connection for 9200

Elasticsearch result

Microservices

Payment

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ docker build -t ecommerce-payment ./services/payment/
Sending build context to Docker daemon  15.87kB
Step 1/7 : FROM golang:1.18beta1-alpine3.15
 ---> 80848e6ab8b2
# ...
Successfully built d33664c6950c
Successfully tagged ecommerce-payment:latest
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f ./services/payment/resources/ecommerce-payment.yaml
service/ecommerce-payment-service created
replicationcontroller/ecommerce-payment-rc created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME                         READY   STATUS      RESTARTS   AGE
ecommerce-payment-rc-dgm46   1/1     Running     0          4s
ecommerce-payment-rc-tcvrl   1/1     Running     0          4s
ecommerce-payment-rc-vllkk   1/1     Running     0          4s
# ...
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

Search

# Image already built previously
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f ./services/search/resources/ecommerce-search.yaml
service/ecommerce-search-service created
replicationcontroller/ecommerce-search-rc created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME                         READY   STATUS      RESTARTS   AGE
# ...
ecommerce-search-rc-fm9h8    1/1     Running     0          3s
ecommerce-search-rc-mz9rd    1/1     Running     0          3s
ecommerce-search-rc-t8v4q    1/1     Running     0          3s
# ...
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

UI

UI will be the “front-end” services which ties up the microservices. Currently it doesn’t do much except shows the product data

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ docker build -t ecommerce-ui ./services/ui/
Sending build context to Docker daemon   12.8kB
Step 1/7 : FROM golang:1.18beta1-alpine3.15
 ---> 80848e6ab8b2
# ...
Successfully built 465d5222665f
Successfully tagged ecommerce-ui:latest
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f ./services/ui/resources/ecommerce-ui.yaml
service/ecommerce-ui-service created
replicationcontroller/ecommerce-ui-rc created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME                         READY   STATUS      RESTARTS   AGE
# ...
ecommerce-ui-rc-k6ps7        1/1     Running     0          7s
ecommerce-ui-rc-kn27f        1/1     Running     0          7s
ecommerce-ui-rc-shwgc        1/1     Running     0          7s
# ...
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl port-forward svc/ecommerce-ui-service "8000:80"
Forwarding from 127.0.0.1:8000 -> 80
Forwarding from [::1]:8000 -> 80
Handling connection for 8000

UI page

NGINX

Will be used as a reverse proxy. Configured to pass the request to each respective microservices, like /payment to payment service, /product to product service, etc.

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ docker build -t nginx-ecommerce www/
Sending build context to Docker daemon  6.144kB
Step 1/3 : FROM nginx:latest
 ---> 605c77e624dd
# ...
Successfully built 15519f7d7e65
Successfully tagged nginx-ecommerce:latest
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl create -f www/resources/nginx.yaml
service/nginx-service created
replicationcontroller/nginx-rc created
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl get pods
NAME                         READY   STATUS      RESTARTS   AGE
# ...
nginx-rc-vt4v2               1/1     Running     0          4s
nginx-rc-w548x               1/1     Running     0          4s
nginx-rc-z65q2               1/1     Running     0          4s
# ...
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ kubectl port-forward svc/nginx-service "8000:80"
Forwarding from 127.0.0.1:8000 -> 80
Forwarding from [::1]:8000 -> 80

Product page

Search page

Running

Buying an item

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ curl -XPOST localhost:8000/payment -H 'Content-Type: application/json' -d '{"product_id": "52a1356b-24eb-4675-af0b-a6aa8cd3722b"}'
{"status": "ok"}[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ 

Product purchased page

Payment page

Updating an item

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ curl -XPOST localhost:8000/product -H 'Content-Type: application/json' -d '{"id": "52a1356b-24eb-4675-af0b-a6aa8cd3722b", "name": "Samsung Galaxy Note Purple", "image_url": "https://images.pexels.com/photos/958029/aesthetic-mountain-clouds-mood-958029.jpeg", "price": 9500000, "stock": {"status": "OK", "count": 150}}'
{"status": "ok"}[email protected]:~/go/src/github.com/taufik-rama/ecommerce$

Product updated page

Cleaning up

[email protected]:~/go/src/github.com/taufik-rama/ecommerce$ minikube delete
🔥  Deleting "minikube" in docker ...
🔥  Deleting container "minikube" ...
🔥  Removing /home/taufik-rama/.minikube/machines/minikube ...
💀  Removed all traces of the "minikube" cluster.
[email protected]:~/go/src/github.com/taufik-rama/ecommerce$

References

GitHub

View Github