1. Rancher Kubernetes 组件-etcd 节点故障排除

Rancher Kubernetes 组件图

etcd 节点故障排除

本文介绍了对具有 etcd 角色的节点进行故障排除的命令和提示。

检查 etcd 容器是否正在运行

etcd 容器的状态应该是 UpUp 后面显示的时间指的是容器运行的时间。

docker ps -a -f=name=etcd$

输出示例:

CONTAINER ID   IMAGE                                 COMMAND                  CREATED          STATUS          PORTS     NAMES
d26adbd23643   rancher/mirrored-coreos-etcd:v3.5.7   "/usr/local/bin/etcd…"   30 minutes ago   Up 30 minutes             etcd

etcd 容器日志记录

容器的日志记录可能包含问题的信息。

docker logs etcd

日志解释
health check for peer xxx could not connect: dial tcp IP:2380: getsockopt: connection refused无法连接到端口 2380 上显示的地址。检查 etcd 容器是否在显示地址的主机上运行。
xxx is starting a new election at term xetcd 集群失去了集群仲裁数量,并正在尝试建立一个新的 leader。运行 etcd 的大多数节点关闭/无法访问时,可能会发生这种情况。
connection error: desc = "transport: Error while dialing dial tcp 0.0.0.0:2379: i/o timeout"; Reconnecting to {0.0.0.0:2379 0 <nil>}主机防火墙正在阻止网络通信。
rafthttp: request cluster ID mismatch具有 etcd 实例日志 rafthttp: request cluster ID mismatch 的节点正在尝试加入已经添加另一个对等节点(peer)的集群。你需要从集群中删除该节点,然后再重新添加。
rafthttp: failed to find member集群状态(/var/lib/etcd)包含加入集群的错误信息。你需要从集群中删除该节点,清理状态目录,然后再重新添加。

etcd 集群和连接检查

运行 etcd 的主机的地址配置决定了 etcd 监听的地址。如果为运行 etcd 的主机配置了内部地址,则需要显式指定 etcdctl 的端点。如果任何命令的响应是 Error: context deadline exceeded,则 etcd 实例不健康(仲裁丢失或实例未正确加入集群)。

检查所有节点上的 etcd 成员

输出应包含具有 etcd 角色的所有节点,而且所有节点上的输出应该是相同的。

命令:

docker exec etcd etcdctl member list

检查端点状态

RAFT TERM 的值应该是相等的,而且 RAFT INDEX 相差不能太大。

命令:

docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl endpoint status --write-out table

输出示例:

+-----------------+------------------+---------+---------+-----------+-----------+------------+
| ENDPOINT        |        ID        | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+-----------------+------------------+---------+---------+-----------+-----------+------------+
| https://IP:2379 | 333ef673fc4add56 |  3.5.7  |   24 MB |     false |        72 |      66887 |
| https://IP:2379 | 5feed52d940ce4cf |  3.5.7  |   24 MB |      true |        72 |      66887 |
| https://IP:2379 | db6b3bdb559a848d |  3.5.7  |   25 MB |     false |        72 |      66887 |
+-----------------+------------------+---------+---------+-----------+-----------+------------+

检查端点健康

命令:

docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl endpoint health

输出示例:

https://IP:2379 is healthy: successfully committed proposal: took = 2.113189ms
https://IP:2379 is healthy: successfully committed proposal: took = 2.649963ms
https://IP:2379 is healthy: successfully committed proposal: took = 2.451201ms

检查端口 TCP/2379 上的连接

命令:

for endpoint in $(docker exec etcd etcdctl member list | cut -d, -f5); do
   echo "Validating connection to ${endpoint}/health"
   docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl -s -w "\n" --cacert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CACERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --cert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --key $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_KEY" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) "${endpoint}/health"
done

输出示例:

Validating connection to https://IP:2379/health
{"health": "true"}
Validating connection to https://IP:2379/health
{"health": "true"}
Validating connection to https://IP:2379/health
{"health": "true"}

检查端口 TCP/2380 上的连接

命令:

for endpoint in $(docker exec etcd etcdctl member list | cut -d, -f4); do
  echo "Validating connection to ${endpoint}/version";
  docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl --http1.1 -s -w "\n" --cacert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CACERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --cert $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_CERT" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) --key $(docker inspect -f '{{range $index, $value := .Config.Env}}{{if eq (index (split $value "=") 0) "ETCDCTL_KEY" }}{{range $i, $part := (split $value "=")}}{{if gt $i 1}}{{print "="}}{{end}}{{if gt $i 0}}{{print $part}}{{end}}{{end}}{{end}}{{end}}' etcd) "${endpoint}/version"
done

输出示例:

Validating connection to https://IP:2380/version
{"etcdserver":"3.5.7","etcdcluster":"3.5.0"}
Validating connection to https://IP:2380/version
{"etcdserver":"3.5.7","etcdcluster":"3.5.0"}
Validating connection to https://IP:2380/version
{"etcdserver":"3.5.7","etcdcluster":"3.5.0"}

etcd 告警

etcd 会触发告警(例如空间不足时)。

命令:

docker exec etcd etcdctl alarm list

触发 NOSPACE 告警的输出示例:

memberID:x alarm:NOSPACE
memberID:x alarm:NOSPACE
memberID:x alarm:NOSPACE

etcd 空间错误

相关的错误消息是 etcdserver: mvcc: database space exceeded 或 applying raft message exceeded backend quota。告警 NOSPACE 会被触发。

解决:

压缩键空间

命令:

rev=$(docker exec etcd etcdctl endpoint status --write-out json | egrep -o '"revision":[0-9]*' | egrep -o '[0-9]*')
docker exec etcd etcdctl compact "$rev"

输出示例:

compacted revision xxx

对所有 etcd 成员进行碎片整理

命令:

docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl defrag

输出示例:

Finished defragmenting etcd member[https://IP:2379]
Finished defragmenting etcd member[https://IP:2379]
Finished defragmenting etcd member[https://IP:2379]

检查端点状态

命令:

docker exec -e ETCDCTL_ENDPOINTS=$(docker exec etcd etcdctl member list | cut -d, -f5 | sed -e 's/ //g' | paste -sd ',') etcd etcdctl endpoint status --write-out table

输出示例:

+-----------------+------------------+---------+---------+-----------+-----------+------------+
| ENDPOINT        |        ID        | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+-----------------+------------------+---------+---------+-----------+-----------+------------+
| https://IP:2379 |  e973e4419737125 |  3.5.7  |  553 kB |     false |        32 |    2449410 |
| https://IP:2379 | 4a509c997b26c206 |  3.5.7  |  553 kB |     false |        32 |    2449410 |
| https://IP:2379 | b217e736575e9dd3 |  3.5.7  |  553 kB |      true |        32 |    2449410 |
+-----------------+------------------+---------+---------+-----------+-----------+------------+

解除告警

如果压缩和整理碎片后确定数据库大小下降了,则需要解除告警来允许 etcd 再次写入。

命令:

docker exec etcd etcdctl alarm list
docker exec etcd etcdctl alarm disarm
docker exec etcd etcdctl alarm list

输出示例:

docker exec etcd etcdctl alarm list
memberID:x alarm:NOSPACE
memberID:x alarm:NOSPACE
memberID:x alarm:NOSPACE
docker exec etcd etcdctl alarm disarm
docker exec etcd etcdctl alarm list

配置日志级别

备注

你无法再动态更改 etcd v3.5 或更高版本中的日志级别。

etcd v3.5 及更高版本

要配置 etcd 的日志级别,请编辑集群 YAML:

services:
  etcd:
    extra_args:
      log-level: "debug"

etcd v3.4 及更早版本

在早期的 etcd 版本中,你可以使用 API 动态更改日志级别。使用以下命令来配置调试日志:

docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl -s -XPUT -d '{"Level":"DEBUG"}' --cacert $(docker exec etcd printenv ETCDCTL_CACERT) --cert $(docker exec etcd printenv ETCDCTL_CERT) --key $(docker exec etcd printenv ETCDCTL_KEY) $(docker exec etcd printenv ETCDCTL_ENDPOINTS)/config/local/log

要将日志级别重置回默认值 (INFO),你可以使用以下命令。

命令:

docker run --net=host -v $(docker inspect kubelet --format '{{ range .Mounts }}{{ if eq .Destination "/etc/kubernetes" }}{{ .Source }}{{ end }}{{ end }}')/ssl:/etc/kubernetes/ssl:ro appropriate/curl -s -XPUT -d '{"Level":"INFO"}' --cacert $(docker exec etcd printenv ETCDCTL_CACERT) --cert $(docker exec etcd printenv ETCDCTL_CERT) --key $(docker exec etcd printenv ETCDCTL_KEY) $(docker exec etcd printenv ETCDCTL_ENDPOINTS)/config/local/log

etcd 内容

如果要查看 etcd 的内容,你可以查看流事件,也可以直接查询 etcd。详情请参阅以下示例。

查看流事件

命令:

docker exec etcd etcdctl watch --prefix /registry

如果你只想查看受影响的键(而不是二进制数据),你可以将 | grep -a ^/registry 尾附到该命令来过滤键。

直接查询 etcd

命令:

docker exec etcd etcdctl get /registry --prefix=true --keys-only

你可以使用以下命令来处理数据,从而获取每个键的计数摘要:

docker exec etcd etcdctl get /registry --prefix=true --keys-only | grep -v ^$ | awk -F'/' '{ if ($3 ~ /cattle.io/) {h[$3"/"$4]++} else { h[$3]++ }} END { for(k in h) print h[k], k }' | sort -nr

更换不健康的 etcd 节点

如果你 etcd 集群中的某个节点变得不健康,在将新的 etcd 节点添加到集群之前,我们建议你修复或删除故障/不健康的节点。

IT干货+136-6258-1235-CSDN博客

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个示例的 `Dockerfile` 和 `.rancher-pipeline.yml` 文件,用于将 Python 应用程序打包成 API 并在 Rancher 上部署: Dockerfile: ``` FROM python:3.8-slim-buster # Set the working directory WORKDIR /app # Install dependencies COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # Copy the application code COPY app.py . # Expose the port EXPOSE 5000 # Start the application CMD [ "python", "app.py" ] ``` .rancher-pipeline.yml: ``` version: 2 # Define the pipeline pipelines: default: # Define the build step build: # Use the Dockerfile to build the image image: dockerfile:1.1.1 dockerfilePath: Dockerfile # Push the image to the Docker registry push: true registry: <your-registry> repository: <your-repository> tag: latest # Define the deploy step deploy: # Use the Rancher provider to deploy the image provider: rancher2 # Specify the Rancher API URL and access key apiURL: https://<your-rancher-url>/v3 accessKey: <your-access-key> secretKey: <your-secret-key> # Specify the Rancher project and namespace projectID: <your-project-id> namespace: <your-namespace> # Specify the Docker image to deploy image: <your-registry>/<your-repository>:latest # Specify the number of replicas to run replicas: 1 # Specify the service name and port serviceName: <your-service-name> servicePort: 5000 ``` 要使用这些文件,请按照以下步骤进行操作: 1. 创建一个名为 `Dockerfile` 的文件,并将上述 Dockerfile 代码复制到其中。 2. 创建一个名为 `requirements.txt` 的文件,并将 Python 应用程序的依赖项列在其中。 3. 创建一个名为 `app.py` 的文件,并将 Python 应用程序的代码复制到其中。 4. 创建一个名为 `.rancher-pipeline.yml` 的文件,并将上述 .rancher-pipeline.yml 代码复制到其中。 5. 将 `<your-registry>`、`<your-repository>`、`<your-rancher-url>`、`<your-access-key>`、`<your-secret-key>`、`<your-project-id>`、`<your-namespace>` 和 `<your-service-name>` 替换为实际值。 6. 将这些文件添加到 Git 存储库中,并在 Rancher 上设置 CI/CD 管道以使用这些文件构建和部署应用程序。 注意:这些文件只是示例,并且可能需要根据您的实际需求进行修改。请参考 Rancher 和 Docker 文档以了解有关如何使用这些工具的更多信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT干货+136-6258-1235

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值