Kubectl 是 Kubernetes 最重要的命令行工具。在 Flant矢空,我們會在 Wiki 和 Slack 上相互分享 Kubectl 的妙用(其實我們還有個搜索引擎铁瞒,不過那就是另外一回事了)闹击。多年以來,我們在 kubectl 方面積累了很多技巧,現(xiàn)在想要將其中的部分分享給社區(qū)冯丙。
我相信很多讀者對這些命令都非常熟悉;然而我還是希望讀者能夠從本文中有所獲益遭京,進而提高生產(chǎn)力胃惜。
下列內(nèi)容有的是來自我們的工程師,還有的是來自互聯(lián)網(wǎng)哪雕。我們對后者也進行了測試船殉,并且確認其有效性。
現(xiàn)在開始吧斯嚎。
獲取 Pod 和節(jié)點
- 我猜你知道如何獲取 Kubernetes 集群中所有 Namespace 的 Pod——使用
--all-namepsaces
就可以利虫。然而不少朋友還不知道挨厚,現(xiàn)在這一開關還有了-A
的縮寫。 - 如何查找非
running
狀態(tài)的 Pod 呢糠惫?kubectl get pods -A --field-selector=status.phase!=Running | grep -v Complete
順便一說疫剃,--field-selector
是個值得深入一點的參數(shù)。 - 如何獲取節(jié)點列表及其內(nèi)存容量:
kubectl get no -o json | \
jq -r '.items | sort_by(.status.capacity.memory)[]|[.metadata.name,.status.capacity.memory]| @tsv'
- 獲取節(jié)點列表硼讽,其中包含運行在每個節(jié)點上的 Pod 數(shù)量:
kubectl get po -o json --all-namespaces | \
jq '.items | group_by(.spec.nodeName) | map({"nodeName": .[0].spec.nodeName, "count": length}) | sort_by(.count)'
- 有時候 DaemonSet 因為某種原因沒能在某個節(jié)點上啟動巢价。手動搜索會有點麻煩:
$ ns=my-namespace
$ pod_template=my-pod
$ kubectl get node | grep -v \"$(kubectl -n ${ns} get pod --all-namespaces -o wide | fgrep ${pod_template} | awk '{print $8}' | xargs -n 1 echo -n "\|" | sed 's/[[:space:]]*//g')\"
- 使用
kubectl top
獲取 Pod 列表并根據(jù)其消耗的 CPU 或 內(nèi)存進行排序:# cpu
$ kubectl top pods -A | sort --reverse --key 3 --numeric
# memory
$ kubectl top pods -A | sort --reverse --key 4 --numeric
- 獲取 Pod 列表,并根據(jù)重啟次數(shù)進行排序: kubectl get pods —sort-by=.status.containerStatuses[0].restartCount 當然也可以使用 PodStatus 以及 ContainerStatus 的其它字段進行排序固阁。
獲取其它數(shù)據(jù)
- 運行 Ingress 時壤躲,經(jīng)常要獲取 Service 對象的
selector
字段,用來查找 Pod备燃。過去要打開 Service 的清單才能完成這個任務碉克,現(xiàn)在使用-o wide
參數(shù)也可以:$ kubectl -n jaeger get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
jaeger-cassandra ClusterIP None <none> 9042/TCP 77d app=cassandracluster,cassandracluster=jaeger-cassandra,cluster=jaeger-cassandra
- 如何輸出 Pod 的
requests
和limits
:$ kubectl get pods -A -o=custom-columns='NAME:spec.containers[*].name,MEMREQ:spec.containers[*].resources.requests.memory,MEMLIM:spec.containers[*].resources.limits.memory,CPUREQ:spec.containers[*].resources.requests.cpu,CPULIM:spec.containers[*].resources.limits.cpu'
NAME MEMREQ MEMLIM CPUREQ CPULIM
coredns 70Mi 170Mi 100m <none>
coredns 70Mi 170Mi 100m <none>
...
-
kubectl run
(以及create
、apply
并齐、patch
)命令有個厲害的參數(shù)--dry-run
漏麦,該參數(shù)讓用戶無需真正操作集群就能觀察集群的行為,如果配合-o yaml
冀膝,就能輸出命令對應的 YAML:$ kubectl run test --image=grafana/grafana --dry-run -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: test
name: test
spec:
replicas: 1
selector:
matchLabels:
run: test
簡單的把輸出內(nèi)容保存到文件唁奢,刪除無用字段就可以使用了。 1.18 開始kubectl run
生成的是 Pod 而非 Deployment窝剖。 - 獲取指定資源的描述清單:
kubectl explain hpa
KIND: HorizontalPodAutoscaler
VERSION: autoscaling/v1
DESCRIPTION:
configuration of a horizontal pod autoscaler.
FIELDS:
apiVersion <string>
...
網(wǎng)絡
- 獲取集群節(jié)點的內(nèi)部 IP:
$ kubectl get nodes -o json | jq -r '.items[].status.addresses[]? | select (.type == "InternalIP") | .address' | \
paste -sd "\n" -
9.134.14.252
- 獲取所有的 Service 對象以及其
nodePort
:$ kubectl get -A svc -o json | jq -r '.items[] | [.metadata.name,([.spec.ports[].nodePort | tostring ] | join("|"))]| @tsv'
kubernetes null
...
- 在排除 CNI(例如 Flannel)故障的時候麻掸,經(jīng)常會需要檢查路由來識別故障 Pod。Pod 子網(wǎng)在這里非常有用:
$ kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}' | tr " " "\n" fix-doc-azure-container-registry-config ?
10.120.0.0/24
10.120.1.0/24
10.120.2.0/24
日志
- 使用可讀的時間格式輸出日志:
$ kubectl logs -f fluentbit-gke-qq9w9 -c fluentbit --timestamps
2020-09-10T13:10:49.822321364Z Fluent Bit v1.3.11
2020-09-10T13:10:49.822373900Z Copyright (C) Treasure Data
2020-09-10T13:10:49.822379743Z
2020-09-10T13:10:49.822383264Z [2020/09/10 13:10:49] [ info] Configuration:
- 只輸出尾部日志:
kubectl logs -f fluentbit-gke-qq9w9 -c fluentbit --tail=10
[2020/09/10 13:10:49] [ info] ___________
[2020/09/10 13:10:49] [ info] filters:
[2020/09/10 13:10:49] [ info] parser.0
...
- 輸出一個 Pod 中所有容器的日志: kubectl -n my-namespace logs -f my-pod —all-containers
- 使用標簽選擇器輸出多個 Pod 的日志: kubectl -n my-namespace logs -f -l app=nginx
- 獲取“前一個”容器的日志(例如崩潰的情況): kubectl -n my-namespace logs my-pod —previous
其它
- 把 Secret 復制到其它命名空間:
kubectl get secrets -o json --namespace namespace-old | \
jq '.items[].metadata.namespace = "namespace-new"' | \
kubectl create-f -
- 下面兩個命令可以生成一個用于測試的自簽發(fā)證書:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=grafana.mysite.ru/O=MyOrganization"
kubectl -n myapp create secret tls selfsecret --key tls.key --cert tls.crt