自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一種新的進(jìn)入容器的方式: WebSocket + Docker Remote API

云計(jì)算 虛擬化
容器是基于操作系統(tǒng)內(nèi)核的一種輕量級(jí)的虛擬化技術(shù)。其可以類比于虛擬機(jī),但其本身并不是虛擬機(jī)。

眾所周知,容器是基于操作系統(tǒng)內(nèi)核的一種輕量級(jí)的虛擬化技術(shù)。其可以類比于虛擬機(jī),但其本身并不是虛擬機(jī)。在傳統(tǒng)的虛擬機(jī)使用場(chǎng)景中,每個(gè)用戶都會(huì)通過堡壘機(jī),根據(jù)自己被分配的權(quán)限,登錄某些機(jī)器的某些賬號(hào)。當(dāng)應(yīng)用部署逐漸轉(zhuǎn)移到基于容器技術(shù)的PaaS平臺(tái)上后,讓用戶進(jìn)入容器進(jìn)行觀察、調(diào)試應(yīng)用已經(jīng)成為了PaaS平臺(tái)的一個(gè)重要且必備的功能。

遠(yuǎn)程進(jìn)入容器功能的傳統(tǒng)實(shí)現(xiàn)方式是基于虛擬機(jī)的思想,在每個(gè)容器中啟動(dòng)一個(gè)sshd進(jìn)程。由于容器PID為1的進(jìn)程的特殊性,為了保證容器不停,容器的ENTRYPOINT需要設(shè)置為類似于Supervisord這樣的進(jìn)程管理程序。在這種多進(jìn)程容器的使用場(chǎng)景中,用戶通過ssh-client指定容器的IP遠(yuǎn)程連接到容器,讓用戶感覺到自己好像就在使用虛擬機(jī)。但是,這種方案會(huì)帶來以下問題:

  1. 權(quán)限管理。如何控制哪些用戶能夠登錄哪些容器?如何和平臺(tái)已有的權(quán)限管理系統(tǒng)集成?這種情況往往都需要通過堡壘機(jī)系統(tǒng)控制。而在PaaS中,引入單獨(dú)的堡壘機(jī)系統(tǒng)會(huì)增加PaaS的復(fù)雜度以及維護(hù)成本。
  2. 登錄方式選擇。無論使用密碼還是私鑰驗(yàn)證登錄,容器內(nèi)的密碼或者authorized_keys的管理都需要通過加入額外的程序解決,無疑會(huì)增加容器的復(fù)雜度。同時(shí)還要面對(duì)同權(quán)限容器的密碼或authorized_keys的一致性問題。

基于以上問題,在我們的LAIN平臺(tái)中,設(shè)計(jì)出了基于WebSocket協(xié)議與Docker Remote API的遠(yuǎn)程登錄方案。LAIN(https://laincloud.com)是一個(gè)基于Docker的PaaS。其面向技術(shù)棧多樣尋求高效運(yùn)維方案的高速發(fā)展中的組織,DevOps人力缺乏的startup以及個(gè)人開發(fā)者。LAIN通過統(tǒng)一高效的開發(fā)工作流,降低應(yīng)用運(yùn)維復(fù)雜度;在IaaS / 私有IDC裸機(jī)的基礎(chǔ)上直接提供應(yīng)用開發(fā),集成,部署,運(yùn)維的一攬子解決方案。

該方案的整體架構(gòu)圖如下:

從圖中可以看出,在LAIN中實(shí)現(xiàn)容器遠(yuǎn)程登錄支持需要以下兩個(gè)組件:

1. Entry應(yīng)用。負(fù)責(zé)如下工作:

  • 調(diào)用Docker Remote API
  • 通過WebSocket 傳遞stdin,stdout和stderr。
  • 根據(jù)protobuf3協(xié)議對(duì)各類消息進(jìn)行序列化與反序列化。
  • 對(duì)用戶登錄的鑒權(quán)。
  • Entry是基于Go語言開發(fā)的,并依賴如下代碼庫(kù):
  • github.com/gorilla/websocket:WebSocket的服務(wù)端實(shí)現(xiàn)。
  • github.com/fsouza/go-dockerclient:Go語言的Docker客戶端。
  • github.com/golang/protobuf/proto:protobuf協(xié)議的支持庫(kù)。

2. 基于命令行的客戶端。負(fù)責(zé)如下工作:

  • WebSocket連接請(qǐng)求的發(fā)送。
  • 監(jiān)聽鍵盤輸入、窗口變化事件以及WebSocket返回的stream。
  • 將遠(yuǎn)端的stdout,stderr輸出到本地終端的標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤。

Entry的工作流程

通過命令行客戶端遠(yuǎn)程登錄容器的過程及其實(shí)現(xiàn)如下:

  1. 用戶通過客戶端命令向Entry應(yīng)用發(fā)送WebSocket連接請(qǐng)求。
  2. Entry應(yīng)用接收到用戶請(qǐng)求,得到請(qǐng)求Header中的access_token以及要進(jìn)入的容器信息,通過調(diào)用LAIN的console接口判斷該用戶是否有權(quán)限進(jìn)入容器。如果沒有權(quán)限,則直接通知客戶端鑒權(quán)失敗,本次連接結(jié)束。
  3. 如果通過了權(quán)限驗(yàn)證,則WebSocket連接會(huì)被建立。緊接著Entry會(huì)去調(diào)用 execCreate 這個(gè)Docker Remote API。在調(diào)用時(shí),需要指定Tty,AttachStdin、AttachStdout和AttachStderr參數(shù)均為true,Cmd參數(shù)為bash,這樣才能獲得bash進(jìn)程的標(biāo)準(zhǔn)輸入輸出和錯(cuò)誤。
  4. 如果調(diào)用execCreate成功,調(diào)用請(qǐng)求會(huì)返回該Exec的ID,Entry會(huì)繼續(xù)根據(jù)這個(gè)ID調(diào)用execStart接口。在調(diào)用時(shí),需要指定Detach和Tty為false,這樣才能連接到bash進(jìn)程的標(biāo)準(zhǔn)輸           入輸出和錯(cuò)誤。調(diào)用execCreate成功后,會(huì)返回一個(gè)HTTP的stream。在Entry中則通過3個(gè)goroutine分別處理stdin,stdout和stderr。
  5. 客戶端會(huì)同時(shí)監(jiān)聽WebSocket連接與鍵盤輸入,對(duì)于WebSocket返回的Message,客戶端會(huì)通過Entry制定的protobuf3消息格式反序列化出消息結(jié)構(gòu),并根據(jù)消息的類型,將數(shù)據(jù)發(fā)送到本地終端的stdout或stderr。對(duì)于鍵盤輸入,客戶端會(huì)將輸入內(nèi)容封裝,經(jīng)過protobuf3序列化后,通過WebSocket發(fā)送給Entry應(yīng)用,Entry應(yīng)用經(jīng)過反序列化后,將輸入發(fā)送給bash的stdin。

以上就是Entry的工作原理。從中我們可以看出,Entry已經(jīng)很好地解決了傳統(tǒng)ssh-client登錄所遇到的問題:

  • Entry通過調(diào)用console的接口完成了身份驗(yàn)證工作,由于所有的權(quán)限都被console統(tǒng)一管理,因此Entry不需要自己維護(hù)權(quán)限信息,即Entry本身是無狀態(tài)應(yīng)用。這種應(yīng)用的優(yōu)勢(shì)在于可以低成本擴(kuò)容,用以應(yīng)對(duì)多并發(fā)的場(chǎng)景。
  • Entry通過Docker Remote API連接容器,這樣只要被連接的容器內(nèi)可以啟動(dòng)bash進(jìn)程,用戶就可以通過客戶端連接到該容器。容器無需啟動(dòng)sshd進(jìn)程,也就無需再以supervisord等進(jìn)程作為entrypoint。更多的容器就可以以單進(jìn)程的形式運(yùn)行,降低了容器本身的維護(hù)成本。

Entry的設(shè)計(jì)細(xì)節(jié)

俗話說,細(xì)節(jié)決定成敗。為了提高使用體驗(yàn),Entry應(yīng)用在設(shè)計(jì)與實(shí)現(xiàn)時(shí)考慮到了很多細(xì)節(jié),在這里拿出來與大家分享。

1. 連接保持:當(dāng)WebSocket連接在一段時(shí)間內(nèi)沒有數(shù)據(jù)傳輸后,會(huì)自動(dòng)斷開。這給用戶的使用帶來了極大的不便。Entry在設(shè)計(jì)時(shí),對(duì)每一個(gè)建立的WebSocket連接,會(huì)有一個(gè)單獨(dú)的goroutine每隔10秒發(fā)送一個(gè)PING類型的Message(不是WebSocket協(xié)議中的PingMessage),這樣保證了在不主動(dòng)斷開的情況下,用戶和容器可以一直保持連接。

2. 使用protobuf3制定消息格式并實(shí)現(xiàn)序列化與反序列化:使用protobuf3可以方便地定義與擴(kuò)展自己的消息格式,同時(shí)在傳輸時(shí)能減小一定的帶寬占用。

Entry的消息格式有兩類,RequestMessage和ResponseMessage??蛻舳税l(fā)送的請(qǐng)求都屬于RequestMessage,服務(wù)端返回的數(shù)據(jù)都封裝在ResponseMessage中。其中:

  • RequestMessage類型包括:PLAIN和WINCH。PLAIN就是用戶通過鍵盤的輸入。WINCH則是終端窗口大小改變的消息,內(nèi)容中會(huì)攜帶新窗口的rows和cols。
  • ResponseMessage類型包括:STDOUT, STDERR,PING和CLOSE。STDOUT和STDERR代表了該消息內(nèi)容是來自于標(biāo)準(zhǔn)輸出還是標(biāo)準(zhǔn)錯(cuò)誤。PING則代表是連接保持專用的信息。CLOSE則是連接將要斷開前Entry返回的信息,會(huì)包含錯(cuò)誤原因或者正常退出的信息。

3. 監(jiān)聽終端窗口大小改變:默認(rèn)的終端窗口大小都是80 * 24,但該標(biāo)準(zhǔn)在當(dāng)前的日常使用中早已過時(shí)。如果在一個(gè)全屏的terminal中仍然使用該大小顯然是不合理的。因此客戶端在成功連接到容器后,客戶端會(huì)首先根據(jù)當(dāng)前的terminal大小發(fā)送一個(gè)WINCH類型的RequestMessage,Entry收到后會(huì)調(diào)用ExecResize接口,這樣之后所有的stdout和stderr都會(huì)按照新的終端大小顯示。客戶端還會(huì)監(jiān)聽窗口大小改變的事件,如果發(fā)生改變,同樣還會(huì)發(fā)送WINCH到Entry。

4. UTF-8編碼檢查:客戶端和服務(wù)端在發(fā)送消息內(nèi)容時(shí),都會(huì)對(duì)緩沖區(qū)內(nèi)要發(fā)送的數(shù)據(jù)做UTF-8編碼檢查。如果發(fā)送數(shù)據(jù)不符合編碼規(guī)則,則會(huì)先發(fā)送最長(zhǎng)符合的緩沖區(qū)前綴,后面剩余的數(shù)據(jù)則被移到緩沖區(qū)的開始,待下次發(fā)送。這種設(shè)計(jì)是為了處理中文等非latin1字符的顯示問題。避免因?yàn)榉欠ǖ腢TF-8編碼造成終端顯示亂碼。

Entry存在的問題

非正常退出時(shí),bash進(jìn)程不會(huì)結(jié)束,而是會(huì)以sleep的狀態(tài)殘留于容器中。如果一個(gè)容器有過多的bash進(jìn)程,很可能因?yàn)閏group的內(nèi)存限制導(dǎo)致容器退出。目前官方并沒有給出類似execKill的API,只能期待在以后版本的docker中能解決這個(gè)問題。

Entry應(yīng)用依賴特定的LAIN客戶端。之前用戶只能通過lain enter命令進(jìn)入容器。但是12月份后我們升級(jí)了console的前端,增加了web terminal功能。用戶只需要通過點(diǎn)擊容器的ID就可以打開一個(gè)含有terminal的web頁面,然后通過該web頁面與容器進(jìn)行交互,不需要再安裝任何客戶端。在這里要十分感謝開源項(xiàng)目xterm.js(https://github.com/sourcelair/xterm.js),該項(xiàng)目基于JavaScript與CSS實(shí)現(xiàn)了一個(gè)近乎完美模擬xterm終端的插件。目前,console的web terminal可以支持Firefox和Chrome,但是無法支持IE和Safari。

總結(jié)

Entry是LAIN中一款設(shè)計(jì)較為精巧、技術(shù)含量較高的應(yīng)用。其利用了WebSocket全雙工傳輸?shù)奶攸c(diǎn),在單進(jìn)程容器的場(chǎng)景下實(shí)現(xiàn)了對(duì)容器的遠(yuǎn)程登錄,同時(shí)保證了登錄權(quán)限的控制。本文希望通過分享LAIN中Entry的設(shè)計(jì)與實(shí)現(xiàn),為需要開發(fā)遠(yuǎn)程登錄容器功能的PaaS同行提供技術(shù)方案參考。Entry已經(jīng)開源,地址在(https://github.com/laincloud/entry),歡迎一起討論交流學(xué)習(xí)。

責(zé)任編輯:武曉燕 來源: 運(yùn)維派
相關(guān)推薦

2022-07-28 11:29:23

數(shù)據(jù)安全數(shù)據(jù)令牌化

2023-03-07 15:08:57

2020-12-16 10:12:52

大數(shù)據(jù)小數(shù)據(jù)人工智能

2024-02-26 00:00:00

sessionredis項(xiàng)目

2025-03-26 08:00:00

2018-12-14 14:30:12

安全檢測(cè)布式系測(cè)試

2016-12-23 21:11:05

深度學(xué)習(xí)思維方式大數(shù)據(jù)

2020-09-09 10:44:32

5G

2020-09-09 10:44:35

5G網(wǎng)絡(luò)運(yùn)營(yíng)方式

2018-07-30 09:00:19

容器Docker鏡像

2025-01-13 08:36:26

2010-11-05 10:15:42

云計(jì)算

2022-08-08 08:22:22

量子計(jì)算

2023-01-26 23:46:15

2025-02-27 00:00:30

SpringJava方式

2013-03-12 14:07:06

Java編程

2013-07-05 13:23:43

蘋果

2022-04-06 12:00:46

HEAT安全架構(gòu)新威脅

2023-12-04 08:21:18

虛擬線程Tomcat

2017-02-20 09:00:49

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)