linux啟動(dòng)過(guò)程
BIOS->MBR->引導(dǎo)加載程序->內(nèi)核文件RIAD
raid0,同一份數(shù)據(jù)交替寫(xiě)入兩個(gè)磁盤(pán)
raid1,同一份數(shù)據(jù)同時(shí)寫(xiě)入兩個(gè)磁盤(pán)
raid5,三個(gè)磁盤(pán),數(shù)據(jù)寫(xiě)入兩個(gè)磁盤(pán),往另外一個(gè)盤(pán)寫(xiě)入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, 通過(guò)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ù)存儲(chǔ):
Etcd
- schedule 的作用
第一個(gè)控制循環(huán):informer path
啟動(dòng)一系列informer,用來(lái)監(jiān)聽(tīng)etcd中的pod,node,service等與調(diào)度相關(guān)的API對(duì)象的變化
將pod放入priorityQueue
第二個(gè)循環(huán):scheduling path
不斷的從調(diào)度隊(duì)列中出隊(duì)一個(gè)pod,然后調(diào)用predicates算法進(jìn)行過(guò)濾
再按照priorities算法對(duì)列表中的node打分
更新scheduler cache中的pod和node的信息,這種基于樂(lè)觀假設(shè)API對(duì)象更新方式,在kubernetes中被稱(chēng)作Assume
Assume之后,調(diào)度器會(huì)創(chuàng)建一個(gè)Goroutine來(lái)異步地向APIServer發(fā)起更新pod的請(qǐng)求,來(lái)完成真正的Bind操作
當(dāng)新的pod在某個(gè)節(jié)點(diǎn)上運(yùn)行起來(lái)之前,該節(jié)點(diǎn)上的kubelet還會(huì)通過(guò)一個(gè)叫做Admit的操作來(lái)驗(yàn)證改pod是否確實(shí)能夠運(yùn)行在該節(jié)點(diǎn)上
搶占調(diào)度:
第一個(gè)隊(duì)列,叫作 activeQ。凡是在 activeQ 里的 Pod,都是下一個(gè)調(diào)度周期需要調(diào)度的對(duì)象。
第二個(gè)隊(duì)列,叫作 unschedulableQ,專(zhuān)門(mén)用來(lái)存放調(diào)度失敗的 Pod。
- kublet的作用是?
設(shè)置listers,注冊(cè)它所關(guān)心的各種事件的Informer,這些Informer,就是sync Loop需要處理的數(shù)據(jù)的來(lái)源
子控制循環(huán):Volume Manager,Image Manager,Node Status Manager
通過(guò)控制器模式,完成kublet的某項(xiàng)具體職責(zé)
kubelet 調(diào)用下層容器運(yùn)行時(shí)的執(zhí)行過(guò)程,并不會(huì)直接調(diào)用 Docker 的 API,而是通過(guò)一組叫作 CRI(Container Runtime Interface,容器運(yùn)行時(shí)接口)的 gRPC 接口來(lái)間接執(zhí)行的。
- controller-manager內(nèi)部結(jié)構(gòu)圖
Controller Manager作為集群內(nèi)部的管理控制中心,負(fù)責(zé)集群內(nèi)的Node、Pod副本、服務(wù)端點(diǎn)(Endpoint)、命名空間(Namespace)、服務(wù)賬號(hào)(ServiceAccount)、資源定額(ResourceQuota)的管理,當(dāng)某個(gè)Node意外宕機(jī)時(shí),Controller Manager會(huì)及時(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ù)可以對(duì)CPU做隔離
cpuacct.usage
cpuacct.usage_percpu
cpu.cfs_period_us
cpu.cfs_quota_us
k8s是平臺(tái)層能力的變革?為什么
k8s怎么做水平拓展的
HPA簡(jiǎn)介
HPA全稱(chēng)Horizontal Pod Autoscaling,即pod的水平自動(dòng)擴(kuò)展。
自動(dòng)擴(kuò)展主要分為兩種,其一為水平擴(kuò)展,針對(duì)于實(shí)例數(shù)目的增減;其二為垂直擴(kuò)展,即單個(gè)實(shí)例可以使用的資源的增減。HPA屬于前者。
云計(jì)算具有水平彈性的特性,這個(gè)是云計(jì)算區(qū)別于傳統(tǒng)IT技術(shù)架構(gòu)的主要特性。對(duì)于Kubernetes中的POD集群來(lái)說(shuō),HPA可以實(shí)現(xiàn)很多自動(dòng)化功能,比如當(dāng)POD中業(yè)務(wù)負(fù)載上升的時(shí)候,可以創(chuàng)建新的POD來(lái)保證業(yè)務(wù)系統(tǒng)穩(wěn)定運(yùn)行,當(dāng)POD中業(yè)務(wù)負(fù)載下降的時(shí)候,可以銷(xiāo)毀POD來(lái)提高資源利用率。
工作方式
HPA的操作對(duì)象是RC、RS或Deployment對(duì)應(yīng)的Pod
根據(jù)觀察到的CPU等實(shí)際使用量與用戶(hù)的期望值進(jìn)行比對(duì),做出是否需要增減實(shí)例數(shù)量的決策。
Horizontal Pod Autoscaling可以根據(jù)CPU使用率或應(yīng)用自定義metrics自動(dòng)擴(kuò)展Pod數(shù)量(支持replication controller、deployment和replica set)。
控制管理器每隔30s(可以通過(guò)–horizontal-pod-autoscaler-sync-period修改)查詢(xún)metrics的資源使用情況
支持三種metrics類(lèi)型
預(yù)定義metrics(比如Pod的CPU)以利用率的方式計(jì)算
自定義的Pod metrics,以原始值(raw value)的方式計(jì)算
自定義的object metrics
支持兩種metrics查詢(xún)方式:Heapster和自定義的REST API(Heapster 1.13版本開(kāi)始廢棄)
支持多metrics (建議metrics server)
客戶(hù)端;
通過(guò)kubectl創(chuàng)建一個(gè)horizontalPodAutoscaler對(duì)象,并存儲(chǔ)到etcd中
服務(wù)端:
api server:負(fù)責(zé)接受創(chuàng)建hpa對(duì)象,然后存入etcd
hpa controler和其他的controler類(lèi)似,每30s同步一次,將已經(jīng)創(chuàng)建的hpa進(jìn)行一次管理(從heapster獲取監(jiān)控?cái)?shù)據(jù),查看是否需要scale, controler的store中就保存著從始至終創(chuàng)建出來(lái)的hpa,當(dāng)做一個(gè)緩存),watch hpa有變化也會(huì)運(yùn)行。
從heapster中獲取scale數(shù)據(jù),和hpa對(duì)比,計(jì)算cup利用率等信息,然后重新調(diào)整scale。
根據(jù)hpa.Spec.ScaleTargetRef.Kind(例如Deployment,然后deployment控制器在調(diào)整pod數(shù)量),調(diào)整其值,發(fā)送到apiserver存儲(chǔ)到etcd,然后更新hpa到etcd.
- k8s的控制器模式和 普通的輪詢(xún)有什么區(qū)別?
控制器模式:控制器通過(guò) apiserver監(jiān)控集群的公共狀態(tài),并致力于將當(dāng)前狀態(tài)轉(zhuǎn)變?yōu)槠谕臓顟B(tài)。
一個(gè)控制器至少追蹤一種類(lèi)型的 Kubernetes 資源。這些 對(duì)象 有一個(gè)代表期望狀態(tài)的 spec 字段。 該資源的控制器負(fù)責(zé)確保其當(dāng)前狀態(tài)接近期望狀態(tài)。
- docker的文件系統(tǒng)是怎么做的
這正是 Docker Volume 要解決的問(wèn)題:Volume 機(jī)制,允許你將宿主機(jī)上指定的目錄或者文件,掛載到容器里面進(jìn)行讀取和修改操作。
$ docker run -v /test ...
$ docker run -v /home:/test ...
只不過(guò),在第一種情況下,由于你并沒(méi)有顯示聲明宿主機(jī)目錄,那么 Docker 就會(huì)默認(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)后,它們會(huì)被聯(lián)合掛載在 /var/lib/docker/aufs/mnt/ 目錄中,這樣容器所需的 rootfs 就準(zhǔn)備好了。
所以,我們只需要在 rootfs 準(zhǔn)備好之后,在執(zhí)行 chroot 之前,把 Volume 指定的宿主機(jī)目錄(比如 /home 目錄),掛載到指定的容器目錄(比如 /test 目錄)在宿主機(jī)上對(duì)應(yīng)的目錄(即 /var/lib/docker/aufs/mnt/[可讀寫(xiě)層 ID]/test)上,這個(gè) Volume 的掛載工作就完成了。
而這里要使用到的掛載技術(shù),就是 Linux 的綁定掛載(bind mount)機(jī)制。它的主要作用就是,允許你將一個(gè)目錄或者文件,而不是整個(gè)設(shè)備,掛載到一個(gè)指定的目錄上。并且,這時(shí)你在該掛載點(diǎn)上進(jìn)行的任何操作,只是發(fā)生在被掛載的目錄或者文件上,而原掛載點(diǎn)的內(nèi)容則會(huì)被隱藏起來(lái)且不受影響。
其實(shí),如果你了解 Linux 內(nèi)核的話,就會(huì)明白,綁定掛載實(shí)際上是一個(gè) inode 替換的過(guò)程。在 Linux 操作系統(tǒng)中,inode 可以理解為存放文件內(nèi)容的“對(duì)象”,而 dentry,也叫目錄項(xiàng),就是訪問(wèn)這個(gè) inode 所使用的“指針”。
正如上圖所示,mount --bind /home /test,會(huì)將 /home 掛載到 /test 上。其實(shí)相當(dāng)于將 /test 的 dentry,重定向到了 /home 的 inode。這樣當(dāng)我們修改 /test 目錄時(shí),實(shí)際修改的是 /home 目錄的 inode。這也就是為何,一旦執(zhí)行 umount 命令,/test 目錄原先的內(nèi)容就會(huì)恢復(fù):因?yàn)樾薷恼嬲l(fā)生在的,是 /home 目錄里。
所以,在一個(gè)正確的時(shí)機(jī),進(jìn)行一次綁定掛載,Docker 就可以成功地將一個(gè)宿主機(jī)上的目錄或文件,不動(dòng)聲色地掛載到容器中。這樣,進(jìn)程在容器里對(duì)這個(gè) /test 目錄進(jìn)行的所有操作,都實(shí)際發(fā)生在宿主機(jī)的對(duì)應(yīng)目錄(比如,/home,或者 /var/lib/docker/volumes/[VOLUME_ID]/_data)里,而不會(huì)影響容器鏡像的內(nèi)容。那么,這個(gè) /test 目錄里的內(nèi)容,既然掛載在容器 rootfs 的可讀寫(xiě)層,它會(huì)不會(huì)被 docker commit 提交掉呢?
也不會(huì)。
這個(gè)原因其實(shí)我們前面已經(jīng)提到過(guò)。容器的鏡像操作,比如 docker commit,都是發(fā)生在宿主機(jī)空間的。而由于 Mount Namespace 的隔離作用,宿主機(jī)并不知道這個(gè)綁定掛載的存在。所以,在宿主機(jī)看來(lái),容器中可讀寫(xiě)層的 /test 目錄(/var/lib/docker/aufs/mnt/[可讀寫(xiě)層 ID]/test),始終是空的。
不過(guò),由于 Docker 一開(kāi)始還是要?jiǎng)?chuàng)建 /test 這個(gè)目錄作為掛載點(diǎn),所以執(zhí)行了 docker commit 之后,你會(huì)發(fā)現(xiàn)新產(chǎn)生的鏡像里,會(huì)多出來(lái)一個(gè)空的 /test 目錄。畢竟,新建目錄操作,又不是掛載操作,Mount Namespace 對(duì)它可起不到“障眼法”的作用。
- 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,都在它對(duì)應(yīng)的 /proc/[進(jìn)程號(hào)]/ns 下有一個(gè)對(duì)應(yīng)的虛擬文件,并且鏈接到一個(gè)真實(shí)的 Namespace 文件上。有了這樣一個(gè)可以“hold 住”所有 Linux Namespace 的文件,我們就可以對(duì) 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è)操作所依賴(lài)的,乃是一個(gè)名叫 setns() 的 Linux 系統(tǒng)調(diào)用。
這段代碼的核心操作,則是通過(guò) open() 系統(tǒng)調(diào)用打開(kāi)了指定的 Namespace 文件,并把這個(gè)文件的描述符 fd 交給 setns() 使用。在 setns() 執(zhí)行后,當(dāng)前進(jìn)程就加入了這個(gè)文件對(duì)應(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 文件完全一樣。這說(shuō)明這兩個(gè)進(jìn)程,共享了這個(gè)名叫 net:[4026532281]的 Network Namespace。
MySQL事務(wù)隔離級(jí)別
MySQL如何解決慢查詢(xún),實(shí)際項(xiàng)目中怎么去優(yōu)化,具體的問(wèn)題,實(shí)際效果提升了多少,有做過(guò)測(cè)試嗎?
后面有繼續(xù)分析問(wèn)題的瓶頸在哪里嗎,最后壓力測(cè)試的QPS
Redis和MySQL相比,為什么更快
Redis單線程為什么性能好
Redis的數(shù)據(jù)結(jié)構(gòu)
Redis和數(shù)據(jù)庫(kù)的使用場(chǎng)景上的區(qū)別
Redis和MySQL 性能差多少?
為什么MySQL的QPS很低
k8s有哪些組件?
bloom filter實(shí)現(xiàn)原理
如果每天早上7點(diǎn)想ping一下美團(tuán)的網(wǎng)站,整個(gè)ping過(guò)程持續(xù)三分鐘,如果延遲超過(guò)100ms就發(fā)出警告給運(yùn)維人員,并把所有ping的結(jié)果寫(xiě)入到日志中,設(shè)計(jì)一個(gè)腳本方案
如果想把ping的時(shí)間記錄進(jìn)去,怎么做
如果發(fā)生了100ms以上的延遲,怎么查找問(wèn)題出在哪
OSPF與RIP的區(qū)別
Mysql高可用怎么做的
Mysql主從的原理,如果主庫(kù)寫(xiě)了bin-log但是還沒(méi)來(lái)得及發(fā)給從庫(kù)就宕機(jī)了,怎么避免數(shù)據(jù)的丟失(我說(shuō)了雙主架構(gòu),所以就有下面的問(wèn)題)
為什么要雙主架構(gòu)、雙主架構(gòu)的優(yōu)勢(shì)和劣勢(shì)
RST標(biāo)志位是什么?為什么需要這個(gè)標(biāo)志位?什么時(shí)候需要
端口不可達(dá)linux內(nèi)存:buffer cache swap講下
Buffer cache 也叫塊緩沖,是對(duì)物理磁盤(pán)上的一個(gè)磁盤(pán)塊進(jìn)行的緩沖,其大小為通常為1k,磁盤(pán)塊也是磁盤(pán)的組織單位。
設(shè)立buffer cache的目的是為在程序多次訪問(wèn)同一磁盤(pán)塊時(shí),減少訪問(wèn)時(shí)間。
系統(tǒng)將磁盤(pán)塊首先讀入buffer cache,如果cache空間不夠時(shí),會(huì)通過(guò)一定的策略將一些過(guò)時(shí)或多次未被訪問(wèn)的buffer cache清空。
程序在下一次訪問(wèn)磁盤(pán)時(shí)首先查看是否在buffer cache找到所需塊,命中可減少訪問(wèn)磁盤(pán)時(shí)間。不命中時(shí)需重新讀入buffer cache。
對(duì)buffer cache的寫(xiě)分為兩種,一是直接寫(xiě),這是程序在寫(xiě)buffer cache后也寫(xiě)磁盤(pán),要讀時(shí)從buffer cache上讀,二是后臺(tái)寫(xiě),程序在寫(xiě)完buffer cache后并不立即寫(xiě)磁盤(pán),因?yàn)橛锌赡艹绦蛟诤芏虝r(shí)間內(nèi)又需要寫(xiě)文件,如果直接寫(xiě),就需多次寫(xiě)磁盤(pán)了。
這樣效率很低,而是過(guò)一段時(shí)間后由后臺(tái)寫(xiě),減少了多次訪磁盤(pán)的時(shí)間。
Buffer cache是由物理內(nèi)存分配,Linux系統(tǒng)為提高內(nèi)存使用率,會(huì)將空閑內(nèi)存全分給buffer cache ,當(dāng)其他程序需要更多內(nèi)存時(shí),系統(tǒng)會(huì)減少cache大小。
Page cache 也叫頁(yè)緩沖或文件緩沖,是由好幾個(gè)磁盤(pán)塊構(gòu)成,大小通常為4k,在64位系統(tǒng)上為8k,構(gòu)成的幾個(gè)磁盤(pán)塊在物理磁盤(pán)上不一定連續(xù),文件的組織單位為一頁(yè), 也就是一個(gè)page cache大小,文件讀取是由外存上不連續(xù)的幾個(gè)磁盤(pán)塊,到buffer cache,然后組成page cache,然后供給應(yīng)用程序。
Page cache在linux讀寫(xiě)文件時(shí),它用于緩存文件的邏輯內(nèi)容,從而加快對(duì)磁盤(pán)上映像和數(shù)據(jù)的訪問(wèn)。
具體說(shuō)是加速對(duì)文件內(nèi)容的訪問(wèn),buffer cache緩存文件的具體內(nèi)容——物理磁盤(pán)上的磁盤(pán)塊,這是加速對(duì)磁盤(pán)的訪問(wèn)。
- swap 作用, swap是在哪,在磁盤(pán)還是在內(nèi)存上
Swap space交換空間,是虛擬內(nèi)存的表現(xiàn)形式。
系統(tǒng)為了應(yīng)付一些需要大量?jī)?nèi)存的應(yīng)用,而將磁盤(pán)上的空間做內(nèi)存使用,當(dāng)物理內(nèi)存不夠用時(shí),將其中一些暫時(shí)不需的數(shù)據(jù)交換到交換空間,也叫交換文件或頁(yè)面文件中。
做虛擬內(nèi)存的好處是讓進(jìn)程以為好像可以訪問(wèn)整個(gè)系統(tǒng)物理內(nèi)存。
因?yàn)樵谝粋€(gè)進(jìn)程訪問(wèn)數(shù)據(jù)時(shí),其他進(jìn)程的數(shù)據(jù)會(huì)被交換到交換空間中。