SSH vs.Kubectl exec
本文轉(zhuǎn)載自微信公眾號(hào)「新鈦云服」,作者祝祥 翻譯 。轉(zhuǎn)載本文請(qǐng)聯(lián)系新鈦云服公眾號(hào)。
讓我們看一下打開(kāi)遠(yuǎn)程shell的兩種流行方法:ssh與kubectl exec。
下面,我們將只看“ kubectl exec”子命令及相關(guān)的命令。kubectl本身就是所有Kubernetes的瑞士軍刀。。將所有這些與ssh進(jìn)行比較就像將systemd與BSD init進(jìn)行比較一樣。
另外,我將使用“SSH”來(lái)表示“OpenSSH”,這是SSH協(xié)議實(shí)現(xiàn)的事實(shí)標(biāo)準(zhǔn)。但大多數(shù)討論要點(diǎn)都適用于任何SSH實(shí)現(xiàn)。
Apples to Oranges
乍一看,這是一個(gè)奇怪的比較。
OpenSSH已經(jīng)存在了二十年,遠(yuǎn)遠(yuǎn)早于云技術(shù)的 誕生。它的設(shè)計(jì)是假設(shè)您要管理幾臺(tái)服務(wù)器,并正在仔細(xì)配置和調(diào)整它們的各個(gè)方面。SSH也已被用作SFTP和Ansible之類的傳輸層協(xié)議。
另一方面,kubectl誕生于云時(shí)代。它處理成千上萬(wàn)的遠(yuǎn)程機(jī)器(或容器)。kubectl exec只是其中的一小部分,用于在出現(xiàn)問(wèn)題時(shí)進(jìn)行調(diào)試。
但是,如果您如果仔細(xì)觀則會(huì)發(fā)現(xiàn):kubectl exec與ssh目的相同。它可以在遠(yuǎn)程計(jì)算機(jī)上運(yùn)行程序,而不會(huì)給您本地終端帶來(lái)麻煩,并嘗試與各種終端功能集成在一起,從而使您感覺(jué)好像已將鍵盤(pán)和顯示器插入了數(shù)據(jù)中心機(jī)架。
順便說(shuō)一句,讓我們深入探討它們的異同。
Authn/z
讓我們從每個(gè)人最喜歡的主題開(kāi)始:安全性。
TL; DR:SSH身份驗(yàn)證非常容易定制,但是大規(guī)模管理很麻煩。kubectl處理授權(quán)要好得多,但是身份驗(yàn)證通常是不透明的,很難調(diào)整。
注意:這里我們不會(huì)討論身份驗(yàn)證方法的優(yōu)缺點(diǎn),這是另外一個(gè)話題,我們下次再討論。
SSH協(xié)議
SSH支持多種身份驗(yàn)證選項(xiàng):
- 基本密碼
- 非對(duì)稱加密密鑰
- 以明文形式在磁盤(pán)上
- 在使用密碼加密的磁盤(pán)上
- 使用硬件令牌(例如YubiKey)
- 證書(shū)(但不是X.509類型)鏈接到專用CA
- 上面有用于存儲(chǔ)私鑰的所有選項(xiàng)
- 通過(guò)GSS AP或PAM的可插拔外部身份驗(yàn)證
- 例如Active Directory,LDAP,OIDC等
- 2FA
- 基于本地的硬件令牌
- 或通過(guò)PAM使用TOTP(例如Google Authenticator)或Duo等進(jìn)行關(guān)聯(lián)
要對(duì)服務(wù)器進(jìn)行身份驗(yàn)證,您可以獲得非對(duì)稱公鑰或證書(shū)。默認(rèn)情況下,SSH使用首次使用信任(TOFU),因此作為預(yù)防措施,您可能希望在客戶端計(jì)算機(jī)上管理?/.ssh/known_hosts。
作為用戶,您可以選擇所需的身份驗(yàn)證方法以及如何在兩側(cè)進(jìn)行配置!
當(dāng)涉及授權(quán)時(shí),情況并不理想。授權(quán)粒度基本上是:“ 用戶X可以登錄到服務(wù)器Y ”,沒(méi)有分組。您必須通過(guò)將用戶的公共密鑰寫(xiě)入?/.ssh/authorized_keys并為其創(chuàng)建本地UNIX用戶,來(lái)配置用戶可能分別登錄的每個(gè)服務(wù)器。將CA與SSH證書(shū)一起使用可以幫助分發(fā)密鑰。PAM管道也可以為您創(chuàng)建用戶。無(wú)論如何,這將需要一些額外工作。
幸運(yùn)的是,如果您愿意擴(kuò)展工具,可以使用更高級(jí)別的軟件來(lái)解決這些問(wèn)題。
Kubectl
大多數(shù)時(shí)候,大家都會(huì)認(rèn)為kubeconfig管理kubernetns中的所有憑證。當(dāng)使用托管的Kubernetes平臺(tái),您甚至可能不會(huì)注意到平臺(tái)后臺(tái)會(huì)自動(dòng)生成它。很少有人會(huì)直接修改kubeconfig內(nèi)容,大多數(shù)情況下,您將使用云或身份驗(yàn)證提供程序生成的內(nèi)容。
這是一個(gè)不錯(cuò)的用戶體驗(yàn),但下面有一些常見(jiàn)的問(wèn)題點(diǎn):
- HTTP基本身份驗(yàn)證(用戶名+密碼為純文本)
- TLS客戶端證書(shū)(磁盤(pán)上的私鑰以純文本格式)
- 不透明的令牌(在磁盤(pán)上以純文本格式)
- 云提供商插件
- 這些被編譯成 kubectl code itself
- 慢慢地逐步淘汰以減少Kubernetes代碼依賴性
- Exec插件
- 在每個(gè)請(qǐng)求上,執(zhí)行一個(gè)外部二進(jìn)制文件以獲取承載令牌或TLS客戶端密鑰/證書(shū)
- 由云提供商使用,以與其定制的身份驗(yàn)證系統(tǒng)集成
- 如果您想要2FA,這可能是可行的方法
服務(wù)器使用TLS進(jìn)行身份驗(yàn)證,通常在kubeconfig中嵌入一個(gè)私有CA。
這里的授權(quán)比SSH好得多!這里沒(méi)有類似SSH的(例如每個(gè)pod)設(shè)計(jì),因?yàn)镵ubernetes pod是短暫的非持久的。
Kubernetes通過(guò)RBAC本地處理授權(quán)。所有kubectl exec請(qǐng)求都通過(guò)Kubernetes API服務(wù)器進(jìn)行傳輸,該服務(wù)器執(zhí)行RBAC規(guī)則。它需要一些學(xué)習(xí),從Internet復(fù)制粘貼的YAML并對(duì)其進(jìn)行調(diào)整。但是,當(dāng)您完成操作后,您可以說(shuō):“ 項(xiàng)目中的每個(gè)人都可以登錄到默認(rèn)的namespace(名稱空間),但是只有核心人員可以管理生產(chǎn)namespace(名稱空間)* ”。
“最難”的部分是確保每個(gè)員工都擁有一個(gè)kubeconfig與您的RBAC規(guī)則相匹配的正確身份。幸運(yùn)的是,SSO集成在大多數(shù)托管平臺(tái)上都相當(dāng)不錯(cuò)。
Shell UX
這個(gè)其實(shí)很接近。SSH和kubectl都處理終端顏色、轉(zhuǎn)義代碼、交互命令甚至窗口大小調(diào)整事件。SSH和kubectl在99%的CLI應(yīng)用程序中應(yīng)該都能很好地工作。
SSH確實(shí)增加了一些比較好的功能:
- 環(huán)境變量定制
- kubectl總是在啟動(dòng)時(shí)設(shè)置提供給容器的環(huán)境變量
- ssh主要依賴于系統(tǒng)登錄shell的程序配置(但也可以通過(guò)PermitUserEnvironment或SendEnv/AcceptEnv接受用戶的環(huán)境)
- 轉(zhuǎn)義序列(不要與ANSI轉(zhuǎn)義代碼混淆)
- 超級(jí)方便,可以關(guān)閉掛起的SSH會(huì)話,而不必等待超時(shí)觸發(fā)
- 下次使用ssh時(shí)可以嘗試輸入“~?”
Non-shell features
文件傳輸
ssh和kubectl都支持在您和服務(wù)器之間傳輸文件。
SSH協(xié)議
SSH有多種工具可以將其作為傳輸工具使用:
- 有內(nèi)置的SCP和更新一點(diǎn)的SFTP
- 盡管需要獨(dú)立安裝,但還有一個(gè)更好的rsync工具
- 您甚至可以使用一些管道符進(jìn)行文件的傳輸
KUBECTL
kubectl cp命令可以復(fù)制文件,但基本上是kubectl exec + tar的簡(jiǎn)單封裝。而且,如果您要處理的容器尚未包含tar命令的話,那么就會(huì)很遺憾。
您可以使用掛載volume的方式去實(shí)現(xiàn)傳輸文件,但這在創(chuàng)建Pod時(shí)需要提前計(jì)劃好,非常不方便。
Port forwarding
SSH協(xié)議
- SSH具有非常靈活的端口轉(zhuǎn)發(fā)支持:
- 本地端口轉(zhuǎn)發(fā)(本地端口->服務(wù)器->任何位置)ssh -L 8080:example.com:80 server
- 遠(yuǎn)程端口轉(zhuǎn)發(fā)(任何地方->服務(wù)器端口->本地端口)ssh -R 80:localhost:8080 server
動(dòng)態(tài)端口轉(zhuǎn)發(fā)(通過(guò)SOCKS5)ssh -D 1080 server
您可以通過(guò)它去實(shí)現(xiàn)各種轉(zhuǎn)發(fā)需求!當(dāng)然也可以在生產(chǎn)環(huán)境中留下后門(mén)...
KUBECTL
kubectl port-forward使您可以通過(guò)本地端口通信到Pod上的遠(yuǎn)程端口。這是SSH本地端口轉(zhuǎn)發(fā)所不能實(shí)現(xiàn)的部分。
Jump hosts
SSH協(xié)議
使用SSH時(shí),通常會(huì)設(shè)置跳轉(zhuǎn)主機(jī)(也稱為堡壘機(jī)),通過(guò)對(duì)堡壘機(jī)權(quán)限的控制而實(shí)現(xiàn)訪問(wèn)的控制。
您確實(shí)需要手動(dòng)設(shè)置它,適當(dāng)?shù)嘏渲每蛻魴C(jī)和服務(wù)器,還需要考慮在該機(jī)上使用多租戶。它會(huì)成為維護(hù)的負(fù)擔(dān)。
KUBECTL
在Kubernetes中,API服務(wù)器實(shí)際上是您的“跳轉(zhuǎn)主機(jī)”。
X11 forwarding
使用SSH,您可以圖形化的管理遠(yuǎn)程應(yīng)用程序:
- user@local $ ssh -X server
- user@server % firefox
它就像一個(gè)遠(yuǎn)程桌面,但是您在服務(wù)器上啟動(dòng)的應(yīng)用程序自然會(huì)融合到本地桌面中,而不是擁有嵌套的桌面。
性能
從用戶角度來(lái)看,SSH和kubectl的性能都很好。您可能會(huì)感覺(jué)到一些卡頓,尤其是在網(wǎng)絡(luò)不穩(wěn)定的情況下,但是兩者之間的速度都明顯慢。
但是我仍然想獲得一些實(shí)際參考數(shù)據(jù),因此讓我們運(yùn)行一些人為的基準(zhǔn)測(cè)試!
TL; DR:kubectl exec在建立連接時(shí)速度更快,但是SSH在發(fā)送/接收會(huì)話數(shù)據(jù)時(shí)速度更快。
以下結(jié)果并不準(zhǔn)確,但仍代表了實(shí)際使用情況:在有無(wú)線網(wǎng)絡(luò)連接的筆記本電腦上進(jìn)行測(cè)試。
客戶端是OpenSSH v8.3和kubectl v1.18。在Kubernetes方面,我使用的是一個(gè)基于busybox創(chuàng)建的簡(jiǎn)單容器kubectl run -it busybox --image=busybox。
本地服務(wù)器是OpenSSH v8.3和運(yùn)行Kubernetes v1.18的minikube。
遠(yuǎn)程服務(wù)器是OpenSSH v8.2和GKE v1.14(相當(dāng)老,是的)。兩者都在同一區(qū)域的GCP上運(yùn)行。
Login/setup latency
首先,讓我們衡量一下建立會(huì)話所需的時(shí)間。
在這兩種情況下,我將遠(yuǎn)程運(yùn)行echo foo 100次,并使用hyperfine測(cè)量計(jì)時(shí)。結(jié)果測(cè)量了建立連接、執(zhí)行authn/z、打開(kāi)遠(yuǎn)程shell然后斷開(kāi)連接所需的時(shí)間。實(shí)際的echo command耗時(shí)<1ms,不應(yīng)影響結(jié)果。
本地
- $ hyperfine 'ssh localhost echo foo' 'kubectl exec -it busybox echo foo' -r 100
- Benchmark #1: ssh localhost echo foo
- Time (mean ± σ): 156.2 ms ± 15.9 ms [User: 14.0 ms, System: 2.1 ms]
- Range (min … max): 112.4 ms … 220.9 ms 100 runs
- Benchmark #2: kubectl exec -it busybox echo foo
- Time (mean ± σ): 113.9 ms ± 16.1 ms [User: 72.4 ms, System: 12.7 ms]
- Range (min … max): 95.8 ms … 157.2 ms 100 runs
- Summary
- 'kubectl exec -it busybox echo foo' ran
- 1.37 ± 0.24 times faster than 'ssh localhost echo foo'
kubectl 最快,快37%!
遠(yuǎn)程
如果我們把網(wǎng)絡(luò)加入其中呢?
- $ hyperfine 'ssh ubuntu echo foo' 'kubectl exec -it busybox echo foo' -r 100
- Benchmark #1: ssh ubuntu echo foo
- Time (mean ± σ): 689.1 ms ± 42.6 ms [User: 41.1 ms, System: 6.1 ms]
- Range (min … max): 653.6 ms … 1022.0 ms 100 runs
- Benchmark #2: kubectl exec -it busybox echo foo
- Time (mean ± σ): 445.7 ms ± 45.3 ms [User: 130.1 ms, System: 31.2 ms]
- Range (min … max): 372.3 ms … 655.2 ms 100 runs
- Summary
- 'kubectl exec -it busybox echo foo' ran
- 1.55 ± 0.18 times faster than 'ssh ubuntu echo foo'
再一次kubectl獲得最佳:速度提高55%!
吞吐量
原始數(shù)據(jù)吞吐量如何?
我將通過(guò)OpenSSH發(fā)送約32MB的數(shù)據(jù),并在遠(yuǎn)端將其回顯。
本地
- $ hyperfine 'find . -type f | xargs cat | ssh localhost cat' 'find . -type f | xargs cat | kubectl exec -it busybox cat' -r 10
- Benchmark #1: find . -type f | xargs cat | ssh localhost cat
- Time (mean ± σ): 5.457 s ± 0.167 s [User: 4.464 s, System: 1.259 s]
- Range (min … max): 5.202 s … 5.657 s 10 runs
- Benchmark #2: find . -type f | xargs cat | kubectl exec -it busybox cat
- Time (mean ± σ): 27.628 s ± 1.725 s [User: 9.920 s, System: 7.203 s]
- Range (min … max): 25.044 s … 30.926 s 10 runs
- Summary
- 'find . -type f | xargs cat | ssh localhost cat' ran
- 5.06 ± 0.35 times faster than 'find . -type f | xargs cat | kubectl exec -it busybox cat'
好吧,這很有趣。SSH通過(guò)發(fā)送數(shù)據(jù)的速度快約5倍!
SSH需要大約5.45s,大約6000 KB/s。
kubectl 大約需要27.62s,大約1200 KB/s。
遠(yuǎn)程
- $ hyperfine 'find . -type f | xargs cat | ssh ubuntu cat' 'find . -type f | xargs cat | kubectl exec -it busybox cat' -r 10
- Benchmark #1: find . -type f | xargs cat | ssh ubuntu cat
- Time (mean ± σ): 28.794 s ± 0.627 s [User: 10.525 s, System: 5.018 s]
- Range (min … max): 27.788 s … 29.921 s 10 runs
- Benchmark #2: find . -type f | xargs cat | kubectl exec -it busybox cat
- Time (mean ± σ): 33.299 s ± 2.679 s [User: 10.831 s, System: 8.902 s]
- Range (min … max): 30.964 s … 40.292 s 10 runs
- Summary
- 'find . -type f | xargs cat | ssh ubuntu cat' ran
- 1.16 ± 0.10 times faster than 'find . -type f | xargs cat | kubectl exec -it busybox cat'
SSH仍然更快,但僅提高了約16%。
結(jié)論
SSH和kubectl之間有很多相似之處,它們都有各自的優(yōu)點(diǎn)和缺點(diǎn)。雖然SSH在架構(gòu)上是一成不變的,但是在管理一些機(jī)器時(shí),高級(jí)軟件可以從Kubernetes那里學(xué)到一些關(guān)于集中配置的東西。SSH還可以借用kubeconfig中的憑證管理方法(即“將所有客戶機(jī)憑據(jù)和服務(wù)器信息放入一個(gè)可以復(fù)制的文件中”)。
kubectl可以改善其no-shell功能,例如端口轉(zhuǎn)發(fā)和文件傳輸。它原始數(shù)據(jù)吞吐量也不足,這使其無(wú)法成為像SSH這樣的傳輸層協(xié)議。實(shí)際上,這些工具是互補(bǔ)的,可以用于不同的任務(wù),而不是僅僅使用其中一個(gè)。希望這篇文章對(duì)您有所幫助!
原文:https://gravitational.com/blog/ssh-vs-kubectl/