k8s_intro_2
Redis on Kubernetes Deployment Guide ②
k3s
☸️ What is k3s?
For this Redis install/test environment we used K3s, a CNCF-certified lightweight Kubernetes distribution.
Differences between k8s (standard Kubernetes) and k3s
| Item | Standard Kubernetes (k8s) | K3s (Lightweight Kubernetes) |
|---|---|---|
| Purpose | Large enterprise datacenters | Lightweight datacenters, Edge, IoT, development, and small-to-medium air-gapped networks |
| Install and size | Complex install and high memory use (>2GB RAM) | Single binary executable (<512MB RAM) |
| Datastore | Dedicated etcd by default | SQLite (default), etcd, and external DB (MySQL/PostgreSQL) |
| Default storage | Requires a separate StorageClass (CSI) | Built-in 'local-path' StorageClass (PVC works immediately) |
| Container runtime | Separate setup for containerd, CRI-O, etc. | containerd included by default, with automatic image loading |
💡 redisgate's Insight: K3s gives strong performance and convenience when you verify and operate Redis in resource-constrained environments or air-gapped networks with no internet.
Installing k3s
containerd and kubectl are included automatically
It provides 100% of the same K8s features needed for Redis tests:
'StatefulSet', 'Headless Service', 'PVC', 'podAntiAffinity' (virtual-node tests), and more.
- Step 1: Install K3s (use the root user)
- 1) Install: # curl -sfL https://get.k3s.io | sh -
- 2) Check status: # k3s kubectl get nodes
💻 Terminal
- Step 2: Grant the regular (redis) user permission to use 'kubectl'
After K3s is installed, the K8s credential file 'k3s.yaml' is created under '/etc/rancher/k3s/', and by default only 'root' can read it. Copy it into the redis user's home directory so you can run kubectl without sudo. (use a regular redis user that can sudo)- ① Create a .kube folder in the redis user's home directory
$ mkdir -p ~/.kube - ② Copy the k3s config file into the redis user's home (sudo required)
$ sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config - ③ Change ownership of the copied file to the redis user (sudo required)
$ sudo chown $(id -u):$(id -g) ~/.kube/config - ④ Set permissions (harden security)
$ chmod 600 ~/.kube/config
- ① Create a .kube folder in the redis user's home directory
- Step 3: Verify as the redis user
You can now query the Kubernetes cluster as the redis user without sudo.
💻 Terminal
- One more step: kubectl command completion and alias tips
Add the settings below to the redis account's '~/.bashrc' file. It is very convenient during tests.
# Add at the end of the redis user's ~/.bashrc
# Apply the changes💻 Terminal
$ source ~/.bashrc
With this setup you can drive K3s with short commands such as 'k get pods' instead of 'kubectl get pods'.
- What the script does
- 'KUBECONFIG':
When the 'kubectl' command runs in a K3s environment, a K3s environment variable or
wrapper script is set so that it first looks at '/etc/rancher/k3s/k3s.yaml' by default.
You must set the 'KUBECONFIG' environment variable so it explicitly uses the
'~/.kube/config' file you copied.
- 'alias k=kubectl': Alias so you can use 'k' the same way as 'kubectl'
- 'kubectl completion bash' auto-completion:
Kubernetes has many long subcommands and resource types to remember:
'get', 'describe', 'logs', 'statefulset', 'persistentvolumeclaim', and more.
'kubectl completion bash' prints a Bash auto-completion script. 'source' it into the shell so that pressing 'Tab' while typing recommends the next command.
* Example effect:
- Type 'kubectl get stat' then 'Tab' -> completes to 'kubectl get statefulsets'!
- Type 'kubectl des' then 'Tab' -> completes to 'kubectl describe'!
- 'complete -o default -F __start_kubectl k':
Meaning: attach the same auto-completion to the alias 'k'.
- 'KUBECONFIG':
When the 'kubectl' command runs in a K3s environment, a K3s environment variable or
wrapper script is set so that it first looks at '/etc/rancher/k3s/k3s.yaml' by default.
You must set the 'KUBECONFIG' environment variable so it explicitly uses the
'~/.kube/config' file you copied.
☸️ Useful Kubernetes commands
- List Pods: kubectl get pods
💻 Terminal
- List Pods with details (IP and running node): kubectl get pods -o wide
💻 Terminal
- Inspect a specific Pod and its events (for root-cause analysis): kubectl describe pod redis-0
💻 Terminal
- Print only Pod name and IP:
kubectl get pods -o custom-columns=POD_NAME:.metadata.name,POD_IP:.status.podIP💻 Terminal
- List disk volumes (PersistentVolumeClaim): kubectl get pvc
💻 Terminal
- Open a Linux shell: kubectl exec -it redis-0 -- /bin/bash
kubectl exec -it redis-0 -- /bin/bash -> general image: connect with bash
kubectl exec -it redis-0 -- /bin/sh -> Alpine image: connect with sh (Alpine images have no bash) - Connect to Redis: kubectl exec -it redis-0 -- redis-cli -p 18504 -a password
- Run a Redis command: kubectl exec -it redis-0 -- redis-cli -p 18504 -a password info
- View Redis logs: kubectl exec -it redis-0 -- tail -f /data/redis.log
- Apply a YAML file: kubectl apply -f redis-config.yaml
- Delete a Pod: kubectl delete pod redis-0
- Delete all redis Pods: kubectl delete statefulset redis
- Delete storage (pvc): kubectl delete pvc redis-data-redis-0
You can specify several: kubectl delete pvc redis-data-redis-0 redis-data-redis-1 redis-data-redis-2 - Delete all storage (pvc): kubectl delete pvc --all
☸️ Kubernetes concepts a Redis engineer must know
- ① StatefulSet (a set of Pods that keep state)
Ordinary web servers (stateless) are managed with 'Deployment', but databases such as Redis (stateful) must be managed with 'StatefulSet'.- Pods get sequential, fixed names (Ordinal Index) such as 'redis-0', 'redis-1', 'redis-2'.
- After a Pod restarts the IP may change, but the name and assigned disk (PVC) stay the same. From Redis 7.0 onward, name-based communication is supported, so an IP change is not a problem.
- ② Headless Service ('clusterIP: None')
A regular Service gives Pods a single representative IP (ClusterIP), but Redis Cluster/Sentinel need each node's own address.
- With 'clusterIP: None', K3s internal DNS automatically maps a stable FQDN such as 'redis-0.redis-service.default.svc.cluster.local' to each Pod's virtual IP.
- ③ initContainers (initialization containers)
One-shot containers that run before the main 'redis-server' process starts.- Copy read-only ConfigMap settings to a writable '/data' path.
- Extract the Pod index ('redis-0' -> '0') and dynamically compute and inject options such as 'replica-priority', 'cluster-announce-hostname', and 'replicaof'.
☸️ Docker, Container, and Pod: concepts and how they relate
When engineers who have run Redis on bare-metal (physical servers) or VMs first enter the
Kubernetes ecosystem, the most common confusion is the conceptual difference between Docker,
containers, and Pods.
Here is a structured view of the three ideas and how they work together.
Docker and Kubernetes are not competitors; they are partners with different roles.
Docker is the tool that 'builds' containers; Kubernetes is the tool that 'manages' those containers.
1. Each concept
- ① Pod: the smallest deployable unit Kubernetes manages
- Definition: the smallest unit Kubernetes schedules and manages, wrapping one or more containers together.
- Etymology: 'Pod' means a plant's bean pod. It pictures several peas (containers) inside one pod.
- Role: Kubernetes does not manage containers alone; it always wraps them in a Pod. Containers in the same Pod share the same Pod IP, the same network namespace (multiple ports are allowed), and the same storage (Volume).
- ② Container: an isolated running 'process'
- Definition: a real program (process) running in isolation on the host OS, with its own memory, filesystem, and process space, based on a Docker image as the 'mold'.
- Analogy: the actual bun baked from a mold, or a real cargo box
- Role: because it shares the host OS kernel, it is not as heavy as a VM, and it is a 'stateless running object' that starts and stops in seconds. But with storage (PVC) you can save and look up state, and restore the original state. In other words, it can be stateful. ➡ In Redis, rewrite of redis.conf, sentinel.conf, and nodes.conf lets you restore the previous state even after a Pod restart.
- ③ Docker: the 'mold' and platform that creates containers
- Definition: a platform (tool) that packages an application and every library/engine it needs into a standard 'container image' file and runs it.
- Analogy: a bun mold, or the standard cargo-container spec and crane
- Role: with 'docker build' you create a runnable image such as 'redis:8.8.2', and you push or pull it from a central registry (Docker Hub and others).
2. An easy analogy at a glance
| Item | Analogy (ecosystem) | Redis environment analogy |
|---|---|---|
| Pod | A 'bean pod' holding peas | The 'redis-0' Pod that contains [Redis] |
| Container | One 'pea' inside the shell | The running 'redis-server' process |
| Docker | The 'pea variety (seed)' | The 'redis:8.8.2' image file |
3. How the three relate (hierarchy)
The three concepts are not independent; lower layers are contained in higher ones (hierarchy).
[ Docker Image ] ──(run)──> [ Container ] ──(wrap/manage)──> [ Pod ]
(hub.docker.com)
(actual process)
(managed by k8s)
- 1) Image build stage (Docker's domain):
• Downloaded from Docker Hub: download from 'https://hub.docker.com/'.
• Built yourself: use Docker to package Redis source and the config file (redis.conf) into a Docker image named 'redis:8.8.2'. - 2) Container creation stage (runtime's domain):
Running a Docker image creates a container with its own memory space on the OS. By analogy, one running Redis process has started. - 3) Kubernetes Pod assembly stage (Kubernetes's domain):
Kubernetes does not control the container directly; it wraps it as a Pod.
• Single-container Pod (Redis Cluster, etc.): 1 Pod = 1 'redis-server' container
• Multi-container Pod (Redis Sentinel sidecar pattern, etc.): 1 Pod = 1 'redis-server' container + 1 'redis-sentinel' container (sidecar)
| << Kubernetes Getting Started ① | Kubernetes Redis Prep ③ >> |
|---|
