Debian-K3s集群的安装、配置与使用 K3s 是一个轻量级的 Kubernetes 发行版,旨在简化和优化 Kubernetes 的安装和运行。K3s 使用了简化的架构,使其更适合在资源受限的环境中运行,如边缘设备、物联网(IoT)设备和低功耗硬件。K3s 的架构基于标准的 Kubernetes 组件,但对其进行了精简和优化。
官方文档:https://docs.k3s.io/zh/
https://docs.rancher.cn/docs/k3s/_index
K3s 集群的典型拓扑
Server 节点指的是运行 k3s server
命令的主机,control plane 和数据存储组件由 K3s 管理。
Agent 节点指的是运行 k3s agent
命令的主机,不具有任何数据存储或 control plane 组件。
Server 和 Agent 都运行 kubelet、容器运行时和 CNI。
1. 单节点模式 在单节点模式下,k3s server
和 k3s agent
运行在同一台机器上。适用于测试环境或资源非常有限的环境。
1 2 3 4 5 6 [Master Node] (K3s server + agent) └── K3s API Server └── K3s Controller Manager └── K3s Scheduler └── etcd (默认使用 SQLite) └── K3s agent (用于运行容器和 Pod)
2. 多节点模式 在多节点模式下,k3s server
可以部署多个实例以提供高可用性,而 k3s agent
部署在多个工作节点上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [Master Node 1] (K3s server) └── K3s API Server └── K3s Controller Manager └── K3s Scheduler └── etcd (或外部 etcd)[Master Node 2] (K3s server) <- 高可用配置 └── K3s API Server └── K3s Controller Manager └── K3s Scheduler[Worker Node 1] (K3s agent) └── K3s agent └── 容器运行时[Worker Node 2] (K3s agent) └── K3s agent └── 容器运行时
部署 K3s 单节点模式是非常简单的。以下是安装步骤,涵盖了从安装 K3s 到验证集群是否正常运行的完整过程。
步骤 1:准备环境 确保你的机器有互联网连接,并且已经更新了系统。
更新系统 : 在安装 K3s 之前,先确保系统是最新的:
1 2 sudo apt updatesudo apt upgrade -y
2.安装Docker
由于 K3s 默认运行环境为 containerd,所以为了使用 Docker 作为运行时,需要先在各节点正常安装 Docker
https://getdocker.quickso.cn/
步骤 2:安装 K3s 默认:
1 curl -sfL https ://get .k3s.io | sh -
国内:
1 2 3 4 curl –sfL \ https://rancher-mirror.rancher.cn /k3s/k3s-install.sh | \ INSTALL_K3S_MIRROR=cn sh -s - \ --system -default-registry "registry.cn-hangzhou.aliyuncs.com"
要使用 Docker 而不是 containerd
默认:
1 curl -sfL https ://get .k3s.io | sh -s -
国内:
1 curl -sfL https://rancher-mirror.rancher.cn /k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - --docker
常用命令
类型
命令
使用方法及示例
集群信息
kubectl cluster-info
显示集群基本信息 kubectl cluster-info
kubectl version
查看客户端和服务器版本 kubectl version --short
节点管理
kubectl get nodes
查看所有节点状态 kubectl get nodes -o wide
kubectl describe node <节点名>
查看节点详细信息 kubectl describe node node01
命名空间
kubectl get ns
查看所有命名空间 kubectl get ns
kubectl create ns <命名空间>
创建命名空间 kubectl create ns test
Pod 管理
kubectl get pods
查看默认命名空间的 Pod kubectl get pods -n <命名空间>
kubectl describe pod <Pod名>
查看 Pod 详细信息 kubectl describe pod nginx-pod
kubectl logs <Pod名>
查看 Pod 日志 kubectl logs nginx-pod -c <容器名>
(多容器场景)
kubectl exec -it <Pod名> -- <命令>
进入 Pod 容器 kubectl exec -it nginx-pod -- /bin/sh
kubectl delete pod <Pod名>
删除 Pod kubectl delete pod nginx-pod --force
(强制删除)
部署管理
kubectl get deployments
查看 Deployment kubectl get deploy -A
(全命名空间)
kubectl scale deploy <Deployment名> --replicas=<数量>
扩缩容 kubectl scale deploy nginx-deploy --replicas=3
kubectl rollout status deploy/<Deployment名>
查看滚动更新状态 kubectl rollout status deploy/nginx-deploy
kubectl rollout undo deploy/<Deployment名>
回滚到上一版本 kubectl rollout undo deploy/nginx-deploy
服务管理
kubectl get services
查看 Service kubectl get svc
kubectl expose deploy <Deployment名> --port=<端口>
创建 Service kubectl expose deploy nginx-deploy --port=80 --type=NodePort
配置管理
kubectl get configmaps
查看 ConfigMap kubectl get cm
kubectl create configmap <名称> --from-file=<文件路径>
从文件创建 ConfigMap kubectl create configmap app-config --from-file=config.properties
存储管理
kubectl get pv
查看持久卷(PV) kubectl get pv
kubectl get pvc
查看持久卷声明(PVC) kubectl get pvc -n default
调试诊断
kubectl top pod
查看 Pod 资源使用 kubectl top pod --sort-by=cpu
kubectl get events --sort-by=.metadata.creationTimestamp
查看事件(按时间排序) kubectl get events -n kube-system
应用部署
kubectl apply -f <YAML文件>
通过 YAML 文件部署资源 kubectl apply -f nginx.yaml
kubectl delete -f <YAML文件>
删除 YAML 定义的资源 kubectl delete -f nginx.yaml
标签筛选
kubectl get pods -l <键>=<值>
按标签筛选资源 kubectl get pods -l app=nginx
端口转发
kubectl port-forward <Pod名> <本地端口>:<Pod端口>
端口转发到本地 kubectl port-forward nginx-pod 8080:80
补丁更新
kubectl patch deploy <名称> -p '{"spec": {"template": {"metadata": {"annotations": {"update": "v2"}}}}}'
热更新 Deployment kubectl patch deploy nginx-deploy -p '{"spec":{"replicas":5}}'
配置镜像 Docker 1 2 3 echo '{"registry-mirrors": ["https://docker.1ms.run"]}' | sudo tee /etc/docker/daemon.json > /dev/null systemctl daemon-reload systemctl restart docker
K3s 1 2 3 4 5 6 7 cat >> /etc/rancher/k3s/registries.yaml <<EOF mirrors: "docker.io": endpoint: - "https://docker.1ms.run" EOF systemctl restart k3s
安装完成后,K3s 会自动启动, 检查K3s服务的状态:
1 sudo systemctl status k3s
工作节点的安装(可选) 查看 K3S_TOKEN
1 sudo cat /var/lib/rancher/k3s/server/node-token
Agent安装 1 root@k 3s-agent-1 :~# curl -sfL https ://get.k3s.io | K3S_URL=https ://MASTER_URL :6443 K3S_TOKEN=NODE_TOKEN sh -
要使用 Docker 而不是 containerd
1 2 3 curl -sfL https://g et.k3s.io | K3S_URL=https:// MASTER_URL:6443 K3S_TOKEN=NODE_TOKEN INSTALL_K3S_EXEC="--docker" sh - curl -sfL http:// rancher-mirror.cnrancher.com/k3s/ k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https:// MASTER_URL:6443 K3S_TOKEN=NODE_TOKEN INSTALL_K3S_EXEC="--docker" sh -
根据需求把上面的 https://MASTER_URL:6443
和 NODE_TOKEN
更换成你的即可
K3s worker 节点的角色默认为none
,如何修改?
可以通过kubectl label node 节点名称 node-role.kubernetes.io/worker=worker
为节点增加 worker 角色。
配套工具 helm
Helm 是一个 Kubernetes 包管理工具,类似于 Linux 下的 apt
或 yum
,它帮助用户管理 Kubernetes 应用的安装、升级和配置。
helm官网地址:https://helm.sh/docs/intro/install/
在上面的文档中找到你的服务器对应系统的安装流程,下面是Ubuntu的安装流程
1 2 3 curl -fsSL -o get_helm .sh https ://raw .githubusercontent .com /helm /helm /main /scripts /get-helm-3 chmod 700 get_helm .sh ./get_helm .sh
也可以Apt安装
1 2 3 4 5 curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/nullsudo apt-get install apt-transport-https --yes echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.listsudo apt-get updatesudo apt-get install helm
然后复制k3s.yml到~/.kube/文件夹下即可
1 cp /etc/rancher/k3s/k3s.yaml ~/.kube/
测试helm命令:
kubepi
KubePi 是一个现代化的 K8s 面板。
KubePi 允许管理员导入多个 Kubernetes 集群,并且通过权限控制,将不同 cluster、namespace 的权限分配给指定用户。它允许开发人员管理 Kubernetes 集群中运行的应用程序并对其进行故障排查,供开发人员更好地处理 Kubernetes 集群中的复杂性。
https://github.com/1Panel-dev/KubePi
文档:https://github.com/1Panel-dev/KubePi/wiki/
安装(持久化部署)
1 wget https:// raw.githubusercontent.com/1Panel-dev/ KubePi/master/ docs/deploy/ kubectl/kubepi-pvc.yaml
获取StorageClass
修改
1 storageClassName: local -path 修改这个配置为你的StorageClass
应用
1 kubectl apply -f kubepi-pvc.yaml
获取访问地址
1 2 3 4 5 6 7 export NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}" )export NODE_PORT=$(kubectl -n kube-system get services kubepi -o jsonpath="{.spec.ports[0].nodePort}" )echo http://$NODE_IP :$NODE_PORT
登录系统 地址: http://$NODE_IP:$NODE_PORT 用户名: admin 密码: kubepi
集群导入
选择集群列表-导入-认证模式选择kubeconfig 文件
在终端执行
1 cat /etc/rancher/k3s/k3s.yaml
将输出的内容复制粘贴到输入框
如果 server IP 为 127.0.0.1,需要将 IP 替换为集群 master 节点 IP
然后修改默认密码,就可以开始使用了,更多内容请看官方文档
卸载 K3s 如果您使用安装脚本安装了 K3s,那么在安装过程中会生成一个卸载 K3s 的脚本。
卸载 K3s 会删除集群数据和所有脚本。要使用不同的安装选项重新启动集群,请使用不同的标志重新运行安装脚本。
要从 server 节点卸载 K3s,请运行:
1 /usr/ local/bin/ k3s-uninstall.sh
要从 agent 节点卸载 K3s,请运行:
1 /usr/ local/bin/ k3s-agent-uninstall.sh
部署服务 以NGINX为例
创建 Pod 将以下代码写入 nginx-pod.yaml
:
1 2 3 4 5 6 7 8 9 10 apiVersion : v1 kind : Pod metadata : name : nginx spec : containers : - name: nginx image : nginx:latest ports : - containerPort: 80
使用如下命令应用:
1 2 root@k3s -server:~/k3s# kubectl apply -f nginx-pod.yaml pod/nginx created
查看运行状态:
1 2 3 root @k3s-server:~# kubectl get podNAME READY STATUS RESTARTS AGEnginx 1 /1 Running 0 11 h
与 Docker 不同,这里进入容器的需要在命令前加上 --
进入 Pod 并测试访问:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 root@k3s-server:~/k3s# kubectl exec -it nginx -- /bin/bash root@nginx:/# curl localhost<!DOCTYPE html > <html > <head > <title > Welcome to nginx!</title > <style > html { color-scheme : light dark; }body { width : 35em ; margin : 0 auto;font-family : Tahoma, Verdana, Arial, sans-serif; }</style > </head > <body > <h1 > Welcome to nginx!</h1 > <p > If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p > <p > For online documentation and support please refer to<a href ="http://nginx.org/" > nginx.org</a > .<br /> Commercial support is available at<a href ="http://nginx.com/" > nginx.com</a > .</p > <p > <em > Thank you for using nginx.</em > </p > </body > </html >
到此为止,我们创建了一个功能正常的 Pod。
创建 Deployment 将以下代码写入 nginx-deployment.yaml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 apiVersion : apps/v1 kind : Deployment metadata : name : nginx spec : selector : matchLabels : app : nginx replicas : 2 template : metadata : labels : app : nginx spec : containers : - name: nginx image : nginx:latest ports : - containerPort: 80
使用如下命令应用:
1 2 root@k3s -server:~/k3s# kubectl apply -f nginx-deployment.yaml deployment.apps/nginx created
查看运行状态:
1 2 3 root @k3s-server:~/k3s# kubectl get deploymentNAME READY UP-TO-DATE AVAILABLE AGEnginx 2 /2 2 2 29 s
此时再查看 Pod,如下:
1 2 3 4 root @k3s-server:~/k3s# kubectl get podNAME READY STATUS RESTARTS AGEnginx -544 dc8b7c4-lzvz9 1 /1 Running 0 3 m4snginx -544 dc8b7c4-5 nbcw 1 /1 Running 0 3 m4s
可以看到,由 Deployment 产生的 Pod 命名规则如下:
1 ${DeploymentName} -${DeploymentUid} -${Hash}
在查看 Pod 的时候,如果加上 -o wide
参数,就可以查看更多信息:
1 2 3 4 root @k3s-server:~/k3s# kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx -544 dc8b7c4-lzvz9 1 /1 Running 0 9 m30s 10.42.1.4 k3s-agent-1 <none> <none>nginx -544 dc8b7c4-5 nbcw 1 /1 Running 0 9 m30s 10.42.3.3 k3s-agent-2 <none> <none>
可以看到,该 nginx 被创建了两个 Pod 副本,分别部署在了 k3s-agent-1
和 k3s-agent-2
上面。
创建 Service Service,将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
举个例子,考虑一个图片处理后端,它运行了 3 个副本。这些副本是可互换的 —— 前端不需要关心它们调用了哪个后端副本。 然而组成这一组后端程序的 Pod 实际上可能会发生变化, 前端客户端不应该也没必要知道,而且也不需要跟踪这一组后端的状态。
Service 定义的抽象能够解耦这种关联。
Service 有两种类型,一种是 NodePort
,选择该种类型的可直接通过 ${serverIP}:${nodePort}
访问内部的服务;另一种是 ClusterIP
类型,它只会在集群内部可以访问到该 Pod,不会把 Pod 的内容映射在某一个外网可以访问的端口上,但这并不意味着不能对外提供服务,而是需要 Ingress 的帮助,来将外网的流量转发到 Service 上来。
NodePort 将以下代码写入 nginx-service-nodeport.yaml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 apiVersion : v1 kind : Service metadata : name : nginx-service spec : selector : app : nginx ports : - protocol: TCP port : 80 targetPort : 80 nodePort : 30080 type : NodePort
这里 nodePort
的范围是 30000-32767
。
使用如下命令应用:
1 2 root@k3s -server:~/k3s# kubectl apply -f nginx-service-nodeport.yaml service/nginx-service created
现在访问 http://10.0.0.39:30080
、 http://10.0.0.31:30080
与 http://10.0.0.32:30080
,都可以正常访问到内容:
查看 Service:
1 2 3 4 root@k3s-server :~/k3s# kubectl get serviceNAME TYPE CLUSTER -IP EXTERNAL -IP PORT(S) AGE kubernetes ClusterIP 10.43 .0 .1 <none > 443 /TCP 12 h nginx-service NodePort 10.43 .74 .219 <none > 80 :30080 /TCP 7 m21s
ClusterIP Service 将以下代码写入 nginx-service-clusterip.yaml
:
1 2 3 4 5 6 7 8 9 10 11 apiVersion : v1 kind : Service metadata : name : nginx-service spec : selector : app : nginx ports : - protocol: TCP port : 80 targetPort : 80
使用如下命令应用:
1 2 root@k3s -server:~/k3s# kubectl apply -f nginx-service-clusterip.yaml service/nginx-service created
这样就创建了 Service,但外部还不能访问,所以需要 Ingress。
Ingress 先做个 DNS 解析:
类型
名称
内容
A
*.k3s.abc.com
10.0.0.39
A
*.k3s.abc.com
10.0.0.31
A
*.k3s.abc.com
10.0.0.32
将以下代码写入 nginx-ingress.yaml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apiVersion : networking.k8s.io/v1 kind : Ingress metadata : name : nginx-ingress spec : rules : - host: nginx.k3s.abc.com http : paths : - path: / pathType : Prefix backend : service : name : nginx-service port : number : 80
使用如下命令应用:
1 2 root@k3s -server:~/k3s# kubectl apply -f nginx-ingress.yaml ingress.networking.k8s.io/nginx-ingress created
现在访问 http://nginx.k3s.abc.com
即可访问到部署的服务:
尝试关掉 k3s-agent-1
:
1 root@k3s -agent-1 :/home/jiji
证实 k3s-agent-1
确实下线了:
1 2 3 4 5 root @k3s-server:~# kubectl get nodeNAME STATUS ROLES AGE VERSIONk3s -server Ready control-plane,master 13 h v1.24 .4 +k3s1k3s -agent-2 Ready <none> 12 h v1.24 .4 +k3s1k3s -agent-1 NotReady <none> 12 h v1.24 .4 +k3s1
再访问 http://nginx.k3s.abc.com
,服务出现不可用,但刷新后也可访问正常。经过两次连续的 ping,我们发现 DNS 解析由原本失效的 10.0.0.31
,变为了 10.0.0.39
。这也就保证了在 Agent 宕机的情况下服务高可用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $ ping nginx.k3s.abc.com 正在 Ping nginx.k3s.abc.com[10.0.0.31] 具有 32 字节的数据 : 来自 10.0.0.1 的回复 : 无法访问目标主机。 来自 10.0.0.1 的回复 : 无法访问目标主机。 来自 10.0.0.1 的回复 : 无法访问目标主机。 来自 10.0.0.1 的回复 : 无法访问目标主机。 10.0.0.31 的 Ping 统计信息 : 数据包 : 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), $ ping nginx.k3s.abc.com 正在 Ping nginx.k3s.abc.com [10.0.0.39] 具有 32 字节的数据 : 来自 10.0.0.39 的回复 : 字节=32 时间=3ms TTL=63 来自 10.0.0.39 的回复 : 字节=32 时间=5ms TTL=63 来自 10.0.0.39 的回复 : 字节=32 时间=5ms TTL=63 来自 10.0.0.39 的回复 : 字节=32 时间=12ms TTL=63 10.0.0.39 的 Ping 统计信息 : 数据包 : 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失), 往返行程的估计时间(以毫秒为单位) : 最短 = 3ms,最长 = 12ms,平均 = 6ms
但当我关闭 k3s-server
的时候,服务出现了不可用,且无自动切换。或许对于高可用 K3s 集群来说,需要至少两台 Server
节点。
HTTPS 1 2 3 root@k3s-server:~# kubectl create secret tls my-tls-secret \ --cert=path /to /cert/file \ --key =path /to /key /file
在 nginx-ingress.yaml
中追加:
1 2 3 4 5 spec : tls : - hosts: - nginx.k3s.abc.com secretName : my-tls-secret