linux啟動(dòng)過程
BIOS->MBR->引導(dǎo)加載程序->內(nèi)核文件RIAD
raid0搓彻,同一份數(shù)據(jù)交替寫入兩個(gè)磁盤
raid1,同一份數(shù)據(jù)同時(shí)寫入兩個(gè)磁盤
raid5嘱朽,三個(gè)磁盤旭贬,數(shù)據(jù)寫入兩個(gè)磁盤,往另外一個(gè)盤寫入paritytcp報(bào)文頭節(jié)點(diǎn)多少字節(jié)搪泳?
tcp報(bào)文頭20字節(jié)稀轨,ip報(bào)文頭20字節(jié)
MTU一般是1500字節(jié)
因此MSS一般最大1460字節(jié)k8s的 pod, deployment, 通過YAML文件 create 一個(gè) pod 岸军,中間發(fā)生了什么奋刽。 當(dāng)我們提交一個(gè)YAML文件,k8s怎么處理
k8s有哪些核心組件
master上的組件:
API Server
Controller Manager
Scheduler
Node上的組件:
networking
kubelet
container runtime
volume plugin
device plugin
元數(shù)據(jù)存儲:
Etcd
- schedule 的作用
第一個(gè)控制循環(huán):informer path
啟動(dòng)一系列informer艰赞,用來監(jiān)聽etcd中的pod佣谐,node,service等與調(diào)度相關(guān)的API對象的變化
將pod放入priorityQueue
第二個(gè)循環(huán):scheduling path
不斷的從調(diào)度隊(duì)列中出隊(duì)一個(gè)pod方妖,然后調(diào)用predicates算法進(jìn)行過濾
再按照priorities算法對列表中的node打分
更新scheduler cache中的pod和node的信息狭魂,這種基于樂觀假設(shè)API對象更新方式,在kubernetes中被稱作Assume
Assume之后党觅,調(diào)度器會創(chuàng)建一個(gè)Goroutine來異步地向APIServer發(fā)起更新pod的請求雌澄,來完成真正的Bind操作
當(dāng)新的pod在某個(gè)節(jié)點(diǎn)上運(yùn)行起來之前,該節(jié)點(diǎn)上的kubelet還會通過一個(gè)叫做Admit的操作來驗(yàn)證改pod是否確實(shí)能夠運(yùn)行在該節(jié)點(diǎn)上
搶占調(diào)度:
第一個(gè)隊(duì)列杯瞻,叫作 activeQ镐牺。凡是在 activeQ 里的 Pod,都是下一個(gè)調(diào)度周期需要調(diào)度的對象魁莉。
第二個(gè)隊(duì)列睬涧,叫作 unschedulableQ,專門用來存放調(diào)度失敗的 Pod旗唁。
- kublet的作用是畦浓?
設(shè)置listers,注冊它所關(guān)心的各種事件的Informer逆皮,這些Informer,就是sync Loop需要處理的數(shù)據(jù)的來源
子控制循環(huán):Volume Manager参袱,Image Manager电谣,Node Status Manager
通過控制器模式秽梅,完成kublet的某項(xiàng)具體職責(zé)
kubelet 調(diào)用下層容器運(yùn)行時(shí)的執(zhí)行過程,并不會直接調(diào)用 Docker 的 API剿牺,而是通過一組叫作 CRI(Container Runtime Interface企垦,容器運(yùn)行時(shí)接口)的 gRPC 接口來間接執(zhí)行的。
- controller-manager內(nèi)部結(jié)構(gòu)圖
Controller Manager作為集群內(nèi)部的管理控制中心晒来,負(fù)責(zé)集群內(nèi)的Node钞诡、Pod副本、服務(wù)端點(diǎn)(Endpoint)湃崩、命名空間(Namespace)荧降、服務(wù)賬號(ServiceAccount)、資源定額(ResourceQuota)的管理攒读,當(dāng)某個(gè)Node意外宕機(jī)時(shí)朵诫,Controller Manager會及時(shí)發(fā)現(xiàn)并執(zhí)行自動(dòng)化修復(fù)流程,確保集群始終處于預(yù)期的工作狀態(tài)薄扁。
- docker 的 namesapce 和 cgroup
pid
mount
network
ipc
uts
user
pids
cpu
cpuacct
cpuset
memory
net_cls
blkio
devices
- cgroup哪些參數(shù)可以對CPU做隔離
cpuacct.usage
cpuacct.usage_percpu
cpu.cfs_period_us
cpu.cfs_quota_us
k8s是平臺層能力的變革剪返?為什么
k8s怎么做水平拓展的
HPA簡介
HPA全稱Horizontal Pod Autoscaling,即pod的水平自動(dòng)擴(kuò)展邓梅。
自動(dòng)擴(kuò)展主要分為兩種脱盲,其一為水平擴(kuò)展,針對于實(shí)例數(shù)目的增減日缨;其二為垂直擴(kuò)展钱反,即單個(gè)實(shí)例可以使用的資源的增減。HPA屬于前者殿遂。
云計(jì)算具有水平彈性的特性诈铛,這個(gè)是云計(jì)算區(qū)別于傳統(tǒng)IT技術(shù)架構(gòu)的主要特性。對于Kubernetes中的POD集群來說墨礁,HPA可以實(shí)現(xiàn)很多自動(dòng)化功能幢竹,比如當(dāng)POD中業(yè)務(wù)負(fù)載上升的時(shí)候,可以創(chuàng)建新的POD來保證業(yè)務(wù)系統(tǒng)穩(wěn)定運(yùn)行恩静,當(dāng)POD中業(yè)務(wù)負(fù)載下降的時(shí)候焕毫,可以銷毀POD來提高資源利用率。
工作方式
HPA的操作對象是RC驶乾、RS或Deployment對應(yīng)的Pod
根據(jù)觀察到的CPU等實(shí)際使用量與用戶的期望值進(jìn)行比對邑飒,做出是否需要增減實(shí)例數(shù)量的決策。
Horizontal Pod Autoscaling可以根據(jù)CPU使用率或應(yīng)用自定義metrics自動(dòng)擴(kuò)展Pod數(shù)量(支持replication controller级乐、deployment和replica set)疙咸。
控制管理器每隔30s(可以通過–horizontal-pod-autoscaler-sync-period修改)查詢metrics的資源使用情況
支持三種metrics類型
預(yù)定義metrics(比如Pod的CPU)以利用率的方式計(jì)算
自定義的Pod metrics,以原始值(raw value)的方式計(jì)算
自定義的object metrics
支持兩種metrics查詢方式:Heapster和自定義的REST API(Heapster 1.13版本開始廢棄)
支持多metrics (建議metrics server)
客戶端;
通過kubectl創(chuàng)建一個(gè)horizontalPodAutoscaler對象风科,并存儲到etcd中
服務(wù)端:
api server:負(fù)責(zé)接受創(chuàng)建hpa對象撒轮,然后存入etcd
hpa controler和其他的controler類似乞旦,每30s同步一次,將已經(jīng)創(chuàng)建的hpa進(jìn)行一次管理(從heapster獲取監(jiān)控?cái)?shù)據(jù)题山,查看是否需要scale, controler的store中就保存著從始至終創(chuàng)建出來的hpa兰粉,當(dāng)做一個(gè)緩存),watch hpa有變化也會運(yùn)行顶瞳。
從heapster中獲取scale數(shù)據(jù)玖姑,和hpa對比,計(jì)算cup利用率等信息慨菱,然后重新調(diào)整scale焰络。
根據(jù)hpa.Spec.ScaleTargetRef.Kind(例如Deployment,然后deployment控制器在調(diào)整pod數(shù)量)抡柿,調(diào)整其值舔琅,發(fā)送到apiserver存儲到etcd,然后更新hpa到etcd.
- k8s的控制器模式和 普通的輪詢有什么區(qū)別洲劣?
控制器模式:控制器通過 apiserver監(jiān)控集群的公共狀態(tài)备蚓,并致力于將當(dāng)前狀態(tài)轉(zhuǎn)變?yōu)槠谕臓顟B(tài)。
一個(gè)控制器至少追蹤一種類型的 Kubernetes 資源囱稽。這些 對象 有一個(gè)代表期望狀態(tài)的 spec 字段郊尝。 該資源的控制器負(fù)責(zé)確保其當(dāng)前狀態(tài)接近期望狀態(tài)。
- docker的文件系統(tǒng)是怎么做的
這正是 Docker Volume 要解決的問題:Volume 機(jī)制战惊,允許你將宿主機(jī)上指定的目錄或者文件流昏,掛載到容器里面進(jìn)行讀取和修改操作。
$ docker run -v /test ...
$ docker run -v /home:/test ...
只不過吞获,在第一種情況下况凉,由于你并沒有顯示聲明宿主機(jī)目錄,那么 Docker 就會默認(rèn)在宿主機(jī)上創(chuàng)建一個(gè)臨時(shí)目錄 /var/lib/docker/volumes/[VOLUME_ID]/_data各拷,然后把它掛載到容器的 /test 目錄上刁绒。而在第二種情況下,Docker 就直接把宿主機(jī)的 /home 目錄掛載到容器的 /test 目錄上烤黍。
而宿主機(jī)上的文件系統(tǒng)知市,也自然包括了我們要使用的容器鏡像。這個(gè)鏡像的各個(gè)層速蕊,保存在 /var/lib/docker/aufs/diff 目錄下嫂丙,在容器進(jìn)程啟動(dòng)后,它們會被聯(lián)合掛載在 /var/lib/docker/aufs/mnt/ 目錄中规哲,這樣容器所需的 rootfs 就準(zhǔn)備好了跟啤。
所以,我們只需要在 rootfs 準(zhǔn)備好之后,在執(zhí)行 chroot 之前隅肥,把 Volume 指定的宿主機(jī)目錄(比如 /home 目錄)关顷,掛載到指定的容器目錄(比如 /test 目錄)在宿主機(jī)上對應(yīng)的目錄(即 /var/lib/docker/aufs/mnt/[可讀寫層 ID]/test)上,這個(gè) Volume 的掛載工作就完成了武福。
而這里要使用到的掛載技術(shù),就是 Linux 的綁定掛載(bind mount)機(jī)制痘番。它的主要作用就是捉片,允許你將一個(gè)目錄或者文件,而不是整個(gè)設(shè)備汞舱,掛載到一個(gè)指定的目錄上伍纫。并且,這時(shí)你在該掛載點(diǎn)上進(jìn)行的任何操作昂芜,只是發(fā)生在被掛載的目錄或者文件上莹规,而原掛載點(diǎn)的內(nèi)容則會被隱藏起來且不受影響。
其實(shí)泌神,如果你了解 Linux 內(nèi)核的話良漱,就會明白,綁定掛載實(shí)際上是一個(gè) inode 替換的過程欢际。在 Linux 操作系統(tǒng)中母市,inode 可以理解為存放文件內(nèi)容的“對象”,而 dentry损趋,也叫目錄項(xiàng)患久,就是訪問這個(gè) inode 所使用的“指針”。
正如上圖所示浑槽,mount --bind /home /test蒋失,會將 /home 掛載到 /test 上。其實(shí)相當(dāng)于將 /test 的 dentry桐玻,重定向到了 /home 的 inode篙挽。這樣當(dāng)我們修改 /test 目錄時(shí),實(shí)際修改的是 /home 目錄的 inode畸冲。這也就是為何嫉髓,一旦執(zhí)行 umount 命令,/test 目錄原先的內(nèi)容就會恢復(fù):因?yàn)樾薷恼嬲l(fā)生在的邑闲,是 /home 目錄里算行。
所以,在一個(gè)正確的時(shí)機(jī)苫耸,進(jìn)行一次綁定掛載州邢,Docker 就可以成功地將一個(gè)宿主機(jī)上的目錄或文件,不動(dòng)聲色地掛載到容器中。這樣量淌,進(jìn)程在容器里對這個(gè) /test 目錄進(jìn)行的所有操作骗村,都實(shí)際發(fā)生在宿主機(jī)的對應(yīng)目錄(比如,/home呀枢,或者 /var/lib/docker/volumes/[VOLUME_ID]/_data)里胚股,而不會影響容器鏡像的內(nèi)容。那么裙秋,這個(gè) /test 目錄里的內(nèi)容琅拌,既然掛載在容器 rootfs 的可讀寫層,它會不會被 docker commit 提交掉呢摘刑?
也不會进宝。
這個(gè)原因其實(shí)我們前面已經(jīng)提到過。容器的鏡像操作枷恕,比如 docker commit党晋,都是發(fā)生在宿主機(jī)空間的。而由于 Mount Namespace 的隔離作用徐块,宿主機(jī)并不知道這個(gè)綁定掛載的存在未玻。所以,在宿主機(jī)看來胡控,容器中可讀寫層的 /test 目錄(/var/lib/docker/aufs/mnt/[可讀寫層 ID]/test)深胳,始終是空的。
不過铜犬,由于 Docker 一開始還是要?jiǎng)?chuàng)建 /test 這個(gè)目錄作為掛載點(diǎn)舞终,所以執(zhí)行了 docker commit 之后,你會發(fā)現(xiàn)新產(chǎn)生的鏡像里癣猾,會多出來一個(gè)空的 /test 目錄敛劝。畢竟,新建目錄操作纷宇,又不是掛載操作夸盟,Mount Namespace 對它可起不到“障眼法”的作用。
- docker的exec -ti 像捶, 底層是怎么做的
$ docker inspect --format '{{ .State.Pid }}' 4ddf4638572d25686
$ ls -l /proc/25686/ns
total 0
lrwxrwxrwx 1 root root 0 Aug 13 14:05 cgroup -> cgroup:[4026531835]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 ipc -> ipc:[4026532278]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 mnt -> mnt:[4026532276]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 net -> net:[4026532281]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 pid -> pid:[4026532279]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 pid_for_children -> pid:[4026532279]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Aug 13 14:05 uts -> uts:[4026532277]
可以看到上陕,一個(gè)進(jìn)程的每種 Linux Namespace,都在它對應(yīng)的 /proc/[進(jìn)程號]/ns 下有一個(gè)對應(yīng)的虛擬文件拓春,并且鏈接到一個(gè)真實(shí)的 Namespace 文件上释簿。有了這樣一個(gè)可以“hold 住”所有 Linux Namespace 的文件,我們就可以對 Namespace 做一些很有意義事情了硼莽,比如:加入到一個(gè)已經(jīng)存在的 Namespace 當(dāng)中庶溶。
這也就意味著:一個(gè)進(jìn)程,可以選擇加入到某個(gè)進(jìn)程已有的 Namespace 當(dāng)中,從而達(dá)到“進(jìn)入”這個(gè)進(jìn)程所在容器的目的偏螺,這正是 docker exec 的實(shí)現(xiàn)原理行疏。
而這個(gè)操作所依賴的,乃是一個(gè)名叫 setns() 的 Linux 系統(tǒng)調(diào)用套像。
這段代碼的核心操作酿联,則是通過 open() 系統(tǒng)調(diào)用打開了指定的 Namespace 文件,并把這個(gè)文件的描述符 fd 交給 setns() 使用夺巩。在 setns() 執(zhí)行后货葬,當(dāng)前進(jìn)程就加入了這個(gè)文件對應(yīng)的 Linux Namespace 當(dāng)中了。
$ ls -l /proc/28499/ns/net
lrwxrwxrwx 1 root root 0 Aug 13 14:18 /proc/28499/ns/net -> net:[4026532281]
$ ls -l /proc/25686/ns/net
lrwxrwxrwx 1 root root 0 Aug 13 14:05 /proc/25686/ns/net -> net:[4026532281]
在 /proc/[PID]/ns/net 目錄下劲够,這個(gè) PID=28499 進(jìn)程,與我們前面的 Docker 容器進(jìn)程(PID=25686)指向的 Network Namespace 文件完全一樣休傍。這說明這兩個(gè)進(jìn)程征绎,共享了這個(gè)名叫 net:[4026532281]的 Network Namespace。
MySQL事務(wù)隔離級別
MySQL如何解決慢查詢磨取,實(shí)際項(xiàng)目中怎么去優(yōu)化人柿,具體的問題,實(shí)際效果提升了多少忙厌,有做過測試嗎凫岖?
后面有繼續(xù)分析問題的瓶頸在哪里嗎,最后壓力測試的QPS
Redis和MySQL相比逢净,為什么更快
Redis單線程為什么性能好
Redis的數(shù)據(jù)結(jié)構(gòu)
Redis和數(shù)據(jù)庫的使用場景上的區(qū)別
Redis和MySQL 性能差多少哥放?
為什么MySQL的QPS很低
k8s有哪些組件?
bloom filter實(shí)現(xiàn)原理
如果每天早上7點(diǎn)想ping一下美團(tuán)的網(wǎng)站爹土,整個(gè)ping過程持續(xù)三分鐘甥雕,如果延遲超過100ms就發(fā)出警告給運(yùn)維人員,并把所有ping的結(jié)果寫入到日志中胀茵,設(shè)計(jì)一個(gè)腳本方案
如果想把ping的時(shí)間記錄進(jìn)去社露,怎么做
如果發(fā)生了100ms以上的延遲,怎么查找問題出在哪
OSPF與RIP的區(qū)別
Mysql高可用怎么做的
Mysql主從的原理琼娘,如果主庫寫了bin-log但是還沒來得及發(fā)給從庫就宕機(jī)了峭弟,怎么避免數(shù)據(jù)的丟失(我說了雙主架構(gòu),所以就有下面的問題)
為什么要雙主架構(gòu)脱拼、雙主架構(gòu)的優(yōu)勢和劣勢
RST標(biāo)志位是什么瞒瘸?為什么需要這個(gè)標(biāo)志位?什么時(shí)候需要
端口不可達(dá)linux內(nèi)存:buffer cache swap講下
Buffer cache 也叫塊緩沖熄浓,是對物理磁盤上的一個(gè)磁盤塊進(jìn)行的緩沖挨务,其大小為通常為1k,磁盤塊也是磁盤的組織單位。
設(shè)立buffer cache的目的是為在程序多次訪問同一磁盤塊時(shí)谎柄,減少訪問時(shí)間丁侄。
系統(tǒng)將磁盤塊首先讀入buffer cache,如果cache空間不夠時(shí)朝巫,會通過一定的策略將一些過時(shí)或多次未被訪問的buffer cache清空鸿摇。
程序在下一次訪問磁盤時(shí)首先查看是否在buffer cache找到所需塊,命中可減少訪問磁盤時(shí)間劈猿。不命中時(shí)需重新讀入buffer cache拙吉。
對buffer cache的寫分為兩種,一是直接寫揪荣,這是程序在寫buffer cache后也寫磁盤筷黔,要讀時(shí)從buffer cache上讀,二是后臺寫仗颈,程序在寫完buffer cache后并不立即寫磁盤佛舱,因?yàn)橛锌赡艹绦蛟诤芏虝r(shí)間內(nèi)又需要寫文件,如果直接寫挨决,就需多次寫磁盤了请祖。
這樣效率很低,而是過一段時(shí)間后由后臺寫脖祈,減少了多次訪磁盤的時(shí)間肆捕。
Buffer cache是由物理內(nèi)存分配,Linux系統(tǒng)為提高內(nèi)存使用率盖高,會將空閑內(nèi)存全分給buffer cache 慎陵,當(dāng)其他程序需要更多內(nèi)存時(shí),系統(tǒng)會減少cache大小喻奥。
Page cache 也叫頁緩沖或文件緩沖荆姆,是由好幾個(gè)磁盤塊構(gòu)成,大小通常為4k映凳,在64位系統(tǒng)上為8k胆筒,構(gòu)成的幾個(gè)磁盤塊在物理磁盤上不一定連續(xù),文件的組織單位為一頁诈豌, 也就是一個(gè)page cache大小仆救,文件讀取是由外存上不連續(xù)的幾個(gè)磁盤塊,到buffer cache矫渔,然后組成page cache彤蔽,然后供給應(yīng)用程序。
Page cache在linux讀寫文件時(shí)庙洼,它用于緩存文件的邏輯內(nèi)容顿痪,從而加快對磁盤上映像和數(shù)據(jù)的訪問镊辕。
具體說是加速對文件內(nèi)容的訪問,buffer cache緩存文件的具體內(nèi)容——物理磁盤上的磁盤塊蚁袭,這是加速對磁盤的訪問征懈。
- swap 作用, swap是在哪揩悄,在磁盤還是在內(nèi)存上
Swap space交換空間卖哎,是虛擬內(nèi)存的表現(xiàn)形式。
系統(tǒng)為了應(yīng)付一些需要大量內(nèi)存的應(yīng)用删性,而將磁盤上的空間做內(nèi)存使用亏娜,當(dāng)物理內(nèi)存不夠用時(shí),將其中一些暫時(shí)不需的數(shù)據(jù)交換到交換空間蹬挺,也叫交換文件或頁面文件中维贺。
做虛擬內(nèi)存的好處是讓進(jìn)程以為好像可以訪問整個(gè)系統(tǒng)物理內(nèi)存。
因?yàn)樵谝粋€(gè)進(jìn)程訪問數(shù)據(jù)時(shí)巴帮,其他進(jìn)程的數(shù)據(jù)會被交換到交換空間中溯泣。