etcd与mysql_彻底搞懂 etcd 系列文章(五):etcdctl 的使用

本文是《彻底搞懂etcd系列文章》的一部分,主要讲解etcdctl,etcd的命令行客户端。etcdctl提供简单命令与etcd交互,包括数据库操作如增删改查,以及非数据库操作。文章介绍了etcdctl的基本用法、常用命令,如版本查看、键值操作、租约查询等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0 专辑概述

etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件。

《彻底搞懂 etcd 系列文章》将会从 etcd 的基本功能实践、API 接口、实现原理、源码分析,以及实现中的踩坑经验等几方面具体展开介绍 etcd。预计会有 20 篇左右的文章,笔者将会每周持续更新,欢迎关注。

1 etcdctl 的实践应用

在前面的文章介绍了 etcd 的相关概念,单机和集群的多种安装方式,以及etcd 安全通信相关的内容。本篇主要基于 etcdctl 介绍 etcd 的常用命令和操作。

etcdctl 是一个命令行客户端,它能提供一些简洁的命令,供用户直接跟etcd服务打交道,而无需基于 HTTP API 方式。可以方便我们在对服务进行测试或者手动修改数据库内容。我们刚开始可以通过 etdctl 来熟悉相关操作。这些操作跟 HTTP API 基本上是对应的。etcdctl 在两个不同的 etcd 版本下的行为方式也完全不同。

export ETCDCTL_API=2

export ETCDCTL_API=3

这里主要以讲解 API 3 为主。

etcd 项目二进制发行包中已经包含了 etcdctl 工具,etcdctl 支持的命令大体上分为数据库操作和非数据库操作两类。

2 常用命令介绍

首先查看一下 etcd 的版本:

$ etcd --version

etcd Version: 3.4.7

Git SHA: e784ba73c

Go Version: go1.12.12

Go OS/Arch: linux/amd64

我们的版本是 etcd 3.4.7 ,下面介绍下 etcdctl 常用的命令。

$ etcdctl -h

NAME:

etcdctl - A simple command line client for etcd3.

USAGE:

etcdctl [flags]

VERSION:

3.4.7

API VERSION:

3.4

COMMANDS:

alarm disarm Disarms all alarms

alarm list Lists all alarms

auth disable Disables authentication

auth enable Enables authentication

check datascale Check the memory usage of holding data for different workloads on a given server endpoint.

check perf Check the performance of the etcd cluster

compaction Compacts the event history in etcd

defrag Defragments the storage of the etcd members with given endpoints

del Removes the specified key or range of keys [key, range_end)

elect Observes and participates in leader election

endpoint hashkv Prints the KV history hash for each endpoint in --endpoints

endpoint health Checks the healthiness of endpoints specified in `--endpoints` flag

endpoint status Prints out the status of endpoints specified in `--endpoints` flag

get Gets the key or a range of keys

help Help about any command

lease grant Creates leases

lease keep-alive Keeps leases alive (renew)

lease list List all active leases

lease revoke Revokes leases

lease timetolive Get lease information

lock Acquires a named lock

make-mirror Makes a mirror at the destination etcd cluster

member add Adds a member into the cluster

member list Lists all members in the cluster

member promote Promotes a non-voting member in the cluster

member remove Removes a member from the cluster

member update Updates a member in the cluster

migrate Migrates keys in a v2 store to a mvcc store

move-leader Transfers leadership to another etcd cluster member.

put Puts the given key into the store

role add Adds a new role

role delete Deletes a role

role get Gets detailed information of a role

role grant-permission Grants a key to a role

role list Lists all roles

role revoke-permission Revokes a key from a role

snapshot restore Restores an etcd member snapshot to an etcd directory

snapshot save Stores an etcd node backend snapshot to a given file

snapshot status Gets backend snapshot status of a given file

txn Txn processes all the requests in one transaction

user add Adds a new user

user delete Deletes a user

user get Gets detailed information of a user

user grant-role Grants a role to a user

user list Lists all users

user passwd Changes password of user

user revoke-role Revokes a role from a user

version Prints the version of etcdctl

watch Watches events stream on keys or prefixes

OPTIONS:

--cacert="" verify certificates of TLS-enabled secure servers using this CA bundle

--cert="" identify secure client using this TLS certificate file

--command-timeout=5s timeout for short running command (excluding dial timeout)

--debug[=false] enable client-side debu

version: '3.7' services: server1: image: base-server container_name: server1 command: ["sh", "-c", "/scripts/start_services.sh"] environment: - VT_HOSTNAME=server1 - VT_TOPOLOGY=etcd:http://server1:2379 ports: - "15000:15000" - "15306:3306" networks: vitess-network: ipv4_address: 172.16.0.101 volumes: - ./scripts:/scripts - etcd-data:/var/lib/etcd # 修改挂载路径 server2: image: mysql-server container_name: server2 command: ["sh", "-c", "while ! nc -z server1 2379; do sleep 1; done; /scripts/init_master.sh"] environment: - VT_HOSTNAME=server2 - VT_TOPOLOGY=etcd:http://server1:2379 - VTDATAROOT=/vt/vtdataroot # 显式指定数据目录 networks: vitess-network: ipv4_address: 172.16.0.102 volumes: - ./scripts:/scripts - mysql-master:/vt/vtdataroot depends_on: - server1 server3: image: mysql-server container_name: server3 command: ["sh", "-c", "while ! nc -z server1 2379; do sleep 1; done; /scripts/init_replica.sh"] environment: - VT_HOSTNAME=server3 - VT_TOPOLOGY=etcd:http://server1:2379 - VTDATAROOT=/vt/vtdataroot networks: vitess-network: ipv4_address: 172.16.0.103 volumes: - ./scripts:/scripts - mysql-replica:/vt/vtdataroot depends_on: - server1 volumes: etcd-data: mysql-master: mysql-replica: networks: vitess-network: driver: bridge ipam: config: - subnet: 172.16.0.0/24 Dockerfile.base: FROM vitess/base USER root RUN chmod 777 /var/lib/etcd USER vitess Dockerfile.server: FROM vitess/base USER root RUN apt-get update && apt-get install -y netcat || yum install -y nc || apk add --no-cache gnu-netcat # 安装 etcdctl 和网络检测工具 RUN apt-get update && \ apt-get install -y curl && \ rm -rf /var/lib/apt/lists/* USER vitess start_services.sh: #!/bin/bash RUN apt-get update && apt-get install -y netcat || yum install -y nc || apk add --no-cache gnu-netcat # 启动 etcd、vtctld、vtgate etcd --data-dir /etcd & sleep 5 vtctld --topo_implementation etcd2 --topo_global_server_address http://localhost:2379 & vtgate --topo_implementation etcd2 --topo_global_server_address http://localhost:2379 --mysql_server_port 3306 & init_master.sh 和 init_replica.sh : #!/bin/bash # 启动 MySQL 从实例和 vttablet vttablet \ --topo_implementation etcd2 \ --topo_global_server_address server1:2379 \ --tablet-path "zone1-101" \ --init_keyspace "test_keyspace" \ --init_shard "0" \ --init_tablet_type "replica" \ --port 15002 \ --grpc_port 16002 \ --db_port 3306 2025-05-21 15:41:10.240 | /scripts/start_services.sh: line 3: RUN: command not found 2025-05-21 15:41:10.244 | /scripts/start_services.sh: line 3: yum: command not found 2025-05-21 15:41:10.248 | /scripts/start_services.sh: line 3: apk: command not found 2025-05-21 15:41:11.117 | {"level":"info","ts":"2025-05-21T07:41:11.109Z","caller":"etcdmain/etcd.go:73","msg":"Running: ","args":["etcd","--data-dir","/etcd"]} 2025-05-21 15:41:11.119 | {"level":"info","ts":"2025-05-21T07:41:11.117Z","caller":"embed/etcd.go:124","msg":"configuring peer listeners","listen-peer-urls":["http://localhost:2380"]} 2025-05-21 15:41:11.124 | {"level":"info","ts":"2025-05-21T07:41:11.124Z","caller":"embed/etcd.go:132","msg":"configuring client listeners","listen-client-urls":["http://localhost:2379"]} 2025-05-21 15:41:11.125 | {"level":"info","ts":"2025-05-21T07:41:11.125Z","caller":"embed/etcd.go:306","msg":"starting an etcd server","etcd-version":"3.5.6","git-sha":"cecbe35ce","go-version":"go1.16.15","go-os":"linux","go-arch":"amd64","max-cpu-set":12,"max-cpu-available":12,"member-initialized":false,"name":"default","data-dir":"/etcd","wal-dir":"","wal-dir-dedicated":"","member-dir":"/etcd/member","force-new-cluster":false,"heartbeat-interval":"100ms","election-timeout":"1s","initial-election-tick-advance":true,"snapshot-count":100000,"max-wals":5,"max-snapshots":5,"snapshot-catchup-entries":5000,"initial-advertise-peer-urls":["http://localhost:2380"],"listen-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://localhost:2379"],"listen-client-urls":["http://localhost:2379"],"listen-metrics-urls":[],"cors":["*"],"host-whitelist":["*"],"initial-cluster":"default=http://localhost:2380","initial-cluster-state":"new","initial-cluster-token":"etcd-cluster","quota-backend-bytes":2147483648,"max-request-bytes":1572864,"max-concurrent-streams":4294967295,"pre-vote":true,"initial-corrupt-check":false,"corrupt-check-time-interval":"0s","compact-check-time-enabled":false,"compact-check-time-interval":"1m0s","auto-compaction-mode":"periodic","auto-compaction-retention":"0s","auto-compaction-interval":"0s","discovery-url":"","discovery-proxy":"","downgrade-check-interval":"5s"} 2025-05-21 15:41:11.125 | {"level":"info","ts":"2025-05-21T07:41:11.125Z","caller":"embed/etcd.go:373","msg":"closing etcd server","name":"default","data-dir":"/etcd","advertise-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://localhost:2379"]} 2025-05-21 15:41:11.125 | {"level":"info","ts":"2025-05-21T07:41:11.125Z","caller":"embed/etcd.go:375","msg":"closed etcd server","name":"default","data-dir":"/etcd","advertise-peer-urls":["http://localhost:2380"],"advertise-client-urls":["http://localhost:2379"]} 2025-05-21 15:41:11.125 | {"level":"warn","ts":"2025-05-21T07:41:11.125Z","caller":"etcdmain/etcd.go:146","msg":"failed to start etcd","error":"cannot access data directory: mkdir /etcd: permission denied"} 2025-05-21 15:41:11.126 | {"level":"fatal","ts":"2025-05-21T07:41:11.125Z","caller":"etcdmain/etcd.go:204","msg":"discovery failed","error":"cannot access data directory: mkdir /etcd: permission denied","stacktrace":"go.etcd.io/etcd/server/v3/etcdmain.startEtcdOrProxyV2\n\tgo.etcd.io/etcd/server/v3/etcdmain/etcd.go:204\ngo.etcd.io/etcd/server/v3/etcdmain.Main\n\tgo.etcd.io/etcd/server/v3/etcdmain/main.go:40\nmain.main\n\tgo.etcd.io/etcd/server/v3/main.go:32\nruntime.main\n\truntime/proc.go:225"} nc: getaddrinfo for host "server1" port 2379: No address associated with hostname nc: getaddrinfo for host "server1" port 2379: No address associated with hostname nc: getaddrinfo for host "server1" port 2379: No address associated with hostname nc: getaddrinfo for host "server1" port 2379: No address associated with hostname nc: getaddrinfo for host "server1" port 2379: No address associated with hostname 启动失败
最新发布
05-22
### 解决方案 #### 关于 `mkdir /etcd: permission denied` 错误 该错误表明宿主机上的 `/etcd` 数据目录没有足够的权限供 Docker 容器内的进程进行读写操作。可以通过以下方式解决: 1. **检查宿主机目录权限** 验证宿主机上 `/etcd` 目录是否存在,并确认其权限是否允许容器中的进程访问。如果不存在,则需手动创建并调整权限: ```bash sudo mkdir -p /etcd sudo chmod 777 /etcd ``` 2. **修改挂载路径的权限** 如果已经存在 `/etcd` 目录,但仍然报错,可能是权限未正确分配给容器用户。可以尝试更改目录所属组和用户为当前登录用户: ```bash sudo chown $(id -u):$(id -g) /etcd ``` 3. **更新 Docker Compose 文件或启动命令** 确保在 Docker 启动时正确挂载了数据卷。例如,在 `docker-compose.yml` 中添加如下配置[^2]: ```yaml services: etcd: image: quay.io/coreos/etcd:v3.5.1 volumes: - /etcd:/etcd-data ``` 或者通过命令行指定挂载选项: ```bash docker run -d \ --name etcd \ -v /etcd:/etcd-data \ quay.io/coreos/etcd:v3.5.1 ``` --- #### 关于 `nc` 无法解析 `server1` 主机名问题 此问题通常由 DNS 配置不正确引起,具体表现为容器内部无法识别外部定义的主机名。 1. **验证主机名解析功能** 使用宿主机上的工具测试 `server1` 是否可被解析: ```bash nslookup server1 ping server1 ``` 若不可解析,说明需要进一步排查 DNS 设置。 2. **配置自定义 DNS 地址** 修改 Docker 的默认 DNS 设置以支持主机名解析。可以在 Docker Daemon 配置文件中加入公共 DNS(如 Google Public DNS),或者指向本地 DNS Server: 编辑 `/etc/docker/daemon.json` 并添加以下内容: ```json { "dns": ["8.8.8.8", "8.8.4.4"] } ``` 然后重启 Docker 服务使更改生效: ```bash systemctl restart docker ``` 3. **使用 Hosts 映射替代 DNS 查询** 对于固定的主机名(如 `server1`),可以直接将其记录写入容器的 `/etc/hosts` 文件。这可通过 `-h` 参数实现,也可以直接编辑 `docker-compose.yml` 文件[^3]: ```yaml services: etcd: image: quay.io/coreos/etcd:v3.5.1 extra_hosts: - "server1:<实际 IP>" ``` 4. **确保网络模式兼容性** 如果容器运行在网络隔离模式下,默认情况下不会继承宿主机的网络栈。此时应考虑切换至桥接网络或其他共享网络模型。例如: ```yaml network_mode: host ``` --- ### 示例代码片段 以下是完整的 `docker-compose.yml` 示例,综合解决了上述两个问题: ```yaml version: "3" services: etcd: image: quay.io/coreos/etcd:v3.5.1 container_name: etcd command: > /bin/sh -c " etcd --data-dir=/etcd-data & sleep infinity " volumes: - /etcd:/etcd-data extra_hosts: - "server1:192.168.1.10" # 替换为实际 IP 地址 networks: default: driver: bridge networks: default: driver_opts: com.docker.network.enable_ipv6: "false" ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值