Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Abril 8 sa kumperensya Saint HighLoad++ 2019, bilang bahagi ng seksyong "DevOps and Operations", isang ulat na "Pagpapalawak at pagpupuno sa Kubernetes" ay ibinigay, sa paglikha kung saan lumahok ang tatlong empleyado ng kumpanya ng Flant. Dito, pinag-uusapan natin ang maraming sitwasyon kung saan gusto naming palawakin at dagdagan ang mga kakayahan ng Kubernetes, ngunit kung saan hindi kami nakahanap ng handa at simpleng solusyon. Mayroon kaming mga kinakailangang solusyon sa anyo ng mga proyektong Open Source, at ang talumpating ito ay nakatuon din sa kanila.

Sa pamamagitan ng tradisyon, kami ay nalulugod na ipakita video ng ulat (50 minuto, higit na nagbibigay-kaalaman kaysa sa artikulo) at ang pangunahing buod sa anyo ng teksto. Go!

Core at mga karagdagan sa K8s

Binabago ng Kubernetes ang industriya at mga diskarte sa pangangasiwa na matagal nang itinatag:

  • Salamat sa kanya abstraction, hindi na kami nagpapatakbo gamit ang mga konsepto tulad ng pag-set up ng config o pagpapatakbo ng command (Chef, Ansible...), ngunit gumagamit ng pagpapangkat ng mga container, serbisyo, atbp.
  • Maaari kaming maghanda ng mga aplikasyon nang hindi iniisip ang tungkol sa mga nuances ng tiyak na site, kung saan ito ilulunsad: bare metal, cloud ng isa sa mga provider, atbp.
  • Sa K8s hindi ka na naging mas madaling ma-access pinakamahusay na kasanayan sa pag-aayos ng imprastraktura: mga diskarte sa pag-scale, pagpapagaling sa sarili, pagpapahintulot sa kasalanan, atbp.

Gayunpaman, siyempre, ang lahat ay hindi masyadong maayos: Ang Kubernetes ay nagdala din ng sarili nitong mga bagong hamon.

Kubernetes hindi ay isang kumbinasyon na lumulutas sa lahat ng mga problema ng lahat ng mga gumagamit. Ang pangunahing Ang Kubernetes ay may pananagutan lamang para sa isang hanay ng mga minimum na kinakailangang function na naroroon bawat kumpol:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Tinutukoy ng core ng Kubernetes ang isang pangunahing hanay ng mga primitive para sa pagpapangkat ng mga container, pamamahala ng trapiko, at iba pa. Napag-usapan namin ang tungkol sa kanila nang mas detalyado sa ulat 2 taon na ang nakakaraan.

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Sa kabilang banda, ang K8s ay nag-aalok ng mahusay na mga pagkakataon upang palawakin ang mga magagamit na function, na tumutulong upang isara ang iba - tiyak β€” pangangailangan ng gumagamit. Ang mga pagdaragdag sa Kubernetes ay responsibilidad ng mga administrator ng cluster, na dapat mag-install at mag-configure ng lahat ng kailangan para makuha ang kanilang cluster "sa tamang hugis" [upang malutas ang kanilang mga partikular na problema]. Anong uri ng mga karagdagan ito? Tingnan natin ang ilang halimbawa.

Mga halimbawa ng mga add-on

Sa pagkakaroon ng pag-install ng Kubernetes, maaaring magulat tayo na ang networking na napakahalaga para sa pakikipag-ugnayan ng mga pod sa loob ng isang node at sa pagitan ng mga node ay hindi gumagana nang mag-isa. Hindi ginagarantiya ng Kubernetes kernel ang mga kinakailangang koneksyon; sa halip, tinutukoy nito ang network interface (CNI) para sa mga third party na add-on. Dapat naming i-install ang isa sa mga add-on na ito, na magiging responsable para sa configuration ng network.

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Ang isang malapit na halimbawa ay ang mga solusyon sa pag-iimbak ng data (lokal na disk, network block device, Ceph...). Sa una sila ay nasa core, ngunit sa pagdating CSI nagbabago ang sitwasyon sa isang bagay na katulad ng inilarawan na: ang interface ay nasa Kubernetes, at ang pagpapatupad nito ay nasa mga third-party na module.

Kasama sa iba pang mga halimbawa ang:

  • Pagpasok-mga controller (tingnan ang kanilang pagsusuri sa ang aming kamakailang artikulo).
  • sertipikadong tagapamahala:

    Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

  • Mga operator ay isang buong klase ng mga add-on (na kinabibilangan ng nabanggit na cert-manager), tinutukoy nila ang (mga) primitive at (mga) controller. Ang lohika ng kanilang trabaho ay limitado lamang sa pamamagitan ng aming imahinasyon at nagbibigay-daan sa amin na gawing mga primitive ang handa na mga bahagi ng imprastraktura (halimbawa, isang DBMS), na mas madaling gamitin (kaysa sa isang hanay ng mga lalagyan at kanilang mga setting). Ang isang malaking bilang ng mga operator ay naisulat na - kahit na marami sa kanila ay hindi pa handa para sa produksyon, ito ay isang oras lamang:

    Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

  • Mga sukatan - isa pang paglalarawan kung paano pinaghiwalay ng Kubernetes ang interface (Metrics API) mula sa pagpapatupad (mga third-party na add-on gaya ng Prometheus adapter, Datadog cluster agent...).
  • Para sa pagsubaybay at istatistika, kung saan sa pagsasanay ay hindi lamang kailangan Prometheus at Grafana, ngunit pati na rin ang kube-state-metrics, node-exporter, atbp.

At hindi ito kumpletong listahan ng mga karagdagan... Halimbawa, kami sa kumpanya ng Flant ay kasalukuyang nag-i-install 29 add-on (lahat ay lumilikha ng kabuuang 249 na bagay sa Kubernetes). Sa madaling salita, hindi natin makikita ang buhay ng isang kumpol nang walang mga karagdagan.

Pag-aautomat

Ang mga operator ay idinisenyo upang i-automate ang mga nakagawiang operasyon na nakakaharap namin araw-araw. Narito ang mga halimbawa sa totoong buhay kung saan ang pagsusulat ng isang operator ay isang mahusay na solusyon:

  1. Mayroong isang pribado (ibig sabihin, nangangailangan ng pag-login) na pagpapatala na may mga larawan para sa application. Ipinapalagay na ang bawat pod ay itinalaga ng isang espesyal na lihim na nagpapahintulot sa pagpapatunay sa pagpapatala. Ang aming gawain ay upang matiyak na ang lihim na ito ay matatagpuan sa namespace upang ang mga pod ay makapag-download ng mga larawan. Maaaring magkaroon ng maraming mga application (ang bawat isa ay nangangailangan ng isang lihim), at ito ay kapaki-pakinabang upang i-update ang mga lihim sa kanilang sarili nang regular, kaya ang opsyon ng paglalatag ng mga lihim sa pamamagitan ng kamay ay inalis. Ito ay kung saan ang operator ay dumating upang iligtas: lumikha kami ng isang controller na maghihintay para sa namespace na lumitaw at, batay sa kaganapang ito, ay magdaragdag ng isang lihim sa namespace.
  2. Hayaan bilang default na pag-access mula sa mga pod sa Internet ay ipinagbabawal. Ngunit kung minsan ay maaaring kailanganin: ito ay lohikal para sa mekanismo ng pahintulot sa pag-access na gumana nang simple, nang hindi nangangailangan ng mga partikular na kasanayan, halimbawa, sa pamamagitan ng pagkakaroon ng isang tiyak na label sa namespace. Paano tayo matutulungan ng operator dito? Ang isang controller ay nilikha na naghihintay para sa label na lumitaw sa namespace at nagdaragdag ng naaangkop na patakaran para sa pag-access sa Internet.
  3. Isang katulad na sitwasyon: ipagpalagay na kailangan naming magdagdag ng isang tiyak mantsa, kung mayroon itong katulad na label (na may ilang uri ng prefix). Ang mga aksyon sa operator ay halata...

Sa anumang kumpol, dapat malutas ang mga nakagawiang gawain, at wasto ito ay maaaring gawin gamit ang mga operator.

Summing up sa lahat ng mga kuwento na inilarawan, kami ay dumating sa konklusyon na para sa komportableng trabaho sa Kubernetes kailangan mo: A) mag-install ng mga add-on, b) bumuo ng mga operator (para sa paglutas ng mga pang-araw-araw na gawain ng admin).

Paano magsulat ng pahayag para sa Kubernetes?

Sa pangkalahatan, ang scheme ay simple:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

... ngunit pagkatapos ay lumalabas na:

  • Ang Kubernetes API ay isang medyo hindi maliit na bagay na nangangailangan ng maraming oras upang makabisado;
  • Ang programming ay hindi rin para sa lahat (ang Go language ay pinili bilang ang ginustong wika dahil mayroong isang espesyal na balangkas para dito - Operator SDK);
  • Ang sitwasyon ay katulad sa mismong balangkas.

Ang bottom line: upang magsulat ng isang controller (operator) ay kailangang gumastos ng makabuluhang mapagkukunan mag-aral ng materyal. Ito ay mabibigyang katwiran para sa "malalaki" na mga operator - sabihin, para sa MySQL DBMS. Ngunit kung naaalala natin ang mga halimbawang inilarawan sa itaas (paglalahad ng mga lihim, pag-access ng mga pod sa Internet...), na gusto rin nating gawin nang tama, mauunawaan natin na ang pagsisikap na ginugol ay hihigit sa resulta na kailangan natin ngayon:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Sa pangkalahatan, lumitaw ang isang dilemma: gumastos ng maraming mapagkukunan at hanapin ang tamang tool para sa pagsusulat ng mga pahayag, o gawin ito sa makalumang paraan (ngunit mabilis). Upang malutas ito - upang makahanap ng kompromiso sa pagitan ng mga sukdulang ito - gumawa kami ng sarili naming proyekto: shell-operator (tingnan din ang kanyang kamakailang anunsyo sa hub).

Shell-operator

Paano siya nagtatrabaho? Ang cluster ay may pod na naglalaman ng Go binary na may shell-operator. Sa tabi niya ay isang set ng mga kawit (higit pang mga detalye tungkol sa kanila - tingnan sa ibaba). Ang shell-operator mismo ay nag-subscribe sa ilang kaunlaran sa Kubernetes API, kapag nangyari kung saan ilulunsad nito ang kaukulang mga kawit.

Paano malalaman ng shell-operator kung aling mga hook ang tatawagan kung aling mga kaganapan? Ang impormasyong ito ay ipinadala sa shell-operator sa pamamagitan ng mga hook mismo, at ginagawa nila ito nang napakasimple.

Ang hook ay isang Bash script o anumang iba pang executable file na tumatanggap ng isang argumento --config at tumugon sa JSON. Tinutukoy ng huli kung aling mga bagay ang interesado dito at kung aling mga kaganapan (para sa mga bagay na ito) ang dapat tumugon sa:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Ilalarawan ko ang pagpapatupad sa shell-operator ng isa sa aming mga halimbawa - nabubulok na mga lihim para sa pag-access sa isang pribadong registry na may mga larawan ng application. Binubuo ito ng dalawang yugto.

Pagsasanay: 1. Sumulat ng kawit

Una sa lahat, sa hook namin ipoproseso --config, na nagpapahiwatig na kami ay interesado sa mga namespace, at partikular, ang sandali ng kanilang paglikha:

[[ $1 == "--config" ]] ; then
  cat << EOF
{
  "onKubernetesEvent": [
    {
      "kind": "namespace",
      "event": ["add"]
    }
  ]
}
EOF
…

Ano ang magiging hitsura ng lohika? Medyo simple din:

…
else
  createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
  kubectl create -n ${createdNamespace} -f - << EOF
Kind: Secret
...
EOF
fi

Ang unang hakbang ay upang malaman kung aling namespace ang nilikha, at ang pangalawa ay ang paglikha nito gamit kubectl sikreto para sa namespace na ito.

Pagsasanay: 2. Pagtitipon ng larawan

Ang natitira na lang ay ipasa ang nilikhang kawit sa shell-operator - paano ito gagawin? Ang shell-operator mismo ay dumating bilang isang Docker na imahe, kaya ang aming gawain ay idagdag ang hook sa isang espesyal na direktoryo sa larawang ito:

FROM flant/shell-operator:v1.0.0-beta.1
ADD my-handler.sh /hooks

Ang natitira na lang ay tipunin ito at itulak:

$ docker build -t registry.example.com/my-operator:v1 .
$ docker push registry.example.com/my-operator:v1

Ang huling pagpindot ay i-deploy ang larawan sa cluster. Upang gawin ito, sumulat tayo paglawak:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-operator
spec:
  template:
    spec:
      containers:
      - name: my-operator
        image: registry.example.com/my-operator:v1 # 1
      serviceAccountName: my-operator              # 2

Mayroong dalawang puntos na dapat bigyang pansin:

  1. indikasyon ng bagong likhang imahe;
  2. Ito ay isang bahagi ng system na (sa pinakamababa) ay nangangailangan ng mga karapatang mag-subscribe sa mga kaganapan sa Kubernetes at maglaan ng mga lihim sa mga namespace, kaya gumawa kami ng ServiceAccount (at isang hanay ng mga panuntunan) para sa hook.

Resulta - nalutas namin ang aming problema mga kamag-anak para sa Kubernetes sa paraang lumilikha ng operator para sa nabubulok na mga lihim.

Iba pang mga tampok ng shell-operator

Upang limitahan ang mga bagay ng iyong napiling uri kung saan gagana ang kawit, maaari silang i-filter, pagpili ayon sa ilang partikular na label (o paggamit matchExpressions):

"onKubernetesEvent": [
  {
    "selector": {
      "matchLabels": {
        "foo": "bar",
       },
       "matchExpressions": [
         {
           "key": "allow",
           "operation": "In",
           "values": ["wan", "warehouse"],
         },
       ],
     }
     …
  }
]

Ibinigay mekanismo ng deduplikasyon, na - gamit ang isang jq filter - ay nagbibigay-daan sa iyong i-convert ang malalaking JSON object sa maliliit, kung saan ang mga parameter lang ang nananatili na gusto naming subaybayan para sa mga pagbabago.

Kapag tinawag ang isang kawit, ipinapasa ito ng shell-operator data ng bagay, na maaaring gamitin para sa anumang pangangailangan.

Ang mga kaganapan na nagpapalitaw ng mga kawit ay hindi limitado sa mga kaganapan sa Kubernetes: ang shell-operator ay nagbibigay ng suporta para sa pagtawag ng mga kawit sa pamamagitan ng oras (katulad ng crontab sa isang tradisyunal na scheduler), pati na rin sa isang espesyal na kaganapan saStartup. Ang lahat ng mga kaganapang ito ay maaaring pagsamahin at italaga sa parehong kawit.

At dalawa pang tampok ng shell-operator:

  1. Gumagana siya asynchronously. Dahil ang isang kaganapan sa Kubernetes (tulad ng isang bagay na nilikha) ay natanggap, ang iba pang mga kaganapan (tulad ng parehong bagay na tinatanggal) ay maaaring naganap sa cluster, at ang mga kawit ay kailangang isaalang-alang ito. Kung ang hook ay naisakatuparan nang may isang error, kung gayon bilang default ito ay magiging muling tawag hanggang sa matagumpay na pagkumpleto (maaaring baguhin ang pag-uugaling ito).
  2. Nag-export ito mga sukatan para sa Prometheus, kung saan maiintindihan mo kung gumagana ang shell-operator, alamin ang bilang ng mga error para sa bawat hook at ang kasalukuyang laki ng pila.

Upang ibuod ang bahaging ito ng ulat:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Pag-install ng mga add-on

Para sa kumportableng trabaho sa Kubernetes, nabanggit din ang pangangailangang mag-install ng mga add-on. Sasabihin ko sa iyo ang tungkol dito gamit ang halimbawa ng landas ng aming kumpanya kung paano namin ito ginagawa ngayon.

Nagsimula kaming magtrabaho kasama ang Kubernetes na may ilang mga cluster, ang tanging karagdagan kung saan ay ang Ingress. Kailangan itong ma-install nang iba sa bawat cluster, at gumawa kami ng ilang configuration ng YAML para sa iba't ibang environment: bare metal, AWS...

Dahil mas marami ang mga kumpol, mas marami ang mga pagsasaayos. Bilang karagdagan, pinahusay namin mismo ang mga pagsasaayos na ito, bilang isang resulta kung saan sila ay naging medyo magkakaiba:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Upang maiayos ang lahat, nagsimula kami sa isang script (install-ingress.sh), na kinuha bilang argumento ang uri ng cluster kung saan kami i-deploy, nabuo ang kinakailangang configuration ng YAML at inilunsad ito sa Kubernetes.

Sa madaling salita, ang aming karagdagang landas at ang pangangatwiran na nauugnay dito ay ang mga sumusunod:

  • upang gumana sa mga pagsasaayos ng YAML, kinakailangan ang isang template engine (sa mga unang yugto ito ay simpleng sed);
  • sa pagtaas ng bilang ng mga kumpol, dumating ang pangangailangan para sa awtomatikong pag-update (ang pinakamaagang solusyon ay ilagay ang script sa Git, i-update ito gamit ang cron at patakbuhin ito);
  • isang katulad na script ang kailangan para sa Prometheus (install-prometheus.sh), gayunpaman, ito ay kapansin-pansin sa katotohanan na nangangailangan ito ng higit pang data ng pag-input, pati na rin ang kanilang imbakan (sa isang mahusay na paraan - sentralisado at sa isang kumpol), at ang ilang data (mga password) ay maaaring awtomatikong mabuo:

    Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

  • patuloy na lumalago ang panganib na magkaroon ng mali sa dumaraming cluster, kaya napagtanto namin na ang mga installer (ibig sabihin, dalawang script: para sa Ingress at Prometheus) ang pagtatanghal ng dula ay kailangan (ilang sangay sa Git, ilang crons upang i-update ang mga ito sa kaukulang: stable o test cluster);
  • с kubectl apply naging mahirap itong gamitin dahil hindi ito deklaratibo at maaari lamang lumikha ng mga bagay, ngunit hindi gumawa ng mga desisyon sa kanilang katayuan/tanggalin ang mga ito;
  • Nawawalan kami ng ilang function na hindi pa namin ipinatupad noong panahong iyon:
    • ganap na kontrol sa resulta ng mga pag-update ng cluster,
    • awtomatikong pagtukoy ng ilang mga parameter (input para sa mga script ng pag-install) batay sa data na maaaring makuha mula sa cluster (pagtuklas),
    • lohikal na pag-unlad nito sa anyo ng patuloy na pagtuklas.

Ipinatupad namin ang lahat ng naipon na karanasang ito sa loob ng balangkas ng aming iba pang proyekto - addon-operator.

Addon-operator

Ito ay batay sa nabanggit na shell-operator. Ang buong sistema ay ganito ang hitsura:

Ang mga sumusunod ay idinagdag sa mga shell-operator hook:

  • imbakan ng halaga,
  • Helm chart,
  • sangkap na sinusubaybayan ang tindahan ng mga halaga at - sa kaso ng anumang mga pagbabago - humihiling sa Helm na muling i-roll ang tsart.

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Kaya, maaari tayong mag-react sa isang kaganapan sa Kubernetes, maglunsad ng isang hook, at mula sa hook na ito maaari tayong gumawa ng mga pagbabago sa storage, pagkatapos nito ay muling ida-download ang chart. Sa resultang diagram, pinaghihiwalay namin ang hanay ng mga kawit at ang tsart sa isang bahagi, na tinatawag namin modyul:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Maaaring mayroong maraming mga module, at sa kanila ay nagdaragdag kami ng mga pandaigdigang kawit, isang pandaigdigang tindahan ng mga halaga, at isang bahagi na sumusubaybay sa pandaigdigang tindahang ito.

Ngayon, kapag may nangyari sa Kubernetes, maaari tayong mag-react dito gamit ang isang global hook at magbago ng isang bagay sa pandaigdigang tindahan. Mapapansin ang pagbabagong ito at magiging sanhi ng paglulunsad ng lahat ng module sa cluster:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Ang scheme na ito ay nakakatugon sa lahat ng mga kinakailangan para sa pag-install ng mga add-on na nakasaad sa itaas:

  • Ang Helm ay may pananagutan para sa template at pagiging declarative.
  • Ang isyu ng auto-update ay nalutas gamit ang isang pandaigdigang hook, na pupunta sa registry sa isang iskedyul at, kung makakita ito ng isang bagong imahe ng system doon, ilalabas ito (i.e. "sarili").
  • Ang mga setting ng pag-iimbak sa cluster ay ipinatupad gamit ConfigMap, na naglalaman ng pangunahing data para sa mga imbakan (sa pagsisimula ay nilo-load ang mga ito sa mga imbakan).
  • Ang mga problema sa pagbuo ng password, pagtuklas at patuloy na pagtuklas ay nalutas gamit ang mga kawit.
  • Nakamit ang staging salamat sa mga tag, na sinusuportahan ng Docker sa labas ng kahon.
  • Ang resulta ay sinusubaybayan gamit ang mga sukatan kung saan natin mauunawaan ang katayuan.

Ang buong sistemang ito ay ipinatupad sa anyo ng isang binary sa Go, na tinatawag na addon-operator. Ginagawa nitong mas simple ang diagram:

Pagpapalawak at pagpupuno sa Kubernetes (pagsusuri at ulat ng video)

Ang pangunahing bahagi sa diagram na ito ay isang hanay ng mga module (naka-highlight sa kulay abo sa ibaba). Ngayon ay maaari na tayong magsulat ng isang module para sa kinakailangang add-on na may kaunting pagsisikap at siguraduhin na ito ay mai-install sa bawat cluster, maa-update at tumugon sa mga kaganapan na kailangan nito sa cluster.

"Flant" gamit addon-operator sa 70+ cluster ng Kubernetes. Kasalukuyang kalagayan - bersyon ng alpha. Ngayon ay naghahanda kami ng dokumentasyon para ilabas ang beta, ngunit sa ngayon ay nasa repositoryo magagamit ang mga halimbawa, sa batayan kung saan maaari kang lumikha ng iyong sariling addon.

Saan ko makukuha ang mga module para sa addon-operator? Ang pag-publish ng aming library ay ang susunod na yugto para sa amin; plano naming gawin ito sa tag-araw.

Mga video at slide

Video mula sa pagganap (~50 minuto):

Presentasyon ng ulat:

PS

Iba pang mga ulat sa aming blog:

Maaari ka ring maging interesado sa mga sumusunod na publikasyon:

Pinagmulan: www.habr.com

Magdagdag ng komento