This project creates a complete micro service demo system in Docker containers. The services are implemented in Java using Spring and Spring Cloud.
It uses four docker microservices:
Apache
homepage and proxyOrder
to process orders.Customer
to handle customer data.Catalog
to handle the items in the catalog.
Apache HTTP is used to provide the web page of the demo at port 8080. It also forwards HTTP requests to the microservices. This is not really necessary as each service has its own port on the Minikube host but it provides a single point of entry for the whole system. Apache HTTP is configured as a reverse proxy for this. Load balancing is left to Kubernetes.
To configure this Apache HTTP needs to get all registered services from Kubernetes. It just uses DNS for that.
Please refer to the subdirectory microservice-kubernetes-demo/apache to see how this works.
The microservices are:
- microservice-kubernetes-demo-catalog is the application to take care of items.
- microservice-kubernetes-demo-customer is responsible for customers.
- microservice-kubernetes-demo-order does order processing. It uses microservice-kubernetes-demo-catalog and microservice-kubernetes-demo-customer.
The microservices use REST to communicate to each other.
See e.g. CatalogClient .
The hostname is configurable to allow tests with stubs.
The default is catalog
which works with Kubernetes.
Other microservices are found using Kubernetes built-in DNS.
Kubernetes does the load balancing on the IP level.
- AWS account
- AWS IAM user - Note this user will need some IAM permissions including roles, policies, OpenID
% aws --version
aws-cli/2.11.5 Python/3.11.2 Darwin/22.3.0 exe/x86_64 prompt/off
% aws sts get-caller-identity
{
"UserId": "YYA4ZRSAMPLE6IDAGV2YP",
"Account": "378929636692",
"Arn": "arn:aws:iam::378929636692:user/dockerbisson"
}
- Install brew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- Install helm:
brew install helm
- Install jq:
brew install jq
- Create account
- Create an org - use the org name in the terraform.tf file
- Terraform variables with AWS credentials
From the top level of the repo
brew install terraform
(first time install only )terraform init
terraform plan
time terraform apply -auto-approve
Get kubectl
config (more details):
aws eks --region us-east-1 update-kubeconfig --name demo-eks
The region
and name
values match those in the main.tf
file.
- Log in to your Docker Hub account by entering
docker login
on the command line. - Set the environment variable
DOCKER_ACCOUNT
to the name of the account and verify it with echo.
export DOCKER_ACCOUNT=your account
echo $DOCKER_ACCOUNT
- If you are running on x86, run
docker-build.sh
in the directorymicroservice-kubernetes-demo
. It builds the images and uploads them to Docker Hub using your account.
3a. If you are running on arm64 (apple silicon), you will need to build images for arm64 and amd64 and push to hub using buildx. Change to the directory microservice-kubernetes-demo
and run ./docker-buildx.sh
Run ./kubernetes-deploy.sh
in the directory
microservice-kubernetes-demo
:
[~/microservice-kubernetes/microservice-kubernetes-demo]./kubernetes-deploy.sh
deployment "apache" created
service "apache" exposed
deployment "catalog" created
service "catalog" exposed
deployment "customer" created
service "customer" exposed
deployment "order" created
service "order" exposed
Confirm the services are running using kubectl
kubectl get all
open "http://$(kubectl get service -o json | jq -r '.items[0].status.loadBalancer.ingress[].hostname')"
- Install the mod header extension for chrome
- Open Docker Desktop
- Install telepresence extension
- Update the kubernetes context in the apache-intercept.yaml and order-intercept.yaml files in the microservice-kubernetes directory - get it from kubectl
kubectl config current-context
Show the app running in EKS, show the homepage is missing the logo and has two links with the same name
Update the index.html page to add the telepresence logo and change the link text for the second catalog link and build the image
- cd to the microservice-kubernetes-demo/apache directory
- Open the index.html file
- Add the telepresence logo image (changes are bolded)
<body>
<img src="images/telepresence-for-docker.svg"/>
<h1>Order Processing</h1>
- change the second catalog link in index.html and save(changes have ** around them)
<a href="/catalog/searchForm.html">**Search** Catalog</a>
- Run
docker build --tag=microservice-kubernetes-demo-apache .
IMPORTANT - the Spec, GUI and CLI telepresence intercept options are separate. You can do each of them, but you need to make sure the intercept is down before switching between them. Please make sure you click the "disconnect/leave" icon when you are switching between these options
- Open Docker Desktop
- Go to the telepresence extension
- Select "Get Started" - the Select Cluster for Telepresence Connection Dialog will appear
- The kubeconfig context should show the aws cluster
- Select "Install telepresence on this cluster" only if this is the first connection since building the cluster
- Select the down arrow next to the connect button, upload intercept spec should display
- Select the apache-intercept.yaml file in the microservice-kubernetes-demo folder
- Telepresence will start the intercept with the image specified in the intercept file
- There may be a warning message show up in a pop up from the container, you can ignore this and close it
- Open Docker Desktop
- Go to the telepresence extension
- Select "Get Started" - the Select Cluster for Telepresence Connection Dialog will appear
- The kubeconfig context should show the aws cluster
- Select "Install telepresence on this cluster" only if this is the first connection since building the cluster
- Select connect
- The default namespace should pop
- The four services service should be listed
- Click Intercept next to the Apache service
- A dialog appears for the Intercept
- Make sure the target docker image is microservice-kubernetes-demo-apache:latest
- Both the Service Port Number and the Target Port Number are 80
- Leave the other settings
- Click Create Intercept
- There may be a warning message show up in a pop up from the container, you can ignore this and close it
- Type
telepresence intercept --docker apache --port 80:80 --docker-run -- -it --rm microservice-kubernetes-demo-apache:latest
- Go to the containers tab
- Show there is a
tp-apache
orintercept-apache
container running - Explain that the telepresence extension runs this container when the intercept starts based on the image you specify
Option 1: HTTP headers
- Copy the request header string shown in the current running intercepts (or on the terminal page)
- Put the
x-telepresence-intercept-id
in the name field in mod header - Put the rest (minus the colon after id) into the value field and make sure the green check is there
- Refresh the order processing homepage page to see the new image and link text
- Turn off the header and show the unchanged page
Option 2: Preview URL
- Click the preview URL link (or copy from the terminal page), put it in a new tab, and show the updated page
- Refresh the original tab to show the unchanged page
- Click stop intercept
- (optional) show the local container has stopped as well
- You may need to click the "leave" icon in the upper right to get back to the connect/startpage in the telepresence extension - there may also be a warning message, you can ignore it.
- type 'telepresence leave' (note this may not be required if you control C the telepresence command)
- Show the app running in EKS, go to the orders page - there are no orders.
- Create an order, add a line with a quantity, and hit submit.
- Click list to see the order
- Click delete next to the order
- Get an error that the method is not allowed
- cd to the microservice-kubernetes-demo/microservice-kubernetes-demo-order/src/main/java/com/ewolff/microservice/order/logic directory
- Open the OrderController.java file
- Update the method that has "DELETE" in it to POST(change in **)
@RequestMapping(value = "/{id}", method = RequestMethod.**POST**)
public ModelAndView post(@PathVariable("id") long id) {
orderRepository.deleteById(id);
- save the file
- cd up to the microservices-kubernetes-demo directory
- Run
./docker-build-order.sh
to recompile and build the image (local only)
IMPORTANT - the Spec, GUI and CLI telepresence intercept options are separate. You can do each of them, but you need to make sure the intercept is down before switching between them.
- Open Docker Desktop
- Go to the telepresence extension
- Select "Get Started" - the Select Cluster for Telepresence Connection Dialog will appear
- The kubeconfig context should show the aws cluster
- Select "Install telepresence on this cluster" only if this is the first connection since building the cluster
- Select the down arrow next to the connect button, upload intercept spec should display
- Select the order-intercept.yaml file in the microservice-kubernetes folder
- Telepresence will start the intercept with the image specified in the intercept file
- Open Docker Desktop
- Go to the telepresence extension
- Select "Get Started" - the Select Cluster for Telepresence Connection Dialog will appear
- The kubeconfig context should show the aws cluster
- Select "Install telepresence on this cluster" only if this is the first connection since building the cluster
- Select connect
- The default namespace should pop
- The four services service should be listed
- Click Intercept next to the Order service
- A dialog appears for the Intercept
- Make sure the target docker image is microservice-kubernetes-demo-order:latest
- Target Port Number is 8080
- Leave the other settings
- Click Create Intercept
- Type
telepresence intercept --docker order --port 8080:8080 --docker-run -- -it --rm microservice-kubernetes-demo-order:latest
Note: you will get logging from the Java service, just scroll up to the telepresence output you need
If you receive the following error, telepresence intercept: error: option --docker cannot be used as long as a daemon is running on the host. Try telepresence quit -s
try running docker network create --ipv6 --subnet=fd25::/64 --gateway=fd25::1 telepresence
Note: you may need to run telepresence helm upgrade --team-mode
- Go to the containers tab
- Show there is a
tp-order
container running - Explain that the telepresence extension runs this container when the intercept starts based on the image you specify
HTTP headers
- Copy the request header string shown in the current running intercepts (or on the terminal page)
- Put the
x-telepresence-intercept-id
in the name field in mod header - Put the rest (minus the colon after id) into the value field and make sure the green check is there
- Go to the orders list - see there are no orders now because the order service has no permament storage
- Create an order, add a line with a quantity, and hit submit.
- Click list to see the order
- Click delete next to the order
- Delete successful
- Click list to see the order is gone
- Turn off header and click list to see original order is there, still can't delete it
- Click stop intercept
- (optional) show the local container has stopped as well
- type 'telepresence leave'
- cd to the apache directory
- Update the index.html file - remove the image link, change the catalog link back and save
- cd to the microservice-kubernetes-demo/microservice-kubernetes-demo-order/src/main/java/com/ewolff/microservice/order/logic directory
- Update the OrderController.java file - change the POST back to DELETE on the delete method (make sure you get the right one)
- cd to the microservices-kubernetes-demo directory
- To remove all services and deployments run
kubernetes-remove.sh
:
[~/microservice-kubernetes/microservice-kubernetes-demo]./kubernetes-remove.sh
service "apache" deleted
service "catalog" deleted
service "customer" deleted
service "order" deleted
deployment "apache" deleted
deployment "catalog" deleted
deployment "customer" deleted
deployment "order" deleted
kubectl get all
- type
kubectl config use-context docker-desktop
From the top-level of the repo
terraform destroy -auto-approve
- Manually delete any load balancers associated with the cluster in the web console
- Manually delete the VPC associated with the cluster in the web console
terraform destroy -auto-approve
again
If needed...
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder