K3s 搭建

K3s 和 K8s 相比较:
大小和性能:K3s 相对于 K8s 来说更加轻量级,占用更少的资源,适用于资源有限的环境。K3s 在二进制文件大小、内存占用和启动时间方面都比 K8s 更加高效。
安装和配置:K3s 的安装和配置相对来说更简单和快速,减少了一些复杂的步骤和依赖项。K8s 则需要更多的配置和管理,适用于大规模、复杂的生产环境。
可扩展性:K8s 具有非常强大的扩展性,可以管理大型集群并处理数千个容器。K3s 在规模和功能方面相对较小,更适合中小规模的部署。
功能和生态系统:K8s 提供了丰富的功能和广泛的生态系统,拥有大量的插件和工具来扩展和定制。K3s 为了精简而移除了一些不常用的功能和组件,因此在功能和生态系统方面相对较小。
安装
机器配置要求具体可以看 https://docs.k3s.io/zh/installation/requirements
1. 安装脚本
1
| curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - --docker
|
k3s 默认使用的是 containerd 作为运行时容器
2. 检查操作系统是否满足需求

3. 写一个 demo 服务
1 2 3
| go mod tidy vim main.go
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package main
import ( "fmt" "net/http" )
func helloHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello") }
func main() { http.HandleFunc("/", helloHandler) err := http.ListenAndServe(":8080", nil) if err != nil { fmt.Println("Error starting the server:", err) } }
|
这里使用 go 语言搭建一个基本 http 服务 访问 ip:8080 就能返回 Hello
Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| FROM golang:1.16-alpine AS build
WORKDIR /app
COPY . .
RUN go init test RUN go build -o app
FROM alpine:latest COPY --from=build /app/app /app/app
CMD ["/app/app"]
|
depolyment 部署文件
以下 depolyment 定义了一个 Deployment 和一个 NodePort 的 service
这里有个注意事项 ⚠️ 请看后面坑 3
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 26 27 28 29 30 31 32 33 34
| apiVersion: apps/v1 kind: Deployment metadata: name: my-app labels: app: my-app spec: replicas: 1 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: containers: - name: my-app image: my-app:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: my-app-srv spec: type: NodePort selector: app: my-app ports: - port: 30001 targetPort: 8080
|
Makefile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| APP_NAME := app DOCKER_IMAGE_NAME := my-app DOCKER_IMAGE_TAG := latest K8S_DEPLOYMENT_NAME := my-app K8S_NAMESPACE := default
docker-build: docker build -t $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) .
k8s-deploy: kubectl apply -f deployment.yaml -n $(K8S_NAMESPACE)
k8s-clean: kubectl delete deployment $(K8S_DEPLOYMENT_NAME) -n $(K8S_NAMESPACE)
deploy: k8s-clean docker-build k8s-deploy
|
5. 配置 ingress
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: traefik.ingress.kubernetes.io/router.entrypoints: web spec: rules: - host: www.hmlxy.cn http: paths: - path: / pathType: Prefix backend: service: name: my-app-srv port: number: 30001
|
创建 ingress
1
| kubectl apply -f ingress.yml
|
5. 服务启动
到这所有准备工作都做完了只需要按下「启动按钮」

查看服务 service

访问 www.hmlxy.cn

成功 啦!!!
总结
这次的 k3s 部署花了将近一天的时间,踩了许许多多的坑,但是最后都解决了,也让我学到了不少新的知识。

踩坑
坑 1:无法从/var/lib/rpm 打开软件包数据库

注:
RPM 是”Red Hat Package Manager”(红帽软件包管理器)的缩写。它是一种常见的软件包管理工具,最初由 Red Hat 开发,并在多个 Linux 发行版中使用。RPM 用于在 Linux 系统上管理和安装软件包。
RPM 软件包是一种打包格式,其中包含软件的二进制文件、配置文件、文档和其他相关资源。使用 RPM,用户可以方便地安装、升级、删除和查询软件包。通过使用 RPM,系统管理员可以轻松地管理大量的软件包,同时确保软件包之间的依赖关系得到满足。
在使用 RPM 时,您可以使用命令行工具(如 rpm 命令)执行各种操作,例如安装软件包、列出已安装的软件包、查询软件包信息、升级软件包等。此外,还可以使用其他工具,如 Yum(基于 RPM 的软件包管理器)和 DNF(Dandified Yum),它们提供了更高级的功能,如解决依赖关系、自动更新等。
需要注意的是,RPM 主要用于基于 Red Hat 和 CentOS 等发行版的 Linux 系统。其他 Linux 发行版(如 Debian 和 Ubuntu)使用的是不同的软件包管理工具,例如 Debian 中的 dpkg 和 apt-get,以及 Ubuntu 中的 dpkg 和 apt。
fix:重新构建 rpm 数据库
1 2 3 4 5
| cd /var/lib/rpm
rm -rf __db.*
rpm --rebuilddb
|
坑 2:操作系统没有打开用户命名空间

fix:打开就好
在 GRUB_CMDLINE_LINUX=”…”这行中添加 user_namespace.enable=1 参数,确保在其他参数之间添加一个空格。
更新 GRUB 配置
1
| sudo grub2-mkconfig -o /boot/grub2/grub.cfg
|
重启电脑
坑 3:无法拉取镜像

可以看到我拉取镜像一直失败了,查看 k8s 文档

由于我一开始将 imagePullPolicy 字段省略了,并且通过我的 Makefile 文件可以看到我的镜像的 tag 是 latest 满足第一条,所以一直从远程拉取导致失败。只需要将 tag 改掉或者将 imagePullPolicy 设置为 IfNotPresent 或者 Never。建议改为 IfNotPresent
坑 4:无法访问程序

访问程序一直 404 curl 也是 404
一直以为是腾讯云域名解析错了的问题,思考了一下既然出了 404 那应该是路由没有匹配上,查看 ingress-controller
1 2 3 4 5
| // 查看ingress-controller 控制器 kubectl get pods -n kube-system
// 查看控制器日志 kubectl logs -n kube-system traefik-56b8c5fb5c-7w7qd
|

果然报了一大堆错误 ❌ 看到「Cannot create service: service not found」这个日志我瞬间明白了,我一直以为 ingress 配置的 backend 是服务的名字,结果是 service 的名字 所以找不到 service 修改 ingress.yml 就好了