Kubernetes 基础设施管理与 API 操作全解析
1. 集群升级
在生产系统中,建议关闭自动升级功能,并在低流量时段或维护窗口进行升级,以确保应用程序受到的干扰最小。当对升级操作有足够信心后,可尝试自动升级。
手动升级节点的命令如下:
gcloud container clusters upgrade [CLUSTER_NAME]
若要升级到特定版本的 Kubernetes,可添加 --cluster-version 标签。
查看集群操作列表,以跟踪升级操作:
gcloud beta container operations list
输出示例:
| NAME | TYPE | ZONE | TARGET | STATUS_MESSAGE | STATUS | START_TIME | END_TIME |
|-----------------------------------|-----------------|-------------|-----------|----------------|--------|-----------------------------------|-----------------------------------|
| operation-1505407677851-8039e369 | CREATE_CLUSTER | us-west1-a | my-cluster | DONE | DONE | 20xx-xx-xxT16:47:57.851933021Z | 20xx-xx-xxT16:50:52.898305883Z |
| operation-1505500805136-e7c64af4 | UPGRADE_CLUSTER | us-west1-a | my-cluster | DONE | DONE | 20xx-xx-xxT18:40:05.136739989Z | 20xx-xx-xxT18:41:09.321483832Z |
| operation-1505500913918-5802c989 | DELETE_CLUSTER | us-west1-a | my-cluster | DONE | DONE | 20xx-xx-xxT18:41:53.918825764Z | 20xx-xx-xxT18:43:48.639506814Z |
描述特定升级操作的命令:
gcloud beta container operations describe [OPERATION_ID]
2. 集群扩展
2.1 GKE 和 AKS 集群
- GKE 集群 :升级 GKE 集群时,只需执行缩放命令来修改节点组中的实例数量。调整控制集群的节点池大小的命令如下:
gcloud container clusters resize [CLUSTER_NAME] \
--node-pool [POOL_NAME] \
--size [SIZE]
新节点将使用与当前节点池中机器相同的配置创建。新的 Pod 将被调度到新节点上,现有 Pod 不会重新定位或重新平衡到新节点。
- AKS 集群 :扩展 AKS 集群引擎的操作类似,需要指定 --resource-group 和所需的节点数量:
az aks scale --name myAKSCluster --resource-group gsw-k8s-group --node-count 1
2.2 自建集群
向自建的 Kubernetes 集群添加资源时,需要做更多工作。若要使节点通过缩放组自动加入或通过基础设施即代码手动加入,需确保通过 --register-node 标志启用节点的自动注册功能(默认开启)。
也可以使用预验证的令牌手动将节点加入集群。使用以下命令初始化 kubeadm:
kubeadm init --token=101tester101 --kubernetes-version $(kubeadm version -o short)
然后使用以下命令将其他节点添加到集群:
kubeadm join --discovery-token-unsafe-skip-ca-verification --token=101tester101:6443
在生产环境中安装 kubeadm 时,通常不直接指定令牌,而是从 kubeadm init 命令中提取并存储。
3. 节点维护
在扩展或缩减集群时,了解节点手动注销和排空的过程至关重要。使用 kubectl drain 命令在从集群中移除节点之前,将节点上的所有 Pod 移除,确保移除节点时实例或 VM 上没有运行的工作负载。
获取可用节点列表的命令:
kubectl get nodes
排空节点的命令:
kubectl drain <node>
此命令执行需要一些时间,因为它要将节点上的工作负载重新调度到其他有可用资源的机器上。排空完成后,可通过首选的编程 API 移除节点。若只是为了维护而移除节点,可使用 uncordon 命令将其重新添加到可用节点列表:
kubectl uncordon <node>
4. 额外配置选项
ksonnet 是一个用于管理 Kubernetes 集群配置的工具,它使用 Jsonnet 来维护集群状态。与 Helm 不同,ksonnet 不通过依赖关系定义包,而是采用可组合的原型方法,通过构建 JSON 模板并由 ksonnet CLI 渲染,将状态应用到集群。从创建原型的部分开始,配置后成为组件,这些组件可组合成应用程序,有助于避免代码重复。更多信息可查看: https://ksonnet.io/ 。
5. 与 Kubernetes API 交互
5.1 理解 OpenAPI
OpenAPI 允许 API 提供者定义操作和模型,使开发者能够自动化工具并生成他们喜欢的语言的客户端与 API 服务器通信。Kubernetes 曾支持 Swagger 1.2,但该规范不完整且无效,难以基于其生成工具或客户端。在 Kubernetes 1.4 中,增加了对 OpenAPI 规范(原 Swagger 2.0)的 alpha 支持,并更新了当前的模型和操作。在 Kubernetes 1.5 中,通过直接从 Kubernetes 源代码自动生成规范,完成了对 OpenAPI 规范的支持,确保规范和文档与操作/模型的未来更改完全同步。新规范提供了更好的 API 文档和自动生成的 Python 客户端。
规范按组版本进行模块化划分,具有前瞻性,可运行支持不同版本的多个 API 服务器,应用程序可逐步过渡到新版本。
5.2 设置代理
为简化访问,可使用 Kubectl 设置代理:
kubectl proxy --port 8080
现在可通过 http://localhost:8080 访问 API 服务器,它将连接到与 Kubectl 配置相同的 Kubernetes API 服务器。
5.3 直接探索 Kubernetes API
直接浏览 API 服务器的 URL http://localhost:8080 ,可获取一个描述所有可用操作的 JSON 文档:
{
"paths": [
"/api",
"/api/v1",
"/apis",
"/apis/apps",
"/apis/storage.k8s.io/v1",
"/healthz",
"/healthz/ping",
"/logs",
"/metrics",
"/swaggerapi/",
"/ui/",
"/version"
]
}
可深入探索其中的路径。例如,访问 /api/v1/namespaces/default 端点的响应如下:
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"creationTimestamp": "2017-12-25T10:04:26Z",
"name": "default",
"resourceVersion": "4",
"selfLink": "/api/v1/namespaces/default",
"uid": "fd497868-e95a-11e7-adce-080027c94384"
},
"spec": {
"finalizers": [
"kubernetes"
]
},
"status": {
"phase": "Active"
}
}
5.4 使用 Postman 探索 Kubernetes API
Postman( https://www.getpostman.com )是一个用于处理 RESTful API 的优秀应用程序,对于喜欢图形界面的用户非常有用。
5.5 使用 httpie 和 jq 过滤输出
API 的输出有时可能过于冗长,可使用 httpie 和 jq 工具进行过滤。例如,获取所有运行服务的名称:
http http://localhost:8080/api/v1/services
输出包含大量无关信息,使用 jq 过滤只显示服务名称的命令如下:
http http://localhost:8080/api/v1/services | jq .items[].metadata.name
输出示例:
"kubernetes"
"kube-dns"
"kubernetes-dashboard"
5.6 通过 Kubernetes API 创建 Pod
给定以下 nginx-pod.json 的 Pod 清单:
{
"kind": "Pod",
"apiVersion": "v1",
"metadata":{
"name": "nginx",
"namespace": "default",
"labels": {
"name": "nginx"
}
},
"spec": {
"containers": [{
"name": "nginx",
"image": "nginx",
"ports": [{"containerPort": 80}]
}]
}
}
使用以下命令通过 API 创建 Pod:
http POST http://localhost:8080/api/v1/namespaces/default/pods @nginx-pod.json
验证 Pod 是否创建成功,提取当前 Pod 的名称和状态:
FILTER='.items[].metadata.name,.items[].status.phase'
http http://localhost:8080/api/v1/namespaces/default/pods | jq $FILTER
6. 通过 Python 客户端访问 Kubernetes API
Kubernetes 孵化器项目提供了一个功能齐全且文档完善的 Python 客户端库,可在 https://github.com/kubernetes-incubator/client-python 找到。
安装步骤:
1. 确保安装了 Python(2.7 或 3.5+)。
2. 安装 Kubernetes 包:
pip install kubernetes
连接到 Kubernetes 集群的示例代码:
from kubernetes import client, config
# 从 Kubectl 配置中读取
config.load_kube_config()
v1 = client.CoreV1Api()
也可以直接连接到运行的代理:
from kubernetes import client, config
client.Configuration().host = 'http://localhost:8080'
v1 = client.CoreV1Api()
7. 剖析 CoreV1API 组
CoreV1API 组的 Python 对象有 481 个公共属性。随机选取 10 个方法查看:
import random
from pprint import pprint as pp
attributes = [x for x in dir(v1) if not x.startswith('__')]
pp(random.sample(attributes, 10))
输出示例:
['patch_namespaced_pod',
'connect_options_node_proxy_with_path_with_http_info',
'proxy_delete_namespaced_pod_with_path',
'delete_namespace',
'proxy_post_namespaced_pod_with_path_with_http_info',
'proxy_post_namespaced_service',
'list_namespaced_pod_with_http_info',
'list_persistent_volume_claim_for_all_namespaces',
'read_namespaced_pod_log_with_http_info',
'create_node']
统计不同动词开头的属性数量:
from collections import Counter
verbs = [x.split('_')[0] for x in attributes]
pp(dict(Counter(verbs)))
输出示例:
{'api': 1,
'connect': 96,
'create': 36,
'delete': 56,
'get': 2,
'list': 56,
'patch': 48,
'proxy': 84,
'read': 52,
'replace': 50}
查看特定属性的帮助信息:
help(v1.create_node)
8. 常见操作示例
8.1 列出对象
列出所有命名空间的示例代码:
for ns in v1.list_namespace().items:
print(ns.metadata.name)
8.2 创建对象
创建一个具有 3 个副本的 nginx-deployment 的示例:
1. 安装 yaml Python 模块:
pip install yaml
- 创建
nginx-deployment.yaml文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
- 运行以下 Python 程序创建部署:
from os import path
import yaml
from kubernetes import client, config
def main():
config.load_kube_config()
with open(path.join(path.dirname(__file__), 'nginx-deployment.yaml')) as f:
dep = yaml.load(f)
k8s = client.AppsV1Api()
status = k8s.create_namespaced_deployment(
body=dep, namespace="default").status
print("Deployment created. status='{}'".format(status))
if __name__ == '__main__':
main()
8.3 监视对象
监视 10 个命名空间事件并打印到屏幕的示例代码:
from kubernetes import client, config, watch
config.load_kube_config()
v1 = client.CoreV1Api()
count = 10
w = watch.Watch()
for event in w.stream(v1.list_namespace, _request_timeout=60):
print(f"Event: {event['type']} {event['object'].metadata.name}")
count -= 1
if count == 0:
w.stop()
print('Done.')
9. 以编程方式调用 Kubectl
Kubectl 通常作为交互式命令行工具使用,也可以通过脚本和程序进行自动化调用。使用 Kubectl 作为 Kubernetes API 客户端的好处包括:
- 易于找到各种使用示例。
- 易于在命令行上进行实验,找到正确的命令和参数组合。
- 支持以 JSON 或 YAML 格式输出,便于快速解析。
- 通过 Kubectl 配置内置了身份验证功能。
Kubernetes 基础设施管理与 API 操作全解析
10. 扩展 Kubernetes API
Kubernetes 的 API 虽然强大,但有时无法满足特定的业务需求,这就需要对其进行扩展。扩展 Kubernetes API 的主要方式是引入自定义资源(Custom Resources)。自定义资源允许用户在 Kubernetes 中定义和使用自己的资源类型,就像使用内置的 Pod、Service 等资源一样。
以下是扩展 Kubernetes API 的一般步骤:
1. 定义自定义资源定义(CRD) :CRD 是一种特殊的 Kubernetes 资源,用于描述自定义资源的结构和行为。可以使用 YAML 文件来定义 CRD,示例如下:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: mycustomresources.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
field1:
type: string
field2:
type: integer
scope: Namespaced
names:
plural: mycustomresources
singular: mycustomresource
kind: MyCustomResource
shortNames:
- mcr
- 应用 CRD :使用
kubectl apply命令将 CRD 应用到 Kubernetes 集群中:
kubectl apply -f mycustomresource-crd.yaml
- 创建自定义资源实例 :定义好 CRD 后,就可以创建自定义资源的实例了。同样使用 YAML 文件来定义实例,示例如下:
apiVersion: example.com/v1
kind: MyCustomResource
metadata:
name: my-custom-resource-instance
spec:
field1: "value1"
field2: 123
- 应用自定义资源实例 :使用
kubectl apply命令将自定义资源实例应用到集群中:
kubectl apply -f mycustomresource-instance.yaml
11. 编写 Kubernetes 和 Kubectl 插件
Kubernetes 支持多种类型的插件,这些插件可以扩展 Kubernetes 的功能,如自定义调度器、授权、准入控制、自定义指标和卷等。
11.1 自定义调度器
自定义调度器可以根据特定的规则和策略来调度 Pod。编写自定义调度器的一般步骤如下:
1. 实现调度逻辑 :使用 Go 语言编写调度器的逻辑,示例代码如下:
package main
import (
"fmt"
"k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/scheduler/framework"
)
type CustomScheduler struct{}
func (s *CustomScheduler) Name() string {
return "custom-scheduler"
}
func (s *CustomScheduler) Filter(pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status {
// 实现过滤逻辑
return framework.NewStatus(framework.Success, "")
}
func (s *CustomScheduler) Score(pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) {
// 实现评分逻辑
return 10, framework.NewStatus(framework.Success, "")
}
- 部署自定义调度器 :将自定义调度器部署到 Kubernetes 集群中,并在调度器配置中引用它。
11.2 授权和准入控制插件
授权和准入控制插件用于控制对 Kubernetes API 的访问和资源的创建、更新、删除操作。可以使用自定义的授权和准入控制插件来实现特定的安全策略。
11.3 自定义指标和卷插件
自定义指标插件可以提供额外的指标数据,用于监控和自动伸缩。自定义卷插件可以支持不同类型的存储卷。
12. 编写 Webhooks
Webhooks 是一种在 Kubernetes 中实现自定义逻辑的强大方式。Webhooks 可以在资源创建、更新、删除等操作前后触发自定义的处理逻辑。
编写 Webhooks 的一般步骤如下:
1. 创建 Webhook 服务 :使用任何编程语言创建一个 Web 服务,处理 Webhook 请求。示例代码(使用 Python Flask)如下:
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
data = request.get_json()
# 处理 Webhook 请求
response = {
"allowed": true,
"status": {
"message": "Webhook processed successfully"
}
}
return jsonify(response)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
- 配置 Webhook :在 Kubernetes 中配置 Webhook,指定 Webhook 的 URL 和触发条件。示例配置如下:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: my-webhook
webhooks:
- name: my-webhook.example.com
rules:
- apiGroups: ["*"]
apiVersions: ["*"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
clientConfig:
url: "http://webhook-service:8080/webhook"
13. 总结
Kubernetes 作为一个强大的容器编排平台,提供了丰富的功能和灵活的扩展机制。通过对 Kubernetes 基础设施的管理,如集群升级、扩展、节点维护等操作,可以确保集群的稳定运行和高效使用。同时,通过与 Kubernetes API 的交互、扩展 API、编写插件和 Webhooks 等方式,可以根据具体的业务需求对 Kubernetes 进行定制化开发,满足不同场景下的应用需求。
以下是本文涉及的主要操作和工具的总结表格:
| 操作/工具 | 描述 | 示例命令/代码 |
| — | — | — |
| 集群升级 | 手动升级 Kubernetes 集群 | gcloud container clusters upgrade [CLUSTER_NAME] |
| 集群扩展 | 扩展 GKE、AKS 或自建集群 | gcloud container clusters resize [CLUSTER_NAME] --node-pool [POOL_NAME] --size [SIZE] 等 |
| 节点维护 | 排空和重新添加节点 | kubectl drain <node> , kubectl uncordon <node> |
| 与 API 交互 | 直接访问、使用工具过滤输出、创建资源等 | http http://localhost:8080/api/v1/services , http POST http://localhost:8080/api/v1/namespaces/default/pods @nginx-pod.json |
| Python 客户端 | 通过 Python 代码访问 Kubernetes API | from kubernetes import client, config; config.load_kube_config(); v1 = client.CoreV1Api() |
| 扩展 API | 定义和使用自定义资源 | 定义 CRD 和创建自定义资源实例的 YAML 文件及 kubectl apply 命令 |
| 编写插件 | 自定义调度器、授权、准入控制等 | 编写 Go 代码实现调度器逻辑等 |
| 编写 Webhooks | 实现自定义处理逻辑 | 创建 Web 服务处理 Webhook 请求及配置 Webhook 的 YAML 文件 |
下面是一个简单的 mermaid 流程图,展示了扩展 Kubernetes API 的主要步骤:
graph LR
A[定义 CRD] --> B[应用 CRD]
B --> C[创建自定义资源实例]
C --> D[应用自定义资源实例]
通过本文的介绍,希望读者能够对 Kubernetes 的基础设施管理和 API 操作有更深入的理解,并能够根据实际需求进行灵活运用和定制开发。
超级会员免费看
1702

被折叠的 条评论
为什么被折叠?



