本文將介紹 k8s 中的一些最基本的命令盅弛,并輔以解釋一些基本概念來方便理解钱骂,也就是說,本文是一篇偏向?qū)嵱眯远菍W(xué)術(shù)性的文章挪鹏,如果你想提前了解一下 k8s 相關(guān)的知識的話见秽,可以通過以下鏈接進(jìn)行學(xué)習(xí):
結(jié)構(gòu)模型
k8s 是經(jīng)典的一對多模型,有一個主要的管理節(jié)點(diǎn)master
和許多的工作節(jié)點(diǎn)slaver
讨盒。當(dāng)然解取,k8s 也可以配置多個管理節(jié)點(diǎn),擁有兩個以上的管理節(jié)點(diǎn)被稱為 高可用返顺。k8s 包括了許多的組件禀苦,每個組件都是單運(yùn)行在一個docker
容器中蔓肯,然后通過自己規(guī)劃的虛擬網(wǎng)絡(luò)相互訪問。你可以通過kubectl get pod -n kube-system
查看所有節(jié)點(diǎn)上的組件容器伦忠。
在管理節(jié)點(diǎn)中會比工作節(jié)點(diǎn)運(yùn)行更多的 k8s 組件省核,我們就是靠著這些多出來的組件來對工作節(jié)點(diǎn)發(fā)號施令稿辙。他們都叫什么這里就不詳細(xì)提了昆码。反正對于”基本使用“來說,這些名字并不重要邻储。
理念
要想理解一個東西就要先明白它的內(nèi)在理念赋咽。通俗點(diǎn)就是,k8s 做了什么吨娜?為了提供更加可靠的服務(wù)脓匿,就要增加服務(wù)器的數(shù)量,減少每個服務(wù)器的體量來平攤負(fù)載宦赠,而越來越多的虛擬機(jī)就會帶來越來越高的運(yùn)維成本陪毡。如何讓少量的運(yùn)維人員就可以管理數(shù)量眾多的服務(wù)器及其上的服務(wù)呢?這就是 k8s 做的工作勾扭。
k8s 把數(shù)量眾多的服務(wù)器重新抽象為一個統(tǒng)一的資源池毡琉,對于運(yùn)維人員來說,他們面前沒有服務(wù)器1妙色、服務(wù)器2的概念桅滋,而是一個統(tǒng)一的資源池,增加新的服務(wù)器對運(yùn)維人員來說身辨,只是增加自資源池的可用量丐谋。不僅如此,k8s 把所有能用的東西都抽象成了資源的概念煌珊,從而提供了一套更統(tǒng)一号俐,更簡潔的管理方式。
接下來定庵,我會把每個基本命令當(dāng)做一節(jié)來進(jìn)行介紹吏饿,并輔以介紹一些基本概念。本文介紹的命令涵蓋了增刪改查四方面洗贰,可參加下面表格找岖,因為篇幅較長,我們將create
及之后的不那么常用的命令放在下一篇文章 k8s 基本使用(下) 里講:
命令名 | 類型 | 作用 |
---|---|---|
get |
查 | 列出某個類型的下屬資源 |
describe |
查 | 查看某個資源的詳細(xì)信息 |
logs |
查 | 查看某個 pod 的日志 |
create |
增 | 新建資源 |
explain |
查 | 查看某個資源的配置項 |
delete |
刪 | 刪除某個資源 |
edit |
改 | 修改某個資源的配置項 |
apply |
改 | 應(yīng)用某個資源的配置項 |
kubectl get 列出資源敛滋!
接下來進(jìn)入正題许布,首先來了解一下 k8s 中最最最常用的命令kubectl get
,要記住绎晃,k8s 把所有的東西都抽象成了資源蜜唾,而kubectl get
就是用來查看這些資源的杂曲。最常見的資源就是 pod 。
什么是 pod袁余?
pod
(豆莢)擎勘。 pod 的概念其實和docker
中的容器非常相似。他是 k8s 中的最小工作單位颖榜。你可以把 pod 理解成一個一個的小機(jī)器人棚饵,而 k8s 抽象出來的大資源池就是他們的工廠。
pod
和docker
容器的關(guān)系掩完?pod 將一個或多個
docker
容器封裝成一個統(tǒng)一的整體進(jìn)行管理并對外提供服務(wù)噪漾。
不僅我們自己的服務(wù)是要包裝成 pod 的,就連 k8s 自己也是運(yùn)行在一堆 pod 上且蓬。接下來就讓我們查看一下 k8s 的 pod :
kubectl get pod -n kube-system
-n
參數(shù)指定了要查看哪個命名空間下的 pod 欣硼。 k8s 所有的 pod 都被放置在kube-system
命名空間下。
什么是命名空間恶阴?
命名空間
namespace
诈胜,是 k8s 中”組“的概念,提供同一服務(wù)的 pod 就應(yīng)該被放置同一命名空間下冯事,而不是混雜在一起焦匈。k8s 可以用命名空間來做權(quán)限控制。如果不指定的話桅咆, pod 將被放置在默認(rèn)的命名空間default
下括授。
執(zhí)行了kubectl get pod -n kube-system
命令后,你就可以看到如下內(nèi)容:
NAME READY STATUS RESTARTS AGE
coredns-bccdc95cf-69zrw 1/1 Running 1 4d1h
coredns-bccdc95cf-77bg4 1/1 Running 1 4d1h
etcd-master1 1/1 Running 6 4d1h
kube-apiserver-master1 1/1 Running 6 4d1h
kube-controller-manager-master1 1/1 Running 2 4d1h
kube-flannel-ds-amd64-2d6tb 1/1 Running 0 47h
kube-flannel-ds-amd64-kp5xs 1/1 Running 0 47h
kube-flannel-ds-amd64-l9728 1/1 Running 0 47h
kube-flannel-ds-amd64-r87qc 1/1 Running 0 47h
kube-proxy-2lz7f 1/1 Running 0 2d23h
kube-proxy-hqsdn 1/1 Running 4 4d1h
kube-proxy-rh92r 1/1 Running 1 4d1h
kube-proxy-tv4mt 1/1 Running 0 3d2h
kube-scheduler-master1 1/1 Running 2 4d1h
其中每一行就是一個資源岩饼,這里我們看到的資源是 pod 荚虚。你看到的 pod 數(shù)量可能和我的不一致,因為這個列表里包含了 k8s 在所有節(jié)點(diǎn)上運(yùn)行的 pod 籍茧,你加入的節(jié)點(diǎn)越多版述,那么顯示的 pod 也就越多。我們來一列一列的看:
-
NAME
:第一列是 pod 的名字寞冯,k8s 可以為 pod 隨機(jī)分配一個五位數(shù)的后綴渴析。 -
READY
:第二列是 pod 中已經(jīng)就緒的 docker 容器的數(shù)量,上文中我們提到了吮龄,pod 封裝了一個或多個 docker 容器俭茧。在這里,1/1
的含義為就緒1個容器/共計1個容器
漓帚。 -
STATUS
:第三列是 pod 的當(dāng)前狀態(tài)母债,下面是一些常見的狀態(tài):
狀態(tài)名 | 含義 |
---|---|
Running |
運(yùn)行中 |
Error |
異常,無法提供服務(wù) |
Pending |
準(zhǔn)備中,暫時無法提供服務(wù) |
Terminaling |
結(jié)束中毡们,即將被移除 |
Unknown |
未知狀態(tài)迅皇,多發(fā)生于節(jié)點(diǎn)宕機(jī) |
PullImageBackOff |
鏡像拉取失敗 |
-
RESTART
:k8s 可以自動重啟 pod,這一行就是標(biāo)記了 pod 一共重啟了多少次衙熔。 -
AGE
:pod 一共存在了多長時間登颓。
kubectl get
可以列出 k8s 中所有資源
這里只介紹了如何用kubectl
獲取 pod 的列表。但是不要把get
和pod
綁定在一起红氯,pod 只是 k8s 中的一種服務(wù)框咙,你不僅可以get pod
,還可以get svc
(查看服務(wù))脖隶、get rs
(查看副本控制器)扁耐、get deploy
(查看部署)等等等等,雖然說kubectl get pod
是最常用的一個产阱,但是如果想查看某個資源而又不知道命令是什么,kbuectl get <資源名>
就對了块仆。
如果你想看更多的信息构蹬,就可以指定-o wide
參數(shù),如下:
kubectl get pod -n kube-system -o wide
加上這個參數(shù)之后就可以看到資源的所在ip
和所在節(jié)點(diǎn)node
了悔据。
記得加上 -n
-n
可以說是kubectl get
命令使用最頻繁的參數(shù)了庄敛,在正式使用中,我們永遠(yuǎn)不會把資源發(fā)布在默認(rèn)命名空間科汗。所以藻烤,永遠(yuǎn)不要忘記在get
命令后面加上-n
。
小結(jié)
kubectl get
命令可以列出 k8s 中的資源头滔,而kubectl get pod
是非常常用的查看 pod 的命令怖亭。而-n
參數(shù)則可以指定 pod 所在的命名空間。
kubectl describe 查看詳情坤检!
kubectl describe
命令可以用來查看某一資源的具體信息兴猩,他同樣可以查看所有資源的詳情,不過最常用的還是查看 pod 的詳情早歇。他也同樣可以使用-n
參數(shù)指定資源所在的命名空間倾芝。
舉個例子,我們可以用下面命令來查看剛才 pod 列表中的某個 pod箭跳,注意不要忘記把 pod 名稱修改成自己的:
kubectl describe pod kube-flannel-ds-amd64-2d6tb -n kube-system
然后你就可以看到很多的信息晨另,咱們分開說,首先是基本屬性谱姓,你可以在詳細(xì)信息的開頭找到它:
基本屬性
# 實例名稱
Name: kube-flannel-ds-amd64-2d6tb
# 所處命名空間
Namespace: kube-system
# 所在節(jié)點(diǎn)
Node: worker2/192.168.56.22
# 啟動時間
Start Time: Wed, 03 Jul 2019 09:31:50 +0000
# 標(biāo)簽
Labels: app=flannel
controller-revision-hash=bfc6b6dd4
pod-template-generation=2
tier=node
# 注解
Annotations: <none>
# 當(dāng)前狀態(tài)
Status: Running
# 所在節(jié)點(diǎn) IP
IP: 192.168.56.22
# 由那種資源生成 / 控制
Controlled By: DaemonSet/kube-flannel-ds-amd64
其中幾個比較常用的借尿,例如Node
、labels
和Controlled By
逝段。通過Node
你可以快速定位到 pod 所處的機(jī)器垛玻,從而檢查該機(jī)器是否出現(xiàn)問題或宕機(jī)等割捅。通過labels
你可以檢索到該 pod 的大致用途及定位。而通過Controlled By
帚桩,你可以知道該 pod 是由那種 k8s 資源創(chuàng)建的亿驾,然后就可以使用kubectl get <資源名>
來繼續(xù)查找問題。例如上文DaemonSet/kube-flannel-ds-amd64
账嚎,就可以通過kubectl get DaemonSet -n kube-system
來獲取上一節(jié)資源的信息莫瞬。
內(nèi)部鏡像信息
在中間部分你可以找到像下面一樣的Containers
段落。該段落詳細(xì)的描述了 pod 中每個 docker 容器的信息郭蕉,常用的比如Image
字段疼邀,當(dāng) pod 出現(xiàn) ImagePullBackOff
錯誤的時候就可以查看該字段確認(rèn)拉取的什么鏡像。其他的字段名都很通俗召锈,直接翻譯即可旁振。
Containers:
kube-flannel:
Container ID: docker://25d2c4896847bbf53735c57a60c5b3146e2b3a0f86811074bcd28a8291213c18
Image: quay.io/coreos/flannel:v0.11.0-amd64
Image ID: docker://sha256:ff281650a721f46bbe2169292c91031c66411554739c88c861ba78475c1df894
Port: <none>
Host Port: <none>
Command:
/opt/bin/flanneld
Args:
--ip-masq
--kube-subnet-mgr
--iface=enp0s8
State: Running
Started: Wed, 03 Jul 2019 09:31:53 +0000
Ready: True
Restart Count: 0
Limits:
cpu: 100m
memory: 50Mi
Requests:
cpu: 100m
memory: 50Mi
Environment:
POD_NAME: kube-flannel-ds-amd64-2d6tb (v1:metadata.name)
POD_NAMESPACE: kube-system (v1:metadata.namespace)
Mounts:
/etc/kube-flannel/ from flannel-cfg (rw)
/run from run (rw)
/var/run/secrets/kubernetes.io/serviceaccount from flannel-token-fsqdv (ro)
事件
在describe
查看詳情的時候,最常用的信息獲取處就是這個Event
段落了涨岁,你可以在介紹內(nèi)容的末尾找到它拐袜,如下:
Events: <none>
是的,如果你看到上面這樣梢薪,沒有任何Events
的話蹬铺,就說明該 pod 一切正常。當(dāng) pod 的狀態(tài)不是Running
時秉撇,這里一定會有或多或少的問題甜攀,長得像下面一樣,然后你就可以通過其中的信息分析 pod 出現(xiàn)問題的詳細(xì)原因了:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Killing 29m kubelet, worker1 Stopping container kube-flannel
Warning FailedCreatePodSandBox 27m (x12 over 29m) kubelet, worker1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to create a sandbox for pod "kube-flannel-ds-amd64-9trbq": Error response from daemon: cgroup-parent for systemd cgroup should be a valid slice named as "xxx.slice"
Normal SandboxChanged 19m (x48 over 29m) kubelet, worker1 Pod sandbox changed, it will be killed and re-created.
Normal Pulling 42s kubelet, worker1 Pulling image "quay.io/coreos/flannel:v0.11.0-amd64"
小結(jié)
kubectl describe <資源名> <實例名>
可以查看一個資源的詳細(xì)信息琐馆,最常用的還是比如kubectl describe pod <pod名> -n <命名空間>
來獲取一個 pod 的基本信息规阀。如果出現(xiàn)問題的話,可以在獲取到的信息的末尾看到Event
段落啡捶,其中記錄著導(dǎo)致 pod 故障的原因姥敛。
kubectl logs 查看日志!
如果你想查看一個 pod 的具體日志瞎暑,就可以通過kubectl logs <pod名>
來查看彤敛。注意,這個只能查看 pod 的日志了赌。通過添加-f
參數(shù)可以持續(xù)查看日志墨榄。例如,查看kube-system
命名空間中某個flannel
pod 的日志勿她,注意修改 pod 名稱:
kubectl logs -f -n kube-system kube-flannel-ds-amd64-2d6tb
然后就可以看到如下輸出:
E0706 06:55:15.848891 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:16.948058 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:17.949165 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:18.954108 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:19.955267 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:21.046592 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:22.048285 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:23.147040 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:24.148350 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:25.247352 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:26.248831 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:27.347224 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:28.348182 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
E0706 06:55:29.350578 1 reflector.go:201] github.com/coreos/flannel/subnet/kube/kube.go:310: Failed to list *v1.Node: Get https://10.96.0.1:443/api/v1/nodes?resourceVersion=0: dial tcp 10.96.0.1:443: connect: connection refused
...
如果你發(fā)現(xiàn)某個 pod 的服務(wù)有問題袄秩,但是狀態(tài)還是顯示Running
,就可以使用kubectl logs
來查看其詳細(xì)日志。
總結(jié)
在本篇文章里之剧,我們了解了 k8s 的宗旨和一些基本概念郭卫,并知道了最為常用的get
、descibe
及logs
命令背稼,知道了這三條命令之后就幾乎可以從 k8s 中獲取所有常用信息了贰军。接下來的 k8s 基本使用(下)里,我們會更深一步蟹肘,來了解 k8s 中如何創(chuàng)建词疼、修改及刪除資源。