15 Practical Exercises With Kubernetes 1

15 Practical Exercises with Kubernetes 1 #

Hello, I am Chrono.

After two weeks of learning, today we are almost done with the “Beginner’s Guide”.

Just like in the previous “Introduction”, in this session, I will do a comprehensive review of the knowledge we have learned so far. After all, there are many new terminologies, concepts, and architectures in the Kubernetes field, and there is a lot of diverse and extensive knowledge. Therefore, this summary review is necessary.

Next, I will briefly list the key points covered in the “Beginner’s Guide”, and then we will apply this knowledge in a practical exercise - setting up a WordPress website on a Kubernetes cluster, instead of using Docker this time.

Review of Key Points of Kubernetes Technology #

Container technology has ushered in the era of cloud-native, but when mature container technology is deployed in production environments, it can be “difficult to move forward.” This is because containers only provide isolation and encapsulation for individual processes, while actual application scenarios require many application processes to work together, with various complex relationships and requirements. It is difficult to control at the container level.

To solve this problem, container orchestration (Container Orchestration) emerged. It can be said that it is the landing practice of previous operations and maintenance work in the cloud-native world. Essentially, it still manages and schedules applications in the cluster. The difference is that the management subject has changed from humans to computers, and the management target has changed from native processes to containers and images.

And now, the king of the container orchestration field is——Kubernetes.

Kubernetes originates from the Borg system. It embodies Google’s internal experience and the wisdom of the CNCF community. Therefore, it has surpassed competitors such as Apache Mesos and Docker Swarm. It has become the de facto standard in the container orchestration field and the basic operating system of the cloud-native era. Learning cloud-native requires mastering Kubernetes.

([Lecture 10]) The Master/Node architecture of Kubernetes is the key to its automated operation and maintenance capabilities, and it is also crucial for our learning. Here, I will use another reference architecture diagram to illustrate its operation mechanism briefly (Image source):

Image

Kubernetes defines the computing resources in the cluster as nodes (Nodes), which are further divided into control plane and data plane.

  • The control plane is the Master node, responsible for managing the cluster and operation monitoring of applications. Its core components are apiserver, etcd, scheduler, controller-manager.
  • The data plane is the Worker node, under the control of the Master node. Its core components are kubelet, kube-proxy, container-runtime.

In addition, Kubernetes also supports a plugin mechanism that can flexibly extend various functions. Common plugins include DNS and Dashboard.

In order to better manage the cluster and business applications, Kubernetes abstracted many concepts from the real world, known as “API objects”, and describing these objects requires the use of the YAML language.

YAML is a superset of JSON, but with a simpler syntax and stronger expressive power. More importantly, it uses a “declarative” approach to describe the state of objects, without involving specific operational details. This allows Kubernetes to rely on the cluster’s state information stored in etcd to continually “control” objects until the actual state matches the desired state. This process is the automated operation and maintenance management of Kubernetes ([Lecture 11]).

There are many API objects in Kubernetes, and the most core object is the “Pod”, which bundles a group of closely collaborating containers that share networking and storage. They must be scheduled and run together in the cluster. With the concept of Pod, Kubernetes simplifies the management of containers, and all other tasks are implemented by repackaging the Pod, which is the smallest unit ([Lecture 12]).

In addition to the core Pod object, based on the principles of “single responsibility” and “object composition”, we have also learned four relatively simple API objects, namely Job/CronJob and ConfigMap/Secret.

  • Job/CronJob corresponds to offline jobs. They wrap Pods in layers and add job control and scheduling rules ([Lecture 13]).
  • ConfigMap/Secret corresponds to configuration information, which needs to be injected into Pods as environment variables or storage volumes so that processes can use them at runtime ([Lecture 14]).

Similar to Docker, Kubernetes also provides a client tool called “kubectl”, which communicates directly with the apiserver on the Master node and sends YAML files to the RESTful interface to trigger Kubernetes’ object management workflow.

kubectl has many commands. To view the built-in documentation, you can use api-resources and explain. To view the status of objects, you can use get, describe, logs. To operate objects, you can use run, apply, exec, delete, etc. ([Lecture 09]).

Using YAML to describe API objects also has a fixed format. The “header fields” that must be written are “apiVersion”, “kind”, and “metadata”, which represent the version, type, name, and other metadata of the object. For entity objects like Pod, Job, and CronJob, the “spec” field describes the desired state of the object, with the most basic being container information. For non-entity objects like ConfigMap and Secret, the “data” field is used to record some static string information.

Alright, we have basically summarized the key points of Kubernetes knowledge in the “Introductory” section. If you find any parts that are not clear, you can review the previous lectures after class to consolidate your understanding.

Basic Architecture of WordPress Website #

Next, let’s build another WordPress website in the Kubernetes cluster. We will still be using the same three applications as in the “Getting Started” guide: WordPress, MariaDB, and Nginx. However, this time we will run them in the form of Pods within the Kubernetes environment.

I have created a simple architecture diagram to illustrate the internal logical relationships of this system:

image

From this diagram, you can see that the overall structure of the website remains the same, as we are still using the same three applications and their dependency relationships have not changed.

So, what are the differences between Kubernetes and Docker systems?

The key differences lie in application encapsulation and network environment.

Now, the WordPress and MariaDB applications are wrapped into Pods (since they are both online services, Jobs/CronJobs are not applicable here). The environment variables required for running these applications have also been rewritten as ConfigMaps, which are managed using a “declarative” approach. This makes it easier to read and manage versions compared to Shell scripts.

In addition, the Kubernetes cluster maintains its own dedicated network, which is isolated from the outside world. Data transmission requires special “port forwarding” methods, and an Nginx reverse proxy is also needed outside the cluster to communicate with this network. This adds some additional complexity compared to Docker’s direct port mapping.

Steps to Build a WordPress Website #

After understanding the basic architecture, we can now build this website system step by step. There are a total of 4 steps.

Step 1 is to set up the MariaDB object. You can refer to the practical exercise in the “Introduction” section for specific running requirements. Here, I won’t repeat it.

MariaDB requires 4 environment variables, such as the database name, username, password, etc. In Docker, we use the --env parameter in the command line, while in Kubernetes, we should use ConfigMap. Therefore, we need to define a maria-cm object:

apiVersion: v1
kind: ConfigMap
metadata:
  name: maria-cm
data:
  DATABASE: 'db'
  USER: 'wp'
  PASSWORD: '123'
  ROOT_PASSWORD: '123'

Then, we define the Pod object maria-pod and inject the configuration information into the Pod, so that MariaDB can read these information from the environment variables during runtime:

apiVersion: v1
kind: Pod
metadata:
  name: maria-pod
  labels:
    app: wordpress
    role: database
spec:
  containers:
  - image: mariadb:10
    name: maria
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 3306
    envFrom:
    - prefix: 'MARIADB_'
      configMapRef:
        name: maria-cm

Note that we are using a new field “envFrom” here. This is because there are many information in the ConfigMap, and it would be very cumbersome and error-prone to write them one by one using env.valueFrom. envFrom allows us to import all the fields from the ConfigMap into the Pod at once, and it can also specify the prefix of the variable name (in this case, MARIADB_), which is very convenient.

After creating this object using kubectl apply, you can use kubectl get pod to check its status. If you want to get the IP address, you need to add the parameter -o wide:

kubectl apply -f mariadb-pod.yml
kubectl get pod -o wide

image

Now the database is successfully running in the Kubernetes cluster, and the IP address is “172.17.0.2”. Note that this address is different from that in Docker and belongs to the private network segment of Kubernetes.

Next is Step 2, which is to set up the WordPress object. Again, we use ConfigMap to define its environment variables:

apiVersion: v1
kind: ConfigMap
metadata:
  name: wp-cm
data:
  HOST: '172.17.0.2'
  USER: 'wp'
  PASSWORD: '123'
  NAME: 'db'

In this ConfigMap, pay attention to the “HOST” field. It must be the IP address of the MariaDB Pod. If it is not written correctly, WordPress will not be able to connect to the database properly.

Then, we write the YAML file for WordPress, and to simplify the setting of environment variables, we also use envFrom:

apiVersion: v1
kind: Pod
metadata:
  name: wp-pod
  labels:
    app: wordpress
    role: website
spec:
  containers:
  - image: wordpress:5
    name: wp-pod
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    envFrom:
    - prefix: 'WORDPRESS_DB_'
      configMapRef:
        name: wp-cm

Again, use kubectl apply to create the object and kubectl get pod to check its status:

kubectl apply -f wp-pod.yml
kubectl get pod -o wide

image

Step 3 is to map the port for the WordPress Pod so that it can be accessed from outside the cluster.

Since Pods are running in a private network segment inside Kubernetes and cannot be directly accessed from the outside, we need to use a dedicated command kubectl port-forward to forward the local port to the port of the target object in the cluster. This command is similar to the -p parameter in Docker and is often used for temporary debugging and testing in Kubernetes.

Here, I will forward the local port “8080” to the “80” port of the WordPress Pod. kubectl will forward all the data of this port to the Pod inside the cluster:

kubectl port-forward wp-pod 8080:80 &

image

Note that I used “&” at the end of the command to let the port forwarding work in the background, so it won’t hinder our subsequent operations.

To stop the port forwarding, you need to type the command fg to bring the background task to the foreground, and then you can simply use “Ctrl + C” to stop the forwarding.

Step 4 is to create a reverse proxy with Nginx to provide external services for our website.

This is because the WordPress website uses URL redirection. Directly using “8080” will cause redirection failure. So, in order to make the website work properly, we should start an Nginx reverse proxy outside Kubernetes to ensure that the external view is still on port “80”. (The details here are not directly related to our course. Interested students can leave comments to discuss and ask questions.)

The Nginx configuration file is similar to [Lesson 7], except that the target address is changed to “127.0.0.1:8080”, which is the local address created using the kubectl port-forward command in Step 3:

server {
  listen 80;
  default_type text/html;

  location / {
      proxy_http_version 1.1;
      proxy_set_header Host $host;
      proxy_pass http://127.0.0.1:8080;
  }
}

Then, we use the docker run -v command to load this configuration file and start the Nginx proxy in a container:

docker run -d --rm \
    --net=host \
    -v /tmp/proxy.conf:/etc/nginx/conf.d/default.conf \
    nginx:alpine

image

With Nginx reverse proxy, we can open the browser, enter “127.0.0.1” on the local machine or the IP address of the virtual machine (in my case, it is still “http://192.168.10.208”), and see the WordPress interface:

image

You can also use the kubectl logs command in Kubernetes to view the running logs of WordPress, MariaDB, and other Pods to verify if they have correctly responded to the requests:

image

Using Dashboard to Manage Kubernetes #

Now that the WordPress website has been successfully set up, our main task is complete. However, I would like to show you the graphical management interface of Kubernetes, known as Dashboard, to demonstrate how to manage Kubernetes without using the command line.

Do you remember the command to start Dashboard? We mentioned it in Lesson 10 when discussing plugins. It requires the use of Minikube, and the command is:

minikube dashboard

This command will automatically open the browser interface, displaying the workloads in the current Kubernetes cluster:

Image

By clicking on the name of any pod, you will enter the management interface where you can view detailed information about the pod. In the top right corner, there are four important functions: viewing logs, entering the pod, editing the pod, and deleting the pod. These functions are equivalent to executing the logs, exec, edit, and delete commands, but the interface is more intuitive and user-friendly than the command line:

Image

For example, if I click on the second button, a shell window will open directly in the browser, providing access to the internal Linux environment of the pod. You can enter any command, making it convenient for checking status or debugging:

Image

ConfigMaps, Secrets, and other objects can also be viewed or edited here:

Image

There are many other operable features in Dashboard, but I have only provided a very basic introduction here. While you may be accustomed to using the keyboard and command line, it can be interesting to occasionally switch to using the mouse and graphical interface for Kubernetes management. If you have the opportunity, give it a try.

Conclusion #

Alright, as the last lesson of the “Beginner’s Guide,” we reviewed the key points of Kubernetes today. I also created a detailed mind map to help you review and summarize after class.

Image

In this lesson, we used Kubernetes to build a WordPress website. Compared to Docker in Lesson 7, we applied container orchestration technology, using a “declarative” YAML to describe the state of the application and its relationships, rather than listing detailed steps. This reduces our mental burden—scheduling, creation, monitoring, and other tasks are all handled by Kubernetes, and we just need to sit back and enjoy the results.

Although we have taken a big step towards cloud native, our container orchestration is still not perfect. The Pod’s IP address still needs to be manually searched and filled in, lacking an automatic service discovery mechanism. Additionally, the way we expose services to the outside world is quite primitive, relying on external forces.

Therefore, our learning journey will continue. In the upcoming “Intermediate Guide,” we will start studying more API objects to solve the problems we encountered here.

Homework #

Now it’s time for homework. I’ll leave you with two hands-on exercises:

  1. Currently, MariaDB and WordPress are using ConfigMap. Can you change it to use Secret instead?
  2. Can you convert the Nginx proxy into a Pod and run it in Kubernetes?

I’m looking forward to hearing your thoughts after you try these exercises. If you find them helpful, feel free to share them with your friends for collaborative learning.

In the next class, we’ll have a video demonstration. See you in the next class!

Image