E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung

E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung

Ëmmer méi kréien Clienten déi folgend Ufroen: "Mir wëllen et wéi Amazon RDS, awer méi bëlleg"; "Mir wëllen et wéi RDS, awer iwwerall, an all Infrastruktur." Fir sou eng verwaltet Léisung op Kubernetes ëmzesetzen, hu mir den aktuellen Zoustand vun de populäersten Betreiber fir PostgreSQL (Solon, Betreiber vu Crunchy Data an Zalando) gekuckt an eis Wiel gemaach.

Dësen Artikel ass d'Erfahrung, déi mir souwuel aus theoretesch Siicht (Iwwerpréiwung vu Léisungen) wéi och vun enger praktescher Säit (wat gewielt gouf a wat doraus komm ass) gewonnen hunn. Awer als éischt, loosst eis bestëmmen wat d'allgemeng Ufuerderunge sinn fir e potenziellen Ersatz fir RDS ...

Wat ass RDS

Wann d'Leit iwwer RDS schwätzen, an eiser Erfahrung, mengen se e geréiert DBMS Service deen:

  1. einfach ze konfiguréieren;
  2. huet d'Fäegkeet mat Snapshots ze schaffen an dovun z'erhuelen (virun allem mat Ënnerstëtzung PITR);
  3. erlaabt Iech Master-Sklave Topologien ze kreéieren;
  4. huet eng räich Lëscht vun Extensiounen;
  5. stellt Audit a Benotzer / Zougang Gestioun.

Allgemeng kënne Approche fir d'Ëmsetze vun der Aufgab ganz ënnerschiddlech sinn, awer de Wee mat bedingte Ansible ass net no bei eis. (Kollegen aus 2GIS koumen zu enger ähnlecher Conclusioun als Resultat sengem Versuch erstellt "e Tool fir séier e Postgres-baséiert Failover Cluster z'installéieren.")

Bedreiwer sinn eng gemeinsam Approche fir ähnlech Problemer am Kubernetes Ökosystem ze léisen. Den techneschen Direkter vun "Flanta" huet scho méi detailléiert iwwer si geschwat a Relatioun mat Datenbanken, déi bannent Kubernetes lancéiert goufen. distol, an ee vu senge Berichter.

NB: Fir séier einfach Betreiber ze kreéieren, empfeelen mir Iech op eisen Open Source Utility opzepassen Shell-Operateur. Mat Hëllef kënnt Dir dëst ouni Wësse vu Go maachen, awer op Weeër méi vertraut fir Systemadministratoren: am Bash, Python, etc.

Et gi verschidde populär K8s Bedreiwer fir PostgreSQL:

  • Stolon;
  • Crunchy Data PostgreSQL Bedreiwer;
  • Zalando Postgres Bedreiwer.

Loosst eis se méi genee kucken.

Operateur Auswiel

Zousätzlech zu de wichtege Fonctiounen, déi schonn uewe genannt goufen, hu mir - als Kubernetes Infrastruktur Operatiounsingenieuren - och déi folgend vun de Betreiber erwaart:

  • Détachement vun Git a mat Benotzerdefinéiert Ressourcen;
  • Pod Anti-Affinitéit Ënnerstëtzung;
  • installéiert Node Affinitéit oder Node selector;
  • Installatioun vun Toleranzen;
  • Disponibilitéit vun Tuning Fähegkeeten;
  • verständlech Technologien a souguer Kommandoen.

Ouni an Detailer op jiddereng vun de Punkten anzegoen (frot an de Kommentaren, wann Dir nach Froen doriwwer hutt nodeems Dir de ganzen Artikel gelies hutt), wäert ech allgemeng bemierken datt dës Parameteren gebraucht ginn fir d'Spezialisatioun vu Clusternoden méi präzis ze beschreiwen fir bestellen se fir spezifesch Uwendungen. Esou kënne mir den optimale Gläichgewiicht a punkto Leeschtung a Käschten erreechen.

Loosst eis elo op d'PostgreSQL Bedreiwer selwer goen.

1. Stolon

Stolon vun der italienescher Firma Sorint.lab an schonn ernimmt Rapport gouf als eng Zort Standard ënner Bedreiwer fir DBMS ugesinn. Dëst ass en zimlech alen Projet: seng éischt ëffentlech Verëffentlechung ass am November 2015 (!) stattfonnt, an de GitHub Repository bitt bal 3000 Stären a 40+ Mataarbechter.

Tatsächlech ass Stolon en exzellent Beispill vu nodenklecher Architektur:

E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung
Den Apparat vun dësem Bedreiwer kann am Detail am Rapport fonnt ginn oder Projet Dokumentatioun. Am Allgemengen geet et duer ze soen datt et alles ka maachen wat beschriwwen ass: Failover, Proxyen fir transparent Client Zougang, Backups ... Ausserdeem bidden Proxyen Zougang iwwer een Endpunktservice - am Géigesaz zu den aneren zwou Léisungen, déi hei ënnen diskutéiert ginn (si hunn all zwee Servicer fir Zougang Basis).

Allerdéngs Stolon keng Benotzerdefinéiert Ressourcen, Dofir kann et net esou agesat ginn datt et einfach a séier ass - "wéi waarm Kuch" - DBMS Instanzen a Kubernetes ze kreéieren. D'Verwaltung gëtt duerch den Utility duerchgefouert stolonctl, Deployment gëtt duerch d'Helm-Diagramm gemaach, a personaliséiert ginn an ConfigMap definéiert a spezifizéiert.

Engersäits stellt sech eraus datt de Bedreiwer net wierklech e Bedreiwer ass (schliisslech benotzt et net CRD). Awer op der anerer Säit ass et e flexibele System deen Iech erlaabt Ressourcen a K8s ze konfiguréieren wéi Dir passt.

Fir ze resuméieren, fir eis perséinlech huet et net optimal geschéngt fir eng separat Diagramm fir all Datebank ze kreéieren. Dofir hu mir ugefaang no Alternativen ze sichen.

2. Crunchy Data PostgreSQL Bedreiwer

Bedreiwer vun Crunchy Data, e jonken amerikanesche Startup, schéngt wéi eng logesch Alternativ. Seng ëffentlech Geschicht fänkt mat der éischter Verëffentlechung am Mäerz 2017 un, zënterhier huet de GitHub Repository just ënner 1300 Stären a 50+ Mataarbechter kritt. Déi lescht Verëffentlechung vum September gouf getest fir mat Kubernetes 1.15-1.18, OpenShift 3.11+ a 4.4+, GKE a VMware Enterprise PKS 1.3+ ze schaffen.

D'Architektur vum Crunchy Data PostgreSQL Operator entsprécht och déi uginn Ufuerderungen:

E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung

Gestioun geschitt duerch den Utility pgo, awer generéiert et am Tour Custom Ressourcen fir Kubernetes. Dofir huet de Bedreiwer eis als potenziell Benotzer gefreet:

  • et gëtt Kontroll iwwer CRD;
  • bequem Benotzerverwaltung (och iwwer CRD);
  • Integratioun mat anere Komponenten Crunchy Data Container Suite - eng spezialiséiert Sammlung vu Containerbiller fir PostgreSQL an Utilities fir domat ze schaffen (inklusiv pgBackRest, pgAudit, Extensiounen vum Contrib, etc.).

Wéi och ëmmer, Versuche fir de Bedreiwer vu Crunchy Data ze benotzen hunn e puer Probleemer opgedeckt:

  • Et war keng Méiglechkeet vu Toleratiounen - nëmmen NodeSelector gëtt zur Verfügung gestallt.
  • Déi erstallt Pods waren Deel vum Deployment, trotz der Tatsaach datt mir eng statesch Applikatioun ofgesat hunn. Am Géigesaz zu StatefulSets kënnen Deployments keng Disken erstellen.

De leschten Nodeel féiert zu witzege Momenter: am Testëmfeld hu mir et fäerdeg bruecht 3 Repliken mat enger Disk ze lafen lokal Stockage, wouduerch de Bedreiwer bericht huet datt 3 Repliken funktionnéieren (och wann se net waren).

Eng aner Feature vun dësem Bedreiwer ass seng fäerdeg Integratioun mat verschiddenen Hëllefssystemer. Zum Beispill ass et einfach pgAdmin an pgBounce z'installéieren, an an Dokumentatioun pre-konfiguréiert Grafana an Prometheus considéréiert ginn. Am leschte Verëffentlechung 4.5.0-beta1 Verbesserte Integratioun mam Projet gëtt separat bemierkt pgMonitor, Dank deem de Bedreiwer eng kloer Visualiséierung vu PgSQL Metriken aus der Këscht bitt.

Wéi och ëmmer, déi komesch Wiel vu Kubernetes-generéierte Ressourcen huet eis zum Besoin gefouert eng aner Léisung ze fannen.

3. Zalando Postgres Bedreiwer

Mir kennen Zalando Produkter fir eng laang Zäit: Mir hunn Erfahrung mat Zalenium an natierlech hu mir probéiert Patroni ass hir populär HA Léisung fir PostgreSQL. Iwwert d'Approche vun der Firma ze schafen Postgres Bedreiwer ee vun hiren Auteuren, Alexey Klyukin, sot op der Loft Postgres-Dënschdeg #5, a mir hunn et gär.

Dëst ass déi jéngst Léisung, déi am Artikel diskutéiert gëtt: déi éischt Verëffentlechung ass am August 2018 stattfonnt. Wéi och ëmmer, och trotz der klenger Zuel vu formelle Verëffentlechungen, ass de Projet e laange Wee komm, schonn iwwerschratt an der Popularitéit d'Léisung vu Crunchy Data mat 1300+ Stären op GitHub an der maximaler Unzuel u Bäiträg (70+).

"Ënnert der Hood" benotzt dësen Bedreiwer Zäit-getest Léisungen:

Dëst ass wéi d'Bedreiwerarchitektur vum Zalando presentéiert gëtt:

E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung

De Bedreiwer gëtt komplett duerch Custom Ressourcen geréiert, erstellt automatesch e StatefulSet aus Container, deen dann personaliséiert ka ginn andeems verschidde Sidecars an de Pod bäigefüügt ginn. All dëst ass e wesentleche Virdeel am Verglach mam Bedreiwer vu Crunchy Data.

Zënter datt mir d'Léisung vum Zalando ënnert den 3 Optiounen, déi berécksiichtegt sinn, gewielt hunn, gëtt eng weider Beschreiwung vu senge Fäegkeeten hei ënnen presentéiert, direkt mat der Praxis vun der Uwendung.

Praxis mam Postgres Bedreiwer aus Zalando

Operator Deployment ass ganz einfach: Luet just déi aktuell Verëffentlechung vum GitHub erof an gëlt d'YAML Dateien aus dem Verzeechnes manifestéiert. Alternativ kënnt Dir och benotzen operatorhub.

No der Installatioun sollt Dir Iech Suergen iwwer d'Konfiguratioun maachen Späichere fir Logbicher a Backups. Dëst gëtt iwwer ConfigMap gemaach postgres-operator am Nummraum wou Dir den Bedreiwer installéiert hutt. Wann d'Repositories konfiguréiert sinn, kënnt Dir Ären éischte PostgreSQL Cluster ofsetzen.

Zum Beispill, eis Standard Deployment gesäit esou aus:

apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
 name: staging-db
spec:
 numberOfInstances: 3
 patroni:
   synchronous_mode: true
 postgresql:
   version: "12"
 resources:
   limits:
     cpu: 100m
     memory: 1Gi
   requests:
     cpu: 100m
     memory: 1Gi
 sidecars:
 - env:
   - name: DATA_SOURCE_URI
     value: 127.0.0.1:5432
   - name: DATA_SOURCE_PASS
     valueFrom:
       secretKeyRef:
         key: password
         name: postgres.staging-db.credentials
   - name: DATA_SOURCE_USER
     value: postgres
   image: wrouesnel/postgres_exporter
   name: prometheus-exporter
   resources:
     limits:
       cpu: 500m
       memory: 100Mi
     requests:
       cpu: 100m
       memory: 100Mi
 teamId: staging
 volume:
   size: 2Gi

Dëst manifestéiert e Stärekoup vun 3 Instanzen mat engem Sidecar an der Form postgres_exporter, aus deem mir Applikatiounsmetriken huelen. Wéi Dir gesitt, ass alles ganz einfach, a wann Dir wëllt, kënnt Dir eng wuertwiertlech onlimitéiert Zuel vu Cluster erstellen.

Et ass derwäert opmierksam ze bezuelen Web Administratioun Panel - postgres-operateur-ui. Et kënnt mam Bedreiwer an erlaabt Iech Cluster ze kreéieren an ze läschen, wéi och mat Backups vum Bedreiwer ze schaffen.

E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung
Lëscht vun PostgreSQL Stärekéip

E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung
Backupsatellit Gestioun

Eng aner interessant Feature ass d'Ënnerstëtzung Teams API. Dëse Mechanismus erstellt automatesch Rollen am PostgreSQL, baséiert op der resultéierender Lëscht vu Benotzernimm. D'API erlaabt Iech dann eng Lëscht vu Benotzer zréckzebréngen fir déi Rollen automatesch erstallt ginn.

Probleemer a Léisungen

Wéi och ëmmer, d'Benotzung vum Bedreiwer huet séier e puer bedeitend Mängel opgedeckt:

  1. Mangel un NodeSelector Ënnerstëtzung;
  2. Onméiglechkeet Backups auszeschalten;
  3. wann Dir d'Datebankschafungsfunktioun benotzt, erschéngen Standardprivilegien net;
  4. Heiansdo fehlt d'Dokumentatioun oder ass net aktuell.

Glécklecherweis kënne vill vun hinnen geléist ginn. Loosst d'vun Enn ufänken - Problemer mat Dokumentatioun.

Wahrscheinlech wäert Dir d'Tatsaach begéinen datt et net ëmmer kloer ass wéi Dir e Backup registréiert a wéi Dir de Backup-Eemer mat der Operator UI verbënnt. D'Dokumentatioun schwätzt iwwer dëst am Vergaangenheet, awer déi richteg Beschreiwung ass eran PR:

  1. muss e Geheimnis maachen;
  2. gitt et un de Bedreiwer als Parameter pod_environment_secret_name an der CRD mat Bedreiwer Astellungen oder am ConfigMap (je no wéi Dir decidéiert de Bedreiwer ze installéieren).

Wéi et sech awer erausstellt, ass dat momentan net méiglech. Dofir hu mir gesammelt Är Versioun vum Bedreiwer mat e puer zousätzlech Entwécklungen vun Drëttubidder. Fir méi Informatiounen doriwwer, kuckt hei ënnen.

Wann Dir d'Parameteren fir de Backup un de Bedreiwer passéiert, nämlech - wal_s3_bucket an Zougang Schlësselen an AWS S3, dann et wäert Backupsatellit alles: net nëmmen Basen an der Produktioun, awer och Inszenéierung. Dëst huet eis net gepasst.

An der Beschreiwung vun de Parameteren fir Spilo, wat de Basis Docker Wrapper fir PgSQL ass wann Dir de Bedreiwer benotzt, huet sech erausgestallt: Dir kënnt e Parameter passéieren WAL_S3_BUCKET eidel, doduerch Backups auszeschalten. Ausserdeem hunn ech zu grousser Freed fonnt prett PR, déi mir direkt an eis Gabel ugeholl hunn. Elo musst Dir just addéieren enableWALArchiving: false zu enger PostgreSQL Cluster Ressource.

Jo, et war eng Geleeënheet et anescht ze maachen andeems se 2 Betreiber lafen: ee fir d'Staging (ouni Backups), an déi zweet fir d'Produktioun. Mee mir konnten eis mat enger maachen.

Ok, mir hu geléiert wéi den Zougang zu den Datenbanken fir S3 transferéiert gëtt an d'Backups hunn ugefaang an d'Späichere kommen. Wéi maachen Backup Säiten Aarbecht am Operator UI?

E kuerzen Iwwerbléck iwwer PostgreSQL Aussoe fir Kubernetes, eis Choixen an Erfarung

Dir musst 3 Variablen an den Operator UI addéieren:

  • SPILO_S3_BACKUP_BUCKET
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Duerno gëtt d'Gestioun vu Backups verfügbar, wat an eisem Fall d'Aarbecht mat der Inszenéierung vereinfacht, wat et eis erlaabt Slice vun der Produktioun do ze liwweren ouni zousätzlech Scripten.

En anere Virdeel war d'Aarbecht mat der Teams API a vill Méiglechkeeten fir Datenbanken a Rollen mat Bedreiwer Tools ze kreéieren. Allerdéngs hunn déi geschaf Rollen hu keng Rechter par défaut. Deementspriechend konnt e Benotzer mat Liesrechter keng nei Dëscher liesen.

Firwat? Trotz der Tatsaach, datt am Code ass néideg GRANT, si sinn net ëmmer benotzt. Et ginn 2 Methoden: syncPreparedDatabases и syncDatabases. d' syncPreparedDatabases - trotz der Tatsaach, datt an der Rubrik preparedDatabases ass et gëtt eng Konditioun defaultRoles и defaultUsers fir Rollen ze kreéieren, Standardrechter ginn net ugewannt. Mir sinn amgaang e Patch ze preparéieren sou datt dës Rechter automatesch applizéiert ginn.

An de leschte Punkt an de Verbesserungen, déi fir eis relevant sinn - Patch, déi Node Affinity zu der erstallt StatefulSet bäidréit. Eis Clientë léiwer dacks d'Käschte reduzéieren andeems se Spot-Instanzen benotzen, a si si kloer net derwäert fir Datebankservicer ze hosten. Dëst Thema kéint duerch Toleratiounen geléist ginn, awer d'Präsenz vun der Node Affinitéit gëtt méi Vertrauen.

Wat ass geschitt?

Baséierend op d'Resultater vun der Léisung vun den uewe genannte Probleemer hu mir de Postgres Bedreiwer aus Zalando an Äre Repository, wou et mat sou nëtzlech Flecken gesammelt gëtt. A fir méi Komfort hu mir och gesammelt Docker Bild.

Lëscht vun PRs, déi an der Gabel akzeptéiert sinn:

Et wäert super sinn wann d'Gemeinschaft dës PRs ënnerstëtzt sou datt se mat der nächster Versioun vum Bedreiwer (1.6) upstream kommen.

Bonus! Produktioun Migratioun Succès Geschicht

Wann Dir Patroni benotzt, kann d'Liveproduktioun op de Bedreiwer migréiert ginn mat minimaler Ausdauer.

Spilo erlaabt Iech Standby Stärekéip via S3 Stockage ze schafen mat Wal-E, wann de PgSQL binäre Log fir d'éischt am S3 gespäichert gëtt an duerno vun der Replica gepompelt gëtt. Awer wat maache wann Dir hutt Net vun Wal-E op al Infrastruktur benotzt? D'Léisung fir dëse Problem ass schonn et gouf proposéiert op der hub.

PostgreSQL logesch Replikatioun kënnt zur Rettung. Wéi och ëmmer, mir ginn net am Detail iwwer wéi Publikatiounen an Abonnementer erstallt ginn, well ... eise Plang war e Fiasko.

D'Tatsaach ass, datt d'Datebank e puer gelueden Dëscher mat Millioune Reihen haten, déi, ausserdeem, permanent replenished a geläscht goufen. Einfach Abonnement с copy_data, Wann déi nei Replica all Inhalt vum Master kopéiert, kann et einfach net mam Master halen. Inhalter kopéieren huet eng Woch laang geschafft, awer ni mam Meeschter agefaangen. Um Enn huet et mir gehollef de Problem ze léisen en Artikel Kollegen vun Avito: Dir kënnt Daten Transfermaart benotzt pg_dump. Ech wäert eis (liicht geännert) Versioun vun dësem Algorithmus beschreiwen.

D'Iddi ass datt Dir e behënnert Abonnement maache kënnt, deen un e spezifesche Replikatiounslot gebonnen ass, an dann d'Transaktiounsnummer korrigéiert. Et waren Repliken verfügbar fir Produktiounsaarbecht. Dëst ass wichteg well d'Replika hëlleft e konsequent Dump ze kreéieren a weider Ännerungen vum Master ze kréien.

Duerno Kommandoen, déi de Migratiounsprozess beschreiwen, benotzen déi folgend Hostnotatiounen:

  1. Meeschtesch - Quell Server;
  2. replika 1 - Streaming Replik op der aler Produktioun;
  3. replika 2 - nei logesch Replica.

Migratioun plangen

1. Schafen en Abonnement op de Meeschtesch fir all Dëscher am Schema public Basis dbname:

psql -h master -d dbname -c "CREATE PUBLICATION dbname FOR ALL TABLES;"

2. Erstellt e Replikatiounslot um Master:

psql -h master -c "select pg_create_logical_replication_slot('repl', 'pgoutput');"

3. Stop Replikatioun op der aler Replik:

psql -h replica1 -c "select pg_wal_replay_pause();"

4. Kritt d'Transaktiounsnummer vum Master:

psql -h master -c "select replay_lsn from pg_stat_replication where client_addr = 'replica1';"

5. Ewechzehuelen der Dump aus der aler Replica. Mir maachen dat an e puer Threads, wat hëlleft de Prozess ze beschleunegen:

pg_dump -h replica1 --no-publications --no-subscriptions -O -C -F d -j 8 -f dump/ dbname

6. Eroplueden den Dump op den neie Server:

pg_restore -h replica2 -F d -j 8 -d dbname dump/

7. Nodeems Dir den Dump erofgelueden hutt, kënnt Dir Replikatioun op der Streaming Replik starten:

psql -h replica1 -c "select pg_wal_replay_resume();"

7. Loosst eis en Abonnement op eng nei logesch Replik erstellen:

psql -h replica2 -c "create subscription oldprod connection 'host=replica1 port=5432 user=postgres password=secret dbname=dbname' publication dbname with (enabled = false, create_slot = false, copy_data = false, slot_name='repl');"

8. Loosst eis kréien oid Abonnementer:

psql -h replica2 -d dbname -c "select oid, * from pg_subscription;"

9. Loosst eis soen datt et ugeholl gouf oid=1000. Loosst eis d'Transaktiounsnummer op den Abonnement uwenden:

psql -h replica2 -d dbname -c "select pg_replication_origin_advance('pg_1000', 'AA/AAAAAAAA');"

10. Loosst d'Replikatioun ufänken:

psql -h replica2 -d dbname -c "alter subscription oldprod enable;"

11. Check den Abonnement Status, Replikatioun soll schaffen:

psql -h replica2 -d dbname -c "select * from pg_replication_origin_status;"
psql -h master -d dbname -c "select slot_name, restart_lsn, confirmed_flush_lsn from pg_replication_slots;"

12. Nodeems d'Replikatioun gestart ass an d'Datebanken synchroniséiert sinn, kënnt Dir iwwerschalten.

13. Nodeems Dir d'Replikatioun deaktivéiert hutt, musst Dir d'Sequenzen korrigéieren. Dëst ass gutt beschriwwen am Artikel op wiki.postgresql.org.

Dank dësem Plang ass den Iwwergang mat minimale Verspéidungen stattfonnt.

Konklusioun

Kubernetes Opérateuren erlaben Iech verschidden Aktiounen ze vereinfachen andeems se op d'Schafung vun K8s Ressourcen reduzéieren. Wéi och ëmmer, nodeems se bemierkenswäert Automatisatioun mat hirer Hëllef erreecht hunn, ass et derwäert ze erënneren datt et och eng Rei onerwaart Nuancen bréngt, also wielt Är Betreiber clever.

Nodeems mir déi dräi populärsten Kubernetes Bedreiwer fir PostgreSQL berücksichtegt hunn, hu mir de Projet vum Zalando gewielt. A mir hu gewësse Schwieregkeeten domat ze iwwerwannen, awer d'Resultat war wierklech erfreelech, also plangen mir dës Erfahrung op e puer aner PgSQL Installatiounen auszebauen. Wann Dir Erfahrung mat ähnlechen Léisungen hutt, wäerte mir frou sinn d'Detailer an de Kommentaren ze gesinn!

PS

Liest och op eisem Blog:

Source: will.com

Setzt e Commentaire