<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用K8s的一些經(jīng)驗(yàn)和體會

          共 6147字,需瀏覽 13分鐘

           ·

          2021-01-21 09:28

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          ? 作者?|? 常見-youmen

          來源 |? urlify.cn/Bjq2ay

          76套java從入門到精通實(shí)戰(zhàn)課程分享

          1、坑

          1.1Java應(yīng)用程序的奇怪案例


          在微服務(wù)和容器化方面,工程師傾向于避免使用 Java,這主要是由于 Java 臭名昭著的內(nèi)存管理。但是,現(xiàn)在情況發(fā)生了改變,過去幾年來 Java 的容器兼容性得到了改善。畢竟,大量的系統(tǒng)(例如Apache Kafka和Elasticsearch)在 Java 上運(yùn)行。


          ?回顧 2017-18 年度,我們有一些應(yīng)用程序在 Java 8 上運(yùn)行。這些應(yīng)用程序通常很難理解像 Docker 這樣的容器環(huán)境,并因堆內(nèi)存問題和異常的垃圾回收趨勢而崩潰。我們了解到,這是由于 JVM 無法使用Linuxcgroup和namespace造成的,而它們是容器化技術(shù)的核心。


          ?但是,從那時(shí)起,Oracle 一直在不斷提高 Java 在容器領(lǐng)域的兼容性。甚至 Java 8 的后續(xù)補(bǔ)丁都引入了實(shí)驗(yàn)性的 JVM標(biāo)志來解決這些,XX:+UnlockExperimentalVMOptions和XX:+UseCGroupMemoryLimitForHeap。

          ?但是,盡管做了所有的這些改進(jìn),不可否認(rèn)的是,Java 在內(nèi)存占用方面仍然聲譽(yù)不佳,與 Python 或 Go 等同行相比啟動(dòng)速度慢。這主要是由 JVM 的內(nèi)存管理和類加載器引起的。

          ?現(xiàn)在,如果我們必須選擇 Java,請確保版本為 11 或更高。并且 Kubernetes 的內(nèi)存限制要在 JVM 最大堆內(nèi)存(-Xmx)的基礎(chǔ)上增加 1GB,以留有余量。也就是說,如果 JVM 使用 8GB 的堆內(nèi)存,則我們對該應(yīng)用程序的 Kubernetes 資源限制為 9GB。

          1.2Kubernetes生命周期管理: 升級

          ?Kubernetes 生命周期管理(例如升級或增強(qiáng))非常繁瑣,尤其是如果已經(jīng)在?裸金屬或虛擬機(jī)?上構(gòu)建了自己的集群。對于升級,我們已經(jīng)意識到,最簡單的方法是使用最新版本構(gòu)建新集群,并將工作負(fù)載從舊版本過渡到新版本。節(jié)點(diǎn)原地升級所做的努力和計(jì)劃是不值得的。


          ?Kubernetes 具有多個(gè)活動(dòng)組件,需要升級保持一致。從 Docker 到 Calico 或 Flannel 之類的 CNI 插件,你需要仔細(xì)地將它們組合在一起才能正常工作。雖然像 Kubespray、Kubeone、Kops 和 Kubeaws 這樣的項(xiàng)目使它變得更容易,但它們都有缺點(diǎn).


          ?我們在 RHEL 虛擬機(jī)上使用 Kubespray 構(gòu)建了自己的集群。Kubespray 非常棒,它具有用于構(gòu)建、添加和刪除新節(jié)點(diǎn)、升級版本的 playbook,以及我們在生產(chǎn)環(huán)境中操作 Kubernetes 所需的幾乎所有內(nèi)容。但是,用于升級的 playbook 附帶了免責(zé)聲明,以避免我們跳過子版本。因此,必須經(jīng)過所有中間版本才能到達(dá)目標(biāo)版本。

          ?關(guān)鍵是,如果你打算使用 Kubernetes 或已經(jīng)在使用 Kubernetes,請考慮生命周期活動(dòng)以及解決這一問題的方案。構(gòu)建和運(yùn)行集群相對容易一些,但是生命周期維護(hù)是一個(gè)全新的體驗(yàn),具有多個(gè)活動(dòng)組件。

          1.3構(gòu)建和部署


          ?在準(zhǔn)備重新設(shè)計(jì)整個(gè)構(gòu)建和部署流水線之前,?我們的構(gòu)建過程和部署必須經(jīng)歷 Kubernetes 世界的完整轉(zhuǎn)型。不僅在 Jenkins 流水線中進(jìn)行了大量的重構(gòu),而且還使用了諸如 Helm 之類的新工具,策劃了新的 git 流和構(gòu)建、標(biāo)簽化 docker 鏡像,以及版本化 helm 的部署 chart。

          ?你需要一種策略來維護(hù)代碼,以及 Kubernetes 部署文件、Docker 文件、Docker 鏡像、Helm chart,并設(shè)計(jì)一種方法將它們組合在一起。

          經(jīng)過幾次迭代,我們決定采用以下設(shè)計(jì):

          • 應(yīng)用程序代碼及其 helm chart 放在各自的 git 存儲庫中。這使我們可以分別對它們進(jìn)行版本控制(語義版本控制)。

          • 然后,我們將 chart 版本與應(yīng)用程序版本關(guān)聯(lián)起來,并使用它來跟蹤發(fā)布。例如,app-1.2.0使用charts-1.1.0進(jìn)行部署。如果只更改 Helm 的 values 文件,則只更改 chart 的補(bǔ)丁版本(例如,從1.1.0到1.1.1)。所有這些版本均由每個(gè)存儲庫中的RELEASE.txt中的發(fā)行說明規(guī)定。

          • 對于我們未構(gòu)建或修改代碼的系統(tǒng)應(yīng)用程序,例如 Apache Kafka 或 Redis ,工作方式有所不同。也就是說,我們沒有兩個(gè) git 存儲庫,因?yàn)?Docker 標(biāo)簽只是 Helm chart 版本控制的一部分。如果我們更改了 docker 標(biāo)簽以進(jìn)行升級,則會升級 chart 標(biāo)簽的主要版本。

          1.4存活和就緒探針(雙刃劍)

          ?Kubernetes 的存活探針和就緒探針是自動(dòng)解決系統(tǒng)問題的出色功能。它們可以在發(fā)生故障時(shí)重啟容器,并將流量從不正常的實(shí)例進(jìn)行轉(zhuǎn)移。但是,在某些故障情況下,這些探針可能會變成一把雙刃劍,并會影響應(yīng)用程序的啟動(dòng)和恢復(fù),尤其是有狀態(tài)的應(yīng)用程序,例如消息平臺或數(shù)據(jù)庫。

          ?我們的 Kafka 系統(tǒng)就是這個(gè)受害者。我們運(yùn)行了一個(gè)3 Broker 3 Zookeeper有狀態(tài)副本集,該狀態(tài)集的ReplicationFactor為 3,minInSyncReplica為 2。當(dāng)系統(tǒng)意外故障或崩潰導(dǎo)致 Kafka 啟動(dòng)時(shí),問題發(fā)生了。這導(dǎo)致它在啟動(dòng)期間運(yùn)行其他腳本來修復(fù)損壞的索引,根據(jù)嚴(yán)重性,此過程可能需要 10?到 30?分鐘。由于增加了時(shí)間,存活探針將不斷失敗,從而向 Kafka 發(fā)出終止信號以重新啟動(dòng)。這阻止了 Kafka 修復(fù)索引并完全啟動(dòng)。

          ?唯一的解決方案是在存活探針設(shè)置中配置initialDelaySeconds,以在容器啟動(dòng)后延遲探針評估。但是,問題在于很難對此加以評估。有些恢復(fù)甚至需要一個(gè)小時(shí),因此我們需要提供足夠的空間來解決這一問題。但是,initialDelaySeconds越大,彈性的速度就越慢,因?yàn)樵趩?dòng)失敗期間 Kubernetes 需要更長的時(shí)間來重啟容器。


          ?因此,折中的方案是評估initialDelaySeconds字段的值,以在 Kubernetes 中的彈性與應(yīng)用程序在所有故障情況(磁盤故障、網(wǎng)絡(luò)故障、系統(tǒng)崩潰等)下成功啟動(dòng)所花費(fèi)的時(shí)間之間取得更好的平衡?。

          ?更新:如果你使用最新版本,Kubernetes 引入了第三種探針類型,稱為“啟動(dòng)探針”,以解決此問題。從 1.16 版開始提供 alpha 版本,從 1.18 版開始提供 beta 版本。

          啟動(dòng)探針會禁用就緒和存活檢查,直到容器啟動(dòng)為止,以確保應(yīng)用程序的啟動(dòng)不會中斷

          1.5公開外部IP

          ?我們了解到,使用靜態(tài)外部 IP 公開服務(wù)會對內(nèi)核的連接跟蹤機(jī)制造成巨大代價(jià)。除非進(jìn)行完整的計(jì)劃,否則它很輕易就破壞了擴(kuò)展性。

          ?我們的集群運(yùn)行在Calico?for?CNI上,在 Kubernetes 內(nèi)部采用BGP作為路由協(xié)議,并與邊緣路由器對等。對于 Kubeproxy,我們使用IP Tables模式。我們在 Kubernetes 中托管著大量的服務(wù),通過外部 IP 公開,每天處理數(shù)百萬個(gè)連接。由于來自軟件定義網(wǎng)絡(luò)的所有 SNAT 和偽裝,Kubernetes 需要一種機(jī)制來跟蹤所有這些邏輯流。為此,它使用內(nèi)核的Conntrack and netfilter工具來管理靜態(tài) IP 的這些外部連接,然后將其轉(zhuǎn)換為內(nèi)部服務(wù) IP,然后轉(zhuǎn)換為 pod IP。所有這些都是通過conntrack表和 IP 表完成的。


          ?但是conntrack表有其局限性。一旦達(dá)到限制,你的 Kubernetes 集群(如下所示的 OS 內(nèi)核)將不再接受任何新連接。在 RHEL 上,可以通過這種方式進(jìn)行檢查。

          sysctl?net.netfilter.nf_conntrack_count?net.netfilter.nf_conntrack_maxnet.netfilter.nf_conntrack_count?=?167012
          net.netfilter.nf_conntrack_max?=?262144
          ?解決此問題的一些方法是使用邊緣路由器對等多個(gè)節(jié)點(diǎn),以使連接到靜態(tài) IP 的傳入連接遍及整個(gè)集群。因此,如果你的集群中有大量的計(jì)算機(jī),累積起來,你可以擁有一個(gè)巨大的conntrack表來處理大量的傳入連接。

          回到 2017 年我們剛開始的時(shí)候,這一切就讓我們望而卻步,但最近,Calico 在 2019 年對此進(jìn)行了詳細(xì)研究,標(biāo)題為“為什么 conntrack 不再是你的朋友”

          2、安全方面

          ?對于大部分 Kubernetes 用戶來說,安全是無關(guān)緊要的,或者說沒那么緊要,就算考慮到了,也只是敷衍一下,草草了事。實(shí)際上 Kubernetes 提供了非常多的選項(xiàng)可以大大提高應(yīng)用的安全性,只要用好了這些選項(xiàng),就可以將絕大部分的攻擊抵擋在門外。為了更容易上手,我將它們總結(jié)成了幾個(gè)最佳實(shí)踐配置,大家看完了就可以開干了。當(dāng)然,本文所述的最佳安全實(shí)踐僅限于 Pod 層面,也就是容器層面,于容器的生命周期相關(guān),至于容器之外的安全配置(比如操作系統(tǒng)啦、k8s 組件啦),以后有機(jī)會再嘮。

          2.1為容器配置Security Context


          ?大部分情況下容器不需要太多的權(quán)限,我們可以通過?`Security Context`?限定容器的權(quán)限和訪問控制,只需加上 SecurityContext 字段:

          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?
          spec:
          ??containers:
          ??-?name:?
          ??image:?
          ????securityContext:


          2.2禁用allowPrivilegeEscalation


          ?allowPrivilegeEscalation=true?表示容器的任何子進(jìn)程都可以獲得比父進(jìn)程更多的權(quán)限。最好將其設(shè)置為?false,以確保 RunAsUser 命令不能繞過其現(xiàn)有的權(quán)限集。

          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?
          spec:
          ??containers:
          ??-?name:?
          ??image:?
          ????securityContext:
          ??????allowPrivilegeEscalation:?false

          2.3不要使用root用戶


          ?為了防止來自容器內(nèi)的提權(quán)攻擊,最好不要使用 root 用戶運(yùn)行容器內(nèi)的應(yīng)用。UID 設(shè)置大一點(diǎn),盡量大于 3000。
          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?
          spec:
          ??securityContext:
          ????runAsUser:?
          ????runAsGroup:?

          2.4限制CPU和內(nèi)存資源

          requests和limits都加上

          2.5不比掛載Service Account Token

          ?ServiceAccount 為 Pod 中運(yùn)行的進(jìn)程提供身份標(biāo)識,怎么標(biāo)識呢?當(dāng)然是通過 Token 啦,有了 Token,就防止假冒偽劣進(jìn)程。如果你的應(yīng)用不需要這個(gè)身份標(biāo)識,可以不必掛載:

          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?
          spec:
          ??automountServiceAccountToken:?false

          2.6確保seccomp設(shè)置正確


          ?對于 Linux 來說,用戶層一切資源相關(guān)操作都需要通過系統(tǒng)調(diào)用來完成,那么只要對系統(tǒng)調(diào)用進(jìn)行某種操作,用戶層的程序就翻不起什么風(fēng)浪,即使是惡意程序也就只能在自己進(jìn)程內(nèi)存空間那一分田地晃悠,進(jìn)程一終止它也如風(fēng)消散了。seccomp(secure computing mode)就是一種限制系統(tǒng)調(diào)用的安全機(jī)制,可以可以指定允許那些系統(tǒng)調(diào)用。

          ?對于 Kubernetes 來說,大多數(shù)容器運(yùn)行時(shí)都提供一組允許或不允許的默認(rèn)系統(tǒng)調(diào)用。通過使用 runtime/default 注釋或?qū)?Pod 或容器的安全上下文中的 seccomp 類型設(shè)置為 RuntimeDefault,可以輕松地在 Kubernetes 中應(yīng)用默認(rèn)值。

          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?
          ??annotations:
          ????seccomp.security.alpha.kubernetes.io/pod:?"runtime/default"
          ?默認(rèn)的seccomp?配置文件應(yīng)該為大多數(shù)工作負(fù)載提供足夠的權(quán)限,如果你有更多的需求,可以自定義配置文件.

          2.7限制容器的capabilities


          ?容器依賴于傳統(tǒng)的Unix安全模型,通過控制資源所屬用戶和組的權(quán)限,來達(dá)到對資源的權(quán)限控制。以 root 身份運(yùn)行的容器擁有的權(quán)限遠(yuǎn)遠(yuǎn)超過其工作負(fù)載的要求,一旦發(fā)生泄露,攻擊者可以利用這些權(quán)限進(jìn)一步對網(wǎng)絡(luò)進(jìn)行攻擊。
          ?默認(rèn)情況下,使用 Docker 作為容器運(yùn)行時(shí),會啟用?`NET_RAW` capability,這可能會被惡意攻擊者進(jìn)行濫用。因此,建議至少定義一個(gè)`PodSecurityPolicy`(PSP),以防止具有 NET_RAW 功能的容器啟動(dòng)。

          通過限制容器的 capabilities,可以確保受攻擊的容器無法為攻擊者提供橫向攻擊的有效路徑,從而縮小攻擊范圍。

          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?
          spec:
          ??securityContext:
          ????runAsNonRoot:?true
          ????runAsUser:?
          ??capabilities:
          ??drop:
          ????-NET_RAW
          ????-ALL


          3、是否一定需要Kubernetes?

          ?它是一個(gè)復(fù)雜的平臺,具有自己的一系列挑戰(zhàn),尤其是在構(gòu)建和維護(hù)環(huán)境方面的開銷。它將改變你的設(shè)計(jì)、思維、架構(gòu),并需要提高技能和擴(kuò)大團(tuán)隊(duì)規(guī)模以適應(yīng)轉(zhuǎn)型。

          ?但是,如果你在云上并且能夠?qū)?Kubernetes 作為一種“服務(wù)”使用,它可以減輕平臺維護(hù)帶來的大部分開銷,例如“如何擴(kuò)展內(nèi)部網(wǎng)絡(luò) CIDR?”或“如何升級我的 Kubernetes 版本?”

          ?今天,我們意識到,你需要問自己的第一個(gè)問題是“你是否一定需要 Kubernetes?”。這可以幫助你評估所遇到的問題以及 Kubernetes 解決該問題的重要性。

          ?Kubernetes 轉(zhuǎn)型并不便宜,為此支付的價(jià)格必須確實(shí)證明“你的”用例的必要性及其如何利用該平臺。如果可以,那么 Kubernetes 可以極大地提高你的生產(chǎn)力。




          粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

          ??????

          ??長按上方微信二維碼?2 秒


          感謝點(diǎn)贊支持下哈?

          瀏覽 45
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级黄色免费视频网站 | 国精品无码一区二区三区四区五区 | 看黄色视频在线进 | 欧美日本视频在线观看 | 国产91 白丝在线播放 |