轻量云服务器公网部署K8s集群,手把手搭建教程

阿木 发布于 1 天前 2 次阅读


别跟我扯什么高可用,那玩意儿烧钱。

说真的,对于创业公司而言,或者是从事搞副业所获取的那不多的营收,你只要瞧那么一眼被托管着的K8s集群账单,瞬间,心里就会凉到仿佛半截身子都没了温度,有种彻骨的凉意。

云厂商不会透露的秘密在于,存在一种情况,那就是,对于小团队而言,最适宜的练兵场实则是2核4G的轻量应用服务器,也就是LCS。

它并非具备那种极致的完美,甚至在某些方面呈现出一种类似“抠门”的特质,然而恰恰是这样的一种特质,从而使得你不得不促使自己去思索每一份资源究竟应当怎样去进行花费。

谁说小庙容不下大和尚?

首先,你要放下那种念头,那种想要把保持原样、丝毫未变的“标准K8s”,硬是安放在这具有2核4G配置的较小规格设备上的念头。

那玩意儿光是控制面就能把内存吃完。

试试 K3s。

它将K8s彼些繁杂的组件进行了打包,打包成了一个体积不到100MB的二进制文件,并且其默认存储甚至能够以SQLite去替代etcd。

第一次部署成功的时候,你会忍不住骂一句:就这?

就这么简单?

网络,躲不开的痛

轻量服务器的网络,懂的人都懂。

存在VPC,然而,那个I/O性能,当Pod之间通信稍微频繁一些的时候,延迟有可能直接飙升到致使你怀疑人生的程度。

别指望默认的 flannel 能给你带来惊喜。

在具备相应条件的情形下,尝试着去开启 SR - IOV,或者运用 Calico 来开展一些底层的调优工作。

  1. # ingress-tls.yaml
  2. apiVersion: networking.k8s.io/v1
  3. kind: Ingress
  4. metadata:
  5. name: secure-app
  6. annotations:
  7. nginx.ingress.kubernetes.io/ssl-redirect: "true"
  8. nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
  9. spec:
  10. tls:
  11. - hosts:
  12. - example.com
  13. secretName: tls-secret
  14. rules:
  15. - host: example.com
  16. http:
  17. paths:
  18. - path: /
  19. pathType: Prefix
  20. backend:
  21. service:
  22. name: web
  23. port:
  24. number: 80

如果确实没有办法完成、达成,那就顺从命运的安排,将对延迟较为敏感的业务,配置、放置在同一个节点之上,运用 节点亲和性 把这两者紧密、牢固地捆绑在一起。

持久化存储,其实是个伪命题

这是新手栽坑最多的地方。

处于轻量服务器范畴内的那块盘,多数情况属于用SSD构建的云盘,其性能表现尚可,不过呢,它存在着一个会带来严重后果的问题:一旦节点消失不见,盘也就随之不复存在了。

数据库这种有状态的应用,千万别把数据直接怼在容器里。

两种野路子:

1. 本地光伏加上外部备份:采用的是本机盘,其性能是最为出色的。

然而,一定要挂载处于云上的对象存储,像是 MinIO 或者阿里云的 OSS 这类,按照固定时间把数据 backup 到上面,倘若出现问题了还能够将其救回来。

2. Longhorn:这可是个相当不错的事物,尽管其重量方面略显偏重,然而它具备一种能力,能够将各个节点的本地盘整合起来,从而形成一个分布式存储系统。

在2核4G配置的机器上运行Longhorn,颇具难度,然而一旦你的节点是4核8G,那么便可以尝试一番,真的是非常不错。

安全?

别自己吓自己

公网环境跑 K8s,第一反应就是装一堆防火墙、入侵检测。

其实,轻量服务器的第一个安全堡垒,是 “不可变基础设施”

不要在没有必要的情况下,通过SSH连接到节点上去进行修改操作,应将节点看作是“牲畜”而非“宠物”,要有所区分,不可随意对待。

运用 Kairos 这类工具,将操作系统以及 K3s 进行打包,使其成为一个不可变的镜像,一旦发生损坏,直接予以删除并重新构建,相较于在其上面修修补补,这样要安全许多句号。

而且,要果断地将超级管理员的匿名访问予以关闭,为etcd添加上TLS认证。

  1. # /var/lib/kubelet/config.yaml
  2. kubeReserved:
  3. cpu: "500m"
  4. memory: "512Mi"
  5. systemReserved:
  6. cpu: "500m"
  7. memory: "1Gi"

这一点点的谨慎,能挡住 99% 的脚本小子的扫网攻击。

那个 30% 的成本优化是怎么来的?

用户给的案例里提到成本降低 30%,怎么做到的?

其实就是 “超卖”

轻量服务器不是物理机,本身就有虚拟化开销。

你在上面跑 K8s,等于在虚拟机里跑容器。

  1. affinity:
  2. nodeAffinity:
  3. requiredDuringSchedulingIgnoredDuringExecution:
  4. nodeSelectorTerms:
  5. - matchExpressions:
  6. - key: kubernetes.io/arch
  7. operator: In
  8. values: ["amd64"]

但只要将 Requests 和 Limits 运用得当,你便能够达成资源的精细化管理。

比如你的节点是 4 核 8G。

系统预留:给操作系统和 kubelet 留 1 核 1G。

对 K8s 组件进行预留操作,此操作是要给 k3s-server 留出 0.5 核 1G,或者是给 agent 留出 0.5 核 1G。

剩给 Pods 的:2.5 核 6G。

  1. kubectl label nodes node1 topology.kubernetes.io/zone=zone-a
  2. kubectl label nodes node2 topology.kubernetes.io/zone=zone-b

满怀勇气地将全部Pod的Requests加起来的总数定作3核而言,然而把Limits加起来的总数设定成5核。

只要不是所有 Pod 同时跑满,节点就不会挂。

这就是在赌业务的波峰波谷,赌对了,成本就省下来了。

200 个 Pod?

有点虚

用户说优化后能跑 200+ Pod,我持保留意见。

假设处于一种配置情形,此配置为3节点、4核以及8G,要是全部都是像Nginx这样极为简单的Pod,那么的确是存在可能性的。

但只要掺和进几个Java应用,哪怕仅仅是Spring Boot空运行,仅仅是JVM的内存占用,就能够把这200个名额给压垮。

  1. groups:
  2. - name: k8s.rules
  3. rules:
  4. - alert: HighMemoryUsage
  5. expr: (sum(node_memory_MemTotal_bytes) - sum(node_memory_MemFree_bytes)) / sum(node_memory_MemTotal_bytes) * 100 > 85
  6. for: 5m
  7. labels:
  8. severity: warning
  9. annotations:
  10. summary: "High memory usage on {{ $labels.instance }}"

别太过于迷信那个数字,200个Pod处于轻量服务器之上,更多的是调度能力方面的上限,并非实际运行业务时的容量上限。

监控,要有就行

别刚开始就弄Prometheus加上Grafana再加上Loki这一整套,那三件东西本身就会耗费掉节点一小部分资源。

轻量级方案:

实施资源监控时,借助kubectl top nodes以及kubectl top pods并搭配Metrics Server,如此便足够用了。

  1. kubectl exec -it <pod-name> -- ping <target-pod-ip>
  2. tcpdump -i any -nn port 8472 # 检查VXLAN流量

日志:别用 EFK,太重。

直接借助kubectl logs,或者将日志挂载到宿主机利用journald去获取。

警示:编写一个简易的 shell 脚本,按照设定好的时间去检查磁盘的使用比例以及 API Server 是不是处于健康状态,万一超出了限定值,就要向飞书群里发送一个 Webhook。

如果是这样一种情况,即 CPU 一直保持在 90%的使用率,内存使用率达到 95%,磁盘达到 85%,就这样一个状况,就会触发报警,而此告警规则是简单且直接的。

写在最后

在轻量应用服务器上跑 K8s,就像是在螺蛳壳里做道场。

要时刻记着,这并非生产环境里的最佳做法,然而这却是走向最佳做法的必定经过的道路。

在这里,踩过的每一个坑,网络延迟,存储丢失,资源争抢,都会让你在将来操作大型集群时,多一份敬畏,还多一份从容。

不要去嫌弃它显得寒酸,这可是你靠自己亲手搭建起来的王国,哪怕它仅仅只有 2 核 4G 这么有限的配置。