目录
- 1. API 概述
- 2. K8s RESTAPI 设计思想
- 3. K8S API 访问方式
- 3.1 kubectl 命令行访问方式
- 3.2 kubectl proxy 访问方式
- 3.3 curl 访问方式(https)
- 3.4 使用证书认证访问方式(https)
- 3.5 Postman 方式
- 4. 通过 API 接口增删改查
- 4.1 Namespace
- (1) 【增】创建 POST 请求
- (2) 【删】删除 DELETE 请求
- (3) 【改】修改 PUT/PATCH 请求
- (4) 【查】查询 GET 请求
- 4.2 Pod
- (1)【增】创建 POST 请求
- (2)【删】删除 DELETE 请求
- (3)【改】修改 PUT/PATCH 请求
- (4)【查】查询 GET 请求
- 4.3 Node
- (1)【增】创建 POST 请求
- (2)【删】删除 DELETE 请求
- (3)【改】修改 PUT/PATCH 请求
- (4)【查】查询 GET 请求
- 4.4 Service
- (1)【增】创建 POST 请求
- (2)【删】删除 DELETE 请求
- (3)【改】修改 PUT/PATCH 请求
- (4)【查】查询 GET 请求
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: {}
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 接口增删改查
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/{name}
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/{name}
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/{name}
(3)【改】修改 PUT/PATCH 请求
替换指定的 pod:/api/v1/namespaces/{namespace}/pods/{name}
(4)【查】查询 GET 请求
查询全部:/api/v1/namespaces/{namespace}/pods
查询指定 pod:/api/v1/namespaces/{namespace}/pods/{name}
4.3 Node
(1)【增】创建 POST 请求
创建 node:/api/v1/nodes
(2)【删】删除 DELETE 请求
删除 node:/api/v1/nodes/{name}
(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/{name}
(3)【改】修改 PUT/PATCH 请求
替换指定的 service:/api/v1/namespaces/{namespace}/services/{name}
(4)【查】查询 GET 请求
查询全部:/api/v1/namespaces/{namespace}/services
查询指定 service:/api/v1/namespaces/{namespace}/services/{name}