Kubernetes 提供了很多好处:拥有大量参与者、自我修复能力等的巨大生态系统。不过,没有免费的午餐。它也有缺点,其中最主要的是它的复杂性和运营成本。
但是,我使用 Kubernetes 的次数越多,我就越认为它最重要的资产是可扩展性。如果您需要平台默认不提供的东西,可以选择自己开发并集成它。在这篇文章中,我想列出这些扩展点。
很多关于 Kubernetes 的解释都集中在架构上。我相信他们进入了太多细节而错过了大局。在这里,我只想强调基本概念。
在最基本的层面上,Kubernetes 只是一个能够运行容器镜像的平台。它将其配置存储在分布式存储引擎中,etcd. 此配置的最重要部分专用于对象的所需状态。例如,您仅在使用kubectl命令行调度 pod 时才更新此状态。
称为控制器的其他组件监视配置更改并读取所需的状态。然后,他们尝试使期望状态与实际状态相协调。这没有什么革命性的:Puppet 基于相同的控制回路方法,而 AFAIK,Chef。通常,控制器管理单一类型的对象,例如管理DeploymentController部署。
制作通用工具背后的想法是遵循帕累托定律:用 20% 的努力解决 80% 的问题。不幸的是,工具越通用,用户群越广泛,定制剩余 20% 的工作量就越大。
Kubernetes 设计人员将此问题视为广泛采用的最关键障碍。因此,Kubernetes 提供了许多扩展点。
在上面的部分中,我提到了调度一个 pod。Pod 是 Kubernetes 开箱即用的众多对象之一。其他对象包括部署、作业、服务等。
一些解决方案很容易适合这个模型。例如,可以轻松创建三个 Hazelcast pod 的部署。它开箱即用:Pod 将通过网络进行多播、找到彼此并形成一个集群。
其他解决方案不是那么均匀。在KIP-500之前,Kafka 将依赖 Zookeeper。At cluster 由至少三个 Zookeeper 节点和所需数量的 Kafka 节点组成。Kubernetes 使得在同一个 pod 上部署多个镜像成为可能。然而,如果所有必需的组件都在同一个 pod 上,而 pod 出现故障,那它就等于没有。我们应该将一个常规组件映射到一个 pod。
在这种情况下,我们需要一个功能齐全的 Kubernetes 清单来描述架构。由于要求不同,我们需要使其可配置。Kubernetes 的生态系统提供了多种解决方案来解决这个问题:Kustomize和Helm count 是最流行的解决方案之一。但两者都不能在所需的抽象级别上工作,即 Kafka 集群。
因此,Kubernetes 允许设计一个新Kafka对象。这种自定义对象称为CRD。这是一个简单的任意Foo对象的示例:
apiVersion: apiextensions.k8s.io/v1 #1
kind: CustomResourceDefinition
metadata:
name: foos.frankel.ch #2
spec:
group: frankel.ch #3
names:
plural: foos #4
singular: foo #5
kind: Foo #6
scope: Namespaced #7
versions:
- name: v1alpha1
served: true #8
storage: true #9
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
bar:
type: string
required: ["bar"]
required: ["spec"]
应用此清单后,您可以管理您的Foo. 让我们创建一个清单来创建一个新Foo对象。
apiVersion: foos.frankel.ch/v1alpha1
kind: Foo
metadata:
name: myfoo
spec:
bar: "whatever"
kubectl Apply -f foo.yml
kubectl get foo
上面的命令已经用新Foo类型更新了数据模型并创建了一个Foo对象。但实际上,我们只是etcd通过 Kubernetes API 存储数据。在我们启动一个控制器来监视新对象并对其进行操作之前,什么都不会发生。请注意,管理 CRD 的控制器的名称是operator。
可以运行第三方工作负载的平台的一个常见问题是只允许经过审查的工作负载。一些工作负载可能会消耗过多的资源;其他人可能是恶意的。
这里有两个具体的场景:
虽然可以通过“构建”管道管理这两种情况,但 Kubernetes 提供了一种开箱即用的解决方案。
正如我上面解释的,Kubernetes 存储配置是etcd在控制器观察变化并对其采取行动的时候。为了防止不需要的行为,最安全的方法是验证更改配置的有效负载;这是准入控制器的角色。
准入控制器是一段代码,它在对象持久化之前截取对 Kubernetes API 服务器的请求,但在请求经过身份验证和授权之后。控制器由以下列表组成,被编译成 kube-apiserver 二进制文件,并且只能由集群管理员配置。在该列表中,有两个特殊的控制器:MutatingAdmissionWebhook和ValidatingAdmissionWebhook. 它们执行在 API 中配置的变异和验证(分别)准入控制 webhook。
--使用准入控制器
简而言之,有两种准入控制器可用:
它们按照下图依次运行:
从Kubernetes 准入控制器指南
每个都可以解决上面突出显示的场景。
在最基本的层面上,kubectl命令行是 REST 客户端的高级抽象。您可以通过设置详细选项来验证它:
kubectl get pods --v=8
:http://kubernetes.io/docs/user-guide/identifiers#names","优先级":0},loader.go:372] Config loaded from file: /Users/nico/.kube/config
round_trippers.go:463] GET https://127.0.0.1:61378/api/v1/namespaces/default/pods?limit=500
round_trippers.go:469] Request Headers:
round_trippers.go:473] Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
round_trippers.go:473] User-Agent: kubectl/v1.24.2 (darwin/arm64) kubernetes/f66044f
round_trippers.go:574] Response Status: 200 OK in 8 milliseconds
round_trippers.go:577] Response Headers:
round_trippers.go:580] Cache-Control: no-cache, private
round_trippers.go:580] Content-Type: application/json
round_trippers.go:580] X-Kubernetes-Pf-Flowschema-Uid: 479e2d49-7b9f-4e4c-8fca-63c273cfb525
round_trippers.go:580] X-Kubernetes-Pf-Prioritylevel-Uid: 4787583d-e7d4-4679-a474-ebb66919a43c
round_trippers.go:580] Date: Sun, 04 Sep 2022 09:32:39 GMT
round_trippers.go:580] Audit-Id: 2f2f163d-fb6d-4149-ba44-ecf4395028aa
request.go:1073] Response Body: {"kind":"Table","apiVersion":"meta.k8s.io/v1","metadata":{"resourceVersion":"263411"},"columnDefinitions":[{"name":"Name","type":"string","format":"name","description":"Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names","priority":0},{"name":"Ready","type":"string","format":"","description":"The aggregate readiness state of this pod for accepting traffic.","priority":0},{"name":"Status","type":"string","format":"","description":"The aggregate status of the containers in this pod.","priority":0},{"name":"Restarts","type":"string","format":"","description":"The number of times the containers in this pod have been restarted and when the last container in this pod has restarted.","priority":0},{"name":"Age","type":"st [truncated 6465 chars]
Kubernetes 的 REST API(大部分?)基于CRUD操作。有时,您需要运行多个命令才能获得所需的结果。例如,我们想查询哪些主体可以执行一个动作。
kubectl包括一种编写代码来编排这些调用的机制。该机制与 Gits 非常相似:
从这一点,kubectl可以发现它。
你可以在你的机器上管理你的插件,但这种方法不能扩展到整个组织。解决方案是插件管理器。认识Krew:
Krew 是kubectl命令行工具的插件管理器。
Krew帮助您:——Krew是什么?
- 发现kubectl插件,
- 将它们安装在您的机器上,
- 并保持安装的插件是最新的。
关于哪些主体可以执行一个动作,这里是如何做到的:
brew install krew #1
kubectl krew completion #2
# follow instructions to update your shell
kubectl krew update #3
kubectl krew install who-can #4
k who-can watch pod #5
No subjects found with permissions to watch pod assigned through RoleBindings
CLUSTERROLEBINDING SUBJECT TYPE SA-NAMESPACE
apisix-clusterrolebinding apisix-ingress-controller ServiceAccount ingress-apisix
cluster-admin system:masters Group
local-path-provisioner-bind local-path-provisioner-service-account ServiceAccount local-path-storage
system:controller:attachdetach-controller attachdetach-controller ServiceAccount kube-system
system:controller:daemon-set-controller daemon-set-controller ServiceAccount kube-system
system:controller:deployment-controller deployment-controller ServiceAccount kube-system
system:controller:endpoint-controller endpoint-controller ServiceAccount kube-system
system:controller:endpointslice-controller endpointslice-controller ServiceAccount kube-system
system:controller:ephemeral-volume-controller ephemeral-volume-controller ServiceAccount kube-system
system:controller:generic-garbage-collector generic-garbage-collector ServiceAccount kube-system
system:controller:job-controller job-controller ServiceAccount kube-system
system:controller:persistent-volume-binder persistent-volume-binder ServiceAccount kube-system
system:controller:pod-garbage-collector pod-garbage-collector ServiceAccount kube-system
system:controller:pvc-protection-controller pvc-protection-controller ServiceAccount kube-system
system:controller:replicaset-controller replicaset-controller ServiceAccount kube-system
system:controller:replication-controller replication-controller ServiceAccount kube-system
system:controller:resourcequota-controller resourcequota-controller ServiceAccount kube-system
system:controller:statefulset-controller statefulset-controller ServiceAccount kube-system
system:coreDNS coredns ServiceAccount kube-system
system:kube-controller-manager system:kube-controller-manager User
system:kube-scheduler system:kube-scheduler User
在这篇文章中,我们浏览了 Kubernetes 中的几个扩展点:数据模型、准入控制器和客户端。这是一个非常简短的介绍,无论是宽度还是深度。然而,我希望它为进一步的研究提供了一个很好的切入点。