Kubernetes basics
Instruction
Control plane vs worker nodes
Control Plane:
- The control plane is installed on your master node
- Can be both a control plane node and a worker node
- It houses the API server, scheduler, and controller manager settings
Worker Nodes:
- This is where the kubelet and kube-proxy are installed
- You can use the kubeadm join command to join workers to the master node to form the cluster
First Test
New Pod
shell-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: shell-demo
spec:
volumes:
- name: shared-data
emptyDir: {}
containers:
- name: nginx
image: nginx
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
hostNetwork: true
dnsPolicy: Default
Create a Pod
kubectl apply -f https://k8s.io/examples/application/shell-demo.yaml
Verify that the container is running
kubectl get pod shell-demo
# Get a shell to the running container
kubectl exec -it shell-demo -- /bin/bash
New Deployment
nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Create a Deployment
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
# Without a yaml file
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
EOF
Verify
kubectl get deployments
kubectl get pods --show-labels
Common commands
Apply a yaml file
myapp.yaml:
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: mem-example
spec:
containers:
- name: memory-demo-ctr
image: polinux/stress
resources:
requests:
memory: "100Mi"
limits:
memory: "200Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
# Create a pod memory-demo
kubectl apply -f myapp.yaml
Kubectl Configuration
kubectl version
kubectl cluster-info
kubectl config view
kubectl config view --minify --raw
Namespace & Node
- Namespace 命名規則:名稱會用於內部的 subdomain,開頭與結尾必須字母數字,不可超過 253 個字元,只能包含小寫字母數字及 hyphen, dot 符號。
# Create a namespace mem-example
kubectl create namespace mem-example
kubectl get ns
# Check the nodes
kubectl get nodes
kubectl describe node
Pod
# Create a pod memory-demo
kubectl apply -f myapp.yaml
# Check the pods
kubectl get pods
kubectl get all -A
kubectl get pod memory-demo --namespace=mem-example
kubectl get pod memory-demo --output=yaml --namespace=mem-example
kubectl top pod memory-demo --namespace=mem-example
kubectl describe pod memory-demo --namespace=mem-example
# Delete a pod
kubectl delete pod memory-demo --namespace=mem-example
# Run Shell in the Pod
kubectl exec -it <pod-name> -n <namespace> -- bash
# Attach the pod
kubectl attach <pod-name> -n <namespace> -i
# Force to delete a pod
kubectl delete pod <pod-name> --force --grace-period=0
Deployment
kubectl get deployments
kubectl rollout status deployment/nginx-deployment
kubectl describe deployment <deployment-name>
# Update a new image
kubectl set image deployment/nginx-deployment nginx=nginx:sometag
# Scale a deployment
kubectl scale deployment deployment --replicas=X
Delete a deployment
NOTE: 刪除 deployment 後,底層的其他相關資源,例如 container, PersistentVolumes, image, kubernetes secrets 仍然存在,必須手動移除。
# Delete the specified deployment
kubectl delete deployment <deployment name> --namespace <namespace name>
# Delete all deployments for the specified namespace
kubectl delete deployment --all --namespace=<namespace name>
# Using yaml file to delete the deployment
kubectl delete -f blog-deployment-1.yaml -f blog-deployment-2.yaml
# Using label selector
kubectl get deployment -l app=my-app
kubectl get all --selector app=[app-label]
kubectl delete deployment -l app=my-app
kubectl delete all --selector app=[app-label]
# Force-delete a hung deployment
kubectl delete deployment <deployment-name> --grace-period=0 --force
kubectl delete replicaset -l app=<label>
kubectl delete pods -l app=<label>
Secret
- 變數的值以 yaml 格式輸出時,會以 base64 編碼顯示。
# Create a secret as environment variables
kubectl create secret generic [secret-name] \
--from-literal=APP_API_KEY='your-api-key' \
--from-literal=EXTERNAL_SERVICE_API_KEY='your-external-key' \
-n [your-namespace]
Pull Docker Images from Private Docker Registries
# Create
kubectl create secret docker-registry [secret-name] \
--docker-server:[address] \
--docker-username=[username] \
--docker-password=[password] \
-n [namespace]
Check the secret
kubectl get secret [secret-name] -n [namespace] -o yaml
PVC
PersistentVolumeClaim
kubectl get pvc -n <namespace>
kubectl delete pvc <pvc-name> -n <namespace>
Label
kubectl label pods <pod-name> <label-key>=<label-value>
# Show labels
kubectl get pods --show-labels -n <namespace>
Service
# Check service
kubectl get svc -n <name-space>
# Create a service to expose the port of a pod
kubectl expose pod <pod-name> --port=<pod-port> --name=<service-name> -n <name-space>
Monitor the log
kubectl logs -f deployment/<deployment-name> -n <name-space>
kubectl logs -f pod/<pod-name> -n <name-space>
Get a yaml file
Get the complete manifest of the deployed Kubernetes object.
kubectl get deploy nginx -n nginx-demo -o yaml
kubectl get svc <service-name> -n <name-space> -o yaml
kubectl get deployment <deployment-name> -n <name-space> -o yaml
檢查環境變數配置
kubectl get deployment your-app-name -n your-namespace-prod -o yaml | grep EXTERNAL_SERVICE_URL
Networking
Inbound Rules for K3s Nodes
| Protocol | Port | Source | Destination | Description |
|---|---|---|---|---|
| TCP | 2379-2380 | Servers | Servers | Required only for HA with embedded etcd |
| TCP | 6443 | Agents | Servers | K3s supervisor and Kubernetes API Server |
| UDP | 8472 | All nodes | All nodes | Required only for Flannel VXLAN |
| TCP | 10250 | All nodes | All nodes | Kubelet metrics |
| UDP | 51820 | All nodes | All nodes | Required only for Flannel Wireguard with IPv4 |
| UDP | 51821 | All nodes | All nodes | Required only for Flannel Wireguard with IPv6 |
| TCP | 5001 | All nodes | All nodes | Required only for embedded distributed registry (Spegel) |
| TCP | 6443 | All nodes | All nodes | Required only for embedded distributed registry (Spegel) |
Typically, all outbound traffic is allowed.
Network access to other pods
- Different Namespace:
http://<service-name>.<namespace>:<port> - Same Namespace:
http://<service-name>:<port>