3.1 Kubernetes API 概述
Kubernetes API 是 Kubernetes 集群的重要组成部分,Kubernetes 中各种资源(对象)的数据都通过该 API 接口被提交到后端的持久化存储(etcd)中,通过该 API 接口也实现了各部件之间的解耦合,并且 Kubernetes 的命令行工具 kubectl 也是通过 API 接口来实现集群的管理功能,所以在介绍 kubectl 之前,我们先来了解一下 Kubernetes API。
Kubernetes API 依然是遵循 RESTful 风格的设计,通过标准的 HTTP 动词(比如:POST、PUT、GET、DELETE 等)完成对相关资源对象的查询、创建、修改、删除等操作。
Kubernetes 开发人员认为,成功的系统都会经历一个不断成长和适应各种变更的过程,因此 Kubernetes API 也是不断变更和增长的。在设计和开发新 API 的时候会向下兼容已经存在的客户需求。Kubernetes API 官方文档的地址为:https://kubernetes.io/docs/reference/ ,可以根据 Kubernetes 的版本不同查看不同的 API 文档 。
Kubernetes API 版本演进策略
为了兼容旧版本的同时继续升级新的 API,Kubernetes 提供了多版本 API 支持,不同的版本通过版本号路径前缀进行区分,一般情况下新旧版本的 API 都可以涵盖所有的 Kubernetes 资源对象,不同的版本之间只是存在一些细微的差别,可以通过 API 的版本号描述 API 的成熟阶段:
- v1:GA 稳定版本
- v1beta3:Beta 版本(预发布版本)
- v1alpha1:Alpha 版本(实验性版本)
当某个 API 的实现达到一个新的 GA 稳定版本时(比如 v2),旧的 GA 版本(比如 v1)和 Beta 版本(比如 v2beta1)会被逐渐废弃。
API Groups(API 组)
为了方便对 API 进行拓展,使用了 API Groups 来标识。API Groups 以 REST URL 中的路径进行定义。目前主要有两类 API Groups:
- Core Groups(核心组):这是 Kubernetes 最核心的 API,它没有组的概念,比如 “v1” 在资源对象的定义中表示为 apiVersion: v1。对于核心资源对象而言是不存在扩展 API Group,所以定义的时候可以直接使用版本号来表示。
- 具有分组信息的 API:在 URL 路径中使用 /apis/$GROUP_NAME/$VERSION 标识,在资源对象的定义中表示为 apiVersion: $GROUP_NAME/$VERSION,比如:"apiVersion: batch/v1"、"apiVersion: extensions:v1beta1"、"apiVersion: apps/v1beta1"。
API 元素的组成
在 Kubernetes API 中,一个 API 的顶层元素由 5 部分组成,分别为:kind、apiVersion、metadata、spec 和 status 。
- kind
kind 一共有 3 种类别,分别是:
- 对象(objects): 表示系统中的资源实体,比如 Pod、Node、Service 等。客户端可以修改这些对象(资源实体)的属性,进行增、删、改、查等操作。
- 列表(list): 一个或多个资源类别集合,比如 PodLists、NodeLists、ServiceLists 等。但是有些单例对象,比如当前用户、系统默认用户等,这些对象就没有列表。
- 简单类别(simple): 表示的是作用在对象上的特殊行为和非持久实体,比如 Binding、Status 等。
- apiVersion
- v1: 这是Kubernetes API的第一个稳定版本。 它包含许多核心对象。
- apps/v1: apps是Kubernetes中最常见的API组,其中包含许多核心对象和v1。 它包括与在Kubernetes上运行应用程序相关的功能,如Deployments,RollingUpdates和ReplicaSets。
- autoscaling/v1: 此API版本允许根据不同的资源使用指标自动调整容器。此稳定版本仅支持CPU扩展,但未来的alpha和beta版本将允许您根据内存使用情况和自定义指标进行扩展。
- batch/v1: batchAPI组包含与批处理和类似作业的任务相关的对象(而不是像应用程序一样的任务,如无限期地运行Web服务器)。 这个apiVersion是这些API对象的第一个稳定版本。
- batch/v1beta1: Kubernetes中批处理对象的新功能测试版,特别是包括允许您在特定时间或周期运行作业的CronJobs。
- certificates.k8s.io/v1beta1: 此API版本添加了验证网络证书的功能,以便在群集中进行安全通信。 您可以在官方文档上阅读更多内容。
- extensions/v1beta1: 此版本的API包含许多新的常用Kubernetes功能。 部署,DaemonSets,ReplicaSet和Ingresses都在此版本中收到了重大更改。
- policy/v1beta1: 此apiVersion增加了设置pod中断预算和pod安全性新规则的功能。
- rbac.authorization.k8s.io/v1:此apiVersion包含Kubernetes基于角色的访问控制的额外功能。这有助于您保护集群。
- metadata
元数据,包含了一组由不同名称定义的属性。每个资源对象都必须包括以下 3 种元数据:
- namespace:对象所在的命名空间。如果不指定默认放在 default 系统命名空间中。
- name:对象的名称。在一个命名空间中必须要有唯一性。
- uid:系统为每个对象都生成的唯一 ID。
另外对象还应该包含的一些其他的元数据:
- labels:标签,主要用于标签选择器。
- annotations:注解,添加更多对于该对象的注解信息。
- resourceVersion:识别该资源内部版本号的字符串。
- createTimestamp:创建对象时的时间戳。
- deletionTimestamp:删除对象时的时间戳。
- selfLink:通过 API 访问资源自身的 URL。
- spec
spec 主要用于定义用户对需要管理的对象的详细描述,包括配置设置、默认值、属性的初始化值等。如果 spec 被删除,那么该对象也会从系统中删除。
- status
status 用于记录对象在系统中的当前状态信息。比如对于最常用的 Pod 而言,status 信息包括 conditions、containerStatuses、hostIP、phase、startTime 等,其中比较重要的两个状态属性是:
- phase:对象所处的生命周期,主要有:Pending(创建中)、Running、Active(正在运行中) 以及 Terminated(已终结)。
- condition:条件,由条件类型和状态值组成。现在只有一种条件类型:Ready,对应的状态值为 True、False 以及 Unknown。
3.2 kubectl 用法
Kubernetes 提供了命令行工具 kubectl,使用这个工具我们可以非常方便的访问 Kubernetes API 来完成对应的操作。
kubeconfig
在使用 kubectl 命令行之前需要配置 kubeconfig 文件,这个文件中配置了如何访问 Kubernetes API,具体包括 Kubernetes API Server 的 URL 和认证信息等,还可以设置不同的上下文环境,快速切换访问环境。
# 该配置文件为 ~/.kube/config
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.0.31:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
namespace: kube-system
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
kubeconfig 文件中包括了以下几个关键的部分:
clusters: Kubernetes API Server 访问 URL 和相关属性。contexts: 设置 kubelet 执行上下文。current-context: 设置 kubelet 执行当前上下文。preferences: 设置 kubelet 其他属性。users: 设置访问 Kubernetes API Server 的认证信息。
可以手动编辑 ~/.kube/config 文件,也可以使用命令进行查看和设置:
kubectl config view: 查看 kubeconfig 文件。kubectl config set-cluster: 设置 kubeconfig 的 clusters。kubectl config set-credentials: 设置 kubeconfig 的 users。kubectl config set-context: 设置 kubeconfig 的 contexts。kubectl config use-context: 设置 kubeconfig 的 current-context。
3.3 kubectl 命令行语法
kubectl 命令行语法为 kubectl [command] [TYPE] [NAME] [flags],其中:
- command:子命令,操作 Kubernetes 集群资源对象的命令,比如:create/delete/describe 等。
- TYPE: 资源对象的类型,可以使用单数、复数、简写形式,区分大小写,比如:pod/pods/po。
- NAME: 资源对象的名称,区分大小写。如果不指定名称会返回属于 TYPE 的全部对象列表,比如:kubectl get pods 会返回所有的 Pod 列表。
- flags: 可选参数。
可以在 zsh 中设置添加 kubectl 自动补全:
echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc
v1.6 版本的 kubectl 命令参考图如下所示:

图片来源:kubernetes-handbook
3.4 kubectl 资源对象类型
下表列出了 kubectl 所有可操作资源对象类型及其简写形式:
| 资源对象类型 | 缩写 |
|---|---|
| clusters | / |
| componentstatues | cs |
| configmaps | cm |
| daemonsets | ds |
| deployments | deploy |
| endpoints | ep |
| events | ev |
| horizontalpodautoscalers | hpa |
| ingresses | ing |
| jobs | / |
| limitranges | limits |
| nodes | no |
| namespaces | ns |
| networkpolicies | / |
| statefulsets | / |
| persistentvolumeclaims | pvc |
| persistentvolumes | pv |
| pods | po |
| podsecuritypolicies | psp |
| podtemplates | / |
| replicasets | rs |
| replicationcontrollers | rc |
| resourcequotas | quota |
| cronjob | / |
| secrets | / |
| serviceaccounts | / |
| services | svc |
| storageclasses | sc |
| thirdpartyresources | / |
在命令中也可以同时对多个资源对象进行操作,比如要获取多个 Pod 的信息:kubectl get pods pod1 pod2,获取多种对象的信息:kubectl get pod/pod1 rs/rs1,还可以同时应用多个 YAML 文件:kubectl create -f pod.yaml -f rc.yaml -f service.yaml。
这里我们列出对于 Pod、和 Service 资源对象常用的操作作为说明:
与 Pod 相关的常用操作
kubectl logs:打印 Pod 中容器的日志输出。如果 Pod 只有一个容器可以直接使用命令kubectl logs mypod,当 Pod 有多个容器的时候需要指定容器kubectl logs mypod container1。kubectl attach:连接到 Pod 中启动的容器。如果不指定容器就选择 Pod 的第一个容器kubectl attach mypod,也可以指定某个特定的容器kubectl attach mypod container1。kubectl exec:用于在 Pod 容器中执行命令。同样的也是如果不指定容器就选择 Pod 的第一个容器kubectl exec mypod -- date,也可以指定某个特定的容器kubectl exec mypod container1 -- date。kubectl port-forward:为 Pod 设置端口转发。可以在本机指定监听端口,访问本机端口的请求就会被转发到 Pod 容器对应的端口上,比如指定本机的 443 端口转发到容器的 80 端口kubectl port-forward mypod 443:80。
与 Service 相关的常用操作
kubectl expose:用于创建 Service。创建的时候需要指定 Pod、Replicasets 或者 Service,从中提取 Lable 来为新建的 Service 配置标签选择器,比如kubectl expose service nginx --port=443 --target-port=8443 --name=nginx-https。
3.5 kubectl 子命令详解
kubectl 的子命令主要包括了对资源对象的创建、删除、查看、修改、配置、运行等操作,具体如下所示:
annotate: 添加或更新资源对象的 annotation 信息。api-versions: 列出当前系统支持的 API 版本列表,格式为 “group/version”。apply: 从配置文件或 stdin 中对资源对象进行配置更新。attach: 附着到一个正在运行的容器上。auth: 检测 RBAC 权限设置。autoscale: 对 Deployment/ReplicaSet/ReplicationController 进行水平自动扩容和缩容的设置。cluster-info: 显示集群 Master 和内置服务的信息。completion: 输出 shell 命令的执行结果码。config: 修改 kubeconfig 文件。convert: 转换配置文件为不同的 API 版本。cordon: 将 Node 标记为不可调用,也就是“隔离”出集群调度范围。create: 从配置文件或 stdin 中创建资源对象。delete: 根据配置文件、stdin、资源名称或标签选择器删除资源对象。describe: 描述一个或多个资源对象的详细信息。diff: 查看配置文件与当前系统中正在运行的资源对象的差异。drain: 首先将 Node 设置为不可调用,然后删除在该 Node 上运行的所有 Pod,但是不会删除不由 API Server 管理的 Pod。edit: 编辑资源对象的属性,在线更新。exec: 执行一个容器中的命令。explain: 对资源对象属性的详细说明。expose: 将一个已经存在的 RC、Service、Deployment 或 Pod 暴露为一个新的 Service。get: 显示一个或多个资源对象的概要信息。label: 设置或更新资源对象的 labels。logs: 在屏幕上打印一个容器的日志。patch: 以 merge 形式对资源对象的部分字段的值进行修改。plugin: 在 kubectl 命令行使用用户自定义的插件。port-forward: 将本机的某个端口映射到 Pod 的端口号,通常用于测试。proxy: 将本机某个端口号映射到 API Server。replace: 从配置文件或 stdin 替换资源对象。rolling-update: 对 RC 进行滚动升级。rollout: 对 Deployment 进行管理,可用操作包括:history、pause、resume、undo、status。run: 基于一个镜像在 Kubernetes 集群上启动一个 Deployment。scale: 扩容、缩容一个 Deployment/ReplicaSet/RC/Job 中 Pod 的数量。set: 设置资源对象的某个特定信息,目前仅支持修改容器的镜像。taint: 设置 Node 的 taint 信息,用于将特定的 Pod 调度到特定的 Node 的操作,为 Alpha 版本的功能。top: 查看 Node/Pod 的资源使用情况,需要在集群中运行 Metrics Server。uncordon: 将 Node 设置为可调用。version: 打印系统的版本信息。
kubectl 参数列表
kubectl 命令行的公共启动参数如下所示:
--alsologtostderr=false: 设置为 true 表示将日志输出到文件的同时输出到 stderr。--as='': 设置本次操作的用户名。--certificate-authority='': 用于 CA 授权的 cert 文件路径。--client-certificate='': 用于 TLS 的客户端证书文件路径。--client-kye='': 用于 TLS 的客户端 key 文件路径。--cluster='': 设置要使用的 kubeconfig 中的 cluster 名。--context='': 设置要使用的 kubeconfig 中的 context 名。--insecure-skip-tls-verify=false: 设置为 true 表示跳过 TLS 安全验证模式,会使得 HTTPS 连接不安全。--kubeconfig='': kubeconfig 配置文件路径,在配置文件中包括 Master 的地址信息以及必要的认证信息。--log-backtrace-at=:0: 记录日志每到 “file: 行号” 时打印一次 stack trace。--log-dir='': 日志文件路径。--log-flush-frequency=5s: 设置 flush 日志文件的时间间隔。--logtostderr=true: 设置为 true 表示将日志输出到 stderr,不输出到日志文件。--match-server-version: 设置为 true 表示客户端版本号需要与服务端一致。--namespace='': 设置本次操作所在的 Namespace。--password='': 设置 API Server 的 basic authentication 的密码。-s, --server='': 设置 API Server 的 URL 地址。--stderrthreshold=2: 在该 threshold 级别之上的日志输出到 stderr。--token='': 设置访问 API Server 的安全 Token。--user='': 指定用户名,这里的用户名应该在 kubeconfig 配置文件中设置过。--username='': 设置 API Server 的 basic authentication 的用户名。--v=0: glog 日志级别。--vmodule=: glog 基于模块的详细日志级别。
如果想要查看某个子命令具体的参数,可以使用 kubectl [command] --help 命令进行查看。
kubectl 输出格式
kubectl 可以通过 -o 参数设置输出结果的多种显示格式:kubectl [command] [TYPE] [NAME] -o=<output\_format>。
其中可选的输出格式有:
-o=custom-columns=<spec>: 根据自定义列名进行输出,以逗号分隔。-o=custom-columns-file=<filename>: 从文件中获取自定义列名进行输出。-o=json: 以 json 格式显示结果。-o=jsonpath=<template>: 输出 jsonpath 表达式定义的字段信息。-o=jsonpath-file=<filename>: 输出 jsonpath 表达式定义的字段信息,来源于文件。-o=name: 仅输出资源对象的名称。-o=wide: 输出额外信息。对于 Pod,将输出 Pod 所在的 Node 名称。-o=yaml: 以 YAML 格式显示结果。
其中比较常用的有:-o=json、-o=wide 以及 -o=yaml。
3.6 kubectl 操作示例
下面我们使用两个 YAML 文件来分别创建 mysql 和 sonarqube 的 Deployment 和 Pod。
新建 yamls 文件夹,在 yamls 文件夹下新建 mysql.yaml 并写入如下内容:
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysql
spec:
replicas: 1
selector:
matchLabels:
name: mysql
template:
metadata:
labels:
name: mysql
spec:
containers:
- name: mysql
image: mysql:5.7.16
ports:
- containerPort: 3306
protocol: TCP
env:
- name: MYSQL_ROOT_PASSWORD
value: "Az123456_"
在 yamls 文件夹下新建 sonar.yaml 文件并写入如下内容:
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: sonarqube
spec:
replicas: 2
selector:
matchLabels:
name: sonarqube
template:
metadata:
labels:
name: sonarqube
spec:
containers:
- name: sonarqube
image: sonarqube:5.6.5
ports:
- containerPort: 9000
protocol: TCP
用 yamls 目录下的所有 .yaml、.yml、.json 文件进行创建:
$ kubectl create -f yamls/
deployment.apps/mysql created
deployment.apps/sonarqube created
可以使用 get 命令来查看刚刚创建的 pod 和 deployment 的信息:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-7b99c6c8b7-hthbk 1/1 Running 0 2m18s
sonarqube-6988954d75-grlqm 1/1 Running 0 2m18s
sonarqube-6988954d75-n6d8w 1/1 Running 0 2m18s
# 使用 -o wide 参数获取到更加详细的信息
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-7b99c6c8b7-hthbk 1/1 Running 0 3m18s 10.20.177.102 kubesphere03 <none> <none>
sonarqube-6988954d75-grlqm 1/1 Running 0 3m18s 10.20.138.37 kubesphere02 <none> <none>
sonarqube-6988954d75-n6d8w 1/1 Running 0 3m18s 10.20.177.103 kubesphere03 <none> <none>
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
mysql 1/1 1 1 3m42s
sonarqube 2/2 2 2 3m42s
同样的,get 命令也可以查看所有 nodes 和 namespaces 的信息:
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kubesphere01 Ready master 64d v1.16.9 192.168.0.31 <none> CentOS Linux 7 (Core) 3.10.0-1127.el7.x86_64 docker://18.9.9
kubesphere02 Ready <none> 64d v1.16.9 192.168.0.32 <none> CentOS Linux 7 (Core) 3.10.0-1127.el7.x86_64 docker://18.9.9
kubesphere03 Ready <none> 64d v1.16.9 192.168.0.33 <none> CentOS Linux 7 (Core) 3.10.0-1127.el7.x86_64 docker://18.9.9
$ kubectl get namespaces
NAME STATUS AGE
default Active 64d
istio-system Active 64d
kube-node-lease Active 64d
kube-public Active 64d
kube-system Active 64d
kubesphere-alerting-system Active 64d
kubesphere-controls-system Active 64d
kubesphere-devops-system Active 64d
kubesphere-logging-system Active 64d
kubesphere-monitoring-system Active 64d
kubesphere-system Active 64d
openpitrix-system Active 64d
user-test Active 23d
使用 describe 查看 kubesphere01 节点和 mysql 容器所在 pod 的详细信息:
$ kubectl describe node kubesphere01
Name: kubesphere01
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=kubesphere01
kubernetes.io/os=linux
node-role.kubernetes.io/master=
...
$ kubectl describe pod mysql-7b99c6c8b7-hthbk
Name: mysql-7b99c6c8b7-hthbk
Namespace: user-test
Priority: 0
Node: kubesphere03/192.168.0.33
...
使用 logs 命令可以查看某个 pod 中的容器的日志:
$ kubectl logs mysql-7b99c6c8b7-hthbk
Initializing database
2020-11-02T14:30:18.990885Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2020-11-02T14:30:19.200463Z 0 [Warning] InnoDB: New log files created, LSN=45790
2020-11-02T14:30:19.232657Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
使用 exec 命令可以进入一个 pod 中的容器执行命令:
# 直接在外面执行命令
$ kubectl exec mysql-7b99c6c8b7-hthbk hostname
mysql-7b99c6c8b7-hthbk
# 登录到容器内部执行命令
$ kubectl exec -it mysql-7b99c6c8b7-hthbk /bin/bash
root@mysql-7b99c6c8b7-hthbk:/# hostname
mysql-7b99c6c8b7-hthbk
root@mysql-7b99c6c8b7-hthbk:/#
cp 命令可用于 pod 和外部进行文件交换,如下所示:
# 在 pod 中创建一个文件 message.log
$ kubectl exec -it mysql-7b99c6c8b7-hthbk /bin/bash
root@mysql-7b99c6c8b7-hthbk:/# pwd
/
root@mysql-7b99c6c8b7-hthbk:/# cd /tmp
root@mysql-7b99c6c8b7-hthbk:/tmp# ls
root@mysql-7b99c6c8b7-hthbk:/tmp# echo "this is a message from `hostname`" > message.log
root@mysql-7b99c6c8b7-hthbk:/tmp# cat message.log
this is a message from mysql-7b99c6c8b7-hthbk
root@mysql-7b99c6c8b7-hthbk:/tmp# exit
exit
# 将文件拷贝出来并进行查看
$ kubectl cp mysql-7b99c6c8b7-hthbk:/tmp/message.log message.log
tar: Removing leading `/' from member names
$ cat message.log
this is a message from mysql-7b99c6c8b7-hthbk
# 修改 message.log 文件内容并将其拷贝回 pod
$ echo "information added in `hostname`" >> message.log
$ cat message.log
this is a message from mysql-7b99c6c8b7-hthbk
information added in kubesphere01
$ kubectl cp message.log mysql-7b99c6c8b7-hthbk:/tmp/message.log
# 查看 pod 中的文件内容是否修改
$ kubectl exec mysql-7b99c6c8b7-hthbk cat /tmp/message.log
this is a message from mysql-7b99c6c8b7-hthbk
information added in kubesphere01
attach 命令可用于获取 pod 一些实时的类似于 kubectl logs 的信息:
$ kubectl attach sonarqube-6988954d75-grlqm
Defaulting container name to sonarqube.
Use 'kubectl describe pod/sonarqube-6988954d75-grlqm -n default' to see all of the containers in this pod.
If you don't see a command prompt, try pressing enter.
cluster-info 可以获取到集群的基本信息,如果想要查看整个集群的全部信息可以使用 cluster-info dump:
$ kubectl cluster-info
Kubernetes master is running at https://192.168.0.31:6443
KubeDNS is running at https://192.168.0.31:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
$ kubectl cluster-info dump > dump.out
最后,当我们执行完所有操作想要删除创建的资源时可以使用 delete 命令:
$ kubectl delete -f yamls/
deployment.apps "mysql" deleted
deployment.apps "sonarqube" deleted
$ kubectl get pods
No resources found in user-test namespace.
$ kubectl get deployments
No resources found in user-test namespace.
评论区