中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Kubernetes 部署微服務項目踩坑經驗分享

發布時間:2020-07-27 22:50:45 來源:網絡 閱讀:407 作者:yzy121403725 欄目:云計算

導讀

本文給你分享我在K8S生產環境上部署微服務項目遇到的問題:

1、限制了容器資源,還經常被殺死?

2、滾動更新之健康檢查重要性

3、滾動更新之流量的丟失

先說一下第一個問題,限制容器資源,還經常去殺死的原因?


就是說部署的java應用,不一會就重啟了,其實重啟就是在重建了,這就意味著你的pod是不健康的,然后k8s重新再幫你去拉取了,這樣的話就要去找問題去排查了,說白了其實就是被殺死了,可以通過describe去查看一下事件,一般都會能看到,由于健康狀態檢查沒通過,然后再去拉取的,因為是java應用,由于堆內存溢出,然后被kill掉,在日志最后一行會出現一個kill的字段,看一下它重啟的原因,之前我遇到的是它的堆內存沒限制住,它本身有jvm,jvm主要有內存做交換數據的,它堆內存主要是性能設計的一個體現,所以他的堆內存很容易就會超出,超出之后呢,很可能會被k8s殺死掉,
為什么k8s會kill它,因為它超出了限制,默認容器會使用宿主機所有的資源,如果不做資源限制,會影響整個宿主機,然后整個宿主機資源不夠會實現飄移,會轉移到其他主機上,然后再異常,可能會起到一種雪崩的效應,所以一般我們都是要做資源限制的,難道這個限制,限制不了java應用嗎?其實它是限制不住的,雖然k8s部署應用還是很方便的,但是部署java應用還是不兼容的,比如它不能識別當前java容器的限制,就是不能識別我們指定的限制,也就是你在yaml去限制的,容器的堆內存沒有限制,它就會超出這個限制,如果超出這個limits的限制,k8s就會把它殺掉,k8s自身它有這個策略,如果超出這個容量的限制,就會幫你殺掉,再幫你拉起。

面對java這樣的堆內存稍微有一點流量突發,就可能資料利用率就上來了,所以這個幅度還是比較大的,這樣就會導致k8s殺掉,然后再拉起,這樣循環,可能一天幾百次的這樣效果。

說到這個問題,怎么來解決docker的資源限制,其實這個資源限制還是用的這個docker來做的,只不過k8s把他轉換成了,只不過k8s去調用接口去做一些限制,其實就是怎么讓docker去識別java堆內存的限制,來解決這個問題。
來解決這個問題有兩種方案,也就是為這個java再配置堆內存的使用,Java -Xmx最大的堆內存使用,一個是-Xms是初始的堆內存使用。

一般都設置一個最大的堆內存使用,如果不設置超出這個設置會不斷使用宿主機的一個內存,而導致物理內存不夠用,而出現堆內存溢出的現象,這個很普遍,我們就用這個java -Xmx就是當快用滿時,它會有一個垃圾回收,再進行循環的使用,這樣能保證這個java應用穩定的運行,所有我們在yaml去配置資源限制肯定是不夠的,我們必須為這個java去設置這個堆內存,我們不可能手動的在Dockerfile去寫這個吧,一般在dockerfile去傳入這個值,在yaml文件里設置一個變量:

env:
?- name: JAVA_OPTS

? ? value: “-Xmx1g “

下面就是我們之前配置的容器資源的一些限制這個變量就會就會傳入pod里面,也就是這個構建鏡像的容器里,也就是起到容器CMD 命令下去傳入$JAVA_OPTS的變量,它會調用我們系統的系統變量,這個系統變量已經賦予它值了,所以它能直接飲用這個變量了,去起到這個應用,從而設置這個堆內存大小,這個值建議要比limlts要小一點,小個10%吧,因為超過這個limits限制就會殺死,再拉取了。
一般設置好,重建一下鏡像,進入容器中去查看一下進程就可以看到,其他的也是這么設置的。

第二個問題,滾動更新之健康檢查的重要性

滾動更新是k8s的默認策略,一般咱們部署到k8s之后第一個會使用到的,當你配置了健康檢查時,滾動更新會根據probe的狀態來判斷是不是繼續的更新允許接入流量,也就是你當前的應用是不是提供服務,這樣你滾動更新的過程中,才會確保你是不是有可用的節點,保證一個平滑的升級,所以這是滾動更新設置的一個之初,那健康狀態檢查是很重要的!

健康狀態檢查在滾動更新啟動什么作用呢?

列入一個副本,啟動之后提供業務需要一分鐘才能提供服務,比如java啟動比較慢,如果沒有健康狀態檢查,來確保他是不是準備好,就直接認為它準備好了,這期間啟動起來,一分鐘之內它是無法提供服務的,所以新來的流量肯定是無法處理的,這是第一種情況,第二種情況,由于人為的配置錯誤,比如連接不上數據庫了,或者連接不上其他地方了,或者配置文件哪里寫錯了,那觸發一個滾動更新,那這個pod呢全部滾動更新完成了,結果都是由問題的,這樣的話,新副本都把舊副本替換掉了,這樣的話,生產環境中后果很嚴重的,很多服務都會無法提供了,所以在配置滾動更新的時候,健康狀態檢查一定要配上,那配上了健康狀態檢查之后,新的副本檢查完成之后才會轉發新的流量,如果它沒有通過它不會全部替換的,也就是它不會繼續更新了,因為它是有一個可用節點的限制,如果可用節點達不到這個數,就不會繼續更新。

健康狀態檢查有兩種類型:

  • readinessProbe:就緒檢查,也就是你的Pod檢查失敗,如果是http,可以通過一個頁面去探測,判斷這個返回狀態碼,如果探測這個本地的端口不通的話,它不會讓它加入service后面,因為service作為你整個的統一訪問入口嘛,如果它不通過的話,新的流量也不會轉發給它,這就是就緒檢查,如果健康狀態不通過不會給你轉發新的流量,另外就是initialDelaySeconds:60,就是檢查60秒,因為一般java應用啟動也就是一分鐘左右,還有一個periodSeconds:10,也就是沒通過10秒鐘在做一次。

  • livenessProbe:存活檢查,也就是檢查失敗它會殺死容器,根據你重啟策略,一般是重建,再給你新拉取一個容器,再判斷有沒有準備好,判斷的方法也是根據端口的探測這些的,或者特可以用其他兩種方法,http,exec,所以一般這兩個都要配置上,就緒檢查呢就是不為你分配新的流量,存活檢查就是去幫你重新拉取。


這兩種檢查也有不同的探測方式,比如http,探測一個url,還有tcp socket,端口的探測,還有一個執行shell命令,執行一個shell命令,判斷一個返回值。

最后一個問題滾動更新之丟失的流量

一般現象就是連接拒絕,響應錯誤,調用不到。
滾動更新是關閉現有的pod,再起一新的pod,關閉現有的其實是就是刪除了一個pod,然后apiserver會通知給kubelet,然后kubelet會關閉這個容器,然后從service后端摘掉,就不分發新的流量了,然后移除掉,然后再告訴kube-proxy,你可以處理新的轉發規則了,然后調度到節點上,其實這也是一個pod的下線周期。
另外再轉發的過程中,轉發新的pod時間段里,它是有間隔的,關閉pod之后會有一個等待時間,在這個時間呢,可能還會接入一些新的流量,但是它的服務已經不再處理新的請求了,所以會導致連接拒絕了,怎么去解決這個問題呢,實際上readiness探針在整個過程中并起到關鍵的作用,一旦endpoint收到pod 的刪除事件后,這已經就與readiness探測結果不相關了。

怎么保證它優雅的去處理呢?
其實之需要在
關閉這個pod 時加個休眠的時間,其實就可以解決這個問題了,在關閉和啟動都是有一個鉤子存在的,所有可以在關閉容器前,執行這個鉤子,鉤子這個定義一個shell,也可以定義一個http請求,也就是支持者兩種類型,也就是在container同級,env這里。
休眠5秒也就是你關閉的容器不會馬上退出,然后休眠5秒鐘,再去關閉著應用,這5秒能夠足夠讓kube-proxy刷新這個規則,這樣的話,就不會將新加入的流量轉發到這個剛關閉的pod上,增加這個鉤子就能暫緩你關閉pod的時間,從而讓kube-proxy增加刷新規則的時間。如下:

lifecycle :
?preStop:
? exec:
? ? ?command :
? ? ? ? ?- sh
? ? ? ? ?- -c
? ? ? ? ?- “sleep 5”

這樣,你不需要修改你應用的代碼,就能解決該問題了。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武陟县| 达州市| 天镇县| 宁都县| 阳西县| 漳平市| 敦化市| 丹江口市| 大冶市| 乾安县| 忻城县| 遂昌县| 翼城县| 灵川县| 枣强县| 丰顺县| 富锦市| 荥阳市| 合山市| 武山县| 逊克县| 福建省| 尉氏县| 镇平县| 兴文县| 开远市| 富川| 融水| 滦平县| 娄烦县| 长武县| 黄陵县| 松潘县| 湄潭县| 靖安县| 泰兴市| 台南市| 堆龙德庆县| 独山县| 拜泉县| 阿坝县|