ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

k3s与Docker集成部署指南:轻量K8s集群的容器运行时切换实践

k3s与Docker集成部署指南:轻量K8s集群的容器运行时切换实践 1. 项目概述为什么选择 k3s 与 Docker 的组合如果你正在寻找一种能在边缘设备、开发机或者资源有限的服务器上快速搭建一个轻量级 Kubernetes 集群的方案那么k3s绝对是一个绕不开的名字。它由 Rancher Labs 出品本质上是一个经过高度精简和优化的 Kubernetes 发行版去掉了很多传统 K8s 中用于支撑超大规模、高可用场景的组件比如 etcd默认使用内置的 SQLite、云控制器管理器等。这使得它的二进制文件极小启动飞快内存和 CPU 占用极低对硬件的要求非常友好。而当我们谈论在 k3s 中运行工作负载时容器运行时是一个核心组件。虽然 k3s 默认集成了containerd作为其容器运行时但在很多实际场景中我们可能更倾向于使用Docker。原因很简单Docker 拥有更庞大、更成熟的生态其命令行工具CLI对于开发者而言更为熟悉和直观围绕 Docker 构建的 CI/CD 流水线、镜像构建流程和运维经验也更为丰富。将 k3s 的容器运行时从 containerd 切换为 Docker意味着你可以继续使用你熟悉的docker build、docker push以及docker logs等命令来直接管理容器同时又能享受到 k3s 带来的轻量级 Kubernetes 编排能力。因此“k3s部署-docker版”这个项目核心目标就是在单节点或多节点环境中部署一个使用 Docker 作为容器运行时的 k3s 集群。这尤其适合以下人群Kubernetes 初学者希望有一个更贴近传统容器体验的学习环境中小团队需要在开发测试环境或资源受限的生产边缘节点快速搭建可用的 K8s 集群以及那些已有深厚 Docker 工具链积累希望平滑过渡到 Kubernetes 的团队。2. 环境准备与前置条件解析在开始部署之前确保你的基础环境是正确和干净的这能避免至少 80% 的后续问题。我强烈建议在一个全新的 Linux 虚拟机或服务器上开始如果条件有限也务必做好现有环境的清理工作。2.1 系统要求与依赖检查k3s 对系统的要求非常宽松但为了获得最佳体验建议遵循以下规范操作系统主流的 Linux 发行版均可例如 Ubuntu 20.04/22.04 LTS、CentOS 7/8、Rocky Linux 8/9 等。我个人更推荐 Ubuntu因为其软件源和社区支持非常活跃遇到问题更容易找到解决方案。硬件资源这是 k3s 的优势所在。对于一个仅用于学习和功能验证的单节点集群1核 CPU、1GB 内存的机器就足以运行 k3s 核心组件及一些轻量级应用。如果计划运行数据库、监控系统等建议至少 2核2GB。对于生产边缘场景请根据实际工作负载评估。网络与防火墙确保节点之间如果是多节点的特定端口可以互通。k3s server控制平面默认使用 6443 端口节点间通信使用 8472 端口Flannel VXLAN。如果开启了防火墙如ufw或firewalld需要放行这些端口。在单节点部署中本地回环通信即可防火墙配置相对简单。一个必须的前置依赖是内核模块。k3s 和 Docker 都需要一些特定的内核模块来支持网络和存储功能。运行以下命令来加载它们并设置为开机自动加载sudo modprobe overlay sudo modprobe br_netfilter为了让这些模块持久化可以创建配置文件cat EOF | sudo tee /etc/modules-load.d/k3s.conf overlay br_netfilter EOF此外还需要配置sysctl参数这是为了让容器内的网络能正常工作例如服务发现、端口映射cat EOF | sudo tee /etc/sysctl.d/k3s.conf net.bridge.bridge-nf-call-ip6tables 1 net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 EOF sudo sysctl --system2.2 清理潜在的运行时冲突这是部署“Docker版”k3s 最关键的一步。如果你的系统上已经安装了旧版本的 Docker、containerd 或者尝试过其他 Kubernetes 发行版如 kubeadm 安装的集群必须进行彻底清理否则端口、套接字和配置文件的冲突会导致安装失败或行为异常。执行以下清理脚本适用于基于 systemd 的系统如 Ubuntu# 停止并禁用可能存在的 k3s 服务 sudo systemctl stop k3s 2/dev/null sudo systemctl disable k3s 2/dev/null sudo rm -f /etc/systemd/system/k3s.service # 清理 k3s 相关文件和目录 sudo rm -rf /var/lib/rancher/k3s sudo rm -rf /etc/rancher/k3s # 彻底清理 Docker如果已安装 sudo systemctl stop docker docker.socket containerd 2/dev/null sudo systemctl disable docker docker.socket containerd 2/dev/null sudo apt-get remove --purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y # Ubuntu/Debian # 对于 CentOS/RHEL: sudo yum remove docker-ce docker-ce-cli containerd.io -y # 清理 Docker 相关文件和目录 sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd sudo rm -rf /etc/docker # 清理可能存在的 Kubernetes 组件 sudo kubeadm reset -f 2/dev/null sudo rm -rf $HOME/.kube # 重启系统可选但推荐确保所有残留进程被清除 sudo reboot注意rm -rf命令是破坏性的请确保你了解其含义并在执行前确认目录无误。清理后重启系统是一个好习惯能确保所有旧的进程和挂载点被彻底释放。3. Docker 运行时安装与配置在部署 k3s 之前我们需要先安装 Docker。这里我们选择 Docker 官方提供的安装脚本它兼容性好能自动处理不同发行版的依赖。3.1 安装 Docker Engine连接到你的服务器执行以下命令# 下载并执行 Docker 官方安装脚本 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh这个脚本会自动检测你的操作系统添加 Docker 的官方软件源并安装最新稳定版的 Docker Engine、CLI、containerd 和 Docker Compose 插件。安装完成后启动 Docker 服务并设置为开机自启sudo systemctl start docker sudo systemctl enable docker验证 Docker 是否安装成功运行一个测试容器sudo docker run hello-world如果能看到 “Hello from Docker!” 等欢迎信息说明 Docker 安装和运行正常。3.2 配置 Docker 镜像加速与存储驱动在国内环境直接从 Docker Hub 拉取镜像速度可能很慢。我们需要配置镜像加速器。这里以阿里云镜像加速服务为例你需要先注册阿里云账号进入容器镜像服务获取专属加速器地址。编辑 Docker 的守护进程配置文件sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [https://your-own-mirror.mirror.aliyuncs.com], exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m }, storage-driver: overlay2 } EOF关键参数解析registry-mirrors将your-own-mirror.mirror.aliyuncs.com替换为你从阿里云控制台获取的实际加速器地址。这能极大提升镜像拉取速度。exec-opts:native.cgroupdriversystemd是至关重要的一步。Kubernetes 推荐使用systemd作为 cgroup 驱动以保持与系统其他服务的一致性。Docker 默认的cgroupfs可能与 k3s 产生不兼容导致节点状态异常。storage-driver:overlay2是目前 Linux 上推荐且性能较好的存储驱动。配置完成后重新加载配置并重启 Dockersudo systemctl daemon-reload sudo systemctl restart docker再次运行sudo docker info | grep -i cgroup确认Cgroup Driver显示为systemd。4. 部署 k3s 并集成 Docker 运行时现在我们来到了核心步骤安装 k3s并告诉它使用我们刚才安装好的 Docker而不是它自带的 containerd。4.1 单 Server 节点部署在目标机器上执行以下一键安装命令curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC--docker sh -这个命令做了以下几件事下载k3s安装脚本。通过环境变量INSTALL_K3S_EXEC向安装脚本传递参数--docker。这个参数就是灵魂所在它指示 k3s 使用 Docker 作为容器运行时。脚本会自动下载 k3s 二进制文件将其安装为系统服务k3s.service并使用--docker参数启动该服务。安装过程大约持续一两分钟。完成后检查服务状态sudo systemctl status k3s你应该看到服务处于active (running)状态。如果失败可以查看日志排错sudo journalctl -u k3s -f。安装成功后k3s 会自动生成一个 kubeconfig 文件位于/etc/rancher/k3s/k3s.yaml。为了能使用kubectl命令我们需要将其复制到用户目录下并设置权限mkdir -p ~/.kube sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config sudo chown $(id -u):$(id -g) ~/.kube/config现在你可以验证集群了kubectl get nodes kubectl get pods -A你应该能看到一个Ready状态的节点以及kube-system命名空间下运行着coredns、metrics-server等核心组件。关键点在于你可以用docker ps命令看到这些 Pod 对应的容器正在运行这证实了 k3s 确实在使用 Docker 运行时。4.2 多节点集群部署Server Agent生产环境通常需要多节点以保证高可用。k3s 的多节点部署也非常简单它区分Server控制平面节点和Agent工作节点。第一步初始化第一个 Server 节点在第一台机器上我们不仅指定--docker还需要生成一个节点令牌token供其他节点加入集群时使用。curl -sfL https://get.k3s.io | K3S_TOKENmy-secret-token INSTALL_K3S_EXEC--docker sh -这里K3S_TOKEN可以自定义一个复杂的字符串例如my-secret-token。安装完成后在第一个 Server 节点上你可以找到两个重要的信息节点令牌我们已经在环境变量里定义了。它也会被保存在/var/lib/rancher/k3s/server/node-token文件中。Server 节点IP记下这台机器的 IP 地址假设为192.168.1.100。第二步添加其他 Server 节点可选用于高可用在第二台希望作为 Server 节点的机器上执行以下命令。它需要知道第一个 Server 的地址和令牌。curl -sfL https://get.k3s.io | K3S_TOKENmy-secret-token K3S_URLhttps://192.168.1.100:6443 INSTALL_K3S_EXEC--docker sh -第三步添加 Agent 节点在工作节点上安装命令与添加 Server 节点类似但需要额外指定K3S_URL并明确角色curl -sfL https://get.k3s.io | K3S_TOKENmy-secret-token K3S_URLhttps://192.168.1.100:6443 INSTALL_K3S_EXEC--docker --node-ip 此节点的IP sh -此节点的IP替换为当前工作节点的 IP。在某些网络环境下如云服务器有多块网卡明确指定--node-ip可以避免节点注册时使用错误的 IP 地址。在所有节点安装完成后回到第一个 Server 节点执行kubectl get nodes应该能看到所有节点都处于Ready状态。4.3 关键配置解析与自定义安装命令中的参数只是冰山一角。k3s 提供了丰富的配置选项可以通过修改其配置文件/etc/rancher/k3s/config.yaml来实现更精细的控制。例如我们想修改默认的服务 CIDR 和 Pod CIDR# /etc/rancher/k3s/config.yaml write-kubeconfig-mode: 0644 tls-san: - k3s.mycompany.com # 添加 TLS 证书的备用名称方便外部访问 API Server cluster-cidr: 10.42.0.0/16 # Pod 网络 CIDR默认值 service-cidr: 10.43.0.0/16 # Service 网络 CIDR默认值 cluster-dns: 10.43.0.10 # CoreDNS 服务地址 docker: true # 明确指定使用 Docker 运行时与 --docker 参数等效 node-ip: 192.168.1.100 # 绑定特定 IP修改配置文件后需要重启 k3s 服务以生效sudo systemctl restart k3s实操心得对于生产环境务必在tls-san中配置你的负载均衡器 IP 或域名否则通过该地址访问 API Server 会报证书错误。cluster-cidr和service-cidr不要与你的物理网络段冲突。5. 部署验证与基础应用部署集群搭建好了我们得验证它是否真的在“健康”地工作并且体验一下如何使用它。5.1 集群状态深度检查除了简单的kubectl get nodes我们还需要进行更深入的检查检查核心组件kubectl get pods -n kube-system确保coredns、metrics-server、local-path-provisionerk3s 自带的存储类等 Pod 都是Running状态。如果coredns一直Pending或ContainerCreating很可能是网络插件Flannel有问题或者节点内存不足。检查 Docker 运行时集成# 查看 k3s 启动参数确认 --docker 已生效 sudo ps aux | grep k3s-server | grep docker # 查看 kubelet 的配置 sudo cat /var/lib/rancher/k3s/agent/etc/kubelet.conf | grep -A5 -B5 docker更直观的方法是部署一个测试 Pod然后去 Docker 里看容器kubectl run test-docker --imagenginx:alpine # 等待 Pod 变为 Running kubectl get pods -l runtest-docker # 在宿主机上你应该能看到这个 nginx 容器 sudo docker ps | grep nginx检查网络# 部署一个简单的网络测试应用 kubectl create deployment net-test --imageappropriate/curl kubectl rollout status deployment/net-test # 进入 Pod 内部测试集群内 DNS 和服务发现 kubectl exec deployment/net-test -- curl -s http://kubernetes.default如果能成功返回 Kubernetes API 的响应说明 Pod 网络、DNS 和服务发现都是正常的。5.2 部署第一个有状态应用MySQL让我们部署一个稍微复杂点的应用比如 MySQL这涉及到配置、存储和密码管理。创建 Secret 存储密码切勿将密码明文写在 YAML 里kubectl create secret generic mysql-secret \ --from-literalmysql-root-passwordyour-strong-password-here创建 PersistentVolumeClaim (PVC)向 k3s 自带的local-path存储类申请存储空间# mysql-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 5Gikubectl apply -f mysql-pvc.yaml创建 MySQL Deployment 和 Service# mysql-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:8.0 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: mysql-root-password ports: - containerPort: 3306 volumeMounts: - name: mysql-storage mountPath: /var/lib/mysql volumes: - name: mysql-storage persistentVolumeClaim: claimName: mysql-pvc --- apiVersion: v1 kind: Service metadata: name: mysql-service spec: selector: app: mysql ports: - protocol: TCP port: 3306 targetPort: 3306 type: ClusterIPkubectl apply -f mysql-deployment.yaml验证kubectl get pods -l appmysql # 查看 Pod 状态 kubectl get pvc # 查看 PVC 是否 Bound kubectl get svc mysql-service # 查看 Service 的集群内 IP # 进入 Pod 测试 MySQL 连接 kubectl exec -it deployment/mysql -- mysql -uroot -p$MYSQL_ROOT_PASSWORD -e SHOW DATABASES;这个例子展示了在 k3s 中如何管理敏感信息、使用持久化存储和部署有状态服务这些都是日常运维中的常见操作。6. 运维、监控与故障排查实录集群跑起来只是开始日常的运维和问题排查才是重头戏。6.1 常用运维命令与日志查看服务管理sudo systemctl status k3s # 查看 k3s 服务状态 sudo systemctl restart k3s # 重启 k3s谨慎操作 sudo systemctl stop k3s # 停止 k3s sudo systemctl start k3s # 启动 k3s日志查看# 查看 k3s 服务日志实时追踪 sudo journalctl -u k3s -f # 查看 kubelet 日志容器生命周期相关 sudo journalctl -u k3s-agent -f # 查看特定 Pod 的日志 kubectl logs pod-name -n namespace kubectl logs -f pod-name -n namespace --tail50 # 实时追踪资源清理# 删除所有非 default 命名空间的资源危险 kubectl delete namespace namespace-name # 强制删除卡在 Terminating 状态的命名空间 kubectl get namespace namespace-name -o json | jq .spec.finalizers [] | kubectl replace --raw /api/v1/namespaces/namespace-name/finalize -f -6.2 集成基础监控Prometheus 与 Grafana监控是生产环境的眼睛。在 k3s 上部署一套 Prometheus Grafana 非常简单我们可以使用 Helm 包管理器。安装 Helmcurl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash添加 Prometheus 社区仓库并部署helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update # 创建一个命名空间 kubectl create namespace monitoring # 安装 kube-prometheus-stack它包含了 Prometheus, Grafana, AlertManager 等全套组件 helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring这个 Chart 配置了自动发现 k3s 集群中的节点、Pod、Service 等目标的规则开箱即用。访问 Grafana 部署完成后需要将 Grafana 的服务类型改为NodePort或通过 Ingress 暴露。kubectl patch svc prometheus-grafana -n monitoring -p {spec: {type: NodePort}} kubectl get svc prometheus-grafana -n monitoring找到prometheus-grafana服务对应的NodePort例如30892然后通过http://你的节点IP:30892访问 Grafana。默认用户名是admin密码可以通过以下命令获取kubectl get secret prometheus-grafana -n monitoring -o jsonpath{.data.admin-password} | base64 --decode ; echo导入 Dashboard登录 Grafana 后可以导入官方提供的 Kubernetes 监控 DashboardID 如13105即可看到丰富的集群监控图表。6.3 常见问题与排查技巧实录在实际操作中你几乎一定会遇到下面这些问题。我把我的踩坑记录分享给你。问题一k3s 服务启动失败日志显示failed to find memory cgroup或类似 cgroup 错误。原因这是最经典的问题。根本原因是 Docker 的 cgroup 驱动 (cgroupfs) 与 k3s或 systemd期望的驱动 (systemd) 不一致。解决方案确保 Docker 的daemon.json中已配置exec-opts: [native.cgroupdriversystemd]并重启 Docker。然后彻底清理 k3s 并重新安装参考第 2.2 节的清理步骤。问题二Pod 一直处于Pending状态kubectl describe pod显示0/1 nodes are available: 1 node(s) had taint {node.kubernetes.io/disk-pressure: }。原因节点存在磁盘压力污点Taint调度器不会将 Pod 调度到该节点。排查与解决检查节点磁盘使用率df -h。清理磁盘空间例如清理 Docker 无用镜像和容器docker system prune -a -f。污点可能会自动移除。也可以手动移除生产环境谨慎kubectl taint nodes node-name node.kubernetes.io/disk-pressure-。问题三Pod 内无法解析集群服务名称如mysql-service.default.svc.cluster.local。原因CoreDNS Pod 没有正常运行或者 Pod 的 DNS 配置不正确。排查步骤kubectl get pods -n kube-system -l k8s-appkube-dns检查 CoreDNS Pod 状态。kubectl logs -n kube-system coredns-pod-name查看 CoreDNS 日志。进入出问题的 Pod检查/etc/resolv.conf文件看 nameserver 是否指向了正确的 ClusterIP通常是10.43.0.10。如果 CoreDNS 有问题尝试重启kubectl delete pod -n kube-system -l k8s-appkube-dns。问题四使用docker ps能看到容器但kubectl get pods显示 Pod 状态异常如Error/CrashLoopBackOff。原因这是 Docker 运行时模式下特有的调试优势。因为容器实际由 Docker 管理你可以直接用 Docker 命令深入排查。排查技巧docker ps -a | grep pod-name找到对应容器。docker logs container-id查看该容器的标准输出和错误日志这通常比kubectl logs更早看到启动失败的原因例如镜像拉取失败、启动命令错误、权限问题等。docker inspect container-id查看容器的详细配置包括环境变量、挂载卷、网络等与你的 Pod 定义进行对比。问题五从节点Agent无法加入主节点Server。原因网络不通、令牌错误或端口未开放。排查清单网络连通性在 Agent 节点上执行telnet server-ip 6443或curl -vk https://server-ip:6443/ping检查 6443 端口是否可达。防火墙确保 Server 节点的防火墙放行了 6443 (TCP) 和 8472 (UDP, Flannel) 端口。令牌确认 Agent 安装命令中的K3S_TOKEN与 Server 节点/var/lib/rancher/k3s/server/node-token文件内容一致。查看日志在 Agent 节点查看sudo journalctl -u k3s-agent -f获取具体的错误信息。问题六如何升级 k3s 版本k3s 的升级非常平滑。对于使用 Docker 运行时的集群升级步骤与常规 k3s 一致# 在 Server 节点上 curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC--docker INSTALL_K3S_VERSIONv1.28.5k3s1 sh - # 在 Agent 节点上先 drain 节点驱逐 Pod然后升级最后 uncordon kubectl drain agent-node-name --ignore-daemonsets curl -sfL https://get.k3s.io | K3S_TOKENmy-secret-token K3S_URLhttps://server-ip:6443 INSTALL_K3S_EXEC--docker INSTALL_K3S_VERSIONv1.28.5k3s1 sh - kubectl uncordon agent-node-name核心避坑指南部署“k3s-docker版”的终极秘诀就是“环境干净驱动一致”。90% 的诡异问题都源于旧组件残留或 cgroup 驱动冲突。养成在全新环境或彻底清理后的环境开始部署的习惯能为你节省大量排错时间。另外善用docker命令直接操作容器进行深度调试是这个方案带给运维人员的独特便利。
返回列表