etcd的使用

启动etcd服务

启动etcd时最主要的是需要准备两个没有使用过的端口,这两个端口一个用于etcd之间同步信息,一个用于etcd向客户端提供服务的端口。

因此启动单个etcd节点,只需按照如下命令行输入即可

server -name myetcd1 -listen-client-urls http://0.0.0.0:12379 \
-advertise-client-urls http://0.0.0.0:12379  \
-listen-peer-urls http://0.0.0.0:12380  \
-initial-advertise-peer-urls http://0.0.0.0:12380 \  
-initial-cluster myetcd1=http://0.0.0.0:12380 

其中listen-client-urls的端口是客户端连接的端口,listen-peer-urls指定的端口是etcd之间同步数据使用的,并且在注册集群的时候,集群指定的端口也是etcd之间同步数据使用的端口

-initial-cluster myetcd1=http://0.0.0.0:12380

如何启动一个etcd集群

对etcd的操作

官方提供了etcdctl来连接etcd,使用etcdctl连接etcd很简单,只需要提供指定的endpoints,然后输入要操作的命令即可

etcdctl --endpoints=$ENDPOINTS get foo
etcdctl --endpoints=$ENDPOINTS --write-out="json" get foo

对etcd数据的增删改查

etcdctl --endpoints=$ENDPOINTS put web1 value1
etcdctl --endpoints=$ENDPOINTS put web2 value2
etcdctl --endpoints=$ENDPOINTS put web3 value3

etcdctl --endpoints=$ENDPOINTS get web --prefix
etcdctl --endpoints=$ENDPOINTS put key myvalue
etcdctl --endpoints=$ENDPOINTS del key

etcdctl --endpoints=$ENDPOINTS put k1 value1
etcdctl --endpoints=$ENDPOINTS put k2 value2
etcdctl --endpoints=$ENDPOINTS del k --prefix

事务型操作

etcdctl --endpoints=$ENDPOINTS put user1 bad
etcdctl --endpoints=$ENDPOINTS txn --interactive

compares:
value("user1") = "bad"

success requests (get, put, delete):
del user1

failure requests (get, put, delete):
put user1 good

对数据进行监听

// 在一个控制端上监听指定数据
etcdctl --endpoints=$ENDPOINTS watch stock1
// 在另外一个控制端上操作数据
etcdctl --endpoints=$ENDPOINTS put stock1 1000
// 在一个控制端上监听所有stock 开头的数据
etcdctl --endpoints=$ENDPOINTS watch stock --prefix
// 在另外一个控制端上操作数据
etcdctl --endpoints=$ENDPOINTS put stock1 10
etcdctl --endpoints=$ENDPOINTS put stock2 20

创建lease并将创建的数据绑定租约上

etcdctl --endpoints=$ENDPOINTS lease grant 300# lease 2be7547fbc6a5afa granted with TTL(300s)

etcdctl --endpoints=$ENDPOINTS put sample value --lease=2be7547fbc6a5afa
etcdctl --endpoints=$ENDPOINTS get sample

etcdctl --endpoints=$ENDPOINTS lease keep-alive 2be7547fbc6a5afa
etcdctl --endpoints=$ENDPOINTS lease revoke 2be7547fbc6a5afa
# or after 300 seconds
etcdctl --endpoints=$ENDPOINTS get sample

etcd提供的分布式锁

// 在一个控制端上创建lock一个Key值
etcdctl --endpoints=$ENDPOINTS lock mutex1

// 另外一个控制端如果想拿到锁,会卡住直到第一个拿到锁的释放锁为止
# another client with the same name blocks
etcdctl --endpoints=$ENDPOINTS lock mutex1

https://etcd.io/docs/v3.5/tutorials/how-to-create-locks/

查看集群状态

etcdctl --write-out=table --endpoints=$ENDPOINTS endpoint status

+------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
|    ENDPOINT      |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| 10.240.0.17:2379 | 4917a7ab173fabe7 |  3.5.0  |   45 kB |      true |      false |         4 |      16726 |              16726 |        || 10.240.0.18:2379 | 59796ba9cd1bcd72 |  3.5.0  |   45 kB |     false |      false |         4 |      16726 |              16726 |        || 10.240.0.19:2379 | 94df724b66343e6c |  3.5.0  |   45 kB |     false |      false |         4 |      16726 |              16726 |        |
+------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------|
etcdctl --endpoints=$ENDPOINTS endpoint health

10.240.0.17:2379 is healthy: successfully committed proposal: took = 3.345431ms
10.240.0.19:2379 is healthy: successfully committed proposal: took = 3.767967ms
10.240.0.18:2379 is healthy: successfully committed proposal: took = 4.025451ms

保存etcd快照

etcdctl --write-out=table --endpoints=$ENDPOINTS snapshot status my.db

+---------+----------+------------+------------+
|  HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+---------+----------+------------+------------+
| c55e8b8 |        9 |         13 | 25 kB      |
+---------+----------+------------+------------+

etcdv2升级到etcdv3

# write key in etcd version 2 storeexport ETCDCTL_API=2
etcdctl --endpoints=http://$ENDPOINT set foo bar

# read key in etcd v2
etcdctl --endpoints=$ENDPOINTS --output="json" get foo

# stop etcd node to migrate, one by one# migrate v2 dataexport ETCDCTL_API=3
etcdctl --endpoints=$ENDPOINT migrate --data-dir="default.etcd" --wal-dir="default.etcd/member/wal"# restart etcd node after migrate, one by one# confirm that the key got migrated
etcdctl --endpoints=$ENDPOINTS get /foo

Etcd特性

客户端必须向leader发送请求吗?

raft算法是以Leader为准-强领导权,领导处理所有客户端的请求,但是客户端不需要知道谁是领导,任何的需要一致性的请求就算发发送给follower也会被转发给leader,非一致性请求任何集群成员都能进行处理

listen-<client,peer>-urls, advertise-client-urls or initial-advertise-peer-urls的区别

listen-client-urls and listen-peer-urls是用来etcd服务端绑定用的,是集群之间连接使用的

advertise-client-urls and initial-advertise-peer-urls是etcd客户端连接服务端用的端口,advertise的地址必须是远程机器可访问的,

etcd的个数

原则上来说etcd是没有个数硬性限制的,然而一个etcd集群个数最好不要超过7个节点,根据google的经验来说节点个数最好保持为5个

当出现request ignored (cluster ID mismatch)” 意味着什么?

每个集群都会根据集群初始化配置和用户提供的initial-cluster-token值来生成一个唯一的cluster ID,根据cluster ID etcd能够防止不同集群之间的交叉访问。

当拆除一些旧集群,然后新集群重新使用同样的地址时会出现这些警告。如果旧集群中任何的etcd成员尝试连接新集群,新集群会忽略请求并发出警告,通常通过确保不同集群之间地址不相交可以避免这些警告。

如何解决mvcc: database space exceeded问题

默认情况下,etcd会保存kv值的所有历史信息而不是周期的进行压缩(可通过设置–auto-comaction来实现自动压缩),当存储空间耗尽时etcd会发出空间配额预警警告以防止进一步的写入集群中信息,只要警告持续,etcd就会对请求返回mvcc: database space exceeded

自动压缩空间
# keep one hour of history
$ etcd --auto-compaction-retention=1
碎片整理

在压缩之后数据库会出现碎片,这些碎片会占用一定的内存空间,这些内存空间etcd数据库可以使用,但是在主机上表现还是占用着内存空间,要想这些内存空间再次归还系统,需要对内存碎片空间进行整理并进行内存释放。

碎片整理可以将这些存储空间归还给文件系统,碎片整理是针对单个集群成员发出的,可以避免集群范围内的延迟峰值。

$ etcdctl defrag
Finished defragmenting etcd member[127.0.0.1:2379]

需要注意的是对一个活动节点进行碎片整理会阻塞读写(一个节点在碎片整理重构状态时)

需要注意的是碎片整理的请求并不会在集群上进行复制,因此请求只是应用到了本地的节点,如果需要对整个集群的成员进行碎片整理需要在–endpoints上或–cluster上指定所有成员来对整个集群中成员进行碎片整理

$ etcdctl defrag --cluster
Finished defragmenting etcd member[http://127.0.0.1:2379]
Finished defragmenting etcd member[http://127.0.0.1:22379]
Finished defragmenting etcd member[http://127.0.0.1:32379]

当etcd集群没有运行时可以通过指定文件夹来对指定文件夹进行碎片整理

etcdctl defrag --data-dir <path-to-etcd-data-dir>
etcd配额

默认情况下etcd的配额是2G,但是有些使用特殊的情况下,比如在虚拟机或者其他嵌入式小型设备中本身的磁盘都没有那么大,那么这个时候就需要对etcd的默认配额进行修改来满足特定的场景了

# set a very small 16MB quota
$ etcd --quota-backend-bytes=$((16*1024*1024))

可以用脚本来测试etcd配额不足的情况

# fill keyspace
$ while [ 1 ]; do dd if=/dev/urandom bs=1024 count=1024  | ETCDCTL_API=3 etcdctl put key  || break; done
...
Error:  rpc error: code = 8 desc = etcdserver: mvcc: database space exceeded
# confirm quota space is exceeded
$ ETCDCTL_API=3 etcdctl --write-out=table endpoint status
+----------------+------------------+-----------+---------+-----------+-----------+------------+
|    ENDPOINT    |        ID        |  VERSION  | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX |
+----------------+------------------+-----------+---------+-----------+-----------+------------+
| 127.0.0.1:2379 | bf9071f4639c75cc | 2.3.0+git | 18 MB   | true      |         2 |       3332 |
+----------------+------------------+-----------+---------+-----------+-----------+------------+
# confirm alarm is raised
$ ETCDCTL_API=3 etcdctl alarm list
memberID:13803658152347727308 alarm:NOSPACE

当出现配额不足时通过压缩和碎片整理来恢复当前etcd

# get current revision
$ rev=$(ETCDCTL_API=3 etcdctl --endpoints=:2379 endpoint status --write-out="json" | egrep -o '"revision":[0-9]*' | egrep -o '[0-9].*')# compact away all old revisions
$ ETCDCTL_API=3 etcdctl compact $rev
compacted revision 1516# defragment away excessive space
$ ETCDCTL_API=3 etcdctl defrag
Finished defragmenting etcd member[127.0.0.1:2379]# disarm alarm
$ ETCDCTL_API=3 etcdctl alarm disarm
memberID:13803658152347727308 alarm:NOSPACE
# test puts are allowed again
$ ETCDCTL_API=3 etcdctl put newkey 123
OK

etcd的使用场景

服务注册与发现

服务注册发现时分布式系统常见的问题之一,即在同一个分布式系统中找到我们需要的目标服务,建立连接,然后完成整个链路的调度。

用通俗的话来说服务发现就是要知道当前集群中的进程监听的udp或tcp端口,并且通过名字就可以进行查找和连接。etcd主要实现以下三种机制来完成服务发现:

  1. 强一致性、高可用的服务存储目录。基于Raft算法的etcd天生就是这样一个强一致性高可用的服务存储目录

  2. 提供注册服务和监控服务健康状态的机制,通过注册key-value值,并且定时保持服务的心跳以达到监控健康状态的效果

  3. 查找和连接服务的机制,通过在etcd指定的主题下注册服务,也能在对应的主题下查找到

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBLqDyWx-1679296449075)(https://ny5odfilnr.feishu.cn/space/api/box/stream/download/asynccode/?code=OTdiMTI3YTcwOTZhMjYwMDVkYTA3ZWJlM2M1N2RmMTVfSDRyVFNUVXRra21LSHZQNmtJRnZrcVJXUzJ4WmxzNFdfVG9rZW46Ym94Y25nOXd4QzJjZlVDZk9kUE45S0Q4REJmXzE2NzkyOTU5NzU6MTY3OTI5OTU3NV9WNA)]

一个用户的API请求可能会调用多个微服务的资源,这些服务我们可以使用etcd进行注册和服务发现
在这里插入图片描述

消息发布和订阅

在 分布式系统中,最适用的一种组件间通信方式就是消息发布与订阅,即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者,通过这种方式可以做到分布式系统配置的集中管理与动态更新。

  • 应用中用到的一些配置信息放到etcd上进行集中管理。启动时获取一次配置信息,同时注册一个watcher并等待,后期有配置更新的时候,etcd都会实时通知订阅者,以此达到获取最新配置信息的目的

  • 分布式搜索服务,索引元信息和服务器机器的节点状态存放到etcd中

  • 分布式日志收集系统

  • 系统中的信息需要动态自动获取与人工干预修改信息请求内容的情况

在这里插入图片描述

负载均衡

负载均衡通常来说有两种:

  • 软负载,通过软件手段实现负载均衡,也被称为4层或7层负载

  • 硬负载,就是靠硬件实现负载均衡,数据包发送转发功能

etcd上实现是软件上实现的负载均衡,在分布式场景下

ETCD

关注公众号:码上有话了解更多

<think>好的,我现在需要帮用户解答如何配置Kubernetes的etcd使用Vault来加密Secret。这个问题看起来有点复杂,我需要仔细理清楚步骤,确保没有遗漏关键点。首先,我应该回忆一下Kubernetes中etcd的作用,以及如何对存储的数据进行加密。 用户提到的是使用Vault来加密,而不是Kubernetes自带的静态加密。可能用户已经了解Kubernetes的EncryptionConfiguration,但想用Vault作为KMS提供商。所以,这可能涉及到Kubernetes的KMS插件机制,以及Vault的配置。 首先,我需要确认Kubernetes支持通过KMS插件进行数据加密。是的,从1.10版本开始,Kubernetes支持使用KMS提供商进行加密。而Vault可以作为KMS的一个选项,但需要配置相关的插件或者集成。 接下来,步骤可能包括:安装和配置Vault,配置Vault的密钥,设置Kubernetes的EncryptionConfiguration指向Vault的KMS插件,然后重启相关组件。不过可能需要更多的细节,比如如何部署Vault,是否使用现有的,或者需要安装到集群中? 然后,关于KMS插件的实现,可能需要使用一个gRPC服务器,作为Kubernetes API服务器和Vault之间的桥梁。比如,Hashicorp Vault可能有相关的插件或者需要自行实现这个接口。比如,Kubernetes社区是否有现成的Vault KMS插件?或者需要用户自己开发? 这里可能需要使用一个KMS插件实现,比如参考Kubernetes的示例,或者查找开源项目。例如,kubernetes-sigs下的kms-vault项目可能是一个可行的选择。或者,用户可能需要自己编写一个gRPC服务,调用Vault的加密API。 假设存在一个现成的插件,比如kms-vault,那么步骤可能包括部署这个插件,配置它连接Vault,然后配置EncryptionConfiguration。但是,如果用户需要手动设置,可能需要详细说明如何搭建这个中间层。 另外,需要考虑Vault的安装和配置,包括启用transit引擎,创建加密密钥,设置访问策略等。这部分需要详细步骤,比如使用vault命令启用transit引擎,创建密钥,生成令牌供KMS插件使用。 然后,配置EncryptionConfiguration文件,指定使用kms提供程序,并指向本地的Unix socket或者某个服务的地址,这个地址是KMS插件监听的。接着,需要重启kube-apiserver,或者如果是kubeadm部署的集群,可能需要更新manifest文件,并重新启动apiserver的Pod。 还有,需要确保所有控制平面节点上的apiserver都应用了这个配置,特别是etcd运行在多个节点的情况下。此外,测试加密是否生效,比如创建Secret,检查etcd中的数据是否加密。 可能遇到的问题包括:插件无法连接Vault,权限问题,配置错误,apiserver无法加载EncryptionConfiguration等。这时候需要检查日志,如kube-apiserver的日志,或者插件的日志。 另外,用户可能想知道如何验证配置是否成功。比如,使用etcdctl查看存储的数据是否为加密的,或者检查apiserver的日志中是否有成功加载KMS配置的信息。 总结一下,步骤大概是: 1. 安装并配置Vault,启用transit引擎,创建加密密钥,设置策略和认证方式(如AppRole)。 2. 部署KMS插件,例如kms-vault,配置它连接Vault的地址、令牌等信息。 3. 创建Kubernetes的EncryptionConfiguration,指定使用kms提供程序,并指向插件的Unix socket。 4. 将EncryptionConfiguration应用到所有kube-apiserver实例,并重启它们。 5. 验证配置是否生效,例如创建Secret并检查etcd中的内容是否加密。 需要注意的细节包括:插件的部署方式(作为DaemonSet或静态Pod),Vault的高可用性,插件与Vault之间的TLS配置,以及如何处理插件故障对Kubernetes的影响。 另外,可能还需要考虑密钥轮换、插件更新等问题,但用户可能暂时不需要这些高级内容。需要确保步骤清晰,并提醒用户在实际操作时注意备份和测试环境验证。</think>以下是配置 Kubernetes 使用 **Vault 加密 etcd 中 Secret** 的步骤指南,通过 Kubernetes 的 KMS 插件机制实现: --- ### **1. 准备工作** - **环境要求**: - Kubernetes 集群(v1.10+,推荐最新稳定版)。 - Vault 服务(已部署且可被 Kubernetes 访问)。 - 集群控制节点的 `kube-apiserver` 可访问 Vault。 --- ### **2. 配置 Vault** #### **2.1 启用 Vault Transit 引擎** ```bash vault secrets enable transit ``` #### **2.2 创建加密密钥** ```bash vault write -f transit/keys/k8s-encryption-key ``` #### **2.3 配置访问策略** 创建策略文件 `k8s-encryption-policy.hcl`: ```hcl path "transit/encrypt/k8s-encryption-key" { capabilities = ["update"] } path "transit/decrypt/k8s-encryption-key" { capabilities = ["update"] } ``` 应用策略: ```bash vault policy write k8s-encryption k8s-encryption-policy.hcl ``` #### **2.4 生成认证令牌(或使用 AppRole)** ```bash vault token create -policy=k8s-encryption -format=json | jq -r .auth.client_token ``` 保存输出的 Token,后续插件将使用它访问 Vault。 --- ### **3. 部署 KMS 插件** Kubernetes 需要与 Vault 通信的 **KMS 插件**(需实现 gRPC 服务)。可使用开源项目如 **[kms-vault](https://github.com/sercanarga/kms-vault)** 或自行开发。 #### **示例:使用 kms-vault** 1. **下载插件二进制**: ```bash wget https://github.com/sercanarga/kms-vault/releases/download/v0.1.0/kms-vault chmod +x kms-vault ``` 2. **创建配置文件 `/etc/kms-vault/config.yaml`**: ```yaml vault: address: "http://vault-server:8200" token: "YOUR_VAULT_TOKEN" key: "k8s-encryption-key" mount: "transit" ``` 3. **启动插件(以 Systemd 服务为例)**: ```bash /path/to/kms-vault --config=/etc/kms-vault/config.yaml --socket=/var/run/kms-vault.sock ``` 插件会监听 Unix socket `/var/run/kms-vault.sock`。 --- ### **4. 配置 Kubernetes Encryption** #### **4.1 创建 EncryptionConfiguration** 创建文件 `/etc/kubernetes/enc/encryption-config.yaml`: ```yaml apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - secrets providers: - kms: name: vault-kms endpoint: unix:///var/run/kms-vault.sock cachesize: 1000 timeout: 3s - identity: {} # 允许未加密资源回退(可选) ``` #### **4.2 修改 kube-apiserver 配置** - **kubeadm 集群**: 编辑 `/etc/kubernetes/manifests/kube-apiserver.yaml`,添加: ```yaml spec: containers: - command: - --encryption-provider-config=/etc/kubernetes/enc/encryption-config.yaml volumeMounts: - name: enc-config mountPath: /etc/kubernetes/enc - name: kms-socket mountPath: /var/run/kms-vault.sock volumes: - name: enc-config hostPath: path: /etc/kubernetes/enc - name: kms-socket hostPath: path: /var/run/kms-vault.sock type: Socket ``` - **重启 kube-apiserver**: 修改后,kubelet 会自动重启 Pod。 --- ### **5. 验证加密** #### **5.1 创建测试 Secret** ```bash kubectl create secret generic test-secret --from-literal=key=supersecret ``` #### **5.2 检查 etcd 数据** 使用 `etcdctl` 查看数据是否加密: ```bash ETCDCTL_API=3 etcdctl --endpoints=https://etcd-node:2379 \ --cacert=/etc/kubernetes/pki/etcd/ca.crt \ --cert=/etc/kubernetes/pki/etcd/server.crt \ --key=/etc/kubernetes/pki/etcd/server.key \ get /registry/secrets/default/test-secret ``` 若输出包含 `k8s:enc:kms:v1:vault-kms` 前缀,表示加密成功。 --- ### **6. 注意事项** - **插件高可用**:确保 KMS 插件多副本部署,避免单点故障。 - **Vault 可用性**:若 Vault 不可用,Kubernetes 可能无法读取加密数据。 - **密钥轮换**:通过 Vault 管理密钥生命周期,定期轮换密钥。 - **备份 EncryptionConfiguration**:丢失配置可能导致数据无法解密。 --- 通过以上步骤,Kubernetes 将使用 Vault 动态加密 etcd 中的 Secret 数据,提升集群安全性。建议在生产环境中提前验证并备份关键数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Achilles.Wang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值