兩年容器云工作經(jīng)驗(yàn)铣减,牛刀小試了幾家公司鸣奔,將面試問(wèn)到的問(wèn)題記錄下來(lái),鞭策自己不斷學(xué)習(xí)睹耐。
1、entrypoint & cmd 指令的區(qū)別
這主要考察 Dockerfile 良好實(shí)踐中關(guān)于容器啟動(dòng)時(shí)運(yùn)行的命令部翘。
entrypoint 和 cmd 命令都是設(shè)置容器啟動(dòng)時(shí)要執(zhí)行的命令硝训,但用法稍有不同。entrypoint 和 cmd 指令都是在 Dockerfile 中定義略就,但在鏡像構(gòu)建過(guò)程中并不會(huì)被執(zhí)行,只有當(dāng)容器啟動(dòng)時(shí)晃酒,entrypoint 和 cmd 指令設(shè)置的命令才會(huì)被執(zhí)行表牢。Dockerfile 中可以有多個(gè) entrypoint 指令,但生效的只有最后一個(gè) entrypoint 指令贝次,cmd 指令也類似崔兴,兩者的區(qū)別主要如下:
entrypoint 指令一般用來(lái)設(shè)置容器啟動(dòng)后要執(zhí)行的命令,這對(duì)容器來(lái)說(shuō)蛔翅,往往是固定不變的敲茄。
cmd 指令一般用來(lái)設(shè)置容器啟動(dòng)后執(zhí)行命令的默認(rèn)參數(shù),這對(duì)容器來(lái)說(shuō)山析,往往是可以改變的堰燎,cmd 能夠被docker run 后面跟的命令行參數(shù)替換,一般而言笋轨,兩者是可以結(jié)合使用的秆剪。
舉個(gè)例子
FROM baseimage:v1.0
ENTRYPOINT ["/usr/sbin/nginx"]
CMD [""]
從以上 Dockerfile 設(shè)置的 entrypoint 和 cmd 指令來(lái)看,容器啟動(dòng)時(shí)會(huì)運(yùn)行 nginx 進(jìn)程爵政,而 cmd 指令可以在執(zhí)行 docker run 傳入?yún)?shù)進(jìn)行覆蓋仅讽,如 docker run --name:** -p **:** -g "daemon off",其中 -g "daemon off" 將會(huì)被作為命令參數(shù)追加到 entrypoint 后面的指令钾挟,也就是說(shuō)最后容器的啟動(dòng)命令為:/usr/sbin/nginx -g "daemon off;"洁灵,以前臺(tái)進(jìn)程來(lái)運(yùn)行 nginx 進(jìn)程。
2掺出、如何覆蓋 entrypoint 和 cmd 指令
這個(gè)問(wèn)題是考察 entrypoint 和 cmd 的格式
CMD 有三種格式:
(1) Exec 格式:CMD ["executabel", "param1", "param2"]徽千,這是 CMD 的推薦格式
(2) CMD ["param1", "param2"],這種模式和 entrypoint 結(jié)合使用汤锨,為 entrypoint 提供額外的參數(shù)罐栈,此時(shí) entrypoint 必須使用 exec 格式。
(3) Shell 格式:CMD command param1 param2
ENTRYPOINT 有兩種格式:
(1) Exec 格式:ENTRYPOINT ["executable", "param1", "param2"]泥畅,這是 ENTRYPOINT 的推薦方式
(2) Shell 格式:ENTRYPOINT command param1 param2
其中荠诬,CMD 無(wú)論是哪種格式琅翻,都會(huì)被 docker run 命令帶的參數(shù)直接覆蓋
而 ENTRYPOINT 無(wú)論是哪種格式,ENTRYPOINT 指令一定會(huì)被執(zhí)行柑贞,并不會(huì)被覆蓋方椎,但 ENTRYPOINT 在選擇格式時(shí)必須格外小心,因?yàn)檫@兩種格式的效果差別很大钧嘶。
Exec 格式
ENTRYPOINT 中的參數(shù)始終會(huì)被使用棠众,而 CMD 的額外參數(shù)可以在容器啟動(dòng)時(shí)動(dòng)態(tài)替換掉。
Shell 格式
ENTRYPOINT 的 shell 格式會(huì)忽略任何 CMD 或者 docker run 提供的任何參數(shù)有决。
3闸拿、ADD 和 COPY 指令有什么區(qū)別?推薦使用哪種方式
這幾道面試題都是 Dockerfile 良好實(shí)踐中的知識(shí)點(diǎn)书幕,這道題主要考察在構(gòu)建鏡像時(shí)新荤,如何向鏡像拷貝文件。
ADD 指令
ADD 指令的功能是將主機(jī)構(gòu)建環(huán)境(上下文)目錄中的文件和目錄台汇,拷貝到鏡像中苛骨,如果源文件是個(gè)歸檔文件(壓縮文件,如tar, gzip, bzip2)苟呐,ADD 指令會(huì)自動(dòng)進(jìn)行解壓痒芝,如:
ADD /foo.tar.gz /tmp/
上述指令會(huì)將 foo.tar.gz 壓縮文件解壓到容器的 /tmp 目錄下。
COPY指令
COPY 指令和 ADD 指令類似牵素,都是負(fù)責(zé)拷貝文件或者目錄到容器里严衬,但 COPY 指令功能更簡(jiǎn)潔和易懂,COPY 是ADD 的一種簡(jiǎn)化版本笆呆,目的在于滿足大多數(shù)人復(fù)制文件到容器的需求瞳步,在大多數(shù)情況下,都建議使用 COPY 指令腰奋,除非你明確需要ADD指令单起。
4、sed劣坊、grep 和 awk 命令的區(qū)別
這道是考察 linux 常見(jiàn)運(yùn)維命令嘀倒。
簡(jiǎn)單理解,grep 命令主要用于關(guān)鍵字的篩選局冰,sed 指令是以行為單位的文本編輯工具测蘑,而 awk 指令通過(guò)指定分割符將一行(一條記錄)劃分為多個(gè)字段,以字段為單位來(lái)處理文本康二,一般結(jié)合 grep 命令來(lái)使用碳胳,比如只打印第一列,如:cat /etc/hosts | grep *** | awk '{print $1}'沫勿,更詳細(xì)的說(shuō)明可以參考以下文檔:
5挨约、兩個(gè) namespace 如何進(jìn)行通信
這道題主要考察 Docker 主機(jī)兩個(gè) namespace(容器)或者是容器與主機(jī)如何進(jìn)行通信的原理味混。
我們都知道,Docker 是基于 LXC容器技術(shù) namespace 來(lái)實(shí)現(xiàn)資源的隔離诫惭,基于 LXC容器技術(shù) cgroups 來(lái)實(shí)現(xiàn)資源的限制翁锡,Docker 采用虛擬網(wǎng)絡(luò)設(shè)置(Virtual Network Device)的方式,將不同命名空間的網(wǎng)絡(luò)設(shè)備連接到一起夕土,這種設(shè)備對(duì)都是成對(duì)存在的馆衔,一端作為容器的網(wǎng)卡eth0,一端連接到宿主機(jī)上的docker網(wǎng)橋 veth怨绣,從而實(shí)現(xiàn) Docker 主機(jī)上不同 namespace通信角溃,詳情可見(jiàn)下圖:
或者參考如下文檔:docker namespace
6、簡(jiǎn)述 Docker 如何用 namespace 來(lái)進(jìn)行資源隔離
這道題主要也是考察 namespace 相關(guān)的知識(shí)篮撑。
Docker 主要通過(guò)六大 Namespace 來(lái)實(shí)現(xiàn)資源的隔離减细,如下:
(1) Mount Namespace,掛載命名空間咽扇,用來(lái)隔離掛載目錄邪财,讓不同 Namespace 擁有獨(dú)立的掛載結(jié)構(gòu)陕壹,而程序中對(duì)掛載信息的修改不會(huì)影響到其他 Namespace 中程序的運(yùn)行质欲。
(2) UTS Namespace,UTS Namespace糠馆,用來(lái)隔離主機(jī)名和域名嘶伟,通過(guò)UTS Namespace,讓不同 Namespace 擁有獨(dú)立的主機(jī)名稱和網(wǎng)絡(luò)訪問(wèn)域名又碌。
(3) IPC Namespace九昧,進(jìn)程通信命名空間,用來(lái)隔離進(jìn)程間通信毕匀,主要作用于 消息隊(duì)列铸鹰、信號(hào)量或者是管道,IPC 只能做到同一個(gè)命名空間進(jìn)行通信皂岔,無(wú)法做到不同命名空間進(jìn)行信息交換通信蹋笼。
(4) PID Namespace,進(jìn)程命名空間躁垛,用來(lái)隔離進(jìn)程的運(yùn)行信息剖毯,PID Namespace 讓命名空間擁有獨(dú)立的進(jìn)程號(hào)管理。
(5) Networt Namespace教馆,網(wǎng)絡(luò)命名空間逊谋,用來(lái)隔離網(wǎng)絡(luò)協(xié)議棧,包括網(wǎng)絡(luò)設(shè)備接口土铺、IPV4 和 IPV6 協(xié)議等胶滋。
(6) User Namespace板鬓,用戶命名空間,用來(lái)隔離用戶和用戶組信息镀钓,通過(guò)嚴(yán)格的用戶隔離機(jī)制穗熬,避免 Namespace 中的程序直接操作到宿主機(jī)或者其他 Namespace 中的用戶。
除了 Namespace 丁溅,還有一項(xiàng)核心技術(shù) Cgroups(控制組)唤蔗,可以參考這篇博客:Docker底層技術(shù)架構(gòu)
7、glusterfs 分布式存儲(chǔ)元數(shù)據(jù)不一致時(shí)窟赏,如何恢復(fù)處理
這道是考察存儲(chǔ)相關(guān)的知識(shí)妓柜。
對(duì)存儲(chǔ)底層了解的不多,因此到時(shí)這道題我就簡(jiǎn)單粗暴地說(shuō)重啟 glusterfs服務(wù)進(jìn)程涯穷,明顯沒(méi)有 get 到面試官的點(diǎn)棍掐。
后來(lái)查閱相關(guān)的資料,說(shuō)是跟時(shí)間戳有關(guān)系拷况,但本人也沒(méi)有驗(yàn)證過(guò)作煌,詳細(xì)可以參考這篇博客:glusterfs 數(shù)據(jù)不一致處理
8、service 對(duì)外提供服務(wù)的方式有幾種
這道是考察外部如何訪問(wèn) k8s 集群內(nèi)的 service 服務(wù)赚瘦。
目前來(lái)說(shuō)總共有以下4種方式:
NodePort 方式
這種方式會(huì)將 Service 的端口映射到集群內(nèi)的所有的 node節(jié)點(diǎn)粟誓,集群內(nèi)的所有 node 節(jié)點(diǎn)都會(huì)起一個(gè)相同的隨機(jī)端口,通過(guò)訪問(wèn):${任一node節(jié)點(diǎn)IP}:${nodeport端口} 就可以訪問(wèn)到 k8s 集群內(nèi)指定的 service 服務(wù)了起意,iptables 會(huì)捕獲這種方式的請(qǐng)求鹰服,根據(jù) iptables 中的規(guī)則轉(zhuǎn)發(fā)到后端具體的 pod 實(shí)例上,這種方式簡(jiǎn)單揽咕,但會(huì)占用 node 節(jié)點(diǎn)的端口資源悲酷,并且 nodeport 沒(méi)有一個(gè)負(fù)載均衡器進(jìn)行路由分發(fā),這也就衍生了第二種方式亲善。
LoadBalancer 方式
這種方式设易,在nodeport的外部搭建一個(gè)負(fù)載均衡器(云服務(wù)提供商),但 LoadBalancer 需要 k8s 集群跑在支持的 Cloud Provider 上蛹头,這對(duì)于企業(yè)內(nèi)部運(yùn)行在私有云上的 k8s 集群不太適合顿肺。
Ingress 方式
Ingress 主要有兩大組件, Ingress 和 Ingress Controller掘而,其中 Ingress 解決的是服務(wù)和域名的對(duì)應(yīng)問(wèn)題挟冠,基本上一個(gè) Ingress 對(duì)象,通過(guò) yaml 文件進(jìn)行創(chuàng)建和更新袍睡,而 Ingress Controller 是將 Ingress 的這種變化動(dòng)態(tài)生成一段 nginx 的配置知染,并通過(guò) apiserver 更新到 nginx 這個(gè) pod 中,并自動(dòng) reload斑胜。
Router 方式
這種方式是 Openshift 特有的方式控淡,通過(guò)為 k8s 集群內(nèi)的每個(gè) service 對(duì)象生成一個(gè) Router 對(duì)象嫌吠,就能實(shí)現(xiàn)外界訪問(wèn) k8s 集群內(nèi)的 service 服務(wù)了。
9掺炭、ovs 訪問(wèn)外部服務(wù) ovs 網(wǎng)橋到物理網(wǎng)卡是如何連接的
這道是考察 sdn 網(wǎng)絡(luò) openvswitch的架構(gòu)和組成辫诅。
正常跨節(jié)點(diǎn)之間的通信是通過(guò) vxlan 隧道 或者是 gre連接來(lái)完成涧狮,見(jiàn)下圖:
但如果集群內(nèi)的容器要訪問(wèn)外部服務(wù)炕矮,是通過(guò)ovs 的 tun0 端口來(lái)完成。
10者冤、介紹家庭背景
這是 hr 問(wèn)的一些常規(guī)問(wèn)題肤视,暫不做解釋,如實(shí)回答即可涉枫,還問(wèn)到校招是否拿到公司的 offer邢滑,有女朋友嗎 等等一些問(wèn)題。