Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Ebrill 8 yn y gynhadledd Saint HighLoad++ 2019, fel rhan o'r adran “DevOps and Operations”, rhoddwyd adroddiad “Ehangu ac ategu Kubernetes”, y cymerodd tri o weithwyr cwmni Flant ran wrth ei greu. Ynddo, rydym yn siarad am nifer o sefyllfaoedd lle'r oeddem am ehangu ac ategu galluoedd Kubernetes, ond ni wnaethom ddod o hyd i ateb parod a syml ar eu cyfer. Mae gennym yr atebion angenrheidiol ar ffurf prosiectau Ffynhonnell Agored, ac mae'r araith hon hefyd wedi'i chysegru iddynt.

Yn ôl traddodiad, rydym yn falch o gyflwyno fideo o'r adroddiad (50 munud, llawer mwy addysgiadol na'r erthygl) a'r prif grynodeb ar ffurf testun. Ewch!

Craidd ac ychwanegiadau yn K8s

Mae Kubernetes yn newid y diwydiant a'r dulliau gweinyddu sydd wedi'u hen sefydlu:

  • Diolch iddo tyniadau, nid ydym bellach yn gweithredu gyda chysyniadau fel sefydlu ffurfwedd neu redeg gorchymyn (Cogydd, Ansible ...), ond yn defnyddio grwpio cynwysyddion, gwasanaethau, ac ati.
  • Gallwn baratoi ceisiadau heb feddwl am naws y safle penodol, y caiff ei lansio arno: metel noeth, cwmwl un o'r darparwyr, ac ati.
  • Gyda K8s nid ydych erioed wedi bod yn fwy hygyrch arferion gorau ar drefnu seilwaith: technegau graddio, hunan-iacháu, goddef diffygion, ac ati.

Fodd bynnag, wrth gwrs, nid yw popeth mor llyfn: daeth Kubernetes â'i heriau newydd ei hun hefyd.

Kubernetes dim yn gyfuniad sy'n datrys holl broblemau'r holl ddefnyddwyr. Y craidd Mae Kubernetes yn gyfrifol am set o'r swyddogaethau lleiaf angenrheidiol sy'n bresennol yn unig pawb clwstwr:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Mae craidd Kubernetes yn diffinio set sylfaenol o gyntefig ar gyfer grwpio cynwysyddion, rheoli traffig, ac ati. Buom yn siarad am danynt yn fanylach yn adroddiad 2 flynedd yn ôl.

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Ar y llaw arall, mae K8s yn cynnig cyfleoedd gwych i ehangu'r swyddogaethau sydd ar gael, sy'n helpu i gau eraill - penodol - anghenion defnyddwyr. Cyfrifoldeb gweinyddwyr clwstwr yw ychwanegiadau i Kubernetes, y mae'n rhaid iddynt osod a ffurfweddu popeth sy'n angenrheidiol i gael eu clwstwr “yn y siâp cywir” [i ddatrys eu problemau penodol]. Pa fath o ychwanegiadau yw'r rhain? Gadewch i ni edrych ar rai enghreifftiau.

Enghreifftiau o ychwanegion

Ar ôl gosod Kubernetes, efallai y byddwn yn synnu nad yw'r rhwydweithio sydd mor angenrheidiol ar gyfer rhyngweithio codennau o fewn nod a rhwng nodau yn gweithio ar ei ben ei hun. Nid yw cnewyllyn Kubernetes yn gwarantu'r cysylltiadau angenrheidiol; yn lle hynny, mae'n pennu'r rhwydwaith y rhyngwyneb (CNI) ar gyfer ychwanegion trydydd parti. Rhaid inni osod un o'r ychwanegion hyn, a fydd yn gyfrifol am gyfluniad y rhwydwaith.

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Enghraifft agos yw datrysiadau storio data (disg leol, dyfais bloc rhwydwaith, Ceph...). Ar y dechrau roedden nhw yn y craidd, ond gyda'r dyfodiad DPC mae'r sefyllfa'n newid i rywbeth tebyg i'r hyn a ddisgrifiwyd eisoes: mae'r rhyngwyneb yn Kubernetes, ac mae ei weithrediad mewn modiwlau trydydd parti.

Mae enghreifftiau eraill yn cynnwys:

  • Mynd i mewn-rheolwyr (gweler eu hadolygiad yn ein herthygl ddiweddar).
  • rheolwr tystysgrif:

    Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

  • Gweithredwyr yn ddosbarth cyfan o ychwanegion (sy'n cynnwys y rheolwr tystysgrif a grybwyllwyd), maent yn diffinio cyntefig(ion) a rheolydd(ion). Mae rhesymeg eu gwaith wedi'i gyfyngu gan ein dychymyg yn unig ac mae'n ein galluogi i droi cydrannau seilwaith parod (er enghraifft, DBMS) yn rhai cyntefig, sy'n llawer haws gweithio gyda nhw (na gyda set o gynwysyddion a'u gosodiadau). Mae nifer enfawr o weithredwyr wedi'u hysgrifennu - hyd yn oed os nad yw llawer ohonynt yn barod i'w cynhyrchu eto, dim ond mater o amser yw hi:

    Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

  • Metrigau - enghraifft arall o sut y gwnaeth Kubernetes wahanu'r rhyngwyneb (Metrics API) o'r gweithredu (ychwanegion trydydd parti fel addasydd Prometheus, asiant clwstwr Datadog...).
  • I monitro ac ystadegau, lle yn ymarferol nid yn unig y mae eu hangen Prometheus a Grafana, ond hefyd kube-state-metrics, nod-allforiwr, ac ati.

Ac nid yw hon yn rhestr gyflawn o ychwanegiadau... Er enghraifft, yn y cwmni yn y Fflint yr ydym yn ei osod ar hyn o bryd 29 o ychwanegiadau (pob un yn creu cyfanswm o 249 o wrthrychau Kubernetes). Yn syml, ni allwn weld bywyd clwstwr heb ychwanegiadau.

Awtomeiddio

Mae gweithredwyr wedi'u cynllunio i awtomeiddio gweithrediadau arferol yr ydym yn dod ar eu traws bob dydd. Dyma enghreifftiau go iawn y byddai ysgrifennu gweithredwr yn ateb ardderchog ar eu cyfer:

  1. Mae yna gofrestrfa breifat (h.y. angen mewngofnodi) gyda delweddau ar gyfer y rhaglen. Tybir bod pob pod yn cael ei neilltuo cyfrinach arbennig sy'n caniatáu dilysu yn y gofrestrfa. Ein tasg ni yw sicrhau bod y gyfrinach hon i'w chael yn y gofod enwau fel y gall codennau lawrlwytho delweddau. Gall fod llawer o gymwysiadau (mae angen cyfrinach ar bob un ohonynt), ac mae'n ddefnyddiol diweddaru'r cyfrinachau eu hunain yn rheolaidd, felly mae'r opsiwn o osod cyfrinachau â llaw yn cael ei ddileu. Dyma lle mae'r gweithredwr yn dod i'r adwy: rydyn ni'n creu rheolydd a fydd yn aros i'r gofod enw ymddangos ac, yn seiliedig ar y digwyddiad hwn, yn ychwanegu cyfrinach i'r gofod enwau.
  2. Gwaherddir mynediad rhagosodedig o godau i'r Rhyngrwyd. Ond weithiau gall fod ei angen: mae'n rhesymegol i'r mecanwaith caniatâd mynediad weithio'n syml, heb fod angen sgiliau penodol, er enghraifft, trwy bresenoldeb label penodol yn y gofod enwau. Sut gall y gweithredwr ein helpu ni yma? Mae rheolydd yn cael ei greu sy'n aros i'r label ymddangos yn y gofod enwau ac yn ychwanegu'r polisi priodol ar gyfer mynediad i'r Rhyngrwyd.
  3. Sefyllfa debyg: mae'n debyg bod angen i ni ychwanegu rhywfaint llygredigaeth, os oes ganddo label tebyg (gyda rhyw fath o rhagddodiad). Mae'r gweithredoedd gyda'r gweithredwr yn amlwg ...

Mewn unrhyw glwstwr, rhaid datrys tasgau arferol, a yn gywir gellir gwneud hyn gan ddefnyddio gweithredwyr.

Wrth grynhoi'r holl straeon a ddisgrifiwyd, daethom i'r casgliad bod ar gyfer gwaith cyfforddus yn Kubernetes ei angen arnoch: a) gosod ychwanegion, b) datblygu gweithredwyr (ar gyfer datrys tasgau gweinyddol bob dydd).

Sut i ysgrifennu datganiad ar gyfer Kubernetes?

Yn gyffredinol, mae'r cynllun yn syml:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

... ond yna mae'n troi allan bod:

  • Mae API Kubernetes yn beth braidd yn ddibwys sy'n cymryd llawer o amser i'w feistroli;
  • nid yw rhaglennu at ddant pawb chwaith (dewiswyd yr iaith Go fel y dewis iaith oherwydd bod fframwaith arbennig ar ei chyfer - Gweithredwr SDK);
  • Mae'r sefyllfa yn debyg i'r fframwaith ei hun.

Mae'r llinell waelod: i ysgrifennu rheolydd (gweithredwr) yn gorfod gwario adnoddau sylweddol i astudio deunydd. Byddai hyn yn cael ei gyfiawnhau ar gyfer gweithredwyr “mawr” - dyweder, ar gyfer y DBMS MySQL. Ond os ydym yn cofio'r enghreifftiau a ddisgrifir uchod (cyfrinachau sy'n datblygu, cyrchu codennau i'r Rhyngrwyd ...), yr ydym hefyd am eu gwneud yn gywir, yna byddwn yn deall y bydd yr ymdrech a wneir yn gorbwyso'r canlyniad sydd ei angen arnom nawr:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Yn gyffredinol, mae cyfyng-gyngor yn codi: treuliwch lawer o adnoddau a dewch o hyd i'r offeryn cywir ar gyfer ysgrifennu datganiadau, neu gwnewch hynny yn y ffordd hen ffasiwn (ond yn gyflym). Er mwyn ei ddatrys - i ddod o hyd i gyfaddawd rhwng yr eithafion hyn - fe wnaethon ni greu ein prosiect ein hunain: cregyn-weithredwr (gw. hefyd ei cyhoeddiad diweddar ar y canolbwynt).

Cregyn-weithredwr

Sut mae e'n gweithio? Mae gan y clwstwr god sy'n cynnwys Go deuaidd gyda gweithredwr cregyn. Wrth ei ymyl mae set o bachau (mwy o fanylion amdanynt - gweler isod). Mae'r gweithredwr cragen ei hun yn tanysgrifio i rai penodol datblygiadau yn API Kubernetes, pan fydd yn lansio'r bachau cyfatebol.

Sut mae'r gweithredwr cragen yn gwybod pa fachau i alw arnynt pa ddigwyddiadau? Trosglwyddir y wybodaeth hon i'r gweithredwr cragen gan y bachau eu hunain, ac maent yn ei wneud yn syml iawn.

Sgript Bash neu unrhyw ffeil weithredadwy arall sy'n derbyn un ddadl yw bachyn --config ac yn ymateb gyda JSON. Mae’r olaf yn pennu pa wrthrychau sydd o ddiddordeb iddo a pha ddigwyddiadau (ar gyfer y gwrthrychau hyn) y dylid ymateb iddynt:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Byddaf yn darlunio gweithrediad un o'n henghreifftiau ar weithredwr cragen - cyfrinachau dadelfennu ar gyfer cyrchu cofrestrfa breifat gyda delweddau cymhwysiad. Mae'n cynnwys dau gam.

Ymarfer: 1. Ysgrifennu bachyn

Yn gyntaf oll, yn y bachyn byddwn yn prosesu --config, sy’n nodi bod gennym ddiddordeb mewn gofodau enwau, ac yn benodol, adeg eu creu:

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

Sut olwg fyddai ar y rhesymeg? Hefyd yn eithaf syml:

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

Y cam cyntaf yw darganfod pa ofod enwau a grëwyd, a'r ail yw ei greu gan ddefnyddio kubectl gyfrinach ar gyfer y gofod enw hwn.

Ymarfer: 2. Cydosod y ddelwedd

Y cyfan sydd ar ôl yw trosglwyddo'r bachyn a grëwyd i'r gweithredwr cragen - sut i wneud hyn? Daw'r gweithredwr cregyn ei hun fel delwedd Docker, felly ein tasg ni yw ychwanegu'r bachyn i gyfeiriadur arbennig yn y ddelwedd hon:

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

Y cyfan sydd ar ôl yw ei gydosod a'i wthio:

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

Y cyffyrddiad olaf yw defnyddio'r ddelwedd i'r clwstwr. I wneud hyn, gadewch i ni ysgrifennu Defnyddio:

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

Mae dau bwynt i roi sylw iddynt:

  1. arwydd o'r ddelwedd newydd;
  2. Mae hon yn gydran system sydd (o leiaf) angen hawliau i danysgrifio i ddigwyddiadau yn Kubernetes ac i ddyrannu cyfrinachau i ofodau enwau, felly rydyn ni'n creu Cyfrif Gwasanaeth (a set o reolau) ar gyfer y bachyn.

Canlyniad - fe wnaethon ni ddatrys ein problem perthnasau ar gyfer Kubernetes mewn ffordd sy'n creu gweithredwr ar gyfer dadelfennu cyfrinachau.

Nodweddion eraill gweithredwr cragen

I gyfyngu ar wrthrychau o'r math o'ch dewis y bydd y bachyn yn gweithio gyda nhw, gellir eu hidlo, dewis yn ôl rhai labeli (neu ddefnyddio matchExpressions):

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

Darperir mecanwaith dad-ddyblygu, sydd - gan ddefnyddio hidlydd jq - yn eich galluogi i drosi gwrthrychau JSON mawr yn rhai bach, lle mai dim ond y paramedrau hynny sy'n weddill yr ydym am eu monitro am newidiadau.

Pan elwir bachyn, mae'r gweithredwr cragen yn ei basio data gwrthrych, y gellir ei ddefnyddio ar gyfer unrhyw angen.

Nid yw'r digwyddiadau sy'n sbarduno bachau yn gyfyngedig i ddigwyddiadau Kubernetes: mae'r gweithredwr cregyn yn darparu cefnogaeth ar gyfer galw bachau erbyn amser (yn debyg i crontab mewn amserlen draddodiadol), yn ogystal â digwyddiad arbennig arCychwyn. Gellir cyfuno'r holl ddigwyddiadau hyn a'u neilltuo i'r un bachyn.

A dwy nodwedd arall i'r gweithredwr cragen:

  1. Mae'n gweithio yn asyncronig. Ers i ddigwyddiad Kubernetes (fel gwrthrych yn cael ei greu) gael ei dderbyn, gallai digwyddiadau eraill (megis yr un gwrthrych yn cael ei ddileu) fod wedi digwydd yn y clwstwr, ac mae angen i fachau roi cyfrif am hyn. Os gweithredwyd y bachyn gyda gwall, yna yn ddiofyn bydd ail-alw nes ei gwblhau'n llwyddiannus (gellir newid yr ymddygiad hwn).
  2. Mae'n allforio metrigau ar gyfer Prometheus, gyda'r hwn y gallwch ddeall a yw'r gweithredwr cragen yn gweithio, darganfyddwch nifer y gwallau ar gyfer pob bachyn a maint y ciw presennol.

I grynhoi’r rhan hon o’r adroddiad:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Gosod ychwanegion

Ar gyfer gwaith cyfforddus gyda Kubernetes, soniwyd hefyd am yr angen i osod ychwanegion. Byddaf yn dweud wrthych amdano gan ddefnyddio'r enghraifft o lwybr ein cwmni i sut rydym yn ei wneud nawr.

Dechreuon ni weithio gyda Kubernetes gyda sawl clwstwr, a'r unig ychwanegiad oedd Ingress. Roedd angen ei osod yn wahanol ym mhob clwstwr, a gwnaethom sawl ffurfweddiad YAML ar gyfer gwahanol amgylcheddau: metel noeth, AWS ...

Gan fod mwy o glystyrau, roedd mwy o gyfluniadau. Yn ogystal, fe wnaethom wella'r cyfluniadau hyn eu hunain, a daethant yn eithaf heterogenaidd o ganlyniad:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

I roi popeth mewn trefn, dechreuon ni gyda sgript (install-ingress.sh), a gymerodd fel dadl y math o glwstwr y byddwn yn ei ddefnyddio, a gynhyrchodd y cyfluniad YAML angenrheidiol a'i gyflwyno i Kubernetes.

Yn fyr, roedd ein llwybr pellach a’r rhesymeg sy’n gysylltiedig ag ef fel a ganlyn:

  • i weithio gyda chyfluniadau YAML, mae angen peiriant templed (yn y camau cyntaf mae hyn yn sed syml);
  • gyda'r cynnydd yn nifer y clystyrau, daeth yr angen am ddiweddaru awtomatig (yr ateb cynharaf oedd rhoi'r sgript yn Git, ei ddiweddaru gan ddefnyddio cron a'i redeg);
  • roedd angen sgript debyg ar gyfer Prometheus (install-prometheus.sh), fodd bynnag, mae'n nodedig am y ffaith bod angen llawer mwy o ddata mewnbwn arno, yn ogystal â'u storio (mewn ffordd dda - wedi'i ganoli ac mewn clwstwr), a gellid cynhyrchu rhywfaint o ddata (cyfrineiriau) yn awtomatig:

    Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

  • roedd y risg o gyflwyno rhywbeth o'i le i nifer cynyddol o glystyrau yn cynyddu'n gyson, felly sylweddolom fod gosodwyr (h.y. dwy sgript: ar gyfer Ingress a Prometheus) roedd angen llwyfannu (sawl cangen yn Git, sawl crons i'w diweddaru yn y clystyrau cyfatebol: sefydlog neu brawf);
  • с kubectl apply mae wedi dod yn anodd gweithio ag ef oherwydd nid yw'n ddatganiadol a gall greu gwrthrychau yn unig, ond ni all wneud penderfyniadau ar eu statws/eu dileu;
  • Roeddem yn colli rhai swyddogaethau nad oeddem wedi eu gweithredu o gwbl bryd hynny:
    • rheolaeth lawn dros ganlyniad diweddariadau clwstwr,
    • penderfyniad awtomatig o rai paramedrau (mewnbwn ar gyfer sgriptiau gosod) yn seiliedig ar ddata y gellir ei gael o'r clwstwr (darganfod),
    • ei ddatblygiad rhesymegol ar ffurf darganfyddiad parhaus.

Gweithredwyd yr holl brofiad cronedig hwn o fewn fframwaith ein prosiect arall - gweithredwr addon.

Addon-weithredwr

Mae'n seiliedig ar y gweithredwr cragen y soniwyd amdano eisoes. Mae'r system gyfan yn edrych fel hyn:

Ychwanegir y canlynol at fachau'r gweithredwr cragen:

  • storio gwerthoedd,
  • Siart llyw,
  • gydran hynny yn monitro'r storfa gwerthoedd ac - rhag ofn y bydd unrhyw newidiadau - yn gofyn i Helm ail-rolio'r siart.

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Felly, gallwn ymateb i ddigwyddiad yn Kubernetes, lansio bachyn, ac o'r bachyn hwn gallwn wneud newidiadau i'r storfa, ac ar ôl hynny bydd y siart yn cael ei ail-lwytho i lawr. Yn y diagram canlyniadol, rydyn ni'n gwahanu'r set o fachau a'r siart yn un gydran, rydyn ni'n ei galw modiwl:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Gall fod llawer o fodiwlau, ac atyn nhw rydym yn ychwanegu bachau byd-eang, storfa werthoedd byd-eang, a chydran sy'n monitro'r storfa fyd-eang hon.

Nawr, pan fydd rhywbeth yn digwydd yn Kubernetes, gallwn ymateb iddo gan ddefnyddio bachyn byd-eang a newid rhywbeth yn y siop fyd-eang. Bydd y newid hwn yn cael ei sylwi a bydd yn achosi i bob modiwl yn y clwstwr gael ei gyflwyno:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Mae'r cynllun hwn yn bodloni'r holl ofynion ar gyfer gosod ychwanegion a nodwyd uchod:

  • Helm sy'n gyfrifol am dempledi a datganolrwydd.
  • Datryswyd y mater o ddiweddariad auto gan ddefnyddio bachyn byd-eang, sy'n mynd i'r gofrestrfa ar amserlen ac, os yw'n gweld delwedd system newydd yno, yn ei chyflwyno (h.y. “ei hun”).
  • Mae gosodiadau storio yn y clwstwr yn cael ei weithredu gan ddefnyddio configMap, sy'n cynnwys y data sylfaenol ar gyfer y storfa (wrth gychwyn maent yn cael eu llwytho i mewn i'r storfa).
  • Datryswyd problemau gyda chynhyrchu cyfrinair, darganfod a darganfod parhaus gan ddefnyddio bachau.
  • Cyflawnir llwyfannu diolch i dagiau, y mae Docker yn eu cefnogi allan o'r bocs.
  • Mae'r canlyniad yn cael ei fonitro gan ddefnyddio metrigau i ni allu deall y statws.

Mae'r system gyfan hon yn cael ei gweithredu ar ffurf deuaidd sengl yn Go, a elwir yn addo-operator. Mae hyn yn gwneud i'r diagram edrych yn symlach:

Ehangu ac ategu Kubernetes (adroddiad trosolwg a fideo)

Y brif gydran yn y diagram hwn yw set o fodiwlau (wedi'i amlygu mewn llwyd isod). Nawr gallwn ysgrifennu modiwl ar gyfer yr ychwanegiad gofynnol gydag ychydig o ymdrech a bod yn siŵr y bydd yn cael ei osod ym mhob clwstwr, yn cael ei ddiweddaru ac yn ymateb i'r digwyddiadau sydd eu hangen arno yn y clwstwr.

Defnyddiau "fflant". gweithredwr addon ar 70+ o glystyrau Kubernetes. Statws presennol - fersiwn alffa. Nawr rydym yn paratoi dogfennaeth i ryddhau'r beta, ond am y tro yn yr ystorfa enghreifftiau ar gael, ar y sail y gallwch greu eich addon eich hun.

Ble alla i gael y modiwlau ar gyfer gweithredwr ychwanegion? Cyhoeddi ein llyfrgell yw’r cam nesaf i ni; rydym yn bwriadu gwneud hyn yn yr haf.

Fideos a sleidiau

Fideo o'r perfformiad (~50 munud):

Cyflwyniad yr adroddiad:

PS

Adroddiadau eraill ar ein blog:

Efallai y bydd gennych ddiddordeb hefyd yn y cyhoeddiadau canlynol:

Ffynhonnell: hab.com

Ychwanegu sylw