共计 4856 个字符,预计需要花费 13 分钟才能阅读完成。
1 Kubernetes 基础架构
在详细了解 etcd 在 Kubernetes 里的应用之前,简单介绍下 Kubernetes 集群的整体架构,搞清楚 etcd 在 Kubernetes 集群中扮演的角色与作用。下图是 Kubernetes 集群的架构图,从图中你可以看到,它由 Master 节点和 Node 节点组成。
控制面 Master 节点主要包含以下组件:
- kube-apiserver,负责对外提供集群各类资源的增删改查及 Watch 接口,它是 Kubernetes 集群中各组件数据交互和通信的枢纽。kube-apiserver 在设计上可水平扩展,高可用 Kubernetes 集群中一般多副本部署。当收到一个创建 Pod 写请求时,它的基本流程是对请求进行认证、限速、授权、准入机制等检查后,写入到 etcd 即可。
- kube-scheduler 是调度器组件,负责集群 Pod 的调度。基本原理是通过监听 kube-apiserver 获取待调度的 Pod,然后基于一系列筛选和评优算法,为 Pod 分配最佳的 Node 节点。
- kube-controller-manager 包含一系列的控制器组件,比如 Deployment、StatefulSet 等控制器。控制器的核心思想是监听、比较资源实际状态与期望状态是否一致,若不一致则进行协调工作使其最终一致。
- etcd 组件,Kubernetes 的元数据存储。
Node 节点主要包含以下组件:
- kubelet,部署在每个节点上的 Agent 的组件,负责 Pod 的创建运行。基本原理是通过监听 APIServer 获取分配到其节点上的 Pod,然后根据 Pod 的规格详情,调用运行时组件创建 pause 和业务容器等。
- kube-proxy,部署在每个节点上的网络代理组件。基本原理是通过监听 APIServer 获取 Service、Endpoint 等资源,基于 Iptables、IPVS 等技术实现数据包转发等功能。
2 etcd 作为 Kubernetes 存储
下面是一个 Kubernetes 集群中的 coredns 一系列资源在 etcd 中的存储格式:
/registry/clusterrolebindings/system:coredns
/registry/clusterroles/system:coredns
/registry/configmaps/kube-system/coredns
/registry/deployments/kube-system/coredns
/registry/events/kube-system/coredns-7fcc6d65dc-6njlg.1662c287aabf742b
/registry/events/kube-system/coredns-7fcc6d65dc-6njlg.1662c288232143ae
/registry/pods/kube-system/coredns-7fcc6d65dc-jvj26
/registry/pods/kube-system/coredns-7fcc6d65dc-mgvtb
/registry/pods/kube-system/coredns-7fcc6d65dc-whzq9
/registry/replicasets/kube-system/coredns-7fcc6d65dc
/registry/secrets/kube-system/coredns-token-hpqbt
/registry/serviceaccounts/kube-system/coredns
从中可以看到,一方面 Kubernetes 资源在 etcd 中的存储格式由
prefix + "/" + 资源类型 + "/" + namespace + "/" + 具体资源名组成
基于 etcd 提供的范围查询能力,非常简单地支持了按具体资源名称查询和 namespace 查询。
kube-apiserver 提供了如下参数给你配置 etcd prefix,并支持将资源存储在多个 etcd 集群。
我们学习了 etcd 的 get 有按照 key 查找和按照范围查找两种方式,当我们用 kubectl 命令时
kubectl get deployments -n default
->
etcdctl get --prefix /registry/deployments/default
kubectl get deployments/helloworld
->
etcdctl get --prefix /registry/deployments/default/helloworld
kubectl get deployments -l hello:hello
->
etcdctl get --prefix /registry/deployments/default
->
然后将结果根据标签 hello:hello 过滤
3 etcdctl 操作
3.1 alias 配置
# etcdctl
alias ectl='ETCDCTL_API=3 etcdctl --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --cacert=/etc/kubernetes/pki/etcd/server.crt --endpoints=https://9.134.236.165:2379'
# etcdhelper
alias ehelper='ETCDCTL_API=3 etcdhelper --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --cacert=/etc/kubernetes/pki/etcd/server.crt --endpoint=https://9.134.236.165:2379'
3.2 读取数据 key
使用以下命令列出所有的 key
[root@centos ~]# ectl get / --prefix --keys-only
参数说明:
--cacert="" verify certificates of TLS-enabled secure servers using this CA bundle
--cert="" identify secure client using this TLS certificate file
--key="" identify secure client using this TLS key file
--endpoints="" gRPC endpoints
[root@VM-236-165-centos ~]# ectl get / --prefix --keys-only
/registry/apiextensions.k8s.io/customresourcedefinitions/alertmanagerconfigs.monitoring.coreos.com
/registry/apiextensions.k8s.io/customresourcedefinitions/alertmanagers.monitoring.coreos.com
/registry/apiextensions.k8s.io/customresourcedefinitions/podmonitors.monitoring.coreos.com
/registry/apiextensions.k8s.io/customresourcedefinitions/probes.monitoring.coreos.com
/registry/apiextensions.k8s.io/customresourcedefinitions/prometheuses.monitoring.coreos.com
/registry/apiextensions.k8s.io/customresourcedefinitions/prometheusrules.monitoring.coreos.com
/registry/apiextensions.k8s.io/customresourcedefinitions/servicemonitors.monitoring.coreos.com
/registry/apiextensions.k8s.io/customresourcedefinitions/thanosrulers.monitoring.coreos.com
/registry/apiregistration.k8s.io/apiservices/v1.
/registry/apiregistration.k8s.io/apiservices/v1.admissionregistration.k8s.io
...
3.2 读取数据 value
由于 k8s 默认 etcd 中的数据是通过 protobuf 格式存储,因此看到的 key 和 value 的值是一串字符串。
[root@VM-236-165-centos ~]# ectl get /registry/namespaces/default -w json |jq
{
"header": {
"cluster_id": 13472981455415017000,
"member_id": 4500814691475925000,
"revision": 20920658,
"raft_term": 2
},
"kvs": [
{
"key": "L3JlZ2lzdHJ5L25hbWVzcGFjZXMvZGVmYXVsdA==",
"create_revision": 155,
"mod_revision": 155,
"version": 1,
"value": "azhzAAoPCgJ2MRIJTmFtZXNwYWNlErIBCpcBCgdkZWZhdWx0EgAaACIAKiQzZmY1ZjI3Ni1lNmExLTQwMTQtYTQ5NC1kOWJjY2U0M2NmODMyADgAQggIjvXqmAYQAHoAigFPCg5rdWJlLWFwaXNlcnZlchIGVXBkYXRlGgJ2MSIICI716pgGEAAyCEZpZWxkc1YxOh0KG3siZjpzdGF0dXMiOnsiZjpwaGFzZSI6e319fRIMCgprdWJlcm5ldGVzGggKBkFjdGl2ZRoAIgA="
}
],
"count": 1
}
其中 key 可以通过 base64 解码出来
[root@VM-236-165-centos ~]# echo "L3JlZ2lzdHJ5L25hbWVzcGFjZXMvZGVmYXVsdA==" | base64 -d
/registry/namespaces/default
value是值可以通过安装etcdhelper工具解析出来
[root@centos ~]# ehelper get /registry/namespaces/default
/v1, Kind=Namespace
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "default",
"uid": "3ff5f276-e6a1-4014-a494-d9bcce43cf83",
"creationTimestamp": "2022-09-09T04:01:18Z",
"managedFields": [
{
"manager": "kube-apiserver",
"operation": "Update",
"apiVersion": "v1",
"time": "2022-09-09T04:01:18Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:status": {
"f:phase": {}
}
}
}
]
},
"spec": {
"finalizers": [
"kubernetes"
]
},
"status": {
"phase": "Active"
}
正文完