本文先理清 kubectl 操作资源对象的三种方式及其背后的差异(命令式与声明式、replace 与 apply),再按使用场景汇总常用命令示例:查看集群与 API 信息、资源对象的增删查改、查看日志、进入容器执行命令以及统计资源占用。
1. kubectl 的三种操作方式 kubectl 的核心功能在于通过 API Server 操作 Kubernetes 的各种资源对象,操作方式有三种:直接命令、命令式对象配置、声明式对象配置。
直接命令 直接通过 kubectl 命令及相关的选项创建资源对象的方式,即为直接命令式操作:
1 2 3 4 5 6 7 [root@k8s01 ~]# kubectl run nginx-deploy --image=nginx:1.12 --replicas=2 Flag --replicas has been deprecated, has no effect and will be removed in the future. [root@k8s01 ~]# kubectl expose deployment/nginx --name=nginx-svc --port=80
命令式对象配置 也可以根据资源清单创建资源对象,即命令式对象配置文件。假设存在定义了 Deployment 对象的 nginx-deploy.yaml 文件,和定义了 Service 对象的 nginx-svc.yaml 文件:
1 kubectl create -f nginx-deploy.yaml -f nginx-svc.yaml
声明式对象配置 还可以把怎么改交由 kubectl 自行确定,用户只需要声明期望的状态,即为声明式对象配置:
1 kubectl apply -f nginx-deploy.yaml -f nginx-svc.yaml
replace 与 apply 的区别 可以简单地理解为,kubectl replace 的执行过程,是使用新的 YAML 文件中的 API 对象,替换原有的 API 对象;而 kubectl apply,则是执行了一个对原有 API 对象的 PATCH 操作。
kube-apiserver 在响应命令式请求(比如 kubectl replace)的时候,一次只能处理一个写请求,否则会有产生冲突的可能。而对于声明式请求(比如 kubectl apply),一次能处理多个写操作,并且具备 Merge 能力。
声明式 API 的价值:以 Istio 的 sidecar 注入为例 上面所说的 Merge 能力并不只是省事,它是很多扩展能力的前提。
Istio 是一个基于 Kubernetes 项目的微服务治理框架,它的架构非常清晰。Istio 最根本的组件,是运行在每一个应用 Pod 里的 Envoy 容器(高性能 C++ 网络代理)。Istio 项目的核心,就是由无数个运行在应用 Pod 中的 Envoy 容器组成的服务代理网格。
Istio 项目把这个代理服务以 sidecar 容器的方式,运行在了每一个被治理的应用 Pod 中。Pod 里的所有容器都共享同一个 Network Namespace,所以 Envoy 容器就能够通过配置 Pod 里的 iptables 规则,把整个 Pod 的进出流量接管下来。这样,Istio 的控制层(Control Plane)里的 Pilot 组件,就能够通过调用每个 Envoy 容器的 API,对这个 Envoy 代理进行配置,从而实现微服务治理。
假设架构图左边的 Pod 是已经在运行的应用,而右边的 Pod 则是刚刚上线的应用的新版本。这时候,Pilot 通过调节这两个 Pod 里 Envoy 容器的配置,从而将 90% 的流量分配给旧版本的应用,将 10% 的流量分配给新版本应用,并且还可以在后续的过程中随时调整。这样,一个典型的「灰度发布」的场景就完成了。比如 Istio 可以调节这个流量从 90%-10% 改到 80%-20%,再到 50%-50%,最后到 0%-100%,就完成了这个灰度发布的过程。
Istio 项目使用的,是 Kubernetes 中的一个非常重要的功能,叫作 Dynamic Admission Control(也叫做 Initializer)。
用户提交的原始 pod.yaml 里并没有 Envoy:
1 2 3 4 5 6 7 8 9 10 11 apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh' , '-c' , 'echo Hello Kubernetes! && sleep 3600' ]
注入 envoy 容器后变成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh' , '-c' , 'echo Hello Kubernetes! && sleep 3600' ] - name: envoy image: lyft/envoy:845747b88f102c0fd262ab234308e9e22f693a1 command: ["/usr/local/bin/envoy" ]
Istio 要做的,就是编写一个用来为 Pod 自动注入 Envoy 容器的 Initializer。Initializer 要做的工作,就是把这部分 Envoy 相关的字段,自动添加到用户提交的 Pod 的 API 对象里。可是用户提交的 Pod 里本来就有 containers 字段和 volumes 字段,所以 Kubernetes 在处理这样的更新请求时,就必须使用类似于 git merge 这样的操作,才能将这两部分内容合并在一起,而这正是声明式 API 最主要的能力。
2. 常用命令示例 获取集群相关信息 1 2 3 4 5 6 7 8 9 10 11 12 13 [root@centos01 ~]# kubectl version --short=true Client Version: v1.18.6 Server Version: v1.18.0 [root@centos01 ~]# kubectl cluster-info Kubernetes master is running at https://192.168.43.25:6443 KubeDNS is running at https://192.168.43.25:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump' . [root@centos01 ~]# kubectl cluster-info dump > ./k8s.log
查看 API 资源与版本 kubectl api-resources 列出当前集群支持的资源类型、简称与所属 API 组,kubectl api-versions 只列出 API 组与版本,写资源清单时用它确认 apiVersion 该怎么填。
⚠️ 注:以下为约 k8s 1.20 集群的 api-resources/api-versions 快照,其中大量 *beta* 版本已在新版中被移除或转正,常见对应关系:batch/v1beta1(CronJob)→ batch/v1(1.25 移除 beta);rbac.authorization.k8s.io/v1beta1 → rbac.authorization.k8s.io/v1(1.22 移除);extensions/v1beta1、networking.k8s.io/v1beta1(Ingress)→ networking.k8s.io/v1(1.22 移除);policy/v1beta1 → policy/v1,其中 PodSecurityPolicy 已于 1.25 整体移除;autoscaling/v2beta1、autoscaling/v2beta2 → autoscaling/v2;discovery.k8s.io/v1beta1 → discovery.k8s.io/v1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 [root@k8s01 ~]# kubectl api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 true Binding componentstatuses cs v1 false ComponentStatus configmaps cm v1 true ConfigMap endpoints ep v1 true Endpoints events ev v1 true Event limitranges limits v1 true LimitRange namespaces ns v1 false Namespace nodes no v1 false Node persistentvolumeclaims pvc v1 true PersistentVolumeClaim persistentvolumes pv v1 false PersistentVolume pods po v1 true Pod podtemplates v1 true PodTemplate replicationcontrollers rc v1 true ReplicationController resourcequotas quota v1 true ResourceQuota secrets v1 true Secret serviceaccounts sa v1 true ServiceAccount services svc v1 true Service mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition apiservices apiregistration.k8s.io/v1 false APIService controllerrevisions apps/v1 true ControllerRevision daemonsets ds apps/v1 true DaemonSet deployments deploy apps/v1 true Deployment replicasets rs apps/v1 true ReplicaSet statefulsets sts apps/v1 true StatefulSet tokenreviews authentication.k8s.io/v1 false TokenReview localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview horizontalpodautoscalers hpa autoscaling/v1 true HorizontalPodAutoscaler cronjobs cj batch/v1beta1 true CronJob jobs batch/v1 true Jobcertificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest leases coordination.k8s.io/v1 true Lease bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration bgppeers crd.projectcalico.org/v1 false BGPPeer blockaffinities crd.projectcalico.org/v1 false BlockAffinity clusterinformations crd.projectcalico.org/v1 false ClusterInformation felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration globalnetworkpolicies gnp crd.projectcalico.org/v1 false GlobalNetworkPolicy globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet hostendpoints crd.projectcalico.org/v1 false HostEndpoint ipamblocks crd.projectcalico.org/v1 false IPAMBlock ipamconfigs crd.projectcalico.org/v1 false IPAMConfig ipamhandles crd.projectcalico.org/v1 false IPAMHandle ippools crd.projectcalico.org/v1 false IPPool kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration networkpolicies crd.projectcalico.org/v1 true NetworkPolicy networksets crd.projectcalico.org/v1 true NetworkSet endpointslices discovery.k8s.io/v1beta1 true EndpointSlice events ev events.k8s.io/v1 true Event ingresses ing extensions/v1beta1 true Ingress flowschemas flowcontrol.apiserver.k8s.io/v1beta1 false FlowSchema prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta1 false PriorityLevelConfiguration nodes metrics.k8s.io/v1beta1 false NodeMetrics pods metrics.k8s.io/v1beta1 true PodMetrics alertmanagerconfigs monitoring.coreos.com/v1alpha1 true AlertmanagerConfig alertmanagers monitoring.coreos.com/v1 true Alertmanager podmonitors monitoring.coreos.com/v1 true PodMonitor probes monitoring.coreos.com/v1 true Probe prometheuses monitoring.coreos.com/v1 true Prometheus prometheusrules monitoring.coreos.com/v1 true PrometheusRule servicemonitors monitoring.coreos.com/v1 true ServiceMonitor thanosrulers monitoring.coreos.com/v1 true ThanosRuler ingressclasses networking.k8s.io/v1 false IngressClass ingresses ing networking.k8s.io/v1 true Ingress networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy runtimeclasses node.k8s.io/v1 false RuntimeClass poddisruptionbudgets pdb policy/v1beta1 true PodDisruptionBudget podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding clusterroles rbac.authorization.k8s.io/v1 false ClusterRole rolebindings rbac.authorization.k8s.io/v1 true RoleBinding roles rbac.authorization.k8s.io/v1 true Role priorityclasses pc scheduling.k8s.io/v1 false PriorityClass csidrivers storage.k8s.io/v1 false CSIDriver csinodes storage.k8s.io/v1 false CSINode storageclasses sc storage.k8s.io/v1 false StorageClass volumeattachments storage.k8s.io/v1 false VolumeAttachment [root@k8s01 ~]# kubectl api-versions admissionregistration.k8s.io/v1 admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 authentication.k8s.io/v1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1 authorization.k8s.io/v1beta1 autoscaling/v1 autoscaling/v2beta1 autoscaling/v2beta2 batch/v1 batch/v1beta1 certificates.k8s.io/v1 certificates.k8s.io/v1beta1 coordination.k8s.io/v1 coordination.k8s.io/v1beta1 crd.projectcalico.org/v1 discovery.k8s.io/v1beta1 events.k8s.io/v1 events.k8s.io/v1beta1 extensions/v1beta1 flowcontrol.apiserver.k8s.io/v1beta1 metrics.k8s.io/v1beta1 monitoring.coreos.com/v1 monitoring.coreos.com/v1alpha1 networking.k8s.io/v1 networking.k8s.io/v1beta1 node.k8s.io/v1 node.k8s.io/v1beta1 policy/v1beta1 rbac.authorization.k8s.io/v1 rbac.authorization.k8s.io/v1beta1 scheduling.k8s.io/v1 scheduling.k8s.io/v1beta1 storage.k8s.io/v1 storage.k8s.io/v1beta1 v1
创建资源对象 创建资源对象常用四个子命令,分别对应上面讲过的三种操作方式:kubectl run、kubectl expose 属于直接命令,kubectl create 为命令式对象配置,kubectl apply 为声明式对象配置。
直接命令还可以顺手指定 Service 类型:
1 kubectl expose pod httpd-app --type ='NodePort' --port 80
不确定要不要真的执行、或者想拿一份清单模板时,加上 --dry-run=client:
1 2 3 4 5 6 7 8 9 10 11 12 [root@k8s01 storage]# kubectl run myapp --image=nginx:1.7.9 --port=80 --dry-run=client pod/myapp created (dry run) [root@k8s01 test ]# kubectl create ns demo --dry-run=client -o yaml > demo-ns.yaml [root@k8s01 test ]# cat demo-ns.yaml apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: demo spec: {} status: {}
查看资源对象 kubectl get 可分类列出资源对象及其相关的状态信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@k8s01 ~]# kubectl get namespaces NAME STATUS AGE default Active 20m kube-node-lease Active 20m kube-public Active 20m kube-system Active 20m [root@k8s01 ~]# kubectl get pods,services -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/nginx-deploy 1/1 Running 0 8m49s 172.18.236.129 k8s02 <none> <none> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30m <none> service/nginx-svc ClusterIP 10.100.63.22 <none> 80/TCP 2m11s run=nginx-deploy kubectl get pod -l app=nginx -o jsonpath={.items..metadata.name}
上面拿到的 Pod IP 与 ClusterIP,在 k8s 集群上任一节点均可访问:
1 curl 172.18.236.129 && curl 10.100.63.22
日常用得最多的还是各类资源的简写查询:
1 2 3 4 5 6 7 kubectl get deployments kubectl get svc kubectl get rs kubectl get pod kubectl get node kubectl get cm kubectl get secret
Pod 较多时可以按时间排序,方便找出最近重建的实例:
1 2 kubectl get pod --sort-by=.status.startTime kubectl get pod --sort-by=.metadata.creationTimestamp
打印资源对象的详细信息 每个资源对象都包含着用户期望的状态(Spec)和现有的实际状态(Status)两种状态信息,kubectl get -o {yaml|json} 或 kubectl describe 命令都能够打印出指定资源对象的详细描述信息。
1 2 3 4 5 kubectl get pods -l component=kube-apiserver -o yaml -n kube-system kubectl describe pods -l component=kube-apiserver -n kube-system
打印容器中的日志信息 通常一个容器中仅会运行一个进程(及其子进程),此进程作为 PID 为 1 的进程接收并处理管理信息,同时将日志直接输出至终端中,而无须再像传统的多进程系统环境那样将日志保存于文件中,因此容器日志信息的获取一般要到其控制台上进行。
kubectl logs 命令可打印 Pod 对象内指定容器的日志信息,命令格式为 kubectl logs [-f] [-p] (POD|TYPE/NAME) [-c CONTAINER] [options],其中 -f 为持续跟踪输出,--tail=100 只看最后 100 行:
1 2 3 4 5 6 7 8 9 kubectl logs kube-apiserver-k8s01 -n kube-system kubectl logs -f kube-apiserver-k8s01 -n kube-system kubectl logs --tail =100 -f kube-apiserver-k8s01 -n kube-system kubectl logs --tail =100 -n rook-ceph rook-ceph-operator-6f7f6b96d-vqx5c > /tmp/rook-ceph-operator.log
在容器中执行命令 kubectl exec 命令用于在指定的容器内运行其他应用程序:
1 2 kubectl exec kube-apiserver-k8s01 -n kube-system -- ps
若 Pod 对象中存在多个容器,则需要以 -c 选项指定容器后再运行。
删除资源对象 kubectl delete 用于删除资源对象。注意对于受控于控制器的对象来说,删除之后其控制器可能会重建出类似的对象:
1 2 3 4 5 6 7 8 9 10 11 12 kubectl delete services nginx-svc kubectl delete pods -l app=monitor -n kube-system kubectl delete pods services -l ver=3.1.1,app=monitor --all-namespaces kubectl delete pods --all -n default
有些资源类型(如 Pod)支持优雅删除的机制,它们有着默认的删除宽限期,不过用户可以在命令中使用 --grace-period 选项或 --now 选项来覆盖默认的宽限期。
查看资源占用情况 需要先安装 metrics-server:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [root@test-173 ~]# kubectl top pod -n kube-system NAME CPU(cores) MEMORY(bytes) calico-kube-controllers-d8d4d9587-cbsn6 7m 17Mi calico-node-dt2bh 46m 35Mi calico-node-fgwkj 43m 23Mi calico-node-fj8gp 58m 22Mi calico-node-tth8k 30m 22Mi coredns-59c8bd8884-pcnbt 9m 16Mi coredns-59c8bd8884-xqnnj 10m 14Mi heapster-7d7fc6648b-kkd9q 1m 17Mi kubernetes-dashboard-96f697bc5-w942c 0m 8Mi metrics-server-67cb878c78-8q7jq 3m 20Mi nginx-ingress-controller-kfht8 14m 77Mi nginx-ingress-controller-rr7tn 9m 80Mi nginx-ingress-controller-wfnmx 10m 77Mi nginx-ingress-controller-whcqg 6m 84Mi nginx-ingress-default-backend-58c5c69f7c-mhr2m 0m 3Mi tiller-deploy-7bb9858659-w84j9 0m 19Mi [root@test-173 ~]# kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% 172.20.40.107 513m 3% 5713Mi 40% 172.20.40.173 915m 2% 13955Mi 46% 172.20.40.196 571m 3% 4313Mi 30% 172.20.40.249 282m 1% 5512Mi 38%