Notes for "Scalable Microservices with Kubernetes"
November 22, 2017 | Kubernetes DockerMy notes for the course “Scalable Microservices with Kubernetes” on Udacity.
- Resources
- Introduction to Microservices
- Building the Containers with Docker
- Kubernetes
- Deploying Microservices
Resources
- Books
- Articles
- Martin Fowler on the Pros and Cons of Microservices
- 12-factor manifesto
- 12-Fractured Apps
- Tools
Introduction to Microservices
Activate Google Cloud Shell.
List available time zones:
Set a time zone:
Set GOPATH:
Get the code:
On shell 1 - build the monolith app:
On shell 1 - run the monolith server:
On shell 2 - test the app on shell 2:
On shell 2 - authenticate (password is password):
It prints out the token. You can copy and paste the long token in to the next command manually, but copying long, wrapped lines in cloud shell is broken. To work around this, you can either copy the JWT token in pieces, or, more easily, by assigning the token to a shell variable as follows.
On shell 2 - login and assign the value of the JWT to a variable
On shell 2 - access the secure endpoint using the JWT:
On shell 2 - check out dependencies
On shell 1 - build and run the hello service
On shell 2 - build and run the auth service
On shell 3 - interact with the auth and hello microservices
Building the Containers with Docker
Cloud shell - set compute/zone (Note: Google Cloud shell is an ephemeral instance and will reset if you don’t use it for more than 30 minutes. That is why you might have to set some configuration values again)
Cloud shell - launch a new VM instance
Cloud shell - log into the VM instance
VM instance - update packages and install nginx
VM instance - start nginx
Check that it’s running
Install Docker
Check Docker images
Pull nginx image
Verify the versions match
Run the first instance
Check if it’s up
Run a different version of nginx
Run another version of nginx
Check how many instances are running
What’s with the container names? If you don’t specify a name, Docker gives a container a random name, such as “stoic_williams”, “sharp_bartik”, “awesome_murdock”, or “evil_hawking”. These are generated from a list of adjectives and names of famous scientists and hackers. The combination of the names and adjectives is random, except for one case. Want to see what the exception is? Check it out in the Docker source code!
List all running container processes
For use in shell scripts you might want to just get a list of container IDs (-a
stands for all instances, not just running, and -q
is for “quiet” - show just the numeric ID):
Inspect the container. You can use either CONTAINER ID or NAMES field, for example for a sudo docker ps
output like this:
You can use either of the following commands:
or
Connect to the nginx using the internal IP. Get the internal IP address either copying from the full inspect file or by assigning it to a shell variable:
You can also get all instance IDs and their corresponding IP addresses by doing this:
Stop an instance
or
Verify no more instances running
Remove the docker containers from the system
or
On the VM Instance, build a static binary of the monolith app
Why did you have to build the binary with such an ugly command line? You have to explicitly make the binary static. This is really important in the Docker community right now because alpine has a different implementation of libc. So your go binary wouldn’t have had the lib it needed if it wasn’t static. You created a static binary so that your application could be self-contained.
Create a container for the app. Look at the Dockerfile
Build the app container
List the monolith image
Run the monolith container and get it’s IP
or
Test the container
or
Important note on security: If you are tired of typing “sudo” in front of all Docker commands, and confused why a lot of examples don’t have that, please read the following article about implications on security - Why we don’t let non-root users run Docker in CentOS, Fedora, or RHEL
Create docker images for the remaining microservices - auth and hello.
Build the auth app
Build the hello app
See the running containers
Public Vs Private Registries (Comparing Four Hosted Docker Registries):
- Docker Hub
- Quay is another popular registry because of it’s rich automated workflow for building containers from github.
- Google Cloud Registry (GCR) is a strong options for large enterprises.
See all images
Add your own tag
For example (you can rename too!)
Create account on Dockerhub. To be able to push images to Dockerhub you need to create an account there
Login and use the docker push command
Repeat for all images you created - monolith, auth and hello!
Kubernetes
- Kubernetes command cheat sheet
- Pods
- Configure Liveness and Readiness Probes
- Configure Containers Using a ConfigMap
- Secrets
- Services
Use project directory
Note: At any time you can clean up by running the cleanup.sh script
Provision a Kubernetes Cluster with GKE using gcloud (GKE is a hosted Kubernetes by Google; GKE clusters can be customized and supports different machine types, number of nodes, and network settings)
Launch a single instance:
Get pods
Expose nginx
List services
Explore config file
Create the monolith pod
Examine pods
It may take a few seconds before the monolith pod is up and running as the monolith container image needs to be pulled from the Docker Hub before we can run it.
Use the kubectl describe command to get more information about the monolith pod
On cloud shell 1 - set up port-forwarding
On cloud shell 2
On cloud shell 2 - log in
On cloud shell 2 - view logs
On cloud shell 3
On cloud shell 2 - exit log watching (Ctrl-C)
You can use the kubectl exec command to run an interactive shell inside the monolith Pod. This can come in handy when you want to troubleshoot from within a container:
For example, once we have a shell into the monolith container we can test external connectivity using the ping command.
When you’re done with the interactive shell be sure to logout.
Creating Secrets
The cert.pem
and key.pem
files will be used to secure traffic on the monolith server and the ca.pem
will be used by HTTP clients as the CA to trust. Since the certs being used by the monolith server where signed by the CA represented by ca.pem
, HTTP clients that trust ca.pem
will be able to validate the SSL connection to the monolith server.
Use kubectl to create the tls-certs secret from the TLS certificates stored under the tls directory:
kubectl will create a key for each file in the tls directory under the tls-certs secret bucket. Use the kubectl describe command to verify that:
Next we need to create a configmap entry for the proxy.conf
nginx configuration file using the kubectl create configmap command:
Use the kubectl describe configmap command to get more details about the nginx-proxy-conf configmap entry:
Accessing A Secure HTTPS Endpoint
Create the secure-monolith Pod using kubectl:
Create a service:
Set up firewall rules for the service port(s)
Get IP addresses of the nodes
Not working yet!
Add labels to Pods:
Now it works!
Deploying Microservices
Create deployments:
Scale deployments:
Rolling updates:
Finally, delete the Kubernetes cluster: