[Study Notes] Kubernetes

Study notes from udemy course docker-kubernetes-the-practical-guide

Why Kubernetes?

de-factor standard for orchestrating container deployments

  • Automatic deployment
  • Scaling & Load Balancing
  • Management

Pod

  • contains and runs one or multiple containers
  • Pods contain shared resources like volumes for all Pod containers
  • has a cluster-internal IP by default so containers inside a pod can communicate via localhost

For Pods to be managed for you, Deployment is needed.

Deployment

  • controls pods by defining which pods and containers to run and number of instances
  • deployments can be paused, deleted, or rolled back
  • deployments can be scaled dynamically and automatically
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: second-app-deployment
labels:
group: example
spec:
replicas: 1
selector:
matchLabels:
app: second-app
tier: backend
template:
metadata:
labels:
app: second-app
tier: backend
spec:
containers:
- name: second-node
image: <REGISTRY>/<IMG_NAME>:<REVISION>
imagePullPolicy: Always
livenessProbe:
httpGet:
path: /
port: 8080
periodSeconds: 10
initialDelaySeconds: 5

Service

  • exposes and allows access from the cluster or from outside
  • groups pods with a shared IP

Accessible IP and port can found with minikube service <SERVICE_NAME>.

# service.yaml
apiVersion: v1
kind: Service
metadata:
name: backend
labels:
group: example
spec:
selector:
app: second-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer

kubectl commands can be run against defined labels: kubectl delete deployments,services -l group=example.

Volumes

Volume’s lifecycle depends on the Pod lifecycle because volumes are part of a pod. Volumes survive container restarts and removals but not pod restarts.

However, with the above approach, there will be data inconsistency issue when there are more than 1 pod (1 replica). hostPath can help solving this problem by allowing multiple pods to share one path.

However, hostPath partially works, meaning it works for minikube but not on multi-node environment, because it is a single node environment. Also, it is still a problem when a pod is removed or replaced. Therefore, sometimes there are cases where pod-independent and node-independent volumes are required. Beside the normal volumes, k8s offers Persistent Volumes.

Persistent Volumes

The main idea is that persistent volume (PV) is detached from the pod lifecycle. PV Claim can be defined in the node to request access to PVs. This will make managing configuration files and volumes easier for bigger projects.

Container Storage Interface (CSI) is a flexible type which allows user to attach any storage solution as long as integration is provided like AWS EFS.

Environment Variables

In node app, environment variable can be used like:

const filePath = path.join(__dirname, process.env.STORY_FOLDER, 'text.txt')

ConfigMap

Networking

Pod-Internal Communication

Scenario:

  • users API container runs on port 8080
  • auth API container runs on port 80
  • users and auth containers are running in the same pod
  • users API makes a request to auth API
  • users API needs to be exposed to the public
/* users backend */
axios.get(`http://${process.env.AUTH_ADDRESS}/some/path`)

Pod-to-Pod Communication

Scenario:

  • users API container runs on port 8080
  • auth API container runs on port 80
  • tasks API container runs on port 8000
  • users, auth, tasks each run in a separate pod
  • users API and tasks API make requests to auth API
  • users API and tasks API need to be exposed to the public

It should be noted that kubernetes automatically injects an environment variable <SERVICE_NAME>_SERVICE_HOST that can be used in the code (for example, AUTH_SERVICE_SERVICE_HOST). In addition to that kubernetes provides CoreDNS for service discovery within the cluster. In this example, CoreDNS is used.

Containerizing Frontend

Imagine there is another pod which hosts a React app in the cluster. This React app makes requests to tasks API.

First, make sure React app makes requests like fetch(‘/api/tasks’).

Second, define reverse proxy in nginx.conf. It is very nice that again DNS can be used to set up the reverse proxy. The port is defined as well because the tasks API container is exposed at port 8000. For the location syntax and how nginx behaves differently with the trailing slashes, refer to the reference at the very bottom.

Third, define kubernetes yaml files

--

--

--

https://www.linkedin.com/in/jaesik-kim-706b4a84

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
J.Kim

J.Kim

https://www.linkedin.com/in/jaesik-kim-706b4a84

More from Medium

Kubernetes Architecture — In Depth

What is Tekton?

Deploying MySQL on Kubernetes

How is security managed in Kubernetes clusters?