基本概念
容器化 + Kubernetes
逐渐成为云计算领域计算资源编排调度管理的事实标准,而 kubectl
则提供了一种非常直观和强大的观察操控 k8s集群的方式。
kubectl 是 kubernetes自带的 21 个命令行程序中的一个,其本身的逻辑并不复杂,使用 cobra 来解析命令行参数,读取 .kube/config
中存储的认证信息经由 k8s restful api
和集群交互。
kubectl 命令基本格式如下:
kubectl [子命令] [资源类型] [资源名称] [选项]
和 docker
、git
这种复杂的命令行程序一样,kubectl
也采用了命令下再分子命令的形式,子命令声明了要执行的动作,如:增删改查,当然 kubeclt 能做的远不止这四个动作,下文会简单介绍一下它们分别都能干什么。
确定了动作之后还需要声明这个动作的对象,在 k8s 中通过资源类型 + 资源名称
唯一确定一个资源。
最后这一部分用于声明命令选项,包括子命令独有的以及 kubectl
全局的一些选项。
子命令
kubectl
将所有的子命令分为了 7 个大类,共 41 条:
基本命令
命令 | 简述 | 实例 |
---|---|---|
create | 创建资源 | kubectl create namespace hello-world |
expose | 将 replica set、deployment 等通过 service 暴露出来供外部访问 | kubectl expose deploy nginx --type=NodePort --port=80 |
run | 快速创建一个deployment来运行镜像 | kubectl run nginx --image=nginx |
set | edit 的简化版,用于快速修改资源的环境变量、镜像、账号等 | |
explain | 查看某个 api 的语法结构,用于编写yaml时参考都有哪些字段 | 查看Service的yaml语法:kubectl explain pod |
get | 查看资源 | kubectl get pod -A |
edit | 编辑资源 | kubectl edit services ${SvcName} |
delete | 删除资源 | kubectl delte namespace hello-word |
部署命令
命令 | 简述 | 实例 |
---|---|---|
rollout | 对资源进行发布管理:暂停发布、回滚、重启、查看状态、查看历史记录等 | 查看deployment发布状态:kubectl rollout status deployment/nginx |
scale | 手动调整容量 | |
autoscale | 会创建一个 HorizontalPodAutoscaler(HPA) 来帮助 deployment 自动扩缩容 | 自动扩缩容,最多5个,阈值CPU使用80%:kubectl autoscale deployment ${DeployName} --max=5 --cpu-percent=80 |
集群管理
命令 | 简述 | 实例 |
---|---|---|
certificate | 通过集群CA根证书签发或者拒绝其他证书签发请求(CSR) | 1. 通过 k get certificatesigningrequest -A 查看签发请求2. 签署:kubectl certificate approve csr-xxx |
cluster-info | 查看master、dashboard、core-dns地址等集群信息 | |
top | 像本地的 top 命令一样,可以查看机器或者实例的CPU、内存等资源占用 | # 查看所有节点的内存、CPU占用情况kubectl top node |
cordon | 将一台节点设为不可调度,不再接受新实例的创建(老的实例不受影响),比如:cordon master 节点来保证集群稳定性 | kubectl cordon $NodeName |
uncordon | 允许调度 | kubectl uncordon $NodeName |
drain | 驱逐Node上的所有实例并拒绝新实例调度,常用于临时维护、升级或者机器下线等场景;drain 了一个机器之后,通过 uncordon 来恢复 |
kubectl drain node-name-xxx --force |
taint | 配合 toleration 可以设置实例对于节点的亲和性,实现:一组实例全部分配、不分配或者优先分配到特定的节点上 | kubectl taint nodes $NodeName dedicated=special-user:NoSchedule |
问题排查
命令 | 简述 | 实例 |
---|---|---|
describe | 查看指定资源的详细信息 | 查看一个Pod的详细信息:kubectl describe pod pod-name-xxx |
logs | 查看一个或者一组容器的日志(标准输出) | 查看一个Pod的实时日志:kubectl logs -f pod-name-xxx |
attach | 和 docker 中的 attach 一样,用于连接到一个正在运行中的容器,由于一个实例内可能存在多个容器,未指定时默认进去第一个容器 | 进入一个运行中的实例打开shell调试:kubectl attach ${PodName} -i -t |
exec | 也和 docker 中的 exec 一样,在容器中运行一个命令 | 查看容器时间:kubectl exec ${PodName} "date" |
port-forward | 端口转发,映射无法直接访问的集群内部服务端口到本地 | 转发服务80端口到本地6789:kubectl port-forward svc/${MySvc} 6789:80 |
proxy | 创建一个本地的 k8s apiserver 代理,这样调试的时候无需配置证书就能直接访问api server | 代理apiserver到本地6789端口:kubectl proxy --port= 6789 |
cp | 复制文件 | 复制本地文件到指定实例内:kubectl cp /tmp/local.txt <some-pod>:/tmp/remote.txt |
auth | 校验是否有权限 | 判断当前sa是否有删除Pod的权限:k auth can-i delete pod |
高级命令
命令 | 简述 | 实例 |
---|---|---|
diff | 指定一个 manifest 判断它相较于当前线上版本有何差异 | |
apply | 应用生效配置文件,用于发布新资源,可以理解为 create 的高级加强版 | kubectl apply -f deploy.yaml |
patch | edit 命令的高级版,增加一部分参数到配置文件上 | kubectl patch node ${NodeName} -p '{"spec":{"unschedulable":true}}' |
replace | 替换配置文件 | |
wait | 阻塞等待直至事件完成,比如:等待一个Pod的删除或者就绪 | 等待Pod就绪,30秒超时:kubectl wait --for=condition=Ready pod/${PodName} --timeout=30s |
convert | 配置文件格式转换 | 把配置文件由yaml的格式转成json:kubectl convert -f pod.yaml --local -o json |
kustomize | 定制化 k8s 配置方式的拓展 |
配置命令
命令 | 简述 | 实例 |
---|---|---|
label | 修改资源的标签 | |
annotate | 增加注解,位于:meta-annotations 字段下方 | kubectl annotate pod ${PodName} description="Hello World" |
completion | 导出 shell 自动补全的示例 | 参见下方常用操作 |
其他命令
命令 | 简述 | 实例 |
---|---|---|
api-resources | 查看所有支持的资源类型,包括自定义的 crd | kubectl api-resources |
api-versions | 查看 k8s 集群所有支持的 api 版本(k8s rest api 中的请求路径) | kubectl api-versions |
config | 修改操作kubeconfig配置文件的简便方式,可以用于修改默认namespace,修改默认集群之类的 | |
plugin | kubectl 插件管理 | 查看所有安装的kubectl插件:kubectl plugin list |
version | 查看 kubectl 和服务端的版本 | kubectl version --short |
主要资源
在用 kubectl 操作资源时,可以直接使用其缩写来简化命令, 当前集群支持的所有资源可以通过命令kubectl api-resources
查看,常见资源如下:
名称 | 缩写 | 说明 |
---|---|---|
events | ev | 实时事件日志 |
namespaces | ns | 命名空间,隔离不同的资源 |
nodes | no | 节点(对应一台机器) |
pods | po | 实例(一个或者一组容器) |
services | svc | 服务(一组实例的抽象) |
deployments | deploy | 部署 |
replicasets | rs | 实例副本集 |
ingresses | ing | 负载均衡配置 |
jobs | 短任务 | |
serviceaccounts | sa | 账号 |
cronjobs | cj | 定时任务 |
常用操作
查看一个 deployment 所有实例的实时日志
kubectl logs
命令指定资源类型和其他的命令还不一样,因为可以不传类型只传实例名称,一个实例有可能就是叫:“deployment”,所以类型和名称要通过 /
符号连接而不是空格,通过 -f
参数流式实时查看:
kubectl logs -f deployment/${deployment.name}
kubectl 获取所有实例
对于大部分的资源,默认都只会获取指定命名空间下的资源,不过可以添加 -A 参数来获取所有命名空间下的资源。
kubectl get pods -A
kubectl 自动补全
自动补全能极大的提高我们的输入效率,脑补一下像操作一个本地文件时文件名的自动补全能应用到 pod、service 名上时会多么的方便。
# BASH
source <(kubectl completion bash)
# ZSH
source <(kubectl completion zsh)
# 如果想要每次打开shell都生效的话,加入对应shell的初始化文件即可
为 kubectl 命令设置别名
kubectl 这个命令每次都要敲7个字符,虽然有自动补全但是会和其他的 kubeXXX 组件冲突,这个时候我们可以设置一个别名来提升 kubectl 这种高频命令的效率,在 .bashrc 或者 .zshrc 等shell初始化文件中加入:
alias k=kubectl
设置默认 namespace
有两种方式可以设置默认的 namespace 来免去每次都要敲 -n xxx 的繁琐:
方式一:
kubectl config set-context --current --namespace=${NAMESPACE}
方式二:
直接修改 kubectl 的配置文件:
vi ~/.kube/config
然后修改当前Context下的namespace字段:
修改kubectl配置文件位置
kubectl 默认会读取当前用户HOME目录下的:.kube/config
作为配置文件,不过也可以通过
- 添加
KUBECONFIG=${FILE_PATH}
环境变量 - 运行时添加
-kubeconfig=${FILE_PATH}
参数
这两种方式来从其他文件中读取。
重启deployment、daemonset
我们可以直接使用 rollout restart
命令来实现重启:
kubectl rollout restart deployment ${DeploymentName}
或者也可以修改配置文件中无关紧要的一些参数来让资源重新发布。
重启 Pod
如果要重启一个 deployment
下托管的 pod,直接删除即可,replica-set controller
会再拉起来一个同样的 pod;
如果是无人托管的野实例,可以通过 replace 命令来删掉原有pod再拉起来一个同样配置的 pod 来实现重启:
kubectl get pod ${PodName} -o yaml | kubectl replace --force -f -
Pod批量执行命令
exec
子命令可以帮助我们在 pod 上执行命令,但是只支持一个实例的执行,我们可以 get
到所有的 pod 之后通过 jsonpath
取出 pod 名称,然后通过 shell for 循环来实现这个操作,比如:查看当前 namespace
下所有实例上的时间:
for a in $(k get pod -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'); kubectl exec $a "date"