Kubernetes API 基础

Kubernetes API 基础

Kubernetes API 架构

API Server 核心职责

┌─────────────────────────────────────────────┐
│         Kubernetes API Server               │
├─────────────────────────────────────────────┤
│  1. 认证 (Authentication)                    │
│     - 客户端证书                             │
│     - Bearer Token                          │
│     - ServiceAccount                        │
├─────────────────────────────────────────────┤
│  2. 授权 (Authorization)                     │
│     - RBAC                                  │
│     - ABAC                                  │
│     - Webhook                               │
├─────────────────────────────────────────────┤
│  3. 准入控制 (Admission Control)             │
│     - MutatingWebhook                       │
│     - ValidatingWebhook                     │
├─────────────────────────────────────────────┤
│  4. 资源验证 & 持久化 (etcd)                 │
└─────────────────────────────────────────────┘

RESTful API 设计

Kubernetes API 完全遵循 REST 规范:

资源类型: Pod
API Group: core (v1)
Namespace: default
资源名称: nginx-pod

完整路径:
/api/v1/namespaces/default/pods/nginx-pod

HTTP 方法映射:
- GET     → 读取资源
- POST    → 创建资源
- PUT     → 更新资源 (完整替换)
- PATCH   → 更新资源 (部分修改)
- DELETE  → 删除资源

API 版本与 Group

API Group 结构

# Core Group (内置资源)
/api/v1
  - pods
  - services
  - configmaps
  - secrets
  - namespaces

# Named Groups (扩展资源)
/apis/apps/v1
  - deployments
  - statefulsets
  - daemonsets

/apis/batch/v1
  - jobs
  - cronjobs

/apis/networking.k8s.io/v1
  - ingresses
  - networkpolicies

/apis/rbac.authorization.k8s.io/v1
  - roles
  - rolebindings
  - clusterroles
  - clusterrolebindings

版本演进

Alpha (v1alpha1, v1alpha2...)
  ↓ 功能测试、可能变更
Beta (v1beta1, v1beta2...)
  ↓ 功能稳定、向后兼容
GA/Stable (v1, v2...)
  ↓ 生产就绪、长期支持

资源对象结构

GVK (Group-Version-Kind)

每个 Kubernetes 资源都由 GVK 唯一标识:

// Group: apps
// Version: v1
// Kind: Deployment

type Deployment struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`
    Spec              DeploymentSpec   `json:"spec,omitempty"`
    Status            DeploymentStatus `json:"status,omitempty"`
}

TypeMeta(类型元数据)

apiVersion: apps/v1  # Group + Version
kind: Deployment     # Kind
type TypeMeta struct {
    Kind       string `json:"kind,omitempty"`
    APIVersion string `json:"apiVersion,omitempty"`
}

ObjectMeta(对象元数据)

metadata:
  name: nginx-deployment        # 资源名称(必须)
  namespace: default             # 命名空间
  uid: a1b2c3d4-...             # 唯一标识(自动生成)
  resourceVersion: "12345"       # 版本号(乐观锁)
  generation: 2                  # spec 修改计数
  creationTimestamp: "2024-01-09T10:00:00Z"
  deletionTimestamp: "2024-01-09T11:00:00Z"  # 软删除标记
  
  labels:                        # 标签(用于选择器)
    app: nginx
    env: production
  
  annotations:                   # 注解(用于元信息)
    description: "My nginx deployment"
    kubernetes.io/change-cause: "Update to v1.21"
  
  ownerReferences:               # 所有者引用(级联删除)
  - apiVersion: apps/v1
    kind: ReplicaSet
    name: nginx-rs-abc
    uid: xyz123
    controller: true
  
  finalizers:                    # 终结器(删除前的清理)
  - kubernetes.io/pvc-protection
type ObjectMeta struct {
    Name                       string
    Namespace                  string
    UID                        types.UID
    ResourceVersion            string
    Generation                 int64
    CreationTimestamp          metav1.Time
    DeletionTimestamp          *metav1.Time
    DeletionGracePeriodSeconds *int64
    Labels                     map[string]string
    Annotations                map[string]string
    OwnerReferences            []metav1.OwnerReference
    Finalizers                 []string
    ManagedFields              []metav1.ManagedFieldsEntry
}

Spec(期望状态)

spec:
  replicas: 3                    # 期望的副本数
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21

Status(实际状态)

status:
  replicas: 3                    # 实际副本数
  availableReplicas: 3           # 可用副本数
  readyReplicas: 3               # 就绪副本数
  conditions:
  - type: Available
    status: "True"
    lastUpdateTime: "2024-01-09T10:00:00Z"
    reason: MinimumReplicasAvailable
    message: "Deployment has minimum availability"

认证方式

1. kubeconfig 文件认证

# ~/.kube/config
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTi...
    server: https://kubernetes.example.com:6443
  name: my-cluster

users:
- name: admin
  user:
    client-certificate-data: LS0tLS1CRUdJTi...
    client-key-data: LS0tLS1CRUdJTi...

contexts:
- context:
    cluster: my-cluster
    user: admin
    namespace: default
  name: my-context

current-context: my-context

2. ServiceAccount Token 认证

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  namespace: default

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-pods
subjects:
- kind: ServiceAccount
  name: my-service-account
  namespace: default
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

获取 Token:

# Kubernetes 1.24+
kubectl create token my-service-account -n default

# Kubernetes < 1.24
kubectl get secret $(kubectl get sa my-service-account -o jsonpath='{.secrets[0].name}') -o jsonpath='{.data.token}' | base64 -d

3. Bearer Token 认证

# 使用 Token 访问 API
TOKEN=$(kubectl create token my-service-account)

curl -k -H "Authorization: Bearer $TOKEN" \
  https://kubernetes.example.com:6443/api/v1/namespaces/default/pods

4. 客户端证书认证

# 使用证书访问 API
curl --cert ./client.crt \
     --key ./client.key \
     --cacert ./ca.crt \
     https://kubernetes.example.com:6443/api/v1/namespaces/default/pods

API 调用方式

1. kubectl proxy(开发推荐)

# 启动代理(自动处理认证)
kubectl proxy --port=8080

# 然后可以直接访问(无需认证)
curl http://localhost:8080/api/v1/namespaces/default/pods

2. 直接调用 API Server

# 获取 API Server 地址
kubectl cluster-info

# 获取 Token
TOKEN=$(kubectl create token default)

# 调用 API
curl -k -H "Authorization: Bearer $TOKEN" \
  https://kubernetes.example.com:6443/api/v1/namespaces/default/pods

3. 使用客户端库(生产推荐)

Go Client:

import "k8s.io/client-go/kubernetes"

config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
clientset, err := kubernetes.NewForConfig(config)

Python Client:

from kubernetes import client, config

config.load_kube_config()
v1 = client.CoreV1Api()

常见 API 端点

核心资源 (Core API)

# 列出所有 Pods
GET /api/v1/pods
GET /api/v1/namespaces/{namespace}/pods

# 获取特定 Pod
GET /api/v1/namespaces/{namespace}/pods/{name}

# 创建 Pod
POST /api/v1/namespaces/{namespace}/pods

# 更新 Pod
PUT /api/v1/namespaces/{namespace}/pods/{name}

# 部分更新 Pod
PATCH /api/v1/namespaces/{namespace}/pods/{name}

# 删除 Pod
DELETE /api/v1/namespaces/{namespace}/pods/{name}

# 获取 Pod 日志
GET /api/v1/namespaces/{namespace}/pods/{name}/log

# Pod Exec
GET /api/v1/namespaces/{namespace}/pods/{name}/exec
  ?command=ls
  &container=nginx
  &stdout=true
  &stderr=true

应用资源 (apps/v1)

# Deployments
GET /apis/apps/v1/namespaces/{namespace}/deployments
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
POST /apis/apps/v1/namespaces/{namespace}/deployments
PUT /apis/apps/v1/namespaces/{namespace}/deployments/{name}
DELETE /apis/apps/v1/namespaces/{namespace}/deployments/{name}

# StatefulSets
GET /apis/apps/v1/namespaces/{namespace}/statefulsets

# DaemonSets
GET /apis/apps/v1/namespaces/{namespace}/daemonsets

批处理资源 (batch/v1)

# Jobs
GET /apis/batch/v1/namespaces/{namespace}/jobs
POST /apis/batch/v1/namespaces/{namespace}/jobs

# CronJobs
GET /apis/batch/v1/namespaces/{namespace}/cronjobs

Watch 机制

Watch 原理

Kubernetes 支持 Watch 机制,通过长连接监听资源变化:

Client                          API Server
  │                                  │
  │  GET /api/v1/pods?watch=true     │
  ├─────────────────────────────────>│
  │                                  │
  │  HTTP 200 OK                     │
  │  Transfer-Encoding: chunked      │
  │<─────────────────────────────────┤
  │                                  │
  │  ADDED: Pod nginx-1              │
  │<─────────────────────────────────┤
  │                                  │
  │  MODIFIED: Pod nginx-1           │
  │<─────────────────────────────────┤
  │                                  │
  │  DELETED: Pod nginx-1            │
  │<─────────────────────────────────┤
  │                                  │

Watch 事件类型

{
  "type": "ADDED",
  "object": {
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
      "name": "nginx-pod",
      "namespace": "default"
    },
    "spec": {...},
    "status": {...}
  }
}

事件类型

  • ADDED: 资源创建
  • MODIFIED: 资源更新
  • DELETED: 资源删除
  • ERROR: 错误事件
  • BOOKMARK: 书签(用于断点续传)

ResourceVersion

# 从最新版本开始 Watch
GET /api/v1/pods?watch=true

# 从特定版本开始 Watch
GET /api/v1/pods?watch=true&resourceVersion=12345

# 列出资源并获取当前 resourceVersion
GET /api/v1/pods
# Response 包含: metadata.resourceVersion

# 使用该版本继续 Watch(断点续传)
GET /api/v1/pods?watch=true&resourceVersion={version}

List 分页

大规模列表查询

# Limit:限制返回数量
GET /api/v1/pods?limit=100

# 返回:
{
  "metadata": {
    "continue": "eyJ2IjoibWV0YS5rOHMuaW8vdjEi..."
  },
  "items": [...]
}

# 使用 continue token 获取下一页
GET /api/v1/pods?limit=100&continue=eyJ2IjoibWV0YS5rOHMuaW8vdjEi...

Label Selector

标签选择器查询

# 相等选择器
GET /api/v1/pods?labelSelector=app=nginx

# 不等选择器
GET /api/v1/pods?labelSelector=app!=nginx

# 集合选择器
GET /api/v1/pods?labelSelector=env in (production,staging)

# 存在性选择器
GET /api/v1/pods?labelSelector=app

# 组合选择器
GET /api/v1/pods?labelSelector=app=nginx,env=production

Field Selector

字段选择器查询

# 按名称过滤
GET /api/v1/pods?fieldSelector=metadata.name=nginx-pod

# 按命名空间过滤
GET /api/v1/pods?fieldSelector=metadata.namespace=default

# 按状态过滤
GET /api/v1/pods?fieldSelector=status.phase=Running

# 组合过滤
GET /api/v1/pods?fieldSelector=status.phase=Running,metadata.namespace=default

API 错误处理

Status 对象

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "pods \"nginx-pod\" not found",
  "reason": "NotFound",
  "details": {
    "name": "nginx-pod",
    "kind": "pods"
  },
  "code": 404
}

常见错误码

HTTP Code Reason 说明
200 OK 成功
201 Created 创建成功
400 BadRequest 请求格式错误
401 Unauthorized 未认证
403 Forbidden 权限不足
404 NotFound 资源不存在
409 Conflict 资源冲突(版本冲突)
422 Invalid 验证失败
429 TooManyRequests 速率限制
500 InternalError 服务器内部错误

API Discovery

发现可用 API

# 列出所有 API Group
GET /apis

# 列出特定 Group 的版本
GET /apis/apps

# 列出特定版本的资源
GET /apis/apps/v1

OpenAPI Spec

# 获取 OpenAPI 规范(Swagger)
GET /openapi/v2

# 获取 OpenAPI v3
GET /openapi/v3

总结

核心概念

  1. GVK: Group-Version-Kind 唯一标识资源
  2. RESTful: 完全遵循 REST 规范
  3. Watch: 长连接监听资源变化
  4. Selector: 标签和字段选择器
  5. 认证授权: 多种认证方式,RBAC 授权

API 调用流程

1. 认证 (Authentication)
   ↓
2. 授权 (Authorization)
   ↓
3. 准入控制 (Admission Control)
   ↓
4. 验证 & 持久化
   ↓
5. 返回结果

最佳实践

使用客户端库:而非直接调用 HTTP API
Watch 而非轮询:实时监听资源变化
使用 List 分页:避免一次加载大量数据
Label Selector:高效过滤资源
ResourceVersion:实现断点续传
错误处理:优雅处理各种错误场景

下一节将详细介绍 Go Client 的深度实战。