K3s 是一个非常轻量的 Kubernets 替代品,你甚至能够运行在 500M 内存的设备上部署 K3s。刚好最近我的工作也会慢慢变得跟 Kubernetes 相关,所以决定在之前购买的一台 1 核 1G 的 VPS 上部署一个 K3s 来熟悉一下 Kubernetes 生态。
Install
这里可以按照 K3s 官网给的脚本来安装:
curl -sfL https://get.k3s.io | sh -
# Check for Ready node, takes maybe 30 seconds
k3s kubectl get node
但是我的服务器系统是 Arch Linux,所以可以很愉快的使用包管理器安装:
pacman -S k3s-bin
安装完成后可以通过下面的命令查看 Systemd Unit 文件的路径:
sudo systemctl status k3s
K3s 开箱自带了一些必备的组件,例如 flannel、CoreDNS、Traefik,这些功能的默认配置位于 /var/lib/rancher/k3s/server/manifests
。但是我发现每次 K3s 重启都会覆盖我对这些配置文件的修改,所以如果需要对这些功能的默认配置进行修改的话,可以通过修改 Systemd Unit 文件自定义启动参数,从而禁用掉需要自定义的组件。例如,我想自己安装 Traefik,只需要将启动命令修改为 k3s server --no-deploy traefik
。
接下来我们就可以启动 K3s 了:
sudo systemctl start k3s
Configuration
经过我的折腾发现,想要修改 K3s 中 Kubernetes 的一些配置跟着 K3s 文档做大多都会以失败告终,反而跟着 Kubernetes 官方的文档来做很容易就可以实现预期的效果。
远程访问 K3s
将 /etc/rancher/k3s/k3s.yaml
从 VPS 上复制到自己电脑上的 ~/.kube/config
文件,然后你就可以在本地电脑上使用 kubectl 来远程管理集群了!
私有镜像仓库
这里完全可以参照 Kubernetes 的文档来操作。如果按照 K3s 提供的办法来修改 registries.toml
,那么在配置有问题的时候,你就会发现 K3s 循环重启,并且占用大量的 CPU 最终导致被 VPS 商家降频 。
安装 Traefik
其实 K3s 的 manifests 目录下都是 helm 配置文件,K3s 默认在启动的时候会使用 helm 部署 manifests 下面的组件,例如 Traefik。我选择自己通过 helm 安装 Traefik,这样修改配置起来是最方便的,通过 helm 安装最好的方式就是查看 helm 仓库中的 README 。
首先我们需要准备一份 values.yaml
,这是 Traefik 的 helm 模板变量:
ssl:
enabled: true # 启用 https endpoint
rbac:
enabled: true # 来自 k3s 的默认配置
kubernetes.ingressEndpoint.useDefaultPublishedService: "true" # 来自 k3s 的默认配置
resources: # 限制 Traefik 的资源使用
limits:
memory: 128Mi
cpu: 100m
requests:
memory: 32Mi
cpu: 50m
dashboard:
enabled: true
domain: traefik.your-domain.com # Traefik 面板域名
auth:
basic:
aUserName: encoded-password-with-htpasswd # 安装 apache-tools 使用 htpasswd 来编码密码
acme:
enabled: true # 启用 Let's Encrypt 证书
staging: false # 禁用测试证书 (1)
logging: true
email: your@email.com # Let's Encrypt 申请证书时使用的邮箱
challengeType: "dns-01" # 通过 DNS 的方式来验证
dnsProvider:
name: cloudflare (2)
cloudflare:
CLOUDFLARE_API_KEY: xxxx
CLOUDFLARE_EMAIL: xxxxx
domains:
enabled: true
domainsList:
- main: "*.your-domain.com" # 为所有的子域名生成一个证书
- sans:
- "your-domain.com" # 根域名与子域名使用同一个证书
1 | acme.staging 默认为 true ,这会让 Let’s Envrypt 签发一个 FAKE 证书。当你准备好正式面对互联网的时候,记得将其设置为 false 。 |
2 | 这里填你的 DNS 服务商的名字,具体的支持列表请看 这里 。 |
然后就可以通过下面的两条命令来安装与修改 Traefik 了:
helm install traefik --namespace kube-system --values values.yaml stable/traefik
helm upgrade traefik stable/traefik -f values.yaml -n kube-system
部署博客系统
说起来你可能不信,我的博客系统目前一共有 3 个服务
-
pgsql 数据库
-
text-maid 文本渲染引擎
-
blog-server 博客网站
这些服务之前都是使用单个 docker-compose.yaml
来部署的,可以使用一个叫做 kompose
的工具将 docker-compose.yaml
转换成对应的 Kubernetes 配置文件。
yay -S kompose-bin
当然,直接这么转换出来的配置文件并不好使,还需要进行一些简单地修改。
创建命名空间
因为之后可能还会有更多的服务(例如站内搜索)加入,所以还是创建一个单独的命名空间来管理吧。
apiVersion: v1
kind: Namespace
metadata:
name: blog
持久化数据库数据
K3s 自带了一个 local-path-provisioner
,然而这个东西我整了半天还是没能成功挂载数据库文件,最终还是用了 Kubernetes 的本地卷存储,配置简单,也是开箱即用:
apiVersion: v1
kind: PersistentVolume
metadata:
name: blog-data-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 300Mi
accessModes:
- ReadWriteOnce
hostPath:
path: "/path/to/blogdata"
光有 PV 还不够,还得创建一个 PVC 让 Pod 来使用刚刚创建的 PV。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: blog-data-pvc
namespace: blog
spec:
accessModes:
- ReadWriteOnce
storageClassName: manual
resources:
requests:
storage: 200Mi
部署数据库
这里用数据库来举例说明一下我是如何部署这些服务的,前面的 kompose 为 pgsql 服务生成了两份文件:deployment.yaml 与 service.yaml,分别用来描述 pgsql 服务的部署方式以及网络访问方式,这里我将这两个文件合并到了一起,方便管理,其他的服务也进行了类似的处理,故不再赘述。
apiVersion: v1
kind: Service
metadata:
name: pgsql
namespace: blog
spec:
selector:
app: pgsql
ports:
- protocol: TCP
port: 5432
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pgsql
namespace: blog
spec:
selector:
matchLabels:
app: pgsql
replicas: 1
strategy:
type: Recreate
template:
metadata:
namespace: blog
labels:
app: pgsql
spec:
containers:
- image: postgres:12-alpine
name: pgsql
resources: (1)
limits:
memory: 256Mi
cpu: 100m
requests:
memory: 32Mi
cpu: 50m
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: blogdata
restartPolicy: Always
volumes:
- name: blogdata
persistentVolumeClaim:
claimName: blog-data-pvc
1 | 因为服务器资源紧张,所以 limits 与 requests 之间留有较大的浮动空间,避免 pgsql 部署失败 |
部署 Ingress
Traefik 会在 kube-system 中监控整个 K3s 集群中的 Ingress,并为这些 Ingress 创建对应的路由,所以我们只需要在 blog 命名空间中创建一个 Ingress 就可以了。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-ingress
namespace: blog
spec:
rules:
- host: gianthard.rocks
http:
paths:
- path: /
backend:
serviceName: blog-server (1)
servicePort: 80
-
因为在同一个命名空间内,所以不需要使用命名空间前缀就可以访问对应的服务
部署成功后,你可以登录 Traefik 的面板查看这个 Ingress 的相关信息:
容器、镜像管理
K3s 默认直接使用 containerd
、runC
来管理容器以及镜像,你也可以在安装的时候切换成 Docker,不过我不准备继续用 Docker 了,所以也没办法继续使用 Docker 命令行工具来管理容器跟镜像。
k3s crictl
K3s 内置了一个 CRI 的客户端,可以通过 k3s crictl --help
查看相关的说明。
buildah
除了管理集群内的镜像外,有时候还需要自己构建镜像,这时候就可以使用 buildah 来完成这项工作。buildah 是一个用来构建 OCI 容器镜像的工具,可以直接使用 Dockerfile 来构建镜像,同时也支持镜像的推送、拉取功能。
目前 K3s 还不支持使用 buildah 来管理镜像与容器,所以只用 buildah 构建、推送镜像就好。 |
buildah 通常跟 podman 一起使用,后者是一款无需 root 权限就可以运行 OCI 容器的工具,日后有机会再深入体验。
最后
经过一番折腾,我的博客站点终于运行在了 K3s 之上,VPS 总体内存占用上升了 200M,果然再轻量的 Kubernetes 都比 Swarm 要消耗资源。为什么我要在 1 核 1G 的 VPS 上折腾 K3s,因为 K3s 就在那里。