<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      去年8月底,百分點與云知聲聯(lián)合發(fā)布了Google開源的
      集群管理系統(tǒng)Kubernetes的“發(fā)行版”——Sextant。在百分點大規(guī)模Kubernetes集群經(jīng)過四五個月的應(yīng)用實踐后,到目前為止,集群上已經(jīng)承載了百分點推薦系統(tǒng)的大部分業(yè)務(wù)組件和部分的運維組件。那么,在使用過程中會遇到哪些問題?如何解決?本篇將詳盡總結(jié)百分點在實踐中的經(jīng)驗教訓,期望能夠更多地回饋社區(qū)。

      從0到1

      先來講講百分點自己的故事:


      在傳統(tǒng)的集群管理方法下,百分點服務(wù)器利用率長期處于20%以下。通常為了完成某個業(yè)務(wù)目標,團隊會申請各自的服務(wù)器,然后工程師使用跳板機登陸到這些服務(wù)器上完成程序的部署。


      這樣的弊端是:首先,這些服務(wù)器上的空閑資源并不會貢獻出來為其他團隊所使用;其次,這些服務(wù)器在解決業(yè)務(wù)高峰問題之后,負載下降,而這時團隊并不希望服務(wù)器被回收,因為不知道如何備份服務(wù)器之上的數(shù)據(jù)。

      這樣,集群服務(wù)器利用率逐步降低,整體集群的維護和管理也變得異常困難,在百分點AI技術(shù)運用增多的趨勢下,常遇到計算資源不足而導致業(yè)務(wù)進展緩慢的情況。

      ?如何解決呢?

      我們做了很多嘗試,最終決定選擇CoreOS、Kubernetes(以下簡稱K8s)、Ceph相結(jié)合的技術(shù)方案。


      對于Kubernetes在生產(chǎn)環(huán)境中的應(yīng)用,百分點是比較早的一批實踐者,從開始關(guān)注Kubernetes1.0,到將1.2版本實際部署到我們的生產(chǎn)環(huán)境中,圍繞Kubernetes做了很多周邊工作,使Kubernetes能夠更好地服務(wù)于業(yè)務(wù)場景。

      限于篇幅原因,這里不展開介紹Kubernetes的基本原理和概念了,感興趣的讀者可以在我們的githubsextant項目中,找到相當豐富的文檔。


      為了達成這樣的目標,我們要求開發(fā)者使用Docker將自己的應(yīng)用程序完成封裝,逐步將手動的集群部署,切換到使用K8S的集群容器編排之上。如下圖所示,需要在團隊項目的gitlab
      repo中增加相應(yīng)的Dockerfile和編排文件內(nèi)容,CI環(huán)境會自動將應(yīng)用完成編譯->單元測試->docker鏡像打包->鏡像提交的工作。封裝在容器中的應(yīng)用使用Ceph存儲數(shù)據(jù),并通過ingress
      LoadBalancer對外部提供服務(wù)。


      ?對于Kubernetes在生產(chǎn)環(huán)境上的部署,我們希望最大限度的簡化K8S集群維護人員的工作。比如擴容一臺機器、下架維修一臺機器等,只需要維護人員直接完成開機/關(guān)機的操作即可。由于K8S的調(diào)度編排,可以屏蔽這類操作對應(yīng)用的影響。

      三步完成集群安裝

      首先要解決的問題,就是如何能夠高效的、自動化的進行組件的部署以減少手動部署可能帶來的問題。


      百分點、云知聲在百度科學家王益帶領(lǐng)下,合作開發(fā)了基于PXE自動化安裝CoreOS+Kubernetes集群的開源Sextant項目,只需要簡單的三個步驟即可完成集群的安裝:規(guī)劃集群->啟動bootstrapper->節(jié)點開機自動安裝。

      ?- PXE采用PXE的技術(shù),從網(wǎng)絡(luò)安裝CoreOS的操作系統(tǒng),完成節(jié)點操作系統(tǒng)的初始化。

      - cluster-desc.yaml
      是集群的描述文件,諸如操作系統(tǒng)類型、Flanneld網(wǎng)絡(luò)模式、Kubernetes版本等都會配置在這個文件中。對于每個待安裝的節(jié)點,需要根據(jù)MAC地址配置相應(yīng)的角色,例如Kube-master,flanneld-master等。

      - Bootstrapper是Sextant項目的核心服務(wù),載入cluster-desc.yaml
      配置文件,并提供web服務(wù),根據(jù)節(jié)點的MAC地址生成相應(yīng)的cloud-config.yaml文件,從而安裝并啟動kubernetes相關(guān)組件。

      - 操作順序:

      - Step 0集群規(guī)劃


      規(guī)劃集群,將集群信息描述為cluster-desc.yaml配置文件,例如操作系統(tǒng)的類型、etcd節(jié)點的數(shù)量、flanneld協(xié)議類型,哪些節(jié)點作為master等等。

      - Step 1編譯、運行bootstrapper

      通過上一步驟的cluster-desc.yaml文件,編譯bootstrapper的docker
      image并啟動,bootstrapper會提供PXE、DHCP、DNS以及Docker Registry等服務(wù)。

      - Step 2安裝kubernetes節(jié)點

      將服務(wù)器接入集群,開機并從網(wǎng)絡(luò)引導安裝,即可自動完成CoreOS以及K8s組件的安裝過程。

      下一步就是應(yīng)用遷移,在收獲中也充滿了痛。

      收獲和痛


      至此,我們自認為可以開始像習大大元旦助詞說的那樣“擼起袖子”,進行逐步的遷移工作了。但經(jīng)過簡單的性能測試后,結(jié)果并不理想。運行在K8S之上的服務(wù)響應(yīng)延遲,導致出現(xiàn)至少20%的性能損耗。在踩坑之后,我們對K8S的網(wǎng)絡(luò)有了更加深入的理解。

      一、打造kubernetes高性能網(wǎng)絡(luò)


      熟悉Docker的讀者可能會了解到,Docker容器有三種網(wǎng)絡(luò)模式,但為了達到容器內(nèi)的網(wǎng)絡(luò)環(huán)境隔離,通常會選擇使用NAT方式完成容器內(nèi)的網(wǎng)絡(luò)包轉(zhuǎn)換和轉(zhuǎn)發(fā)。這樣,在同一臺主機上啟動的容器或不同主機啟動的容器之間,除了配置NAT端口的4層地址可訪問外,都不可以直接互相訪問。


      Kubernetes的解決思路和Bridged模式的虛擬機群很像——用一個通用的IP地址分配服務(wù),為運行在各個host上的container統(tǒng)一分配IP地址。這樣運行在不同host上的containers之間通信,直接使用對方的container
      IP地址就可以了,而不需要考慮host IP。這實際上把Docker模式中的host IP和containerIP這兩層IP地址變成了一層。

      在Kubernetes的文檔里闡述了一個叫Pod的概念,并且解釋一個Pod里可以運行一個或者多個Docker
      containers。實際上,一個Pod就是一個Docker
      container。所謂在Pod里運行的多個containers,實際上是啟動的時候加了--net=container:<pod-container>參數(shù)的containers,它們不會得到自己的IP地址,而是和pod
      container共享IP地址。這樣一來,一個pod里的containers之間通信的時候可以用localhost地址,而跨越pod的通信用pod IP。
      看上去Kubernetes的做法里相對于Docker的做法,多了一層Pod的概念。

      但是實際上每個container里約定俗成地只運行一個服務(wù)進程,所以還是三層概念:

      節(jié)點(node)

      Pod

      Container

      ?Kubernetes實現(xiàn)這種網(wǎng)絡(luò)結(jié)構(gòu)有多種方法,如overlay networking、BGP和其他SDN技術(shù),常見的實現(xiàn)包括:Flannel、
      Calico、 L2 networking、OpenVSwitch等,我們對常用并活躍的項目進行了針對性評測,結(jié)論如下:


      ?可以看到,在L2模式下,針對高性能web應(yīng)用場景可以達到最佳性能。當然如果有專用的SDN交換機設(shè)備,也可以大大提高SDN的網(wǎng)絡(luò)性能。但綜合成本、方案復雜程度、方案后續(xù)可擴展性考慮,最終選擇flannel
      host-gw模式。這個模式,要求所有host保持穩(wěn)定的2層網(wǎng)絡(luò)連接,然后通過Linux路由表,將Docker bridge的包完成3層轉(zhuǎn)發(fā)。

      另外一點,
      在評測過程中發(fā)現(xiàn),linux加在netfilter和iptables相關(guān)內(nèi)核模塊之后,平均網(wǎng)絡(luò)延遲會下降10%左右。但就目前狀態(tài)來說,使用iptables
      NAT作為Kubernetes的service負載均衡仍然是性能最高、最簡單的方式。后續(xù)如果可以使用更優(yōu)秀的方法提供service負載均衡,可以去掉iptables以降低容器之間的網(wǎng)絡(luò)延遲。


      在這種網(wǎng)絡(luò)部署下,使用普通的千兆網(wǎng)卡和千兆交換機,即可以較低成本來搭建大規(guī)模的集群,并獲得相對可觀的性能。在針對網(wǎng)絡(luò)延遲有更高要求的服務(wù),比如Redis等,則考慮直接物理部署作為折中方案。

      二、打造高可用的前端負載均衡器

      從上面的介紹可以看出,Kubernetes service主要仍是針對數(shù)據(jù)中心內(nèi)部互相訪問,若要方便地提供HTTP
      web服務(wù)的創(chuàng)建,則需要引入Ingress的概念。


      眾所周知的是,Kubernetes中的Service可以將一組pod提供的服務(wù)暴露出來供外部使用,并默認使用iptables的方式提供負載均衡的能力。Service通過使用iptables,在每個主機上根據(jù)Kubernetes
      service定義,自動同步NAT表,將請求均衡的轉(zhuǎn)發(fā)到后端pod上,并在pod故障時自動更新NAT表。相對于使用userspace方式直接轉(zhuǎn)發(fā)流量有更高的效率。常用的Service有ClusterIP、Loadbalancer以及NodePort方式。

      -
      ClusterIP是通過每個節(jié)點的kuber-proxy進程修改本地的iptables,使用DNAT的方式將ClusterIP轉(zhuǎn)換為實際的endpoint地址。

      - NodePort是為了Kubernetes集群外部的應(yīng)用方便訪問kubernetes的服務(wù)而提供的一種方案,它會在每個機器上。

      -
      由于NAT性能的問題,NodePort會帶來一定的性能損失,在一些場景下,我們也會選用Loadbalancer作為k8s集群外部應(yīng)用訪問K8s集群內(nèi)部應(yīng)用的統(tǒng)一入口。百分點采用的Loadbalancer負載均衡器是基于haproxy,通過watcher
      Kubernetes-apiserver中service以及endpoint信息,動態(tài)修改haproxy轉(zhuǎn)發(fā)規(guī)則來實現(xiàn)的。

      從上面的介紹可以看出,Kubernetes service仍是主要針對數(shù)據(jù)中心內(nèi)部互相訪問,若要方便地提供HTTP
      web服務(wù)的創(chuàng)建,則需要引入Ingress的概念。


      1. Ingress


      對于對外提供服務(wù)的web應(yīng)用來說,需要提供7層反向代理的機制,使得公網(wǎng)的流量可以轉(zhuǎn)入集群之中。百分點采用的是Nginx,通過WatcherKubernetes中Ingress資源信息,動態(tài)修改對應(yīng)的service匹配endpoint的地址,使得整個配置流程只需通過kubctl提交一個配置即可。Ingress作為數(shù)據(jù)中心web請求的入口,將流量引入到集群內(nèi)部,完成處理后經(jīng)由Ingress返回外部請求者。這樣一來,任何一個部署在kubernetes上的web應(yīng)用,都可以簡單的通過提交一個Ingress資源,完成web請求對外的開通。

      2. Ingress HA


      Ingress的機器是整個集群的入口,如果其中一臺機器出現(xiàn)故障,帶來的影響將會是致命的。我們也曾考慮過使用F5等技術(shù)做前端的高可用,但最后基于成本和可維護性考慮,最終使用Keepalived+vip的方案。

      ?3. Ingress優(yōu)化

      - 性能優(yōu)化

      由于NginxIngress
      Controller要監(jiān)聽物理機上的80端口,我們最初的做法是給他配置了hosrtport,但當大量業(yè)務(wù)上線時,我們發(fā)現(xiàn)QPS超過500/s就會出現(xiàn)無法轉(zhuǎn)發(fā)數(shù)據(jù)包的情況。經(jīng)過排查發(fā)現(xiàn),系統(tǒng)軟中斷占用的CPU特別高,hostport會使用iptables進行數(shù)據(jù)包的轉(zhuǎn)發(fā),后來將Ingress
      Controller修改為hostnetwork模式,直接使用Docker的host模式,性能得到提升,QPS可以達到5k以上。

      - Nginx配置優(yōu)化

      Nginx
      IngressController大致的工作流程是先通過監(jiān)聽Service、Ingress等資源的變化然后根據(jù)Service、Ingress的信息以及nginx.temple文件,將每個service對應(yīng)的endpoint填入模板中生成最終的Nginx配置。但是很多情況下模板中默認的配置參數(shù)并不滿足我們的需求,這時需要通過kubernetes中ConfigMap機制基于Nginx
      Ingress Controller使用我們定制化的模板。

      - 日志回滾


      默認情況下Docker會將日志記錄在系統(tǒng)的/var/lib/docker/container/xxxx下面的文件里,但是前端日志量是非常大的,很容易就會將系統(tǒng)盤寫滿,通過配置ConfigMap的方式,可以將日志目錄改到主機上,通過配置logrotate服務(wù)可以實現(xiàn)日志的定時回滾、壓縮等操作。

      - 服務(wù)應(yīng)急


      當線上服務(wù)出現(xiàn)不可用的情況時,我們會準備一套應(yīng)急的服務(wù)作為備用,一但服務(wù)出現(xiàn)問題,我們可以將流量切換到應(yīng)急的服務(wù)上去。在k8s上,這一系列操作變得更加簡單,這需再準備一套ingress規(guī)則,將生產(chǎn)環(huán)境的Servuce改為應(yīng)急的Service,切換的時候通過kubectl
      replace -f xxx.yaml 將相應(yīng)的Ingress替換,即可實現(xiàn)服務(wù)的無感知切換。

      三、打造一體化Kubernetes集群服務(wù)


      作為一個集群化的操作系統(tǒng),基礎(chǔ)服務(wù)必不可少,開發(fā)者通常需要經(jīng)常查看服務(wù)的日志,查看監(jiān)控數(shù)據(jù),查看運行狀態(tài)等。我們?yōu)镵ubernetes集群配置了很多基礎(chǔ)類服務(wù),使集群使用起來更加高效。

      1. 日志管理


      當我們的應(yīng)用運行在集群操作系統(tǒng)上時,如何高效地查看、分析服務(wù)日志是一個必須要解決的問題。百分點采用了Fluented+Elasticsearch+Kibana的方案,整個套件也都是運行在Kubernetes集群上的。

      ?- Fluentd

      Fluented是使用Kubernetes中Daemonset的機制,使得fluented啟動在每一個節(jié)點上,并自動采集Docker
      Container的日志到ES集群中。

      - Elasticsearch


      ES自帶的Discovery機制并不能在kubernetes中完美的運行,這里使用kubernetes的插件,使其他通過Service的方式使master節(jié)點能夠自動發(fā)現(xiàn)client和data節(jié)點的endpoint地址,組成集群。ES中數(shù)據(jù)節(jié)點的存儲是放在Ceph集群中的,保證了數(shù)據(jù)可靠性。

      - Kibana

      Kibana中能夠根據(jù)用戶自定義篩選、聚合,方便用戶查詢使用。

      2 . 系統(tǒng)監(jiān)控

      通過heapster+collectd+influxdb+grafana解決多源數(shù)據(jù)采集、監(jiān)控數(shù)據(jù)存儲、查詢展現(xiàn)的問題。

      ?- heapster負責從cAdvisor中采集宿主機以及container中的監(jiān)控數(shù)據(jù)并寫入influxdb中。

      - collectd負責采集類似nginx組件的監(jiān)控數(shù)據(jù)寫入influxdb中。

      - influxdb負責按時間序列存儲監(jiān)控數(shù)據(jù),并且支持類SQL的語法來訪問數(shù)據(jù) 。

      - grafana提供了WebUI,通過用戶自定義的查詢規(guī)則,生成SQL語句來查詢influxdb中的數(shù)據(jù),并最終以圖表的形式展現(xiàn)給用戶。

      3. 統(tǒng)一Dashboard

      為了簡化kubernetes集群的使用,百分點的技術(shù)團隊開發(fā)了Sirius <>系統(tǒng),使用戶使用起來更加的方便,并且此項目也在Github上進行了開源。

      ?4. 持續(xù)化集成

      Docker是我們落地Devops理念的核心技術(shù),從開發(fā)人員寫下第一行代碼開始,我們構(gòu)建了這樣一條持續(xù)集成的流水線。

      ?我們選擇了Gitlab作為代碼倉庫,當開發(fā)人員向Gitlab提交代碼,Jenkins會監(jiān)聽每個tag,每次push事件,有選擇的自動構(gòu)建為docker
      image,并推向Docker
      Registry,存儲在我們的Docker倉庫中。隨后,Jenkins會將新版本的鏡像推到集成測試的Kubernetes集群中,完成一次構(gòu)建、測試、預(yù)上線的流程。待測試通過后,再發(fā)布到生產(chǎn)環(huán)境。

      5. 持續(xù)化部署


      在逐步將線上應(yīng)用遷移到kubernetes集群過程中,當然也遇到不少問題,每個應(yīng)用在提交之后需要經(jīng)過多次修改和更新才可以正式上線,為了方便更新、并盡量減少人為操作的失誤,我們使用“編排文件版本管理+kubernetes
      deployment”完成持續(xù)化部署。

      - 什么是Deployment?


      Deployment描述了待部署Pod的狀態(tài),只需要定義我們期望的一組Pod的狀態(tài),kube-controller會幫助我們在集群上維持這一狀態(tài),并且可以很方便地在上面做roll-out和roll-back。

      - 如何更新Deployment?

      直接使用kubectl editdeployment/{your
      deployment}即可對相應(yīng)deployment進行修改。并且可以指定最大不可用的Pod個數(shù)來控制滾動更新的進度。每次執(zhí)行edit命令之后,就會觸發(fā)deployment的rolling
      update,應(yīng)用會在后臺完成逐個平滑升級。

      - 持續(xù)部署

      在每個應(yīng)用的代碼倉庫中,會增加一個.kube的目錄,下面存放本應(yīng)用的yaml編排文件,每次部署升級都直接使用對應(yīng)版本的編排文件即可完成部署。

      四、打造統(tǒng)一持久化存儲平臺


      Kubernetes在運行時是基于容器技術(shù)的,這就意味著容器的停止會銷毀容器中的數(shù)據(jù)。若應(yīng)用要使用持久化的存儲,如果直接掛在容器所在主機的磁盤目錄,這個編排系統(tǒng)會顯得十分混亂。雖然Kubernetes提供了諸如hostPath機制,除非應(yīng)用和主機具有非常明確的綁定關(guān)系,否則不推薦使用。這樣,我們需要一個通過網(wǎng)絡(luò)可訪問的存儲池,作為統(tǒng)一的集群存儲平臺。選型的問題這里不詳細展開,我們最中使用ceph作為Kubernetes的后端存儲。


      在部署時,考慮到kubernetes編排的網(wǎng)絡(luò)請求可能和ceph的數(shù)據(jù)存儲請求搶占網(wǎng)卡帶寬而導致整體集群癱瘓,預(yù)先將kubernetes訪問ceph集群的網(wǎng)絡(luò)使用單獨的兩個網(wǎng)口做bond0之后連接ceph集群的交換機。同時為了防止多個容器突發(fā)性的高IOPS對ceph集群的訪問,我們正在開發(fā)storage-iops的qos限制功能。

      雖然ceph提供了3種存儲訪問的方式,我們還是選用了相對穩(wěn)定的rbd,沒有使用ceph
      filesystem模式。在rbd模式下,首先要保證內(nèi)核已經(jīng)加在了rbd.ko內(nèi)核模塊,和ceph-common包。這一步,我們在前面提到的sextant自動安裝系統(tǒng)中已經(jīng)完成打包。

      接下來在使用rbd作為pod存儲時可以參考示例:

      {

      "apiVersion": "v1beta3",

      "id": "rbdpd2",

      "kind": "Pod",

      "metadata": {

      "name": "rbd2"

      },

      "spec": {

      "containers": [

      {

      "name": "rbd-rw",

      "image": "kubernetes/pause",

      "volumeMounts": [

      {

      "mountPath": "/mnt/rbd",

      "name": "rbdpd"

      }

      ]

      }

      ],

      "volumes": [

      {

      "name": "rbdpd",

      "rbd": {

      "monitors": [

      "192.168.0.1:6789"

      ],

      "pool": "rbd",

      "image": "foo",

      "user": "admin",

      "secretRef": {

      "name": "ceph-secret"

      },

      "fsType": "ext4",

      "readOnly": true

      }

      }

      ]

      }

      }

      目前,我們已經(jīng)使用kubernetes+ceph
      rbd部署使用了MySQL、MongoDB、Redis、InfluxDB、ElasticSearch等服務(wù)和應(yīng)用。

      本文轉(zhuǎn)自掘金-你想要的百分點大規(guī)模Kubernetes集群應(yīng)用實踐來了
      <https://yq.aliyun.com/go/articleRenderRedirect?url=https%3A%2F%2Fmy.oschina.net%2Fxiaominmin%2Fblog%2F1598544>

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          成人视频在线无码在线观看 | 口述3p做爰全过程 | 在线观看网站av 欧美亚洲操逼 | 用力挺进她的花苞啊~视频 | 国产三区视频在线观看 | 雷谢一级毛片 | 欧美亂伦视频网站 | 国产91亚洲精品成人AA片p站 | 日本淫视频 | 亚洲秘 无码一区二区三区密桃 |