Khám phá chi tiết máy chủ API trong Kubernetes

Mục lục- 1. Tổng quan về API

    1. Nguyên tắc thiết kế REST API của Kubernetes
    1. Các phương thức truy cập API Kubernetes
  • 3.1 Sử dụng dòng lệnh kubectl
  • 3.2 Sử dụng kubectl proxy
  • 3.3 Sử dụng curl (https)
  • 3.4 Sử dụng xác thực chứng chỉ (https)
  • 3.5 Sử dụng Postman
    1. Thực hiện CRUD qua API
  • 4.1 Namespace
  • (1) Tạo mới - POST
  • (2) Xóa - DELETE
  • (3) Cập nhật - PUT/PATCH
  • (4) Truy vấn - GET
  • 4.2 Pod
  • (1) Tạo mới - POST
  • (2) Xóa - DELETE
  • (3) Cập nhật - PUT/PATCH
  • (4) Truy vấn - GET
  • 4.3 Node
  • (1) Tạo mới - POST
  • (2) Xóa - DELETE
  • (3) Cập nhật - PUT/PATCH
  • (4) Truy vấn - GET
  • 4.4 Service
  • (1) Tạo mới - POST
  • (2) Xóa - DELETE
  • (3) Cập nhật - PUT/PATCH
  • (4) Truy vấn - GET
  1. Tổng quan về API =========

Máy chủ API (apiServer) trong Kubernetes là thành phần cung cấp khả năng truy cập vào cụm, hoạt động như kênh giao tiếp cho tất cả các thành phần khác. Nó cung cấp các giao diện HTTP REST cho việc thực hiện các thao tác CRUD (tạo, đọc, cập nhật, xóa) và theo dõi (watch) đối với các đối tượng tài nguyên (pod, ReplicationController, Service, v.v.). Đây được xem như hệ thống tổng线和 trung tâm dữ liệu của toàn bộ hệ thống. Các thành phần khác không tương tác trực tiếp với nhau mà đều đi qua apiServer. apiServer cũng đóng vai trò như một cổng gateway với các chức năng xác thực, phân quyền, kiểm soát và giới hạn lưu lượng.

apiServer được cung cấp bởi tiến trình kube-apiserver, mặc định cung cấp dịch vụ REST trên cổng 8080 của máy chủ (--insecure-port), hoặc có thể kích hoạt cổng HTTPS an toàn (--secure-port=6443)

Chức năng của Kubernetes API Server:

  • Cung cấp giao diện REST API cho quản lý cụm (bao gồm xác thực, phân quyền, kiểm tra dữ liệu và thay đổi trạng thái cụm)
  • Là điểm trung tâm cho việc trao đổi dữ liệu và giao tiếp giữa các module khác (các module khác truy vấn hoặc sửa đổi dữ liệu qua API Server, chỉ API Server mới thao tác trực tiếp với etcd)
  • Là điểm vào cho kiểm soát hạn mức tài nguyên
  • Có cơ chế bảo mật cụm hoàn chỉnh

![](https://img-blog.csdnimg.cn/f16ee3c84abf4bf3aa84d6b3443968ad.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5a-S5rGf5a2k5b2xMDA3,size_20,color_FFFFFF,t_70,g_se,x_16)

Tệp cấu hình (/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: {}

  1. Nguyên tắc thiết kế REST API của Kubernetes ===================

Vì API của Kubernetes dựa trên nguyên tắc thiết kế REST, các loại yêu cầu HTTP khác nhau sẽ tương ứng với các thao tác khác nhau. Mối quan hệ tương ứng phổ biến là:

  • GET (SELECT): Lấy tài nguyên từ máy chủ (một hoặc nhiều). Yêu cầu GET tương ứng với chức năng lấy thông tin của API Kubernetes. Do đó, tất cả các lệnh lấy thông tin đều sử dụng phương thức GET để gửi yêu cầu HTTP.
  • POST (CREATE): Tạo một tài nguyên mới trên máy chủ. Yêu cầu POST tương ứng với chức năng tạo của API Kubernetes. Do đó, khi cần tạo Pods, ReplicaSets hoặc service, hãy sử dụng phương thức này để gửi yêu cầu.
  • PUT (UPDATE): Cập nhật tài nguyên trên máy chủ (khách hàng cung cấp tài nguyên đầy đủ sau khi thay đổi). Tương ứng với cập nhật trạng thái nodes hoặc Pods, số lượng sao lưu tự động của ReplicaSets, v.v.
  • PATCH (UPDATE): Cập nhật tài nguyên trên máy chủ (khách hàng cung cấp các thuộc tính thay đổi).
  • DELETE (DELETE): Xóa tài nguyên khỏi máy chủ.
  1. Các phương thức truy cập API Kubernetes ===============

3.1 Sử dụng dòng lệnh 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 Sử dụng kubectl proxy

Kích hoạt cổng 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

Kiểm tra

[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 Sử dụng curl (https)

Tạo người dùng quản trị, cấp quyền, lấy 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

Lấy token

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

Tạo biến

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

Ví dụ yêu cầu curl (https)

-k: cho phép curl sử dụng kết nối ssl không an toàn và truyền dữ liệu (chứng chỉ không đáng tin cậy)

[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 Sử dụng xác thực chứng chỉ (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 Sử dụng Postman

Lấy token để truy cập api

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

Thiết lập Token

Vô hiệu hóa kiểm tra chứng chỉ SSL (giống curl -k ở trên)

Gửi yêu cầu

  1. Thực hiện CRUD qua API ================

4.1 Namespace

(1) Tạo mới - 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) Xóa - DELETE

Xóa 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  # Hiển thị trạng thái Terminating
test001                Terminating   2m31s
[root@master ~]#kubectl delete ns test001  # Lệnh xóa sẽ bị treo ở đây
namespace "test001" deleted
^C

Buộc xóa namespace:

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) Cập nhật - PUT/PATCH

Cập nhật namespace cụ thể: /api/v1/namespaces/{name} Cập nhật trạng thái namespace cụ thể: /api/v1/namespaces/{name}/status Nếu muốn cập nhật một phần, có thể sử dụng 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) Truy vấn - GET

Truy vấn tất cả: /api/v1/namespaces Truy namespace cụ thể: /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"
  }
}

Không chỉ hỗ định dạng json, mà còn hỗ trợ định dạng 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) Tạo mới - POST

Tạo pod: /api/v1/namespaces/{namespace}/pods

(2) Xóa - DELETE

Xóa pod: /api/v1/namespaces/{namespace}/pods/

(3) Cập nhật - PUT/PATCH

Thay thế pod cụ thể: /api/v1/namespaces/{namespace}/pods/

(4) Truy vấn - GET

Truy vấn tất cả: /api/v1/namespaces/{namespace}/pods Truy vấn pod cụ thể: /api/v1/namespaces/{namespace}/pods/

4.3 Node

(1) Tạo mới - POST

Tạo node: /api/v1/nodes

(2) Xóa - DELETE

Xóa node: /api/v1/nodes/

(3) Cập nhật - PUT/PATCH

Thay thế node cụ thể: /api/v1/nodes/{name} Thay thế trạng thái node cụ thể: /api/v1/nodes/{name}/status

(4) Truy vấn - GET

Truy vấn tất cả: /api/v1/nodes Truy vấn node cụ thể: /api/v1/nodes/{name} Truy vấn thông tin tất cả Pod trong node: /api/v1/nodes/{name}/pods/ Truy vấn thống kê tài nguyên vật lý trong node: /api/v1/nodes/{name}/stats/ Truy vấn thông tin tóm tắt của node: /api/v1/nodes/{name}/spec/

4.4 Service

(1) Tạo mới - POST

Tạo service: /api/v1/namespaces/{namespace}/services

(2) Xóa - DELETE

Xóa service: /api/v1/namespaces/{namespace}/services/

(3) Cập nhật - PUT/PATCH

Thay thế service cụ thể: /api/v1/namespaces/{namespace}/services/

(4) Truy vấn - GET

Truy vấn tất cả: /api/v1/namespaces/{namespace}/services Truy vấn service cụ thể: /api/v1/namespaces/{namespace}/services/

Thẻ: Kubernetes API Server REST API container orchestration

Đăng vào ngày 31 tháng 5 lúc 03:46