Ubuntu 22.04 LTS 二进制搭建高可用的ETCD集群

1. etcd 介绍

1.1 什么是 etcd?

etcd 是一个 分布式、可靠的键值存储系统,用于存储 分布式系统中的关键数据。它提供了 高可用性、强一致性(CP)高性能,被广泛应用于 Kubernetes、微服务架构、分布式锁、配置管理 等场景。

etcd 的核心特点:

  • 简单:提供清晰、面向用户的 gRPC API,易于集成。

  • 安全:支持 TLS 加密,可选 客户端证书身份验证,确保数据安全。

  • 快速:以 每秒 10,000 次写入 作为性能基准。

  • 可靠:基于 Raft 共识算法,确保数据复制的一致性。

1.2 etcd 的工作原理

etcd 由 Go 语言 编写,使用 Raft 共识算法 维护数据一致性。
Raft 通过 选主(Leader Election)、日志复制(Log Replication) 等机制,确保集群中的数据始终保持一致。

当客户端向 etcd 集群写入数据时:

  1. 数据提交到 Leader

  2. Leader 将日志复制到所有 Follower

  3. 超过半数 Follower 确认数据后,Leader 提交变更

  4. 所有节点更新状态,确保数据一致

1.3 etcd 的核心组件

1.3.1 etcd 服务

etcd 运行在服务器上,存储和管理键值数据,支持 HTTP/gRPC API 进行读写操作。

1.3.2 etcdctl(命令行工具)

etcdctl 是 etcd 提供的官方 CLI 工具,用户可以通过它进行数据存储、查询等操作。

示例:

# 存储键值
etcdctl put /config/db_user "root"

# 获取键值
etcdctl get /config/db_user

# 监听键值变化
etcdctl watch /config/db_user
1.3.3 etcd API 版本

etcd 主要有 v2 和 v3 两个 API 版本

  • etcd v3推荐的生产环境版本性能更强、功能更完善
  • etcd v2 不兼容 v3,数据格式不同。

切换 API 版本:

export ETCDCTL_API=3  # 使用 v3 API
export ETCDCTL_API=2  # 使用 v2 API

1.4 etcd 在生产环境中的应用

etcd 被广泛应用于多个分布式系统,以下是几个典型的应用场景:

1.4.1 Kubernetes

Kubernetes 依赖 etcd 存储 集群状态、Pod 信息、Service 配置 等核心数据:

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-config
data:
  key: "value"
1.4.2 分布式锁

etcd 支持 乐观并发控制,可以用于 分布式锁

etcdctl lock mylock "echo locked"
1.4.3 配置管理

etcd 可以作为 集中式配置存储,应用程序可以监听配置变化,做到 热更新

etcdctl watch /config/app_settings

1.5 生产环境最佳实践

  • 使用 etcd v3 版本,避免 v2 的兼容性问题

  • 启用 TLS 进行加密通信,避免数据泄露:

    etcd --cert-file=mycert.pem --key-file=mykey.pem --peer-cert-file=peercert.pem --peer-key-file=peerkey.pem
    
  • 合理设置集群规模,推荐 奇数个节点(3、5、7) 以提高容错能力。

  • 使用 snapshot 进行数据备份,防止数据丢失:

    etcdctl snapshot save backup.db
    etcdctl snapshot restore backup.db
    

1.6 参考资料

  • 官方 GitHub 仓库:https://github.com/etcd-io/etcd
  • 官方文档:https://etcd.io/docs/

2. 安装 etcd 的方式

  • 包管理方式安装: 安装简单,但是版本低
apt -y install etcd-client
  • 通过二进制文件安装:可以安装任意版本

3. 准备 etcd 程序包

3.1 下载 etcd 的软件包

[root@etcd90:~]# wget https://github.com/etcd-io/etcd/releases/download/v3.5.19/etcd-v3.5.19-linux-amd64.tar.gz

3.2 解压并移动到 /usr/local/bin/

[root@etcd90:~]# tar xf etcd-v3.5.19-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin etcd-v3.5.19-linux-amd64/etcd{,ctl}
[root@etcd90:~]# ll /usr/local/bin/etcd*
-rwxr-xr-x 1 jasper jasper 24064152 Mar  6 03:34 /usr/local/bin/etcd*
-rwxr-xr-x 1 jasper jasper 18419864 Mar  6 03:34 /usr/local/bin/etcdctl*

3.3 验证安装

[root@etcd90:~]# etcdctl version
etcdctl version: 3.5.19
API version: 3.5

3.4 将软件包下发到所有节点

[root@etcd90:~]# scp /usr/local/bin/etcd* 10.0.0.91:/usr/local/bin/
[root@etcd90:~]# scp /usr/local/bin/etcd* 10.0.0.92:/usr/local/bin/

4. 准备 etcd 的证书文件

4.1 安装 cfssl 证书管理工具

# 下载 fssl 工具
[root@etcd90:~]# wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl-certinfo_1.6.5_linux_amd64
[root@etcd90:~]# wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssljson_1.6.5_linux_amd64
[root@etcd90:~]# wget https://github.com/cloudflare/cfssl/releases/download/v1.6.5/cfssl_1.6.5_linux_amd64

# 安装 rename 工具,方便修改文件名
[root@etcd90:~]# apt install rename

# 批量重命名文件,去除多余的部分
[root@etcd90:~]# rename -v "s/_1.6.5_linux_amd64//g" cfssl*

# 查看重命名后的文件列表
[root@etcd90:~]# ll cfssl*
-rw-r--r-- 1 root root 11890840 Mar  6  2024 cfssl
-rw-r--r-- 1 root root  8413336 Mar  6  2024 cfssl-certinfo
-rw-r--r-- 1 root root  6205592 Mar  6  2024 cfssljson

# 将 cfssl 工具移动到 /usr/local/bin 目录下
[root@etcd90:~]# mv cfssl* /usr/local/bin/

# 给所有 cfssl 工具添加可执行权限
[root@etcd90:~]# chmod +x /usr/local/bin/cfssl*

# 查看安装后的 cfssl 工具
[root@etcd90:~]# ll /usr/local/bin/cfssl*
-rwxr-xr-x 1 root root 11890840 Mar  6  2024 /usr/local/bin/cfssl*
-rwxr-xr-x 1 root root  8413336 Mar  6  2024 /usr/local/bin/cfssl-certinfo*
-rwxr-xr-x 1 root root  6205592 Mar  6  2024 /usr/local/bin/cfssljson*

4.2 创建证书存储目录

# 创建用于存放证书的目录,并切换到该目录
[root@etcd90:~]# mkdir -p /jasper/certs/etcd && cd /jasper/certs/etcd

4.3 生成证书的 CSR 文件

[root@etcd90:etcd]# cat > etcd-ca-csr.json <<EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "GuangDong",
      "L": "ShenZhen",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF

字段解释

  • "CN": "etcd"
    • Common Name(CN),证书的主机名。
  • "key": { "algo": "rsa", "size": 2048 }
    • algo:加密算法,采用 RSA
    • size:密钥大小,设为 2048 位
  • "names": [...]
    • C(Country):国家代码,这里填写 “CN”(中国)
    • ST(State/Province):省份或州,这里填写 “GuangDong”(广东)
    • L(Locality):城市,这里填写 “ShenZhen”(深圳)
    • O(Organization):组织名称,这里填写 “etcd”,即 etcd 组件
    • OU(Organizational Unit):组织单位(部门),填写 “Etcd Security”,表示用于 etcd 安全认证
  • "ca": { "expiry": "876000h" }
    • expiry:证书有效期,876000 小时 = 100 年

4.4 生成 etcd CA 证书和 CA 证书的 key

# 基于上述的 CSR 文件生成 etcd CA 证书和私钥
[root@etcd90:etcd]# cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /jasper/certs/etcd/etcd-ca

# 查看生成的证书文件
[root@etcd90:etcd]# ll /jasper/certs/etcd/etcd-ca*
-rw-r--r-- 1 root root  252 Mar 20 16:42 /jasper/certs/etcd/etcd-ca-csr.json
-rw------- 1 root root 1675 Mar 20 16:44 /jasper/certs/etcd/etcd-ca-key.pem
-rw-r--r-- 1 root root 1054 Mar 20 16:44 /jasper/certs/etcd/etcd-ca.csr
-rw-r--r-- 1 root root 1326 Mar 20 16:44 /jasper/certs/etcd/etcd-ca.pem

4.5 生成 etcd 证书的有效期为 100 年

[root@etcd90:etcd]# cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "876000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF

字段解释

# "expiry": "876000h"  # 默认有效期为 100 年
# "usages": [...]      # 配置证书的用途
# "expiry": "876000h"  # 证书有效期为 100 年

4.6 生成证书的 CSR 文件

[root@etcd90:etcd]# cat > etcd-csr.json <<EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "GuangDong",
      "L": "ShenZhen",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ]
}
EOF

4.7 基于自建的 etcd CA 证书生成 etcd 的证书

[root@etcd90:etcd]# cfssl gencert \
  -ca=/jasper/certs/etcd/etcd-ca.pem \
  -ca-key=/jasper/certs/etcd/etcd-ca-key.pem \
  -config=ca-config.json \
  --hostname=127.0.0.1,etcd90,etcd91,etcd92,10.0.0.90,10.0.0.91,10.0.0.92 \
  --profile=kubernetes \
  etcd-csr.json  | cfssljson -bare /jasper/certs/etcd/etcd-server

命令详解

# 1. `cfssl gencert`
- `cfssl gencert`:使用 **CFSSL** 生成证书。

# 2. `-ca=/jasper/certs/etcd/etcd-ca.pem`
- **指定 CA 证书**,用 `/jasper/certs/etcd/etcd-ca.pem` 作为 **签发者**。

# 3. `-ca-key=/jasper/certs/etcd/etcd-ca-key.pem`
- **指定 CA 私钥**,用 `/jasper/certs/etcd/etcd-ca-key.pem` 来 **签名证书**。

# 4. `-config=ca-config.json`
- **指定 CA 配置文件**,用于定义签名策略,如证书的有效期、用途等。

# 5. `--hostname=127.0.0.1,etcd90,etcd91,etcd92,10.0.0.90,10.0.0.91,10.0.0.92`
- 设置证书的主机名(SANs - Subject Alternative Names):
  - 允许 `127.0.0.1`(本地回环地址)
  - 允许 `etcd90``etcd91``etcd92`(etcd 集群主机名)
  - 允许 `10.0.0.90``10.0.0.91``10.0.0.92`(etcd 节点的 IP)

# 6. `--profile=kubernetes`
- 使用 `ca-config.json` 配置文件中 `kubernetes` 这一签名策略,可能包含:
  - `server auth`:服务器认证
  - `client auth`:客户端认证
  - `signing`:签名
  - `key encipherment`:密钥加密
  - `expiry`:证书有效期(例如 100 年)

# 7. `etcd-csr.json`
- 指定证书签名请求(CSR)文件,包含:
  - 证书的通用名称(CN)
  - 组织信息(O、OU、C、ST、L)
  - 加密算法和密钥长度(RSA 2048# 8. `| cfssljson -bare /jasper/certs/etcd/etcd-server`
- `cfssl gencert` 生成的 JSON 格式证书数据,通过 `|` 管道传递给 `cfssljson` 进行转换,并生成以下文件:
  - `/jasper/certs/etcd/etcd-server.pem`(etcd 服务器证书)
  - `/jasper/certs/etcd/etcd-server-key.pem`(etcd 服务器私钥)
  - `/jasper/certs/etcd/etcd-server.csr`(证书签名请求)
[root@etcd90:etcd]# ll /jasper/certs/etcd/etcd-server*
-rw------- 1 root root 1679 Mar 20 17:01 /jasper/certs/etcd/etcd-server-key.pem
-rw-r--r-- 1 root root 1110 Mar 20 17:01 /jasper/certs/etcd/etcd-server.csr
-rw-r--r-- 1 root root 1448 Mar 20 17:01 /jasper/certs/etcd/etcd-server.pem

4.8 将 etcd 证书拷贝到其他两个 master 节点

[root@etcd90:etcd]# scp -r /jasper/certs 10.0.0.91:/jasper/
[root@etcd90:etcd]# scp -r /jasper/certs 10.0.0.92:/jasper/

5. 创建 etcd 集群各节点配置文件

5.1 etcd90 节点的配置文件

[root@etcd90:etcd]# mkdir -p /jasper/softwares/etcd
[root@etcd90:etcd]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd90'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.0.0.90:2380'
listen-client-urls: 'https://10.0.0.90:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors: ""
initial-advertise-peer-urls: 'https://10.0.0.90:2380'
advertise-client-urls: 'https://10.0.0.90:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy: ""
discovery-srv: ""
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
  auto-tls: false
peer-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
EOF

配置文件解释:

[root@etcd90:etcd]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd90'  # 节点名称
data-dir: /var/lib/etcd  # 数据存储目录
wal-dir: /var/lib/etcd/wal  # Write-Ahead Log 存储目录
snapshot-count: 5000  # 每 5000 次写操作生成一个快照
heartbeat-interval: 100  # 心跳间隔,单位:毫秒
election-timeout: 1000  # 选举超时时间,单位:毫秒
quota-backend-bytes: 0  # 后端存储配额,设置为 0 表示不限制
listen-peer-urls: 'https://10.0.0.90:2380'  # 节点之间通信的 URL
listen-client-urls: 'https://10.0.0.90:2379,http://127.0.0.1:2379'  # 对外提供的 API 服务 URL
max-snapshots: 3  # 最大快照数量,超过时会自动删除最旧的
max-wals: 5  # 最大 WAL 文件数量
cors: ""  # 允许跨域访问,设置为空表示不使用
initial-advertise-peer-urls: 'https://10.0.0.90:2380'  # 初始的 peer URL
advertise-client-urls: 'https://10.0.0.90:2379'  # 初始的 client URL
discovery:
  discovery-fallback: 'proxy'  # 如果不能发现节点,则回退到代理模式
  discovery-proxy: ""  # 代理 URL,留空表示不使用
  discovery-srv: ""  # DNS 服务发现,留空表示不使用
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380'  # 初始集群配置
initial-cluster-token: 'etcd-k8s-cluster'  # 集群标识符
initial-cluster-state: 'new'  # 新集群
strict-reconfig-check: false  # 是否严格检查集群配置
enable-v2: true  # 启用 v2 API
enable-pprof: true  # 启用 pprof 性能分析
proxy: 'off'  # 禁用代理模式
proxy-failure-wait: 5000  # 代理失败后的重试等待时间
proxy-refresh-interval: 30000  # 代理刷新间隔
proxy-dial-timeout: 1000  # 代理连接超时时间
proxy-write-timeout: 5000  # 代理写操作超时时间
proxy-read-timeout: 0  # 代理读操作超时时间

client-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'  # 客户端证书
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'  # 客户端私钥
  client-cert-auth: true  # 启用客户端证书认证
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'  # 客户端受信任的 CA 证书
  auto-tls: false  # 禁用自动 TLS 生成

peer-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'  # 节点间通信的证书
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'  # 节点间通信的私钥
  peer-client-cert-auth: true  # 启用节点间通信证书认证
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'  # 受信任的 CA 证书
EOF

5.2 etcd91 节点的配置文件

[root@etcd91:~]# mkdir -p /jasper/softwares/etcd
[root@etcd91:~]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd91'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.0.0.91:2380'
listen-client-urls: 'https://10.0.0.91:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors: ""
initial-advertise-peer-urls: 'https://10.0.0.91:2380'
advertise-client-urls: 'https://10.0.0.91:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy: ""
discovery-srv: ""
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
  auto-tls: false
peer-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
EOF

5.3 etcd92 节点的配置文件

[root@etcd92:~]# mkdir -p /jasper/softwares/etcd
[root@etcd92:~]# cat > /jasper/softwares/etcd/etcd.config.yml <<'EOF'
name: 'etcd92'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://10.0.0.92:2380'
listen-client-urls: 'https://10.0.0.92:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors: ""
initial-advertise-peer-urls: 'https://10.0.0.92:2380'
advertise-client-urls: 'https://10.0.0.92:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy: ""
discovery-srv: ""
initial-cluster: 'etcd90=https://10.0.0.90:2380,etcd91=https://10.0.0.91:2380,etcd92=https://10.0.0.92:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
  auto-tls: false
peer-transport-security:
  cert-file: '/jasper/certs/etcd/etcd-server.pem'
  key-file: '/jasper/certs/etcd/etcd-server-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/jasper/certs/etcd/etcd-ca.pem'
EOF

5.4 每个节点编写 etcd 启动脚本

cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Jasper's Etcd Service
Documentation=https://coreos.com/etcd/docs/latest/
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/bin/etcd --config-file=/jasper/softwares/etcd/etcd.config.yml
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
Alias=etcd3.service
EOF

6. 启动 etcd 集群

systemctl daemon-reload && systemctl enable --now etcd
systemctl status etcd

7. 查看 etcd 集群状态

[root@etcd90:etcd]# etcdctl --endpoints="10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem  endpoint status --write-out=table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|    ENDPOINT    |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 |  3.5.19 |   20 kB |     false |      false |         2 |          9 |                  9 |        |
| 10.0.0.91:2379 | b207a358c2aaa147 |  3.5.19 |   20 kB |      true |      false |         2 |          9 |                  9 |        |
| 10.0.0.92:2379 | 432a416a50e3d3d5 |  3.5.19 |   20 kB |     false |      false |         2 |          9 |                  9 |        |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

8. 验证 etcd 高可用集群

8.1 停止 leader 节点

[root@etcd91:~]# netstat -tnulp | egrep '2379|2380'
tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      3283/etcd           
tcp        0      0 10.0.0.91:2380          0.0.0.0:*               LISTEN      3283/etcd           
tcp        0      0 10.0.0.91:2379          0.0.0.0:*               LISTEN      3283/etcd  
[root@etcd91:~]# systemctl stop etcd
[root@etcd91:~]# netstat -tnulp | egrep '2379|2380'
[root@etcd91:~]# 

8.2 查看现有集群环境,发现新 leader 诞生

[root@etcd90:etcd]# etcdctl --endpoints="10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem  endpoint status --write-out=table
{"level":"warn","ts":"2025-03-20T17:47:09.999291+0800","logger":"etcd-client","caller":"v3@v3.5.19/retry_interceptor.go:63","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc000014000/10.0.0.90:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = context deadline exceeded"}
Failed to get the status of endpoint 10.0.0.91:2379 (context deadline exceeded)
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|    ENDPOINT    |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 |  3.5.19 |   20 kB |      true |      false |         3 |         10 |                 10 |        |
| 10.0.0.92:2379 | 432a416a50e3d3d5 |  3.5.19 |   20 kB |     false |      false |         3 |         10 |                 10 |        |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

8.3 重新启动停止的节点

[root@etcd91:~]# systemctl start etcd
[root@etcd90:etcd]# etcdctl --endpoints="10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem endpoint status --write-out=table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|    ENDPOINT    |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 |  3.5.19 |   20 kB |      true |      false |         3 |         11 |                 11 |        |
| 10.0.0.91:2379 | b207a358c2aaa147 |  3.5.19 |   20 kB |     false |      false |         3 |         11 |                 11 |        |
| 10.0.0.92:2379 | 432a416a50e3d3d5 |  3.5.19 |   20 kB |     false |      false |         3 |         11 |                 11 |        |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+

9. 添加别名

[root@etcd91:~]# echo 'alias etcdctl="etcdctl --endpoints=\"10.0.0.90:2379,10.0.0.91:2379,10.0.0.92:2379\" --cacert=/jasper/certs/etcd/etcd-ca.pem --cert=/jasper/certs/etcd/etcd-server.pem --key=/jasper/certs/etcd/etcd-server-key.pem"' >> /root/.bashrc && source /root/.bashrc

[root@etcd91:~]# etcdctl endpoint status --write-out=table
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|    ENDPOINT    |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.0.0.90:2379 | 830d704ba59d8354 |  3.5.19 |   20 kB |      true |      false |         3 |         11 |                 11 |        |
| 10.0.0.91:2379 | b207a358c2aaa147 |  3.5.19 |   20 kB |     false |      false |         3 |         11 |                 11 |        |
| 10.0.0.92:2379 | 432a416a50e3d3d5 |  3.5.19 |   20 kB |     false |      false |         3 |         11 |                 11 |        |
+----------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
### 如何正确地从电脑中移除或重置 Ubuntu 22.04 LTS #### 卸载 Ubuntu 22.04 LTS 对于希望完全移除 Ubuntu 的情况,通常是指从双系统安装环境中删除 Ubuntu 或者是在虚拟机内停止使用该操作系统。具体操作取决于当前环境: - **如果是双启动配置的一部分**:需要通过 Windows 中的磁盘管理工具或者其他分区软件来删除 Linux 分区,并且更新引导加载程序 (GRUB),以便只保留 Windows 启动选项。 - **在虚拟机环境下**:可以直接关闭并删除对应的 VM 文件夹即可完成卸载过程[^1]。 #### 彻底清除数据与设置 为了确保所有由 Ubuntu 创建的数据都被彻底清理掉,在实际物理硬盘上执行上述动作之前还应该考虑以下几点: - 使用 `apt-get purge` 命令可以更深入地移除应用程序及其配置文件。 ```bash sudo apt-get purge <package_name> ``` - 对于手动安装的应用和服务,则需查阅官方文档了解具体的卸载方法;例如 Elasticsearch 可能会涉及到特定目录下的二进制文件位置查询 ```bash sudo find / -type d -name 'bin' 2>/dev/null | grep 'elasticsearch' ``` - 清理残留的 APT 密钥环和其他资源链接也可能有助于保持系统的整洁度 ```bash sudo rm -rf /etc/apt/keyrings/* ``` 请注意这些命令应当谨慎对待,错误的操作可能会导致不必要的破坏性后果。 #### 重置 Ubuntu 22.04 LTS 到初始状态 另一种可能是想要恢复到出厂默认设定而不必重新安装整个 OS 。这可以通过多种方式实现: - 如果只是想还原某些服务的状态,比如 Kubernetes 集群组件 Calico 和 Kube-proxy ,则可以根据实际情况重启相关 Pods 来达到目的 ```bash kubectl delete pod -n kube-system -l k8s-app=calico-node kubectl delete pod -n kube-system -l k8s-app=kube-proxy ``` - 若要全面初始化系统参数,可尝试调整 GRUB 参数以禁用图形界面加速从而解决问题后再做进一步处理 修改 `/etc/default/grub` 文件内的 `"quiet splash"` 字符串为 `"quiet splash vga=normal nomodeset"` 最后运行 `update-grub` 更新更改后的设置[^4].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值