服务器K8s部署实战:k3s搭建Redis集群完整教程

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


树莓派在角落里闪着绿灯,4G内存,跑着三个Redis节点。

这事儿搁标准K8s早炸了,但k3s就稳得很。

你说神奇不神奇?

那60MB的二进制包,犹如一把瑞士军刀,存在捅不进去之处,它却可以捅进去。

谁他妈规定数据库必须跑在裸金属上?

轻,本身就是一种暴力

首次于工控机之上安装k3s,望着kubectl get nodes的输出,居然有种仿若偷吃了禁果般的快感。

标准K8s那套,太肥了,像穿西装的胖子挤进smart。

k3s砍掉的不是功能,是虚胖。

IoT网关那点算力,跑个Redis还得抠抠搜搜。

40%的内存省下来,留给Redis做缓存不香吗?

  1. # 主节点初始化
  2. curl -sfL https://get.k3s.io | sh -s -- --write-kubeconfig-mode 644
  3. # 工作节点加入(在主节点执行后获取token)
  4. curl -sfL https://get.k3s.io | K3S_URL=https://<master-ip>:6443 K3S_TOKEN=<token> sh -

有的人非得要去争辩所谓的“K8s正统”,去你的什么正统,能够顺利运行起来而不出现OOM情况这才属于正义范畴。

Redis在k3s上的那种疼

真干活的时候才发现,持久化才是爹。

  1. kubectl get nodes
  2. # 应显示类似输出:
  3. # NAME STATUS ROLES AGE VERSION
  4. # k3s-master Ready control-plane,master 5m v1.24.8+k3s1

拥有状态的集合加上持久卷声明,这样的组合如同夫妻共同经营的小店那般,看上去土里土气的,却着实给人一种踏实可靠的感觉标点符号。

pod重启了,数据还在,像老狗认得回家路。

某次出现节点断电的情况,待恢复之后,Redis自行将数据加载回来,那种所产生的感动之情,相较于观看情书而言还要更为热烈一些。

  1. # redis-single.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: redis-single
  6. spec:
  7. containers:
  8. - name: redis
  9. image: redis:6.2-alpine
  10. ports:
  11. - containerPort: 6379
  12. resources:
  13. limits:
  14. memory: "512Mi"
  15. requests:
  16. memory: "256Mi"
  17. command: ["redis-server", "--appendonly", "yes"]

但坑也多。

默认配置下,内存限制忘了设,Redis能把宿主吃死。

如果QoS类没有被调整成,那个被称为Guaranteed的存在,那么在那个关键的时刻,被kubelet所干掉的,将会是主节点。

  1. kubectl apply -f redis-single.yaml
  2. kubectl port-forward pod/redis-single 6379:6379

priorityClassName等于一后边九个零这样的数字,一眼看上去,似乎像是电话号码模样,然而实际上它却是护身符哟。

  1. redis-cli -h 127.0.0.1 ping
  2. # 应返回PONG

你得这么干,才像老炮

Helm是神,别手写yaml。

使用Bitnami的那个chart操作,一下子全部投入,以集群模式直接拉起6个pod;主集群与从集群进行了清晰划分。

  1. # redis-master.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: redis-master
  6. spec:
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. app: redis
  11. role: master
  12. template:
  13. metadata:
  14. labels:
  15. app: redis
  16. role: master
  17. spec:
  18. containers:
  19. - name: master
  20. image: redis:6.2-alpine
  21. ports:
  22. - containerPort: 6379
  23. command: ["redis-server", "--appendonly", "yes"]
  24. ---
  25. # redis-slave.yaml
  26. apiVersion: apps/v1
  27. kind: Deployment
  28. metadata:
  29. name: redis-slave
  30. spec:
  31. replicas: 2
  32. selector:
  33. matchLabels:
  34. app: redis
  35. role: slave
  36. template:
  37. metadata:
  38. labels:
  39. app: redis
  40. role: slave
  41. spec:
  42. containers:
  43. - name: slave
  44. image: redis:6.2-alpine
  45. ports:
  46. - containerPort: 6379
  47. command: ["sh", "-c", "redis-server --slaveof redis-master 6379"]

我那会儿傻,手撸部署文件,三天没睡好觉。

后来察觉到,“helm install redis-cluster oci://registry-1.docker.io/bitnamicharts/redis-cluster”,这样一行指令,世界就变得清净了。

网络,得用hostNetwork。

搜了一圈棒子国的技术博客,Kakao那帮人玩得野。

那个Redis cluster的mesh拓扑,pod之间进行通信时走overlay吗,延迟直接就达到了1.2ms。

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: redis-master
  5. spec:
  6. selector:
  7. app: redis
  8. role: master
  9. ports:
  10. - protocol: TCP
  11. port: 6379
  12. targetPort: 6379

一旦开启hostNetwork,便直接变为0.7ms,虽说这有悖于K8s的纯正血统,然而速度快就是正义。

tcp-check send AUTH YourPassword
tcp-check expect string +OK

把这样的配置插到haproxy当中,在外网就能够安全地摸触到Redis,感觉特别爽。

那个下午,我看着监控面板发呆

  1. # 添加bitnami仓库
  2. helm repo add bitnami https://charts.bitnami.com/bitnami
  3. # 创建命名空间
  4. kubectl create ns redis-cluster
  5. # 部署集群(3主3从)
  6. helm install redis-cluster bitnami/redis-cluster
  7. --namespace redis-cluster
  8. --set cluster.nodes=6
  9. --set cluster.replicas=1
  10. --set password="your-secure-password"
  11. --set master.persistence.size=8Gi
  12. --set slave.persistence.size=8Gi

P99延迟8ms,每天20亿次写入。

数字在Grafana上跳动,像心电图。

突然在那一刻觉得,技术这个事物,并非是为了去炫耀,而是旨在使得如此庞大的量看上去好似未曾有任何事情发生过。

哨兵还是集群?

别纠结。

6节点起步,3主3从,slots铺满16384。

  1. # redis-exporter.yaml
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: redis-exporter
  6. spec:
  7. template:
  8. spec:
  9. containers:
  10. - name: exporter
  11. image: oliver006/redis_exporter:v1.34.0
  12. args: ["-redis.addr=redis-master:6379"]
  13. ---
  14. apiVersion: v1
  15. kind: Service
  16. metadata:
  17. name: redis-exporter
  18. spec:
  19. ports:
  20. - name: metrics
  21. port: 9121
  22. targetPort: 9121
  23. selector:
  24. app: redis-exporter

每个主挂一个从,物理机错开,别让俩兄弟死一台机器上。

有人在群里问,k3s跑Redis稳吗?

稳个屁。

  1. # 在容器启动命令中添加
  2. command:
  3. - redis-server
  4. - "--maxmemory 2gb"
  5. - "--maxmemory-policy allkeys-lru"

没配好持久化,节点重启就丢数据。

未配置反亲和性,全部的pod都集中在同一个node上,一旦物理机出现宕机状况那就全都完蛋了。

没配资源limit,内存飙起来,node把pod扬了。

所以你得跪着学,跪着试。

  1. # 在redis.conf中设置
  2. io-threads 4 # 根据CPU核心数调整

有些道理是摔出来的

那次生产事故,至今记得。

集群分裂了,脑裂,两个主互相不认识。

监控告警疯狂响,像产房的心电图报警。

最终经过查找得出,是网络出现抖动情况,并且,cluster-node-timeout所设置的时长太短了。

现在我在values里写:

cluster-node-timeout: 15000
cluster-require-full-coverage: no

后一个必须设no,不然网络抖一下就拒绝服务,那才是真完蛋。

写在凌晨三点

K3s加上Redis,恰似两名为背影相对贴合的瘦者,具备扛事儿的能力,且不会占据过多空间。

树莓派上那三个节点还在跑,绿灯一闪一闪,像在呼吸。

我想,这就是边缘计算该有的样子:不吵不闹,把活干了

  1. # 编辑k3s配置文件
  2. vim /etc/rancher/k3s/config.yaml
  3. # 添加:
  4. flannel-backend: "host-gw"

设置监控,使其在内存达到85%时发出告警,备份采用crontab加上dump.rdb,并且每天将其挪走。

TLS加密配上,RBAC锁死。

剩下的,就交给它们自己玩吧。

对了,别信什么“一键部署”的鬼话。

这世上就没有一键的事,每个坑都得自己踩过,才叫经验。