Mục lục- 1. Tổng quan về API
-
- Nguyên tắc thiết kế REST API của Kubernetes
-
- 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
-
- 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
- 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
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: {}
- 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ủ.
- 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
- 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/