Skip to main content

Kubernetes

minikube 安装

https://minikube.sigs.k8s.io/docs/start/

以 ubuntu 22 为例

创建 docker 用户并安装 docker

sudo useradd -m -s /bin/bash docker
sudo passwd docker
sudo usermod -aG sudo docker

安装 docker
https://docs.docker.com/engine/install/ubuntu/

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# Install Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Verify Installation
sudo docker run hello-world
curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64

启动和停止

minikube start
minikube stop

安装 kubectl

https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

kubectl version --client
Client Version: v1.32.1
Kustomize Version: v5.5.0

查看节点

kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 127m v1.32.0

查看服务

kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 128m

查看 pod

kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-668d6bf9bc-bwj9m 1/1 Running 0 56s
kube-system etcd-minikube 1/1 Running 0 61s
kube-system kube-apiserver-minikube 1/1 Running 0 61s
kube-system kube-controller-manager-minikube 1/1 Running 0 61s
kube-system kube-proxy-cmmfw 1/1 Running 0 56s
kube-system kube-scheduler-minikube 1/1 Running 0 62s
kube-system storage-provisioner 1/1 Running 1 (26s ago) 59s
apiVersion: apps/v1
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.26
ports:
- containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 10000
type: NodePort

secret

docker@GreenCloud:~$ echo '1234' > pass.txt
docker@GreenCloud:~$ kubectl create secret generic pass --from-file=pass.txt
secret/pass created
docker@GreenCloud:~$ kubectl get secrets
NAME TYPE DATA AGE
pass Opaque 1 7s

Pod 与容器

kubernetes 中最小的调度单元。

常见使用方式有 2 中:运行单个容器的 pod 和运行多个协同容器的 pod

但通常不会直接管理 pod ,而是通过 deployment 和 job 等负载管理,如果要跟踪状态则用 statefulSet

查询 pod

# 查询 pod (默认命名空间)
kubectl get po|pod|pods

# 查询所有命名空间
kubectl get pod -A

# 查询详细信息
kubectl get pod -o wide

# 监控状态
kubectl get pod -w

# 指定命名空间
kubectl get pod -n kube-system

# 查看帮助
kubectl get pod --help

手动创建一个 pod

kubectl run mynginx --image=nginx:1.27.3

查看详细信息

kubectl describe pod mynginx

便携 mynginx.yml 文件

# api 版本
apiVersion: v1
# 类型
kind: Pod
# 元数据
metadata:
name: mynginx
spec:
containers:
- name: nginx
image: nginx:1.27.3
ports:
- containerPort: 80

通过 yml 文件创建 pod ,使用 kubectl create/apply 命令, create 只能创建一次,apply 不存在会创建,存在则更新

$ kubectl apply -f nginx-pod.yml 
pod/mynginx created

删除 pod

kubectl delete pod mynginx
kubectl delete -f nginx-pod.yml

进入 pod 的容器

kubectl exec -it <pod name> -c <container name> -- <command>

# 不指定容器则进入 pod 的第一个容器
kubectl exec -it mynginx -- /bin/bash

查看日志

kubectl logs -f mynginx

创建包含多个容器的 pod

apiVersion: v1
kind: Pod
metadata:
name: nginx-redis
labels:
env: dev
name: nginx-redis
spec:
containers:
- name: nginx
image: nginx:1.27.3
ports:
- containerPort: 80
- name: redis
image: redis:7.4
ports:
- containerPort: 6379

查看 pod

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-redis 2/2 Running 0 7s

查看日志

# redis 容器日志
kubectl logs -f nginx-redis -c redis
# nginx 容器日志
kubectl logs -f nginx-redis -c nginx

标签

标签的值为 0-63 个字符,支持大小写,数字,下划线,横岗,点,需要以字母开头

可以在刚才的 yml 文件中添加自定义标签

apiVersion: v1
kind: Pod
metadata:
name: nginx-redis
labels:
env: dev
name: nginx-redis

查看 pod

$ kubectl get po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-redis 2/2 Running 0 11s env=dev,name=nginx-redis

Pod 的生命周期

起始 Pending,正常启动 Running ,成功或失败结束的 Succeed Faild ,unknown 位置状态,通常是与节点通信失败

容器的生命周期:Waiting 仍然没有完全启动, Running 正在运行,且 postStart 回调已经执行, Terminated 已终止且 preStop 已经执行

apiVersion: v1
kind: Pod
metadata:
name: life
spec:
containers:
- name: nginx
image: nginx:1.27.3
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo postStart >> /start.txt"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo preStop >> /stop.txt && sleep 50"]
ports:
- containerPort: 80

重启策略

通过 spec.restartPolicy 字段配置重启策略,适用于所有容器。Always 总是重启, OnFailure 异常退出状态非 0 时重启,Nerver 不重启,默认 Always

创建一个 pod 用于测试

apiVersion: v1
kind: Pod
metadata:
name: policy
spec:
containers:
- name: nginx
image: nginx:1.27.3
restartPolicy: Always

查看容器。另外打开一个 terminal ,进入容器并停止 nginx -s stop,可以看到一个 pod 重新启动

$ kubectl get po -w
NAME READY STATUS RESTARTS AGE
policy 1/1 Running 0 10s
policy 0/1 Completed 0 45s
policy 1/1 Running 1 (2s ago) 47s

如果设为 Never ,可以观察到

$ kubectl get po -w
NAME READY STATUS RESTARTS AGE
policy 1/1 Running 0 1s
policy 0/1 Completed 0 17s
policy 0/1 Completed 0 18s

传递启动参数

Kubernetes 可以通过 command 和 args 来修改容器启动默认命令和传递参数

开启 redis 容器的持久化,使用 redis-server --appendonly yes 作为启动命令

apiVersion: v1
kind: Pod
metadata:
name: redis-command
spec:
containers:
- name: redis
image: redis:7.4
command: ["redis-server"]
args: ["--appendonly yes"]

验证

$ kubectl exec -it redis-command -- ls
appendonlydir

资源限制

可以对 cpu 和内存进行资源限制,有 2 种限制:request 可以使用的基础资源, limit 可以使用的最大资源,超过最大资源会被 kill

apiVersion: v1
kind: Pod
metadata:
name: nginx-limit
spec:
containers:
- name: nginx
image: nginx:1.27.3
resources:
requests:
memory: "100Mi"
cpu: "500m"
limits:
memory: "200Mi"
cpu: "1"

Init 容器

在 pod 内容器启动之前运行,进行一些前置操作。如果 Init 容器失败,kubernetes 会不断重启知道成功为止。

apiVersion: v1
kind: Pod
metadata:
name: testinit
spec:
containers:
- name: init
image: busybox:1.36
command: ["sh", "-c", "echo the app is running! && sleep 3600"]
imagePullPolicy: IfNotPresent
initContainers:
- name: init-service
image: busybox:1.36
command: ["sh", "-c", "echo init service is running && sleep 5"]
- name: init-db
image: busybox:1.36
command: ["sh", "-c", "echo init db is running && sleep 5"]

运行

$ kubectl apply -f testinit.yml 
pod/testinit created

$ kubectl get po -w
NAME READY STATUS RESTARTS AGE
testinit 0/1 Init:1/2 0 7s
testinit 0/1 Init:1/2 0 7s
testinit 0/1 PodInitializing 0 12s
testinit 1/1 Running 0 13s

$ kubectl describe pod testinit
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 83s default-scheduler Successfully assigned default/testinit to minikube
Normal Pulled 83s kubelet Container image "busybox:1.36" already present on machine
Normal Created 83s kubelet Created container: init-service
Normal Started 83s kubelet Started container init-service
Normal Pulled 77s kubelet Container image "busybox:1.36" already present on machine
Normal Created 77s kubelet Created container: init-db
Normal Started 77s kubelet Started container init-db
Normal Pulled 71s kubelet Container image "busybox:1.36" already present on machine
Normal Created 71s kubelet Created container: init
Normal Started 71s kubelet Started container init

Controller

控制器监控集群的状态,并致力于将当前状态转变为期望的状态

常见的 Controller :Deployment, Job, Daemonset, StatefulSet

Deployment 最常用的 Controller
Daemonset 最多只运行一个 pod 副本的场景
Statefulset pod 的名称在整个生命周期不变,保证副本按照顺序启动,更新,删除
Job 运行结束就删除

Controller 通过 label 关联 pod