rancher 自定义集群恢复
本文永久链接: https://www.xtplayer.cn/rancher/backup-restore/rancher-custom-cluster-restore/
根据 etcd 集群的容错机制,可以从机器重启这样的临时故障中自动恢复。对于永久性故障(比如由于硬件故障导致成员节点无法再连接到集群),它支持最多 (N-1)/2
个成员节点永久断开连接。 如果超过(N-1)/2
个成员节点断开连接,则 etcd 集群因为无法进行仲裁而无法继续正常运行,这个时候所有的 etcd 实例都将变成只读状态。
注意: 以下两种恢复方法要求 K8S 集群没有从 Rancher UI 中删除。
在有自动备份情况下恢复集群(UI 上集群未删除)
提示: 此方法适用于 Rancher v2.2.0 及以后版本创建的自定义 k8s 集群,并且 k8s 集群未从 Rancher UI 删除。
注意: 如果有在 Rancher v2.2.0 之前版本创建的 k8s 集群,在升级 Rancher 之后,您必须编辑并更新集群,以便启用自动备份功能。即使在 Rancher v2.2.0 之前创建了备份,也必须执行此步骤,因为旧的备份无法用于通过 Rancher UI 恢复 etcd 数据。
先决条件
要使用自定义 k8s 集群恢复功能,需要在创建集群时开启自动备份功能。如果集群变动比较频繁,可以把备份间隔缩短一些,根据磁盘大小设置保留的副本数。
系统会定时在 /opt/rke/etcd-snapshots
目录生成备份文件,并且在集群\工具\备份
视图下可以查看到历史备份。
操作步骤
在全局\集群视图中,定位到需要数据恢复的集群;
点击集群右侧的省略号菜单,点击从备份恢复;
选择要恢复的备份,点击保存;
在无自动备份情况下恢复集群(UI 上集群未删除)
提示: 此方法适用于所有 Rancher 版本创建的自定义 k8s 集群,并且 k8s 集群未从 Rancher UI 删除。
如果集群原有两个 ETCD 节点而坏掉一个,或者原有三个 ETCD 节点坏掉两个。这个时候 ETCD 集群将自动降级,所有键值对变成只读状态,这种情况下只能进行 ETCD 集群恢复。
对于早期没有自动备份功能的 Rancher 版本创建的集群,或者没有开启自动备份的 k8s 集群,只能通过使用 /var/lib/etcd
目录的 etcd 数据进行恢复,如果 /var/lib/etcd
目录被丢失,将无法进行恢复。
操作步骤
停止异常的 ETCD 节点或者在异常 ETCD 节点上执行 docker rm -f etcd 删除 ETCD 容器,保证环境中只有一个 ETCD 实例运行;
在剩下的最后一个 etcd 节点上,运行以下命令:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
registry.cn-shenzhen.aliyuncs.com/rancher/runlike etcd运行此命令将输出 etcd 的 running 命令,例如:
docker run --name=etcd --hostname=ubuntu2 \
--env="ETCDCTL_API=3" \
--env="ETCDCTL_CACERT=/etc/kubernetes/ssl/kube-ca.pem" \
--env="ETCDCTL_CERT=/etc/kubernetes/ssl/kube-etcd-1-1-1-133.pem" \
--env="ETCDCTL_KEY=/etc/kubernetes/ssl/kube-etcd-1-1-1-133-key.pem" \
--env="ETCDCTL_ENDPOINT=https://0.0.0.0:2379" \
--env="ETCD_UNSUPPORTED_ARCH=x86_64" \
--env="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
--volume="/var/lib/etcd:/var/lib/rancher/etcd/:z" \
--volume="/etc/kubernetes:/etc/kubernetes:z" \
--network=host \
--restart=always \
--label io.rancher.rke.container.name="etcd" \
--detach=true rancher/coreos-etcd:v3.2.24-rancher1 /usr/local/bin/etcd \
--peer-client-cert-auth \
--client-cert-auth \
--peer-cert-file=/etc/kubernetes/ssl/kube-etcd-1-1-1-133.pem \
--initial-cluster-token=etcd-cluster-1 \
--initial-cluster=etcd-1.1.1.128=https://1.1.1.128:2380,etcd-1.1.1.133=https://1.1.1.133:2380 \
--peer-trusted-ca-file=/etc/kubernetes/ssl/kube-ca.pem \
--key-file=/etc/kubernetes/ssl/kube-etcd-1-1-1-133-key.pem \
--data-dir=/var/lib/rancher/etcd/ \
--advertise-client-urls=https://1.1.1.133:2379,https://1.1.1.133:4001 \
--listen-client-urls=https://0.0.0.0:2379 \
--trusted-ca-file=/etc/kubernetes/ssl/kube-ca.pem \
--peer-key-file=/etc/kubernetes/ssl/kube-etcd-1-1-1-133-key.pem \
--heartbeat-interval=500 \
--initial-advertise-peer-urls=https://1.1.1.133:2380 \
--listen-peer-urls=https://0.0.0.0:2380 \
--cert-file=/etc/kubernetes/ssl/kube-etcd-1-1-1-133.pem \
--election-timeout=5000 \
--name=etcd-1.1.1.133 \
--initial-cluster-state=new在剩下的最后一个 ETCD 节点中,停止运行的 ETCD 容器并将其重命名为 etcd-old
docker stop etcd
docker rename etcd etcd-old在剩下的最后一个 ETCD 节点中,执行以下命令进行 ETCD 集群初始化:
# 定义节点 IP
## 注意,如果是多 IP 主机,需要根据第二步中显示的 IP 来判断其他节点中默认使用的是什么接口的 IP,因为在 `/etc/kubernetes/ssl/` 会以 IP 为格式命名生成 ETCD SSL 证书文件。
NODE_IP=1.1.1.128
ETCD_IMAGES=rancher/coreos-etcd:v3.2.24-rancher1
docker run --name=etcd --hostname=`hostname` \
--env="ETCDCTL_API=3" \
--env="ETCDCTL_CACERT=/etc/kubernetes/ssl/kube-ca.pem" \
--env="ETCDCTL_CERT=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`.pem" \
--env="ETCDCTL_KEY=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`-key.pem" \
--env="ETCDCTL_ENDPOINT=https://0.0.0.0:2379" \
--env="ETCD_UNSUPPORTED_ARCH=x86_64" \
--env="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
--volume="/var/lib/etcd:/var/lib/rancher/etcd/:z" \
--volume="/etc/kubernetes:/etc/kubernetes:z" \
--network=host \
--restart=always \
--label io.rancher.rke.container.name="etcd" \
--detach=true \
$ETCD_IMAGES \
/usr/local/bin/etcd \
--peer-client-cert-auth \
--client-cert-auth \
--peer-cert-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`.pem \
--peer-key-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`-key.pem \
--cert-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`.pem \
--trusted-ca-file=/etc/kubernetes/ssl/kube-ca.pem \
--initial-cluster-token=etcd-cluster-1 \
--peer-trusted-ca-file=/etc/kubernetes/ssl/kube-ca.pem \
--key-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`-key.pem \
--data-dir=/var/lib/rancher/etcd/ \
--advertise-client-urls=https://$NODE_IP:2379,https://$NODE_IP:4001 \
--listen-client-urls=https://0.0.0.0:2379 \
--listen-peer-urls=https://0.0.0.0:2380 \
--initial-advertise-peer-urls=https://$NODE_IP:2380 \
--election-timeout=5000 \
--heartbeat-interval=500 \
--name=etcd-`echo $NODE_IP|sed 's/\./-/g'` \
--initial-cluster=etcd-`echo $NODE_IP|sed 's/\./-/g'`=https://$NODE_IP:2380 \
--initial-cluster-state=new \
--force-new-cluster在剩下的最后一个 ETCD 节点中,执行以下命令添加第一个 ETCD MEMBER 节点
MEMBER_IP=1.1.1.133
docker exec -ti etcd etcdctl member add etcd-`echo $MEMBER_IP | sed 's/\./-/g'` --peer-urls=https://$MEMBER_IP:2380执行以上命令后将输出以下信息,请保存这些信息,在运行 member 节点时将要使用。
root@ubuntu1:~# docker exec -ti etcd etcdctl member add etcd-`echo $NODE2_IP | sed 's/\./-/g'` --peer-urls=https://$NODE2_IP:2380
Member 5ca934ee06d672a8 added to cluster e51c3a946e907f98
ETCD_NAME="etcd-1-1-1-133"
ETCD_INITIAL_CLUSTER="etcd-1-1-1-133=https://1.1.1.133:2380,etcd-1-1-1-128=https://1.1.1.128:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"执行以下命令查看成员状态,正常情况新加的成员会处于未开始状态,因为新的 ETCD 实例未运行。
docker exec -ti etcd etcdctl member list
root@ubuntu1:~# docker exec -ti etcd etcdctl member list
5ca934ee06d672a8, unstarted, , https://1.1.1.133:2380,
a57e863dc32700cb, started, etcd-1-1-1-128, https://1.1.1.128:2380, https://1.1.1.128:2379, https://1.1.1.128:4001在第一个 member 节点上执行以下命令添加第一个 member 节点。
# 定义节点 IP
## 注意,如果是多 IP 主机,需要根据第二步中显示的 IP 来判断其他节点中默认使用的是什么接口的 IP,因为在 `/etc/kubernetes/ssl/` 会以 IP 为格式命名生成 ETCD SSL 证书文件。
# 备份原有 ETCD 数据
mv /var/lib/etcd /var/lib/etcd-bak-$(date +"%Y%m%d%H%M")
NODE_IP=1.1.1.133
ETCD_IMAGES=rancher/coreos-etcd:v3.2.24-rancher1
# 以下三个配置为添加成员时返回
ETCD_NAME="etcd-1-1-1-133"
ETCD_INITIAL_CLUSTER="etcd-1-1-1-133=https://1.1.1.133:2380,etcd-1-1-1-128=https://1.1.1.128:2380"
ETCD_INITIAL_CLUSTER_STATE="existing"
docker run --name=etcd --hostname=`hostname` \
--env="ETCDCTL_API=3" \
--env="ETCDCTL_CACERT=/etc/kubernetes/ssl/kube-ca.pem" \
--env="ETCDCTL_CERT=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`.pem" \
--env="ETCDCTL_KEY=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`-key.pem" \
--env="ETCDCTL_ENDPOINT=https://0.0.0.0:2379" \
--env="ETCD_UNSUPPORTED_ARCH=x86_64" \
--env="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
--volume="/var/lib/etcd:/var/lib/rancher/etcd/:z" \
--volume="/etc/kubernetes:/etc/kubernetes:z" \
--network=host \
--restart=always \
--label io.rancher.rke.container.name="etcd" \
--detach=true \
$ETCD_IMAGES \
/usr/local/bin/etcd \
--peer-client-cert-auth \
--client-cert-auth \
--peer-cert-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`.pem \
--peer-key-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`-key.pem \
--cert-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`.pem \
--trusted-ca-file=/etc/kubernetes/ssl/kube-ca.pem \
--initial-cluster-token=etcd-cluster-1 \
--peer-trusted-ca-file=/etc/kubernetes/ssl/kube-ca.pem \
--key-file=/etc/kubernetes/ssl/kube-etcd-`echo $NODE_IP|sed 's/\./-/g'`-key.pem \
--data-dir=/var/lib/rancher/etcd/ \
--advertise-client-urls=https://$NODE_IP:2379,https://$NODE_IP:4001 \
--listen-client-urls=https://0.0.0.0:2379 \
--listen-peer-urls=https://0.0.0.0:2380 \
--initial-advertise-peer-urls=https://$NODE_IP:2380 \
--election-timeout=5000 \
--heartbeat-interval=500 \
--name=$ETCD_NAME \
--initial-cluster=$ETCD_INITIAL_CLUSTER \
--initial-cluster-state=$ETCD_INITIAL_CLUSTER_STATE
再次查看集群成员列表
root@ubuntu1:~# docker exec -ti etcd etcdctl member list
ba3bb38009530a59, started, etcd-1-1-1-128, https://1.1.1.128:2380, https://1.1.1.128:2379,https://1.1.1.128:4001
fa12c62d5695c420, started, etcd-1-1-1-133, https://1.1.1.133:2380, https://1.1.1.133:2379,https://1.1.1.133:4001重复上一步骤添加更多 member 节点
RKE 恢复(UI 上集群已删除)
注意: 以下的恢复方法是集群已从 UI 中删除。
在前面两种恢复方案中,前提是自定义集群没有从 UI 中删除。某些原因导致自定义集群从 UI 中删除从而导致集群配置全部丢失,对于这种场景,目前不支持通过 UI 来恢复自定义集群。但可以通过备份的数据并使用 RKE 来恢复 K8S 集群,然后再把恢复的 K8S 导入 Rancher 中管理。
存在旧集群的自动备份文件
如果之前的自定义集群开启了自动备份功能,那么在/opt/rke/etcd-snapshots/下会保存 ETCD 的备份数据。这个数据是通过 ZIP 压缩的,RKE 恢复的时候需要解压,比如:unzip 2020-01-12T09:14:51Z_etcd.zip。
恢复步骤
准备恢复节点,恢复节点可以是全新的节点,或者是之前集群中经过初始化的某个节点;
拷贝旧集群的备份文件到恢复节点的某个路径,比如/home/restore;
执行以下命令恢复备份文件到 ETCD 默认数据目录
/var/lib/etcd
,此目录不能已存在,etcdctl 会自动创建。这里需要使用 etcdctl 工具,下载地址:https://github.com/etcd-io/etcd/releases
NODE_IP='' (当前节点 ip)
ETCD_NAME=$( echo etcd-$( echo $NODE_IP | sed 's/\./-/g' ) )
ETCD_INITIAL_CLUSTER="$( echo $ETCD_NAME=https://${NODE_IP}:2380 )"
ETCDCTL_API=3 etcdctl snapshot restore xxxxxxxxx \
--data-dir="/var/lib/etcd" \
--initial-cluster=${ETCD_INITIAL_CLUSTER} \
--initial-advertise-peer-urls="https://${NODE_IP}:2380"根据RKE 配置示例创建集群的 cluster.yaml 配置文件;
执行 rke up –config xxxx.yaml 拉起新的集群;
INFO[0039] [addons] Successfully saved ConfigMap for addon rke-metrics-addon to Kubernetes
INFO[0039] [addons] Executing deploy job rke-metrics-addon
INFO[0040] [addons] Metrics Server deployed successfully
INFO[0040] [ingress] removing installed ingress controller
WARN[0108] Failed to deploy addon execute job [rke-ingress-controller]: Failed to get job complete status for job rke-ingress-controller-delete-job in namespacekube-system
INFO[0108] [addons] Setting up user addons
INFO[0108] [addons] no user addons defined
INFO[0108] Finished building Kubernetes cluster successfully注意: 此处的 WARN 可以忽略,因为在 ETCD 数据中已经保存了 ingress 服务,而在 rke up 的时候会删除旧的 ingress 数据,比如 ingress SVC 和 ingress 对应的命名空间。删除 ingress 命名空间的时候可能会出现一直无法删除而超时的情况,最后无法获取 JOB 的状态,所以这个错误可以忽略。
删除残留文件(可选)
集群恢复有可能会导致一些组件对应的 SA 鉴权失效,通过查看
kubectl --kubeconfig=kube_config_rancher-cluster-restore.yml get pods --all-namespaces
可以看到很多 pod 一直无法正常运行,查看 pod 日志可以看到Authentication failed
等信息。这个时候需要删除一些旧的认证配置然后重新生成。kubeconfig=kube_config_cluster.yml
# 重建 SA Token 密文
kubectl --kubeconfig=$kubeconfig -n kube-system get secrets | \
grep 'kubernetes.io/service-account-token'| awk '{print $1}' | \
grep -E 'coredns|flannel|metrics-server|horizontal|canal|calico' | \
xargs kubectl -n kube-system --kubeconfig=$kubeconfig delete --force --grace-period=0 secrets
kubectl --kubeconfig=$kubeconfig -n cattle-system get secrets | \
grep 'kubernetes.io/service-account-token'| awk '{print $1}' | grep -E 'rancher|cattle' | \
xargs kubectl -n cattle-system --kubeconfig=$kubeconfig delete --force --grace-period=0 secrets
kubectl --kubeconfig=$kubeconfig -n ingress-nginx get secrets | \
grep 'kubernetes.io/service-account-token'| awk '{print $1}' | \
grep -E 'nginx-ingress-serviceaccount' | \
xargs kubectl -n ingress-nginx --kubeconfig=$kubeconfig delete --force --grace-period=0 secrets
# 重建 kube-system 命名空间的 pod
kubectl -n kube-system --kubeconfig=$kubeconfig get pod | awk '{print $1}' | \
grep -E 'coredns|flannel|metrics-server|horizontal|canal|calico' | \
xargs kubectl -n kube-system --kubeconfig=$kubeconfig delete --force --grace-period=0 pod
# 重建 cattle-system 命名空间的 pod
kubectl -n cattle-system --kubeconfig=$kubeconfig get pod | awk '{print $1}' | \
grep -E 'rancher|cattle-node|cattle-cluster-agent' | \
xargs kubectl -n cattle-system --kubeconfig=$kubeconfig delete --force --grace-period=0 pod
# 重建 ingress-nginx 命名空间的 pod
kubectl -n ingress-nginx --kubeconfig=$kubeconfig get pod | awk '{print $1}' | \
grep -E 'nginx-ingress-controller' | \
xargs kubectl -n ingress-nginx --kubeconfig=$kubeconfig delete --force --grace-period=0 pod接着在 rancher 中创建导入集群,然后把恢复的集群导入 rancher 中管理。
重新导入的时候可能会提示 serviceaccount 或者 clusterrolebinding 已存在,那么需要通过以下命令去删除。
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrole.rbac.authorization.k8s.io/proxy-clusterrole-kubeapiserver
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrolebinding.rbac.authorization.k8s.io/proxy-role-binding-kubernetes-master
kubectl --kubeconfig=$kubeconfig delete -n cattle-system serviceaccount/cattle
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrolebinding.rbac.authorization.k8s.io/cattle-admin-binding
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrole.rbac.authorization.k8s.io/cattle-admin
kubectl --kubeconfig=$kubeconfig delete -n cattle-system deployment.apps/cattle-cluster-agent
kubectl --kubeconfig=$kubeconfig delete -n cattle-system daemonset.apps/cattle-node-agent
kubectl --kubeconfig=$kubeconfig -n cattle-system get secrets | \
grep cattle-credentials | awk '{print $1}' | \
xargs kubectl --kubeconfig=$kubeconfig delete -n cattle-system secret
没有旧集群的自动备份文件
对于早期的 rancher 版本,没有通过 UI 备份也没有开启自动备份。对于这种场景,只能通过/var/lib/etcd 目录来重建集群,请检查/var/lib/etcd 目录是否还存在。
恢复步骤
准备恢复节点。恢复节点可以是全新的节点,或者是之前集群中经过初始化的某个节点;
拷贝旧集群节点中/var/lib/etcd 目录到恢复节点的相同路径;
根据RKE 配置示例创建集群的 cluster.yaml 配置文件;
执行 rke up –config xxxx.yaml 拉起新的集群;
INFO[0039] [addons] Successfully saved ConfigMap for addon rke-metrics-addon to Kubernetes
INFO[0039] [addons] Executing deploy job rke-metrics-addon
INFO[0040] [addons] Metrics Server deployed successfully
INFO[0040] [ingress] removing installed ingress controller
WARN[0108] Failed to deploy addon execute job [rke-ingress-controller]: Failed to get job complete status for job rke-ingress-controller-delete-job in namespacekube-system
INFO[0108] [addons] Setting up user addons
INFO[0108] [addons] no user addons defined
INFO[0108] Finished building Kubernetes cluster successfully注意: 此处的 WARN 可以忽略,因为在 ETCD 数据中已经保存了 ingress 服务,而在 rke up 的时候会删除旧的 ingress 数据,比如 ingress SVC 和 ingress 对应的命名空间。删除 ingress 命名空间的时候可能会出现一直无法删除而超时的情况,最后无法获取 JOB 的状态,所以这个错误可以忽略。
删除残留文件(可选)
集群恢复有可能会导致一些组件对应的 SA 鉴权失效,通过查看
kubectl --kubeconfig=kube_config_rancher-cluster-restore.yml get pods --all-namespaces
可以看到很多 pod 一直无法正常运行,查看 pod 日志可以看到Authentication failed
等信息。这个时候需要删除一些旧的认证配置然后重新生成。kubeconfig=kube_config_cluster.yml
# 重建 SA Token 密文
kubectl --kubeconfig=$kubeconfig -n kube-system get secrets | \
grep 'kubernetes.io/service-account-token'| awk '{print $1}' | \
grep -E 'coredns|flannel|metrics-server|horizontal|canal|calico' | \
xargs kubectl -n kube-system --kubeconfig=$kubeconfig delete --force --grace-period=0 secrets
kubectl --kubeconfig=$kubeconfig -n cattle-system get secrets | \
grep 'kubernetes.io/service-account-token'| awk '{print $1}' | grep -E 'rancher|cattle' | \
xargs kubectl -n cattle-system --kubeconfig=$kubeconfig delete --force --grace-period=0 secrets
kubectl --kubeconfig=$kubeconfig -n ingress-nginx get secrets | \
grep 'kubernetes.io/service-account-token'| awk '{print $1}' | \
grep -E 'nginx-ingress-serviceaccount' | \
xargs kubectl -n ingress-nginx --kubeconfig=$kubeconfig delete --force --grace-period=0 secrets
# 重建 kube-system 命名空间的 pod
kubectl -n kube-system --kubeconfig=$kubeconfig get pod | awk '{print $1}' | \
grep -E 'coredns|flannel|metrics-server|horizontal|canal|calico' | \
xargs kubectl -n kube-system --kubeconfig=$kubeconfig delete --force --grace-period=0 pod
# 重建 cattle-system 命名空间的 pod
kubectl -n cattle-system --kubeconfig=$kubeconfig get pod | awk '{print $1}' | \
grep -E 'rancher|cattle-node|cattle-cluster-agent' | \
xargs kubectl -n cattle-system --kubeconfig=$kubeconfig delete --force --grace-period=0 pod
# 重建 ingress-nginx 命名空间的 pod
kubectl -n ingress-nginx --kubeconfig=$kubeconfig get pod | awk '{print $1}' | \
grep -E 'nginx-ingress-controller' | \
xargs kubectl -n ingress-nginx --kubeconfig=$kubeconfig delete --force --grace-period=0 pod接着在 rancher 中创建导入集群,然后把恢复的集群导入 rancher 中管理。
重新导入的时候可能会提示 serviceaccount 或者 clusterrolebinding 已存在,那么需要通过以下命令去删除。
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrole.rbac.authorization.k8s.io/proxy-clusterrole-kubeapiserver
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrolebinding.rbac.authorization.k8s.io/proxy-role-binding-kubernetes-master
kubectl --kubeconfig=$kubeconfig delete -n cattle-system serviceaccount/cattle
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrolebinding.rbac.authorization.k8s.io/cattle-admin-binding
kubectl --kubeconfig=$kubeconfig delete -n cattle-system clusterrole.rbac.authorization.k8s.io/cattle-admin
kubectl --kubeconfig=$kubeconfig delete -n cattle-system deployment.apps/cattle-cluster-agent
kubectl --kubeconfig=$kubeconfig delete -n cattle-system daemonset.apps/cattle-node-agent
kubectl --kubeconfig=$kubeconfig -n cattle-system get secrets | \
grep cattle-credentials | awk '{print $1}' | \
xargs kubectl --kubeconfig=$kubeconfig delete -n cattle-system secret