Kubernetes API Server 详解


1. API 概述

  k8s apiServer 是访问 k8s 的组件,是 k8s 所有组件交互的通道,提供了 k8s 各类资源对象(pod、RC、Service 等)的增删改查及 watch 等 HTTP Rest 接口,是整个系统的数据总线和数据中心。其它组件不会两两交互,都通过 apiServer 组件交互。apiServer 也是一个网关,有认证、鉴权、准入、限流的作用。

api server 是通过 kube-apiserver 进程来提供服务的,默认情况下在本机 8080 端口提供 rest 服务 (--insecure-port),也可以启用 HTTPS 安全端口 (--secure-port=6443)

kubernetes API Server 的功能:

  • 提供了集群管理的 REST API 接口 (包括认证授权、数据校验以及集群状态变更)
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd)
  • 是资源配额控制的入口
  • 拥有完备的集群安全机制

配置文件(/etc/kubernetes/manifests/kube-apiserver.yaml

[root@master ~]#cat /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.10.65:6443
  creationTimestamp: null
  labels:
    component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    - --advertise-address=192.168.10.65
    - --allow-privileged=true
    - --authorization-mode=Node,RBAC
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --enable-admission-plugins=NodeRestriction
    - --enable-bootstrap-token-auth=true
    - --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
    - --etcd-servers=https://127.0.0.1:2379
    - --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
    - --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
    - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
    - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
    - --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
    - --requestheader-allowed-names=front-proxy-client
    - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
    - --requestheader-extra-headers-prefix=X-Remote-Extra-
    - --requestheader-group-headers=X-Remote-Group
    - --requestheader-username-headers=X-Remote-User
    - --secure-port=6443
    - --service-account-issuer=https://kubernetes.default.svc.cluster.local
    - --service-account-key-file=/etc/kubernetes/pki/sa.pub
    - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
    - --service-cluster-ip-range=10.96.0.0/12
    - --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
    - --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
    - --feature-gates=RemoveSelfLink=false
    image: registry.aliyuncs.com/google_containers/kube-apiserver:v1.22.5
    imagePullPolicy: IfNotPresent
    livenessProbe:
      failureThreshold: 8
      httpGet:
        host: 192.168.10.65
        path: /livez
        port: 6443
        scheme: HTTPS
      initialDelaySeconds: 10
      periodSeconds: 10
      timeoutSeconds: 15
    name: kube-apiserver
    readinessProbe:
      failureThreshold: 3
      httpGet:
        host: 192.168.10.65
        path: /readyz
        port: 6443
        scheme: HTTPS
      periodSeconds: 1
      timeoutSeconds: 15
    resources:
      requests:
        cpu: 250m
    startupProbe:
      failureThreshold: 24
      httpGet:
        host: 192.168.10.65
        path: /livez
        port: 6443
        scheme: HTTPS
      initialDelaySeconds: 10
      periodSeconds: 10
      timeoutSeconds: 15
    volumeMounts:
    - mountPath: /etc/ssl/certs
      name: ca-certs
      readOnly: true
    - mountPath: /etc/pki
      name: etc-pki
      readOnly: true
    - mountPath: /etc/kubernetes/pki
      name: k8s-certs
      readOnly: true
  hostNetwork: true
  priorityClassName: system-node-critical
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  volumes:
  - hostPath:
      path: /etc/ssl/certs
      type: DirectoryOrCreate
    name: ca-certs
  - hostPath:
      path: /etc/pki
      type: DirectoryOrCreate
    name: etc-pki
  - hostPath:
      path: /etc/kubernetes/pki
      type: DirectoryOrCreate
    name: k8s-certs
status: {}

k8s 官网文档

2. K8s RESTAPI 设计思想

由于 k8s 的 Api 是基于 REST 的设计思想,因此不同种类的 HTTP 请求也就对应了不同的操作。比较常用的对应关系是:

  • GET(SELECT):从服务器取出资源(一项或多项)。GET 请求对应 k8s api 的获取信息功能。因此,如果是获取信息的命令都要使用 GET 方式发起 HTTP 请求。
  • POST(CREATE):在服务器新建一个资源。POST 请求对应 k8s api 的创建功能。因此,需要创建 Pods、ReplicaSet 或者 service 的时候请使用这种方式发起请求。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。对应更新 nodes 或 Pods 的状态、ReplicaSet 的自动备份数量等等。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源。

3. K8S API 访问方式

3.1 kubectl 命令行访问方式

kubectl get --raw /api/
kubectl get --raw /api/v1
kubectl get --raw /api/v1/namespaces
[root@master ~]#kubectl get --raw /api/
{"kind":"APIVersions","versions":["v1"],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"192.168.10.65:6443"}]}

3.2 kubectl proxy 访问方式

开启代理端口

[root@master ~]#kubectl proxy --port=8080 &
[1] 6319
[root@master ~]#error: listen tcp 127.0.0.1:8080: bind: address already in use

[1]+  Exit 1                  kubectl proxy --port=8080

查看

[root@master ~]#curl http://localhost:8080/api/ '{"versions": ["v1"]}'
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "192.168.10.65:6443"
    }
  ]
}curl: (3) [globbing] nested braces not supported at pos 14

3.3 curl 访问方式(https)

创建管理员用户,授权,获取 token

[root@master ~]#cat << EOF > CreateServiceAccountRoleBinding.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF
[root@master ~]#ls
CreateServiceAccountRoleBinding.yaml
[root@master ~]#kubectl apply -f CreateServiceAccountRoleBinding.yaml 
serviceaccount/admin-user created
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
[root@master ~]#kubectl get sa -n kube-system admin-user
NAME         SECRETS   AGE
admin-user   1         15s

获取 token

kubectl describe secret -n kube-system `kubectl get secret -n kube-system|grep admin-user|awk '{print $1}'`|grep '^token:'|awk '{print $2}'

生成变量

TOKEN=$(kubectl describe secret -n kube-system `kubectl get secret -n kube-system|grep admin-user|awk '{print $1}'`|grep '^token:'|awk '{print $2}')

curl 请求示例(https)

-k:允许 curl 使用非安全的 ssl 连接并且传输数据(证书不受信)

[root@master ~]#curl -k --header "Authorization: Bearer $TOKEN"  https://192.168.10.65:6443/api
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "192.168.10.65:6443"
    }
  ]
}

3.4 使用证书认证访问方式(https)

[root@master ~]#ll /etc/kubernetes/pki/ca.crt 
-rw-r--r-- 1 root root 1099 Jul  9 17:01 /etc/kubernetes/pki/ca.crt
[root@master ~]#CACERT=/etc/kubernetes/pki/ca.crt
[root@master ~]#curl --cacert $CACERT --header "Authorization: Bearer $TOKEN"  https://192.168.10.65:6443/api
{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "192.168.10.65:6443"
    }
  ]
}

3.5 Postman 方式

取到 token 访问 api

kubectl describe secret -n kube-system `kubectl get secret -n kube-system|grep admin-user|awk '{print $1}'`|grep '^token:'|awk '{print $2}'

设置 Token

禁用 SSL 证书校验(跟上面的 curl -k 一样)

Send

4. 通过 API 接口增删改查

k8s API v1.22 官方文档

4.1 Namespace

(1) 【增】创建 POST 请求

API 接口:/api/v1/namespaces

cat >> test001.json << EOF
{
    "kind": "Namespace",
    "apiVersion": "v1",
    "metadata": {
        "name": "test001",
        "labels": {
            "app": "test001"
        }
    }
}
EOF

curl -XPOST -H 'Content-Type:application/json' -d@test001.json -k --header "Authorization: Bearer $TOKEN" https://192.168.10.65:6443/api/v1/namespaces/
[root@master ~]#kubectl get ns | grep test001
test001                Active   19s

(2) 【删】删除 DELETE 请求

删除 namespace:/api/v1/namespaces/

curl -XDELETE -H 'Content-Type:application/json' -k --header "Authorization: Bearer $TOKEN"  https://192.168.10.65:6443/api/v1/namespaces/test001
[root@master ~]#kubectl get ns | grep test001
test001                Active   2m26s
[root@master ~]#curl -XDELETE -H 'Content-Type:application/json' -k --header "Authorization: Bearer $TOKEN"  https://192.168.10.65:6443/api/v1/namespaces/test001
......
[root@master ~]kubectl get ns | grep test001  # 显示 Terminating 状态
test001                Terminating   2m31s
[root@master ~]#kubectl delete ns test001  # 此时删除会卡住
namespace "test001" deleted
^C

强制删除命名空间链接

kubectl get namespace test001 -o json \
            | tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" \
            | kubectl replace --raw /api/v1/namespaces/test001/finalize -f -

#----------------------------------------------------------------------------------
[root@master ~]#kubectl get namespace test001 -o json \
>             | tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" \
>             | kubectl replace --raw /api/v1/namespaces/test001/finalize -f -
{"kind":"Namespace","apiVersion":"v1","metadata":
......
......
[root@master ~]#
[root@master ~]#kubectl get ns | grep test001
[root@master ~]#

(3) 【改】修改 PUT/PATCH 请求

修改指定的命名空间:/api/v1/namespaces/{name}
修改指定名称空间的状态:/api/v1/namespaces/{name}/status
如果部分更新可以用 PATCH

cat >> test002.json << EOF
{
    "apiVersion": "v1",
    "kind": "Namespace",
    "metadata": {
        "name": "test002",
        "labels": {
            "name": "development"
        }
    },
    "spec": {
        "finalizers": [
            "openshift.com/origin",
            "kubernetes"
        ]
    },
    "status": {
        "phase": "Active"
    }
}
EOF

curl -XPOST -H 'Content-Type:application/json' -d@test001.json -k --header "Authorization: Bearer $TOKEN" https://192.168.10.65:6443/api/v1/namespaces/
curl -XPUT -H 'Content-Type:application/json' -d@test002.json -k --header "Authorization: Bearer $TOKEN"  https://192.168.10.65:6443/api/v1/namespaces/test001

(4) 【查】查询 GET 请求

查询全部:/api/v1/namespaces
查询指定 namespace:/api/v1/namespaces/

curl -XGET -H 'Content-Type:application/json' -k --header "Authorization: Bearer $TOKEN" https://192.168.10.65:6443/api/v1/namespaces/test001/
[root@master ~]#curl -XGET -H 'Content-Type:application/json' -k --header "Authorization: Bearer $TOKEN" https://192.168.10.65:6443/api/v1/namespaces/test001/
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "test001",
    "selfLink": "/api/v1/namespaces/test001",
    "uid": "f2b3ac0e-45cf-4c4c-b6d0-76e91c6155e5",
    "resourceVersion": "639582",
    "creationTimestamp": "2022-08-06T16:49:27Z",
    "labels": {
      "kubernetes.io/metadata.name": "test001",
      "name": "development"
    },
    "managedFields": [
      {
        "manager": "curl",
        "operation": "Update",
        "apiVersion": "v1",
        "time": "2022-08-06T17:14:27Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {"f:metadata":{"f:labels":{".":{},"f:kubernetes.io/metadata.name":{},"f:name":{}}},"f:spec":{"f:finalizers":{}}}
      }
    ]
  },
  "spec": {
    "finalizers": [
      "kubernetes"
    ]
  },
  "status": {
    "phase": "Active"
  }
}

不仅支持 json 格式,还支持 yaml 格式

-H 'Content-Type: application/yaml'

curl -XPOST -H 'Content-Type: application/yaml' --data '
apiVersion: v1
kind: Namespace
metadata:
  name: test003
' -k --header "Authorization: Bearer $TOKEN"  https://192.168.10.65:6443/api/v1/namespaces/
[root@master ~]#curl -XPOST -H 'Content-Type: application/yaml' --data '
> apiVersion: v1
> kind: Namespace
> metadata:
>   name: test003
> ' -k --header "Authorization: Bearer $TOKEN"  https://192.168.10.65:6443/api/v1/namespaces/
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "test003",
    "selfLink": "/api/v1/namespaces/test003",
......
[root@master ~]kubectl get ns
NAME                   STATUS        AGE
......
test001                Active        33m
test003                Active        5s

4.2 Pod

(1)【增】创建 POST 请求

创建 pod:/api/v1/namespaces/{namespace}/pods

(2)【删】删除 DELETE 请求

删除 pod:/api/v1/namespaces/{namespace}/pods/

(3)【改】修改 PUT/PATCH 请求

替换指定的 pod:/api/v1/namespaces/{namespace}/pods/

(4)【查】查询 GET 请求

查询全部:/api/v1/namespaces/{namespace}/pods
查询指定 pod:/api/v1/namespaces/{namespace}/pods/

4.3 Node

(1)【增】创建 POST 请求

创建 node:/api/v1/nodes

(2)【删】删除 DELETE 请求

删除 node:/api/v1/nodes/

(3)【改】修改 PUT/PATCH 请求

替换指定的 node:/api/v1/nodes/{name}
替换指定 node 的状态:/api/v1/nodes/{name}/status

(4)【查】查询 GET 请求

查询全部:/api/v1/nodes
查询指定 node:/api/v1/nodes/{name}
查询指定节点内所有 Pod 的信息:/api/v1/nodes/{name}/pods/
查询指定节点内物理资源的统计信息:/api/v1/nodes/{name}/stats/
查询指定节点的概要信息:/api/v1/nodes/{name}/spec/

4.4 Service

(1)【增】创建 POST 请求

创建 service:/api/v1/namespaces/{namespace}/services

(2)【删】删除 DELETE 请求

删除 service:/api/v1/namespaces/{namespace}/services/

(3)【改】修改 PUT/PATCH 请求

替换指定的 service:/api/v1/namespaces/{namespace}/services/

(4)【查】查询 GET 请求

查询全部:/api/v1/namespaces/{namespace}/services
查询指定 service:/api/v1/namespaces/{namespace}/services/


https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/


posted @ 2022-08-06 14:12  公博义  阅读(497)  评论(0编辑  收藏  举报