【编者的话】etcd 是 Kubernetes 集群的数据核心,最严重的情况是,当 etcd 出问题彻底无法恢复的时候,解决问题的办法可能只有重新搭建一个环境。因此围绕 etcd 相关的运维知识就比较重要,etcd 可以容器化部署,也可以在宿主机自行搭建,以下内容是通用的。 集群的备份和恢复 添加备份

#!/bin/bash
IP=123.123.123.123
BACKUP_DIR=/alauda/etcd_bak/
mkdir -p $BACKUP_DIR
export ETCDCTL_API=3
etcdctl --endpoints=http://$IP:2379 snapshot save $BACKUP/snap-$(date +%Y%m%d%H%M).db

备份一个节点的数据就可以恢复,实践中,为了防止定时任务配置的节点异常没有生成备份,建议多加几个

恢复集群

!/bin/bash使用 etcdctl snapshot restore 生成各个节点的数据比较关键的变量是
--data-dir 需要是实际 etcd 运行时的数据目录
--name  --initial-advertise-peer-urls  需要用各个节点的配置
--initial-cluster  initial-cluster-token 需要和原集群一致ETCD_1=10.1.0.5
ETCD_2=10.1.0.6
ETCD_3=10.1.0.7for i in ETCD_1 ETCD_2 ETCD_3
doexport ETCDCTL_API=3
etcdctl snapshot restore snapshot.db \
--data-dir=/var/lib/etcd \
--name $i \
--initial-cluster ${ETCD_1}=http://${ETCD_1}:2380,${ETCD_2}=http://${ETCD_2}:2380,${ETCD_3}=http://${ETCD_3}:2380 \
--initial-cluster-token k8s_etcd_token \
--initial-advertise-peer-urls http://$i:2380 && \
mv /var/lib/etcd/ etcd_$idone

把 etcd_10.1.0.5 复制到 10.1.0.5节点,覆盖/var/lib/etcd(同--data-dir路径) 其他节点依次类推

用 etcd 自动创建的 SnapDb 恢复

!/bin/bash
export ETCDCTL_API=3
etcdctl snapshot restore snapshot.db \
--skip-hash-check \
--data-dir=/var/lib/etcd \
--name 10.1.0.5 \
--initial-cluster 10.1.0.5=http://10.1.0.5:2380,10.1.0.6=http://10.1.0.6:2380,10.1.0.7=http://10.1.0.7:2380 \
--initial-cluster-token k8s_etcd_token \
--initial-advertise-peer-urls http://10.1.0.5:2380

也是所有节点都需要生成自己的数据目录,参考上一条 和上一条命令唯一的差别是多了 --skip-hash-check (跳过完整性校验) 这种方式不能确保 100% 可恢复,建议还是自己加备份 通常恢复后需要做一下数据压缩和碎片整理,可参考相应章节

踩过的坑 [ 3.0.14 版 etcd restore 功能不可用 ] github.com/etcd-io/etc…

使用更新的 etcd 即可。

总结:恢复就是要拿 DB 去把 etcd 的数据生成一份,用同一个节点的,可以保证除了 restore 时候指定的参数外,所有数据都一样。这就是用一份 DB,操作三次(或者5次)的原因。 集群的扩容——从 1 到 3 执行添加

!/bin/bash
export ETCDCTL_API=2
etcdctl --endpoints=http://10.1.0.6:2379 member add 10.1.0.6 http://10.1.0.6:2380
etcdctl --endpoints=http://10.1.0.7:2379 member add 10.1.0.7 http://10.1.0.7:2380ETCD_NAME="etcd_10.1.0.6" ETCD_INITIAL_CLUSTER="10.1.0.6=http://10.1.0.6:2380,10.1.0.5=http://10.1.0.5:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"

准备添加的节点 etcd 参数配置

!/bin/bash
/usr/local/bin/etcd
--data-dir=/data.etcd
--name 10.1.0.6
--initial-advertise-peer-urls http://10.1.0.6:2380
--listen-peer-urls http://10.1.0.6:2380
--advertise-client-urls http://10.1.0.6:2379
--listen-client-urls http://10.1.0.6:2379
--initial-cluster 10.1.0.6=http://10.1.0.6:2380,10.1.0.5=http://10.1.0.5:2380
--initial-cluster-state exsiting
--initial-cluster-token k8s_etcd_token

--initial-cluster 集群所有节点的 name=ip:peer_url --initial-cluster-state exsiting 告诉 etcd 自己归属一个已存在的集群,不要自立门户

踩过的坑 从 1 到 3 期间,会经过集群是两节点的状态,这时候可能集群的表现就像挂了,endpoint status 这些命令都不能用,所以我们需要用 member add 先把集群扩到三节点,然后再依次启动 etcd 实例,这样做就能确保 etcd 就是健康的。

从 3 到更多,其实还是 member add 啦,就放心搞吧。 集群加证书 生成证书

curl -s -L -o /usr/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
curl -s -L -o /usr/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x /usr/bin/{cfssl,cfssljson}
cd /etc/kubernetes/pki/etcdcat ca-config.json
{
"signing": {
"default": {"expiry": "100000h"
},
"profiles": {"server": {"usages": ["signing", "key encipherment", "server auth", "client auth"],"expiry": "100000h"},"client": {"usages": ["signing", "key encipherment", "server auth", "client auth"],"expiry": "100000h"}
}
}
} cat ca-csr.json
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{"C": "CN","L": "Beijing","O": "Alauda","OU": "PaaS","ST": "Beijing"
}
]
} cat server-csr.json
{
"CN": "etcd-server",
"hosts": [
"localhost",
"0.0.0.0",
"127.0.0.1",
"所有master 节点ip ",
"所有master 节点ip ",
"所有master 节点ip "
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{"C": "CN","L": "Beijing","O": "Alauda","OU": "PaaS","ST": "Beijing"
}
]
} cat client-csr.json{
"CN": "etcd-client",
"hosts": [
""
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{"C": "CN","L": "Beijing","O": "Alauda","OU": "PaaS","ST": "Beijing"
}
]
} cd /etc/kubernetes/pki/etcdcfssl gencert -initca ca-csr.json | cfssljson -bare cacfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare servercfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client-csr.json | cfssljson -bare client

参考链接:lihaoquan.me/2017/3/29 ... .html 首先更新节点的peer-urls

export ETCDCTL_API=3
etcdctl --endpoints=http://x.x.x.x:2379 member list1111111111  ..........2222222222  ..........3333333333  ..........
etcdctl --endpoints=http://172.30.0.123:2379 member update 1111111111 --peer-urls=https://x.x.x.x:2380
# 执行三次把三个节点的peer-urls都改成https

修改配置

#  vim /etc/kubernetes/main*/etcd.yaml#  etcd启动命令部分修改 http 为 https,启动状态改成 existing
- --advertise-client-urls=https://x.x.x.x:2379
- --initial-advertise-peer-urls=https://x.x.x.x:2380
- --initial-cluster=xxx=https://x.x.x.x:2380,xxx=https://x.x.x.x:2380,xxx=https://x.x.x.x:2380
- --listen-client-urls=https://x.x.x.x:2379
- --listen-peer-urls=https://x.x.x.x:2380
- --initial-cluster-state=existing#  etcd 启动命令部分插入
- --cert-file=/etc/kubernetes/pki/etcd/server.pem
- --key-file=/etc/kubernetes/pki/etcd/server-key.pem
- --peer-cert-file=/etc/kubernetes/pki/etcd/server.pem
- --peer-key-file=/etc/kubernetes/pki/etcd/server-key.pem
- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem
- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem
- --peer-client-cert-auth=true
- --client-cert-auth=true#  检索hostPath在其后插入
- hostPath:path: /etc/kubernetes/pki/etcdtype: DirectoryOrCreate
name: etcd-certs#  检索mountPath在其后插入
- mountPath: /etc/kubernetes/pki/etcdname: etcd-certs#  vim /etc/kubernetes/main*/kube-apiserver.yaml
#  apiserver 启动部分插入,修改 http 为https
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.pem
- --etcd-certfile=/etc/kubernetes/pki/etcd/client.pem
- --etcd-keyfile=/etc/kubernetes/pki/etcd/client-key.pem
- --etcd-servers=https://x.x.x.x:2379,https://x.x.x.x:2379,https://x.x.x.x:2379

总结下就是,先准备一套证书。然后修改 etcd 内部通信地址为https,这时候etcd日志会报错(可以忽略),然后用etcd --带证书的参数启动,把所有链接etcd的地方都用上证书,即可。 遇到的坑 [ etcd 加证书后,apiserver 的健康检查还是 http 请求,etcd 会一直刷日志 ] github.com/etcd-io/etc… 2018-02-06 12:41:06.905234 I | embed: rejected connection from "127.0.0.1:35574" (error "EOF", ServerName "")

解决办法:直接去掉 apiserver 的健康检查,或者把默认的检查命令换成 curl(apiserver 的镜像里应该没有 curl,如果是刚需的话自己重新 build 一下吧) 集群升级 已经是 v3 的的集群不需要太多的配置,保留数据目录,替换镜像(或者二进制)即可;

v2 到 v3 的升级需要一个 merge 的操作,我并没有实际的实践过,也不太推荐这样做。 集群状态检查 其实上述所有步骤都需要这些命令的辅助——

#!/bin/bash
# 如果证书的话,去掉--cert --key --cacert 即可
# --endpoints= 需要写了几个节点的url,endpoint status就输出几条信息
export ETCDCTL_API=3etcdctl \
--endpoints=https://x.x.x.x:2379 \
--cert=/etc/kubernetes/pki/etcd/client.pem \
--key=/etc/kubernetes/pki/etcd/client-key.pem \
--cacert=/etc/kubernetes/pki/etcd/ca.pem \
endpoint status -w tableetcdctl --endpoints=xxxx endpoint healthetcdctl --endpoints=xxxx member listkubectl get cs

数据操作(删除、压缩、碎片整理) 删除

ETCDCTL_API=2 etcdctl rm --recursive            # v2 的 api 可以这样删除一个“目录”
ETCDCTL_API=3 etcdctl --endpoints=xxx del /xxxxx --prefix # v3 的版本# 带证书的话,参考上一条添加 --cert --key --cacert 即可

遇到的坑:在一个客户环境里发现 Kubernetes 集群里的 “事件” 超级多,就是 kubectl describe xxx 看到的 events 部分信息,数据太大导致 etcd 跑的很累,我们就用这样的方式删掉没用的这些数据。 碎片整理

ETCDCTL_API=3 etcdctl --endpoints=xx:xx,xx:xx,xx:xx defrag
ETCDCTL_API=3 etcdctl --endpoints=xx:xx,xx:xx,xx:xx endpoint status # 看数据量

压缩 ETCDCTL_API=3 etcdctl --endpoints=xx:xx,xx:xx,xx:xx compact


# 这个在只有 K8s 用的 etcd 集群里作用不太大,可能具体场景我没遇到
# 可参考这个文档
# https://www.cnblogs.com/davygeek/p/8524477.html
# 不过跑一下不碍事etcd --auto-compaction-retention=1# 添加这个参数让 etcd 运行时自己去做压缩

常见问题 etcd 对时间很依赖,所以集群里的节点时间一定要同步 磁盘空间不足,如果磁盘是被 etcd 自己吃完了,就需要考虑压缩和删数据啦 加证书后所有请求就都要带证书了,要不会提示 context deadline exceeded 做各个操作时 etcd 启动参数里标明节点状态的要小心,否则需要重新做一遍前面的步骤很麻烦

日志收集 etcd 的日志暂时只支持 syslog 和 stdout 两种——github.com/etcd-io/etc…

etcd 的日志在排查故障时很有用,如果我们用宿主机来部署 etcd,日志可以通过 systemd 检索到,但 kubeadm 方式启动的 etcd 在容器重启后就会丢失所有历史。我们可以用以下的方案来做—— shell 的重定向 etcd --xxxx --xxxx > /var/log/etcd.log

# 配合 logratate 来做日志切割
# 将日志通过 volume 挂载到宿主机

supervisor supervisor 从容器刚开始流行时,就是保持服务持续运行很有效的工具。 sidecar 容器(后续我在 GitHub 上补充一个例子,github.com/jing2uo) Sidecar 可以简单理解为一个 Pod 里有多个容器(比如 kubedns)他们彼此可以看到对方的进程,因此我们可以用传统的 strace 来捕捉 etcd 进程的输出,然后在 Sidecar 这个容器里和 shell 重定向一样操作。 strace -e trace=write -s 200 -f -p 1

Kubeadm 1.13 部署的集群 最近我们测试 Kubernetes 1.13 集群时发现了一些有趣的改变,诈一看我们上面的命令就没法用了——

kubernetes.io/docs/set ... logy/

区分了 Stacked etcd topology 和 External etcd topology,官方的链接了这个图很形象—— B70D000C-83B2-4B9C-A612-53925238D0DA.png

这种模式下的 etcd 集群,最明显的差别是容器内 etcd 的initial-cluster 启动参数只有自己的 IP,会有点懵挂了我这该怎么去恢复。其实基本原理没有变,Kubeadm 藏了个 ConfigMap,启动参数被放在了这里——

kubectl get cm  etcdcfg -n kube-system -o yamletcd:local:serverCertSANs:- "192.168.8.21"peerCertSANs:- "192.168.8.21"extraArgs:initial-cluster: 192.168.8.21=https://192.168.8.21:2380,192.168.8.22=https://192.168.8.22:2380,192.168.8.20=https://192.168.8.20:2380initial-cluster-state: newname: 192.168.8.21listen-peer-urls: https://192.168.8.21:2380listen-client-urls: https://192.168.8.21:2379advertise-client-urls: https://192.168.8.21:2379initial-advertise-peer-urls: https://192.168.8.21:2380

Q&A Q:请问 etcd 监控和告警如何做的?告警项都有哪些? A:告警要看用的什么监控吧,和 Kubernetes 配套比较常见的是普罗米修思和 Grafana 了。告警项我没有具体配过,可以关注的点是:endpoint status -w table 里可以看到数据量,endpoints health 看到健康状态,还有内存使用这些,具体可以参考普罗米修思的 exporter 是怎么做的。 Q:使用 Kubeadm 部署高可用集群是不是相当于先部署三个独立的单点 Master,最后靠 etcd 添加节点操作把数据打通? A:不是,Kubeadm 部署会在最开始就先建一个 etcd 集群,apiserver 启动之前就需要准备好 etcd,否则 apiserver 起不了,集群之间就没法通信。可以尝试手动搭一下集群,不用 Kubeadm,一个个把组件开起来,之后对Kubernetes的组件关系会理解更好的。 Q:etcd 跨机房高可用如何保证呢?管理 etcd 有好的 UI 工具推荐么? A:etcd 对时间和网络要求很高,所以跨机房的网络不好的话性能很差,光在那边选请输入链接描述举去了。我分享忘了提一个 etcd 的 mirror,可以去参考下做法。跨机房的话,我觉得高速网络是个前提吧,不过还没做过。UI 工具没找过,都是命令行操作来着。 Q:Kubeadm 启动的集群内 etcd节 点,kubectl 操作 etcd 的备份恢复有尝试过吗? A:没有用 kubectl 去处理过 etcd 的备份恢复。etcd 的恢复依赖用 SnapDb 生成数据目录,把 etcd 进程丢进容器里,类似的操作避免不了,还有启动的状态需要修改。kubeadm 启动的 etcd 可以通过 kubectl 查询和 exec,但是数据操作应该不可以,比如恢复 etcd ing 时,无法连接 etcd,kubectl 还怎么工作? Q:kubeadm-ha 启动 3 个 Master,有 3 个 etcd 节点,怎么跟集群外的 3 个 etcd 做集群,做成 3 Master 6 etcd? A:可以参考文档里的扩容部分,只要保证 etcd 的参数正确,即使一个集群一部分容器化,一部分宿主机,都是可以的(当然不建议这么做)。可以先用 kubeadm 搭一个集群,然后用扩容的方式把其他三个节点加进来,或者在 kubeadm 操作之前,先搭一个 etcd 集群。然后 kubeadm 调用它就可以。 Q:有没有试过 Kubeadm 的滚动升级,etcd 版本变更,各 Master 机分别重启,数据同步是否有异常等等? A:做过。Kubeadm 的滚动升级公司内部有从 1.7 一步步升级到 1.11、1.12 的文档,或多或少有一点小坑,不过今天主题是 etcd 所以没提这部分。各个 Master 分别重启后数据的一致我们测试时没问题,还有比较极端的是直接把三 Master 停机一天,再启动后也能恢复。 以上内容根据2019年1月3日晚微信群分享内容整理。分享人郭靖,灵雀云运维开发工程师,有大规模集群运维经验,对自动化迷之热衷,精通Ansible,HashiCorp工具集,容器和Kubernetes鼓捣了三年,喜欢用Python和Go写小工具,DevOps推崇及践行者,近期关注和期待OpsMop。DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesd,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

转载于:https://juejin.im/post/5c37130c518825251077bd5d

etcd 集群运维实践相关推荐

  1. 阿里巴巴大规模神龙裸金属 Kubernetes 集群运维实践

    戳蓝字"CSDN云计算"关注我们哦! 导读:值得阿里巴巴技术人骄傲的是 2019 年阿里巴巴 双11 核心系统 100% 以云原生的方式上云,完美支撑了 54.4w 峰值流量以及 ...

  2. 管理大规模容器集群能力包括_阿里巴巴大规模神龙裸金属 Kubernetes 集群运维实践...

    导读:值得阿里巴巴技术人骄傲的是 2019 年阿里巴巴 双11 核心系统 100% 以云原生的方式上云,完美支撑了 54.4w 峰值流量以及 2684 亿的成交量.背后承载海量交易的计算力就是来源于容 ...

  3. 阿里云注册集群+Prometheus 解决多云容器集群运维痛点

    作者:左知 容器集群可观测现状 随着 Kubernetes(K8s)容器编排工具已经成为事实上行业通用技术底座,容器集群监控经历多种方案实践后,Prometheus 最终成为容器集群监控的事实标准. ...

  4. Kafka的灵魂伴侣Logi-KafkaManger(4)之运维管控–集群运维(数据迁移和集群在线升级)

    推荐一款非常好用的kafka管理平台,kafka的灵魂伴侣 滴滴开源Logi-KafkaManager 一站式Kafka监控与管控平台 技术交流 有想进滴滴LogI开源用户群的加我个人微信: jjdl ...

  5. 集群运维:All datanodes DatanodeInfoWithStorage[10.21.131.179:50010,DS-6fca3fba-7b13-4855-b483-342df8432e

    规划出一个集群日常维护系列,分享各种奇葩案例,集群运维事故,欢迎大家交流投稿.集群的运维故障排查是一个任重而道远的事情. 1.集群故障现象 Error: java.lang.RuntimeExcept ...

  6. 第二课 ceph基础学习-OSD扩容换盘和集群运维

    第二课 ceph基础学习-OSD扩容换盘和集群运维 文章目录 第二课 ceph基础学习-OSD扩容换盘和集群运维 第一节 OSD扩容 1.1 扩容背景 1.2 横向扩容 1.3 纵向扩容 1.4 数据 ...

  7. 升腾威讯怎么恢复集群_PB级大规模Elasticsearch集群运维与调优实践

    导语 | 腾讯云Elasticsearch 被广泛应用于日志实时分析.结构化数据分析.全文检索等场景中,本文将以情景植入的方式,向大家介绍与腾讯云客户合作过程中遇到的各种典型问题,以及相应的解决思路与 ...

  8. PB 级大规模 Elasticsearch 集群运维与调优实践

    作者:bellen,腾讯云大数据研发工程师. 腾讯云 Elasticsearch 被广泛应用于日志实时分析.结构化数据分析.全文检索等场景中,本文将以情景植入的方式,向大家介绍与腾讯云客户合作过程中遇 ...

  9. PB级大规模Elasticsearch集群运维与调优实践

    导语 | 腾讯云Elasticsearch 被广泛应用于日志实时分析.结构化数据分析.全文检索等场景中,本文将以情景植入的方式,向大家介绍与腾讯云客户合作过程中遇到的各种典型问题,以及相应的解决思路与 ...

最新文章

  1. Python3 除法取整取余,上下取整
  2. spyder 崩溃解决方案
  3. 边缘计算架构_边缘计算到底是个什么技术?边缘计算硬件架构
  4. 源于 Node.js的HTML 模板引擎Jade的一个hello world项目
  5. 这4种钱没有也要借,不能等
  6. python生成yaml文件_Python实践34-读写yaml文件
  7. 单基因GSEA怎么做?
  8. 04:输出保留3位小数的浮点数
  9. 2019武汉大学计算机学院拟录取,武汉大学2019年招收攻读硕士研究生复试成绩拟录取名单...
  10. 中英文对照 —— 软件与病毒、电子与硬件
  11. 仿射解密c语言程序实验报告,仿射加密解密 - 依姆哣特的个人空间 - OSCHINA - 中文开源技术交流社区...
  12. C#相关控件使用总结
  13. python foc电机库_No.3 FOC SDK5.0电机库软件系统分析
  14. Tomcat7安装(jdk 1.7环境)
  15. python调用adb shell命令_Python3 执行 adb shell 命令详解
  16. 查看已连接的WiFi密码
  17. Android 状态栏背景颜色修改与状态栏字体颜色修改
  18. 8. Celery 4.3.0 Periodic Tasks 周期性任务调度
  19. c语言人民邮电出版社课后答案,C语言程序设计教程(人民邮电出版社) 课后习题解答6-10...
  20. 计算机打印设置方法,针式打印机设置教程详解,小编教你针式打印机设置共享/纸张大小方法...

热门文章

  1. UML类图、接口、包、关系
  2. 85. Maximal Rectangel
  3. 从零开始学习 webservice第一集,java webservice简单实例入门教程
  4. 企业文化建设不能仅仅靠大声疾呼
  5. juniper srx系列配置端口映射 转载
  6. 【裴蜀定理】BZOJ 1441 MIN
  7. ELK(Logstash+Elasticsearch+Kibana)的原理和详细搭建
  8. jQ进阶篇--jQuery封装placeholder效果,让低版本浏览器支持该效果
  9. 解密SSL流量,发现隐藏威胁
  10. 大数据应用开发八大基本原则