2024-10-16 06:37:41 +08:00

204 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

因收到Google相关通知网站将会择期关闭。相关通知内容
13 庖丁解牛etcd
整体概览
+----------------------------------------------------------+
| Master |
| +-------------------------+ |
| +------->| API Server |<--------+ |
| | | | | |
| v +-------------------------+ v |
| +----------------+ ^ +--------------------+ |
| | | | | | |
| | Scheduler | | | Controller Manager | |
| | | | | | |
| +----------------+ v +--------------------+ |
| +------------------------------------------------------+ |
| | | |
| | Cluster state store | |
| | | |
| +------------------------------------------------------+ |
+----------------------------------------------------------+
在第 3 宏观认识整体架构 我们也认识到了 etcd 的存在知道了 Master K8S 是集群的大脑 etcd 则是大脑的核心为什么这么说本节我们一同来看看 etcd 为何如此重要
etcd 是什么
先摘录官方文档的一句说明:
etcd is a consistent distributed key-value store. Mainly used as a separate coordination service, in distributed systems. And designed to hold small amounts of data that can fit entirely in memory.
etcd 是由 CoreOS 团队发起的一个分布式强一致的键值存储它用 Go 语言编写使用 Raft 协议作为一致性算法多数情况下会用于分布式系统中的服务注册发现或是用于存储系统的关键数据
etcd 有什么作用
etcd K8S 最主要的作用便是其高可用强一致的键值存储以及监听机制
kube-apiserver 收到对应请求经过一系列的处理后最终如果是集群所需要存储的数据便会存储至 etcd 主部分主要是集群状态信息和元信息
我们来实际操作 K8S 集群中的 etcd 看下真实情况
查找集群中的 etcd Pod
# 默认集群中的 etcd 会放到 kube-system Namespace 中
master $ kubectl -n kube-system get pods | grep etcd
etcd-master 1/1 Running 0 1h
进入该 Pod 并查看 etcd 集群的 member
master $ kubectl -n kube-system exec -it etcd-master sh
/ # ETCDCTL_API=3 etcdctl --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --cacert=/etc/kubernetes/pki/etcd/ca.crt member list
a874c87fd42044f, started, master, https://127.0.0.1:2380, https://127.0.0.1:2379
这里由于在 K8S 1.11.3 中默认使用的是 etcd 3.2 版本所以需要加入 ETCDCTL_API=3 的环境变量 etcd 2 3 很明显的一个变化也是使用上的变化 2 中是 HTTP 接口的
我们通过传递证书等相关参数进去完成校验查看 member
查看存储的元信息
etcd 中存储的 K8S 集群元信息基本都是 /registry 我们可通过下面的方式进行查看
/ # ETCDCTL_API=3 etcdctl --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --cacert=/etc/kubernetes/pki/etcd/ca.crt get /registry --prefix --keys-only
/registry/apiregistration.k8s.io/apiservices/v1.
/registry/clusterroles/system:aggregate-to-admin
/registry/configmaps/kube-public/cluster-info
/registry/masterleases/172.17.0.53
/registry/namespaces/default
/registry/namespaces/kube-public
/registry/namespaces/kube-system
/registry/pods/kube-system/etcd-master
/registry/pods/kube-system/kube-apiserver-master
/registry/ranges/serviceips
/registry/ranges/servicenodeports
...
# 篇幅原因,删掉了很多输出
可以看到有各种类型的资源我们直接以 Namespaces 为例
查看 Namespaces 信息
/ # ETCDCTL_API=3 etcdctl --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --cacert=/etc/kubernetes/pki/etcd/ca.crt get /registry/namespaces --prefix --keys-only
/registry/namespaces/default
/registry/namespaces/kube-public
/registry/namespaces/kube-system
使用 kubectl 创建名为 moelove Namespaces
master $ kubectl create ns moelove
namespace/moelove created
查看 Namespaces 信息
/ # ETCDCTL_API=3 etcdctl --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --cacert=/etc/kubernetes/pki/etcd/ca.crt get /registry/namespaces --prefix --keys-only
/registry/namespaces/default
/registry/namespaces/kube-public
/registry/namespaces/kube-system
/registry/namespaces/moelove
发现刚创建的 moelove Namespaces 已经在 etcd 中了
etcd 是如何被使用的
首先 staging/src/k8s.io/apiserver/pkg/server/options/etcd.go 存在一处声明
var storageTypes = sets.NewString(
storagebackend.StorageTypeUnset,
storagebackend.StorageTypeETCD2,
storagebackend.StorageTypeETCD3,
)
1.13 发布时etcd 2 的相关代码已经移除其中就包含上面声明中的 storagebackend.StorageTypeETCD2
这里是在过渡期间为了同时兼容 etcd 2 3 而增加的
我们来看下实际对各类资源的操作还是以对 Namespace 的操作为例代码在 pkg/registry/core/namespace/storage/storage.go
比如Get
func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
return r.store.Get(ctx, name, options)
}
REST 则是这样定义的
type REST struct {
store *genericregistry.Store
status *genericregistry.Store
}
通过 REST 实现了一个 RESTStorage实际使用时也是调用了 staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go 对接口的封装
func (e *Store) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
obj := e.NewFunc()
key, err := e.KeyFunc(ctx, name)
if err != nil {
return nil, err
}
if err := e.Storage.Get(ctx, key, options.ResourceVersion, obj, false); err != nil {
return nil, storeerr.InterpretGetError(err, e.qualifiedResourceFromContext(ctx), name)
}
if e.Decorator != nil {
if err := e.Decorator(obj); err != nil {
return nil, err
}
}
return obj, nil
}
在该处实现了对各类基本方法的封装各种资源类型都会统一去调用而更上层则是对 storagebackend 的统一封装最终会调用 etcd 客户端的实现完成想对应的操作这里就不再多展开了
总结
在本节中我们介绍了 etcd 以及它在 K8S 中的作用以及如何使用我们还介绍了如何通过 etcdctl 工具去操作 etcd
在某些极端情况下也许你需要通过直接操作 etcd 集群去变更数据这里没有介绍所有的操作命令感兴趣的可以自行通过下方的链接看官方文档进行学习
但通常情况下不建议直接操作 etcd 除非你已经明确自己在做什么
另外由于 etcd 集群使用 Raft 一致性算法通常情况下 etcd 集群需要部署奇数个节点 357 etcd 集群维护也相对容易很容易可以做成高可用集群。(这也是保障 K8S 集群高可用的重要一环
学习了 etcd 之后下节我们来学习同样很重要的一个组件 Controller Manager学习它是如何保障集群符合预期状态的
参考链接
What is etcd