{"id":34841,"date":"2019-10-31T22:00:43","date_gmt":"2019-10-31T19:00:43","guid":{"rendered":"https:\/\/prohoster.info\/blog\/avtomatizatsiya-zameny-diskov-s-pomoshhyu-ansible\/"},"modified":"2019-10-31T22:00:43","modified_gmt":"2019-10-31T19:00:43","slug":"avtomatizatsiya-zameny-diskov-s-pomoshhyu-ansible","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/avtomatizatsiya-zameny-diskov-s-pomoshhyu-ansible","title":{"rendered":"Automatisering af diskudskiftninger med Ansible","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/c60a2326ab13e7766eafda3ae5ac39c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHej alle. Jeg arbejder som senior systemadministrator hos OK og har ansvaret for portalen's stabilitet. Jeg vil gerne fort\u00e6lle om, hvordan vi har opbygget en proces for automatisk skiftnings af harddiske, og hvordan vi derefter udelukkede administratoren fra denne proces og erstattede ham med en bot.<\/p>\n<p>Denne artikel er en form for transliterering <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/watch?v=5WhbG3FQveE&amp;list=FLKN7KW1sxju7fWJvKuyKxEQ\">foredrag<\/a><\/noindex> til HighLoad+ 2018<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Opbygning af processen for skift af harddiske<\/h2>\n<p><\/p>\n<h3>F\u00f8rst nogle tal<\/h3>\n<p>\nOK er en gigantisk tjeneste, der bruges af millioner af mennesker. Den drives af cirka 7.000 servere, der er placeret i 4 forskellige datacentre. Serverne har over 70.000 harddiske. Hvis man l\u00e6gger dem oven p\u00e5 hinanden, f\u00e5r man et t\u00e5rn, der er over 1 km h\u00f8jt. <\/p>\n<p>Harddiske er den komponent i servere, der oftest svigter. Med s\u00e5danne m\u00e6ngder skal vi skifte omkring 30 diske om ugen, og denne procedure er blevet en mindre behagelig rutine.<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/5e915e9077994efcc4e74a26fc6286fa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>H\u00e6ndelser<\/h3>\n<p>\nI vores virksomhed er der indf\u00f8rt fuld h\u00e6ndelsesh\u00e5ndtering. Hver h\u00e6ndelse registreres i Jira, hvorefter vi l\u00f8ser og gennemg\u00e5r den. Hvis h\u00e6ndelsen havde en effekt for brugerne, samles vi og overvejer, hvordan vi hurtigt kan reagere i s\u00e5danne tilf\u00e6lde, hvordan vi kan reducere effekten, og selvf\u00f8lgelig hvordan vi kan forhindre gentagelser.<\/p>\n<p>Lagringsenheder er ingen undtagelse. Deres tilstand overv\u00e5ges af Zabbix. Vi monitorerer beskeder i Syslog for fejl ved skrivning\/l\u00e6sning, analyserer tilstanden af HW\/SW-RAID, overv\u00e5ger SMART, og for SSD'er beregner vi slid. <\/p>\n<h3>Hvordan diskene blev skiftet tidligere<\/h3>\n<p>\nN\u00e5r der i Zabbix t\u00e6ndes for en alarm, oprettes der en h\u00e6ndelse i Jira, som automatisk tildeles de relevante ingeni\u00f8rer i datacentrene. Vi g\u00f8r dette for alle HW-h\u00e6ndelser, det vil sige s\u00e5danne, der kr\u00e6ver fysisk arbejde med udstyr i datacentret. <br \/>\nDatacenter-ingeni\u00f8ren er den person, der h\u00e5ndterer sp\u00f8rgsm\u00e5l relateret til hardware, st\u00e5r for installation, vedligeholdelse, og afmontering af servere. N\u00e5r han modtager en ticket, g\u00e5r ingeni\u00f8ren i gang. I diskkabinet skifter han selv diske. Men hvis han ikke har adgang til den n\u00f8dvendige enhed, henvender ingeni\u00f8ren sig til de vagthavende systemadministratorer for hj\u00e6lp. F\u00f8rst skal disken tages ud af rotation. For dette skal de n\u00f8dvendige \u00e6ndringer foretages p\u00e5 serveren, applikationerne stoppes, og disken afmonteres.<\/p>\n<p>Den vagthavende systemadministrator er ansvarlig for portalens drift i l\u00f8bet af arbejdsdagen. Han unders\u00f8ger h\u00e6ndelser, udf\u00f8rer reparationer og hj\u00e6lper udviklerne med mindre opgaver. Han besk\u00e6ftiger sig dog ikke med harddiske.<\/p>\n<p>Tidligere kommunikerede datacenter-ingeni\u00f8rer med systemadministratorer i chatten. Ingeni\u00f8rerne sendte links til Jira-billetter, og administratoren fulgte dem, f\u00f8rte en log over arbejdet i en eller anden notesbog. Men for s\u00e5danne opgaver er chatten upraktisk: informationen er ikke struktureret og g\u00e5r hurtigt tabt. Desuden kunne administratoren blot v\u00e6re v\u00e6k fra computeren og ikke svare p\u00e5 anmodninger i et stykke tid, mens ingeni\u00f8ren stod ved serveren med en bunke diske og ventede.<\/p>\n<p>Det v\u00e6rste var dog, at administratorerne ikke kunne se det store billede: hvilke diskproblemer der eksisterede, og hvor potentielle problemer kunne opst\u00e5. Dette skyldes, at vi overdrager alle HW-h\u00e6ndelser til ingeni\u00f8rerne. Ja, man kunne vise alle h\u00e6ndelser p\u00e5 administratorens dashboard. Men der er s\u00e5 mange, og administratoren blev kun involveret i nogle af dem.<\/p>\n<p>Derudover kunne ingeni\u00f8ren ikke korrekt prioritere, fordi han ikke vidste noget om form\u00e5let med de specifikke servere, eller hvordan informationen var fordelt p\u00e5 lagermedierne.<\/p>\n<h3>Ny udskiftningsprocedure<\/h3>\n<p>\nDet f\u00f8rste, vi gjorde, var at opdele alle diskproblemer i en s\u00e6rskilt type \"HW-disk\" og tilf\u00f8je felterne \"navn p\u00e5 blokenhed\", \"st\u00f8rrelse\" og \"disktype\", s\u00e5 denne information blev gemt i billetten, og vi ikke konstant skulle udveksle den i chatten. <\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/c4526bf668e31d90e0fbd061de44f1a7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nVi blev ogs\u00e5 enige om, at vi kun ville udskifte \u00e9n disk inden for \u00e9n h\u00e6ndelse. Dette har v\u00e6sentligt forenklet den efterf\u00f8lgende automatiseringsproces, indsamlingen af statistik og arbejdet. <\/p>\n<p>Derudover tilf\u00f8jede vi feltet \"ansvarlig administrator\". Der inds\u00e6ttes automatisk den vagthavende sysadmin. Det er meget praktisk, fordi ingeni\u00f8ren altid kan se, hvem der er ansvarlig. Man beh\u00f8ver ikke at g\u00e5 ind i kalenderen og lede. Netop dette felt gjorde det muligt at vise billetter p\u00e5 administratorens dashboard, hvor hans hj\u00e6lp m\u00e5ske vil v\u00e6re n\u00f8dvendig.<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/5097e5dcca1fddd68d1e5f296c09f60a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nFor all participants to gain the maximum benefit from the innovations, we created filters and dashboards, and informed the team about them. When people understand the changes, they do not distance themselves from them as something unnecessary. It is important for the engineer to know the rack number where the server is located, the size and type of the disk. The administrator needs, first and foremost, to understand what group of servers this is and what effect there may be from replacing the disk.<\/p>\n<p>Having fields and their display is convenient, but it has not relieved us from the need to use chats. For this, we had to change the workflow. <\/p>\n<p>It used to be like this:<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/2b79cdb7ec88b5ae3d2917ad8b164c6d.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nToday, this is how engineers continue to work when they do not require the administrator's assistance.<\/p>\n<p>The first thing we did was introduce a new status <b>Investigate<\/b>. In this status, the ticket is located when the engineer still hasn't decided whether they will need the administrator or not. Through this status, the engineer can pass the ticket to the administrator. Additionally, we use this status to mark tickets when a disk replacement is required, but the disk itself is not on site. This can happen in the case of CDN and remote sites.<\/p>\n<p>We also added a status <b>Klar<\/b>. Tickets are transferred to this status after the disk replacement. This means everything is already done, but the HW\/SW RAID is synchronizing on the server. This can take quite a long time.<\/p>\n<p>If the administrator is involved in the work, the scheme becomes a bit more complicated.<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/5b6aacbb0d4049e62e7cb9ee28eb6498.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nFrom the status <b>\u00c5ben<\/b> , the ticket can be transferred by both the system administrator and the engineer. In the status <b>In progress<\/b> , the administrator removes the disk from rotation so that the engineer can simply pull it out: they turn on the light, unmount the disk, stop applications, depending on the specific group of servers.<\/p>\n<p>Then the ticket is transferred to <b>Ready to change<\/b>: this is a signal to the engineer that the disk can be pulled out. All fields in Jira are already filled in, and the engineer knows the type and size of the disk. This information is filled in either automatically in the previous status or by the administrator.<\/p>\n<p>After the disk replacement, the ticket is transferred to the status <b>Changed<\/b>. It is checked that the correct disk was inserted, marking is done, the application is started, and some data recovery tasks are executed. Additionally, the ticket can be transferred to the status <b>Klar<\/b>, in which case the administrator will remain responsible, because they registered the disk in rotation. The complete scheme looks like this.<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/32f8d488e2ff6a28a3341114b66de0a3.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nTilf\u00f8jelsen af nye felter har betydeligt lettet vores arbejde. Folkene arbejder nu med struktureret information, og det er blevet klart, hvad og hvorn\u00e5r der skal g\u00f8res noget. Prioriteterne er blevet langt mere relevante, da de nu fasts\u00e6ttes af administratoren.<\/p>\n<p>Behovet for chats er forsvundet. Selvf\u00f8lgelig kan administratoren skrive til ingeni\u00f8ren \"her skal der skiftes hurtigere\", eller \"det er allerede aften, n\u00e5r kan du skifte?\". Men vi kommunikerer ikke l\u00e6ngere dagligt i chats om disse emner.<\/p>\n<p>Diske skiftes nu i st\u00f8rre m\u00e6ngder. Hvis administratoren kommer lidt tidligere p\u00e5 arbejde, har han lidt tid og der er ikke opst\u00e5et noget endnu, kan han forberede en r\u00e6kke servere til udskiftning: angive felter, fjerne diske fra rotation og overdrage opgaven til ingeni\u00f8ren. Ingeni\u00f8ren kommer lidt senere til datacenteret, ser opgaven, henter de n\u00f8dvendige lagringsenheder fra lageret og skifter dem med det samme. Resultatet er, at udskiftningshastigheden er steget.<\/p>\n<h3>Erfaringer fra opbygningen af Workflow<\/h3>\n<p><\/p>\n<ul>\n<li><b>N\u00e5r man opbygger proceduren, skal man indsamle information fra forskellige kilder.<\/b><br \/>\nNogle af vores administratorer vidste ikke, at ingeni\u00f8ren selv skifter diske. Nogle troede, at ingeni\u00f8rerne holdt \u00f8je med synkroniseringen af MD RAID, selvom nogle af dem ikke engang havde adgang til det. Nogle af de f\u00f8rende ingeni\u00f8rer gjorde det, men ikke altid, fordi processen ikke var dokumenteret nogen steder.<\/li>\n<li><b>Proceduren skal v\u00e6re simpel og forst\u00e5elig.<\/b><br \/>\nDet er sv\u00e6rt for et menneske at holde styr p\u00e5 mange trin. De vigtigste sammenh\u00e6ngende statuser i Jira skal vises p\u00e5 hovedsk\u00e6rmen. Man kan omd\u00f8be dem, for eksempel kalder vi \"In progress\" for \"Ready to change\". De \u00f8vrige statuser kan skjules i en dropdown-menu, s\u00e5 de ikke forstyrrer. Men det er bedst ikke at begr\u00e6nse folk, men give dem mulighed for at lave overgange.<br \/>\nForklar v\u00e6rdien af \u00e6ndringerne. N\u00e5r folk forst\u00e5r, tager de bedre imod den nye procedure. For os var det meget vigtigt, at folk ikke bare klikkede sig igennem hele processen, men fulgte den. Senere opbyggede vi automatisering baseret p\u00e5 dette.<\/li>\n<li><b>Vent, analyser, forst\u00e5.<\/b><br \/>\nVi brugte cirka en m\u00e5ned p\u00e5 at opbygge proceduren, den tekniske implementering, m\u00f8der og diskussioner. Og det tog mere end tre m\u00e5neder at gennemf\u00f8re. Jeg har set, hvordan folk langsomt begynder at bruge nyheden. I de tidlige faser var der meget negativitet. Men det var slet ikke afh\u00e6ngigt af selve proceduren eller dens tekniske implementering. For eksempel brugte en administrator ikke Jira, men et Jira-plugin i Confluence, og nogle ting var utilg\u00e6ngelige for ham. Da vi viste ham Jira, steg hans produktivitet b\u00e5de p\u00e5 generelle opgaver og ved diskudskiftninger.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Automatisering af diskudskiftninger<\/h2>\n<p>\nVi har fors\u00f8gt at automatisere diskudskiftninger flere gange. Vi havde allerede nogle forberedelser, scripts, men de fungerede enten interaktivt eller manuelt og kr\u00e6vede en opstart. Og f\u00f8rst efter implementeringen af den nye procedure inds\u00e5 vi, at det netop var den, vi havde manglet.<\/p>\n<p>Da vi nu har opdelt udskiftningsprocessen i faser, hvor hver fase har en bestemt ansvarlig og en liste over handlinger, kan vi implementere automatiseringen trin for trin i stedet for at g\u00f8re det hele p\u00e5 \u00e9n gang. For eksempel kan den enkleste fase - Ready (kontrol af RAID\/data synkronisering) - nemt delegeres til en bot. N\u00e5r botten har l\u00e6rt sig lidt, kan vi give den en mere ansvarlig opgave - at indf\u00f8re disken i rotation mm.<\/p>\n<h3>Zoologisk have af ops\u00e6tninger<\/h3>\n<p>\nF\u00f8r vi fort\u00e6ller om botten, lad os lave en lille ekskurs til vores zoologiske have af installationer. For det f\u00f8rste skyldes det den enorme st\u00f8rrelse af vores infrastruktur. For det andet pr\u00f8ver vi at finde den optimale hardwarekonfiguration til hver service. Vi har omkring 20 modeller af hardware RAID, prim\u00e6rt LSI og Adaptec, men der findes ogs\u00e5 HP og DELL i forskellige versioner. Hver RAID-controller har sit eget administrationsv\u00e6rkt\u00f8j. S\u00e6ttet af kommandoer og output kan variere fra version til version for hver RAID-controller. Hvor hardware-RAID ikke anvendes, kan mdraid v\u00e6re til stede.<\/p>\n<p>N\u00e6sten alle nye installationer laver vi uden diskreserv\u00e9ringer. Vi fors\u00f8ger at undg\u00e5 at bruge hardware- og software RAID, da vi reserv\u00e9r vores systemer p\u00e5 datacenter-niveau og ikke server-niveau. Men selvf\u00f8lgelig er der mange legacy-servere, som vi skal vedligeholde.<\/p>\n<p>Nogle steder anvendes diske i RAID-controllere som r\u00e5 enheder, mens andre steder bruger JBOD. Der findes konfigurationer med \u00e9n systemdisk i serveren, og hvis den skal udskiftes, skal serveren geninstalleres med operativsystemet og applikationerne, herunder de samme versioner, hvorefter konfigurationsfilerne tilf\u00f8jes, og applikationerne startes. Der er ogs\u00e5 mange grupper af servere, hvor redundans ikke administreres p\u00e5 niveauet for det diskbaserede system, men direkte i selve applikationerne.<\/p>\n<p>I alt har vi mere end 400 unikke grupper af servere, der k\u00f8rer omkring 100 forskellige applikationer. For at d\u00e6kke et s\u00e5 stort antal varianter havde vi brug for et multifunktionelt automatiseringsv\u00e6rkt\u00f8j. Gerne med et simpelt DSL, s\u00e5 det kunne vedligeholdes ikke kun af den, der skrev det.<\/p>\n<p>Vi valgte Ansible, fordi det er agentl\u00f8st: der var ikke behov for at forberede infrastrukturen, og det kan komme i gang hurtigt. Desuden er det skrevet i Python, som er accepteret som standard i teamet.<\/p>\n<h3>Generelt skema<\/h3>\n<p>\nLad os se p\u00e5 det overordnede automatiseringsskema med eksemplet p\u00e5 en h\u00e6ndelse. Zabbix opdager, at disken sdb er defekt, en trigger aktiveres, og der oprettes en ticket i Jira. Administratoren har kigget p\u00e5 den, forst\u00e5et, at det ikke er en duplikat eller en falsk positiv, hvilket betyder, at disken skal udskiftes, og han flytter ticketen til 'In progress'.<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/673df0fe9600bc65633841222f436d37.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nApplikationen DiskoBot, skrevet i Python, foresp\u00f8rger periodisk Jira om nye billetter. Den bem\u00e6rker, at der er oprettet en ny ticket 'In progress', den relevante tr\u00e5d aktiveres, som starter playbook'en i Ansible (det g\u00f8res for hver status i Jira). I dette tilf\u00e6lde aktiveres Prepare2change.<\/p>\n<p>Ansible sendes til v\u00e6rten, tager disken ud af rotation og rapporterer status til applikationen via Callbacks. <\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/8bfc13129f8deca640eb63ea81f616c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nBaseret p\u00e5 resultatet overs\u00e6tter botten automatisk ticketen til 'Ready to change'. Ingeni\u00f8ren modtager en meddelelse og g\u00e5r for at udskifte disken, hvorefter han \u00e6ndrer ticketens status til 'Changed'. <\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/eeda06b6966f435e2172d3f9c61b341e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIf\u00f8lge den beskrevne proces kommer ticketen tilbage til botten, som starter en anden playbook, g\u00e5r til v\u00e6rten og tager disken tilbage i rotation. Botten lukker ticketen. Hurra!<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/51b8c7050b0c10c16ad6a6d4974c3ebf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nLad os nu tale om nogle komponenter i systemet.<\/p>\n<h3>Diskobot<\/h3>\n<p>\nDenne applikation er skrevet i Python. Den v\u00e6lger billetter fra Jira i henhold til JQL. Afh\u00e6ngigt af statusen for ticketen sendes den til den relevante behandler, som derefter starter det relevante Ansible playbook i forhold til status.<\/p>\n<p>JQL og sp\u00f8rgselsintervaller er defineret i applikationskonfigurationsfilen.<\/p>\n<pre><code class=\"plaintext\">jira_states:\n  investigate:\n    jql: '\u2026 status = Open and \"Disk Size\" is EMPTY'\n    interval: 180\n\n  inprogress:\n    jql: '\u2026  and \"Disk Size\" is not EMPTY and \"Device Name\" is not EMPTY'\n \n  ready:\n    jql: '\u2026 and (labels not in (\"dbot_ignore\") or labels is EMPTY)'\n    interval: 7200\n<\/code><\/pre>\n<p>\nFor eksempel, blandt billetter i status In progress v\u00e6lges kun dem, hvor felterne Disk size og Device name er udfyldt. Device name er navnet p\u00e5 blokkeringsenheden, n\u00f8dvendig for at udf\u00f8re playbook\u2019en. Disk size er n\u00f8dvendig, s\u00e5 ingeni\u00f8ren ved, hvilken st\u00f8rrelse disk der er n\u00f8dvendig.<\/p>\n<p>Blandt billetter i status Ready filtreres der billetter med etiketten dbot_ignore. For \u00f8vrigt bruger vi Jira-etiketter b\u00e5de til denne filterering og til at markere duplikater af billetter samt til at indsamle statistik.<\/p>\n<p>I tilf\u00e6lde af en fejl i playbook\u2019en tildeler Jira etiketten dbot_failed, s\u00e5 det senere kan blive unders\u00f8gt. <\/p>\n<h3>Interaktion med Ansible<\/h3>\n<p>\nApplikationen interagerer med Ansible gennem <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.ansible.com\/ansible\/latest\/dev_guide\/developing_api.html\">Ansible Python API<\/a><\/noindex>. I playbook_executor sender vi filnavnet og s\u00e6ttet af variable. Dette g\u00f8r det muligt at holde Ansible-projektet i form af almindelige yml-filer i stedet for at beskrive det i Python-kode. <\/p>\n<p>Desuden sendes navnene p\u00e5 blokkeringsenheder, status p\u00e5 billetten og callback_url via *extra_vars*, hvor issue key er indkapslet \u2014 det bruges til callback i HTTP.<\/p>\n<p>For hver k\u00f8rsel genereres en midlertidig inventory, best\u00e5ende af en v\u00e6rt og en gruppe, som denne v\u00e6rt tilh\u00f8rer, s\u00e5 group_vars anvendes.<\/p>\n<p>Her er et eksempel p\u00e5 en opgave, hvor HTTP callback er implementeret.<\/p>\n<p>Resultatet af playbooks\u2019 udf\u00f8relse opn\u00e5r vi gennem callback(-ene). De er af to typer:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.ansible.com\/ansible\/latest\/plugins\/callback.html\">Ansible callback plugin<\/a><\/noindex>, det giver data om resultaterne af playbook\u2019ens udf\u00f8relse. Her beskrives de opgaver, der er blevet k\u00f8rt, enten med succes eller uden succes. Denne callback kaldes ved afslutningen af afspilningen af playbook\u2019en.<\/li>\n<li>HTTP callback for at modtage information under afspilningen af playbook\u2019en. I Ansible-opgaven udf\u00f8rer vi en POST\/GET anmodning til vores applikation.<\/li>\n<\/ul>\n<p>\nGennem HTTP callback(-e) sendes de variable, der blev defineret under udf\u00f8relsen af playbook\u2019en og som vi \u00f8nsker at gemme og bruge i fremtidige k\u00f8rsel. Disse data skriver vi i sqlite.<\/p>\n<p>Gennem HTTP callback lader vi ogs\u00e5 kommentarer og \u00e6ndrer status p\u00e5 billetten.<\/p>\n<p><b class=\"spoiler_title\">HTTP callback<\/b><\/p>\n<pre><code class=\"plaintext\"># Make callback to Diskobot App\n# Variables:\n#    callback_post_body: # A dict with follow keys. All keys are optional\n#       msg: If exist it would be posted to Jira as comment\n#       data: If exist it would be saved in Incident.variables\n#       desire_state: Set desire_state for incident\n#       status: If exist Proceed issue to that status\n\n  - name: Callback to Diskobot app (jira comment\/status)\n    uri:\n      url: \"{{ callback_url }}\/{{ devname }}\"\n      user: \"{{ diskobot_user }}\"\n      password: \"{{ diskobot_pass }}\"\n      force_basic_auth: True\n      method: POST\n      body: \"{{ callback_post_body | to_json }}\"\n      body_format: json\n    delegate_to: 127.0.0.1\n<\/code><\/pre>\n<p>Som mange lignende opgaver har vi flyttet den til en separat common fil og inkluderer den efter behov for ikke konstant at gentage den i playbooks. Her optr\u00e6der callback_url, der indeholder issue key og host name. N\u00e5r Ansible udf\u00f8rer denne POST-foresp\u00f8rgsel, forst\u00e5r botten, at den er kommet inden for en bestemt h\u00e6ndelse.<\/p>\n<p>Her er et eksempel fra playbooken, hvor vi fjernede en disk fra et MD-udstyr:<\/p>\n<pre><code class=\"plaintext\">  # Save mdadm configuration\n  - include: common\/callback.yml\n    vars:\n      callback_post_body:\n        status: 'Ready to change'\n        msg: \"Removed disk from mdraid {{ mdadm_remove_disk.msg | comment_jira }}\"\n        data:\n          mdadm_data: \"{{ mdadm_remove_disk.removed }}\"\n          parted_info: \"{{ parted_info | default() }}\"\n    when:\n      - mdadm_remove_disk | changed\n      - mdadm_remove_disk.removed\n<\/code><\/pre>\n<p>\nDenne opgave flytter Jira-ticketen til status \"Ready to change\" og tilf\u00f8jer en kommentar. Desuden gemmes listen over md-udstyr, hvorfra disken er blevet fjernet, i variablen mdam_data, mens parted_info indeholder et dump af partitionen fra parted. <\/p>\n<p>N\u00e5r ingeni\u00f8ren inds\u00e6tter en ny disk, kan vi bruge disse variabler til at genoprette dumpet af partitionerne samt registrere disken i de md-udstyr, hvorfra den blev fjernet.<\/p>\n<h3>Ansible check mode<\/h3>\n<p>\nDet var skr\u00e6mmende at aktivere automatiseringen. Derfor besluttede vi at k\u00f8re alle playbooks i tilstanden <br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/docs.ansible.com\/ansible\/latest\/user_guide\/playbooks_checkmode.html\">dry run<\/a><\/noindex>, hvor Ansible ikke udf\u00f8rer nogen handlinger p\u00e5 serverne, men kun efterligner dem. <\/p>\n<p>Denne opstart k\u00f8res gennem et separat callback-modul, og resultatet af playbookens udf\u00f8relse gemmes i Jira som en kommentar.<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/b02d7f1dc428f2797ae8556cd496b115.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFor det f\u00f8rste gjorde det det muligt at validere botens og playbookernes funktion. For det andet \u00f8gede det administratorernes tillid til botten. <\/p>\n<p>Da vi havde gennemg\u00e5et validationen og indset, at vi kunne k\u00f8re Ansible ikke kun i dry run-tilstand, lavede vi en knap i Jira med teksten Run Diskobot for at k\u00f8re den samme playbook med de samme variabler p\u00e5 den samme host, men i normal tilstand. <\/p>\n<p>Desuden bruges knappen til at genstarte playbooken i tilf\u00e6lde af fejl.<\/p>\n<h3>Struktur af Playbooks<\/h3>\n<p>\nJeg har allerede n\u00e6vnt, at botten k\u00f8rer forskellige playbooks afh\u00e6ngigt af status for Jira-ticketen.<\/p>\n<p>For det f\u00f8rste g\u00f8r det det meget lettere at organisere indgangen. <br \/>\nFor det andet er det i nogle tilf\u00e6lde ganske n\u00f8dvendigt. <\/p>\n<p>For eksempel, n\u00e5r man skifter systemdisken, skal man f\u00f8rst g\u00e5 ind i distributionssystemet, oprette en opgave, og efter korrekt distribution bliver serveren tilg\u00e6ngelig via ssh, hvorefter applikationen kan installeres. Hvis vi havde gjort alt dette i \u00e9n playbook, kunne Ansible ikke have udf\u00f8rt den p\u00e5 grund af utilg\u00e6ngeligheden af v\u00e6rten.<\/p>\n<p>Vi bruger Ansible-roller for hver gruppe af servere. Her kan man se, hvordan playbook(-e) er organiseret i \u00e9n af dem. <\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/7a14035392b33f01d3182d5fff779321.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDet er praktisk, fordi man med det samme kan se, hvor forskellige opgaver er placeret. I main.yml, som er indgangen til Ansible-rollen, kan vi blot have en include baseret p\u00e5 ticketstatus eller generelle opgaver, der er n\u00f8dvendige for alle, for eksempel at gennemg\u00e5 identifikation eller f\u00e5 en token.<\/p>\n<h4>Investigation.yml<\/h4>\n<p>\nK\u00f8rer for billetter med status Investigation og Open. Det vigtigste for denne playbook er navnet p\u00e5 den blokkerede enhed. Denne information er ikke altid tilg\u00e6ngelig. <\/p>\n<p>For at f\u00e5 adgang til denne information analyserer vi Jira-sammenfatningen, den seneste v\u00e6rdi fra Zabbix-triggeren. Der kan v\u00e6re navnet p\u00e5 den blokkerede enhed \u2014 heldigt. Eller det kan indeholde mount point, \u2014 i s\u00e5 fald skal vi g\u00e5 til serveren, parse og beregne den n\u00f8dvendige disk. Triggeren kan ogs\u00e5 overf\u00f8re SCSI-adressen eller anden information. Men nogle gange er der slet ingen spor, og vi m\u00e5 analysere.<\/p>\n<p>N\u00e5r vi har fundet navnet p\u00e5 den blokkerede enhed, indsamler vi information om typen og st\u00f8rrelsen p\u00e5 disken for at udfylde felterne i Jira. Vi indsamler ogs\u00e5 information om producenten, modellen, firmwaren, ID, SMART, og alt dette inds\u00e6tter vi i kommentaren i Jira-billetten. Administrator og ingeni\u00f8r beh\u00f8ver ikke l\u00e6ngere at lede efter disse data. \ud83d\ude42<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/259bf8712c013ee00d238f111b4280fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h4>prepare2change.yml<\/h4>\n<p>\nFjernelse af disken fra rotation, forberedelse til udskiftning. Den mest komplekse og ansvarlige fase. Her kan man stoppe applikationen, n\u00e5r den ikke kan stoppes. Eller tr\u00e6kke disken, der manglede replikater, og dermed p\u00e5virke brugerne, miste nogle data. Her har vi flest tjek og notifikationer i chatten.<\/p>\n<p>I det enkleste tilf\u00e6lde handler det om at fjerne disken fra HW\/MD RAID. <\/p>\n<p>I mere komplekse situationer (i vores lagersystemer), n\u00e5r redundans udf\u00f8res p\u00e5 applikationsniveau, skal vi g\u00e5 ind i applikationen via API, informere om, at disken fjernes, deaktivere den og starte genoprettelsen.<\/p>\n<p>Vi migrerer nu massivt til <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/odnoklassniki\/blog\/346868\">cloud<\/a><\/noindex>, og hvis serveren er cloud-baseret, s\u00e5 kontakter Diskobot cloud API, fort\u00e6ller, at den skal arbejde med denne minion \u2014 serveren, hvor containerne k\u00f8rer \u2014 og beder \"migrer alle containere fra denne minion\". Og t\u00e6nder samtidig diskens belysning, s\u00e5 ingeni\u00f8ren straks kan se, hvilken der skal tr\u00e6kkes ud.<\/p>\n<h4>changed.yml<\/h4>\n<p>\nEfter udskiftning af disken kontrollerer vi f\u00f8rst og fremmest dens tilg\u00e6ngelighed. <\/p>\n<p>Ingeni\u00f8rer installerer ikke altid nye diske, s\u00e5 vi har tilf\u00f8jet en kontrol af de SMART-v\u00e6rdier, der opfylder vores krav.<\/p>\n<p><b class=\"spoiler_title\">Hvilke attributter vi ser p\u00e5<\/b>Reallocated Sectors Count (5) &lt; 100<br \/>\nCurrent Pending Sector Count (107) == 0<\/p>\n<p>Hvis disken ikke klarer testen, bliver ingeni\u00f8ren informeret om at erstatte den. Hvis alt er i orden, slukkes belysningen, der p\u00e5f\u00f8res markering, og disken tages i rotation.<\/p>\n<h4>ready.yml<\/h4>\n<p>\nDen enkleste case: kontrol af synkronisering mellem HW\/SW raid eller afslutning af datasykronisering i applikationen.<\/p>\n<h3>Applikations-API'er<\/h3>\n<p>\nJeg har n\u00e6vnt flere gange, at botten ofte tilg\u00e5r applikations-API'er. Selvf\u00f8lgelig havde ikke alle applikationer de n\u00f8dvendige metoder, s\u00e5 vi m\u00e5tte udvikle dem. Her er de vigtigste metoder, som vi bruger:<\/p>\n<ul>\n<li>Status. Status for klyngen eller disken for at forst\u00e5, om den kan anvendes;\n<\/li>\n<li>Start\/stop. Aktivere\/deaktivere disken;\n<\/li>\n<li>Migrate\/restore. Migrering og gendannelse af data under og efter udskiftning.\n<\/li>\n<\/ul>\n<p><\/p>\n<h3>Erfaring produceret i Ansible<\/h3>\n<p>\nJeg elsker Ansible. Men ofte, n\u00e5r jeg ser p\u00e5 forskellige open source-projekter og ser, hvordan folk skriver playbooks, bliver jeg lidt skr\u00e6mt. Komplekse logiske sammenfletninger af when\/loop, mangel p\u00e5 fleksibilitet og idempotens p\u00e5 grund af hyppigt brug af shell\/command.<\/p>\n<p>Vi besluttede at forenkle det hele ved at udnytte Ansible's styrker \u2014 modul\u00e6rt design. P\u00e5 det h\u00f8jeste niveau findes playbooks, som enhver administrator eller ekstern udvikler, der har lidt kendskab til Ansible, kan skrive.<\/p>\n<pre><code class=\"plaintext\">- name: Blink disk\n  become: True\n  register: locate_action\n  disk_locate:\n      locate: '{{ locate }}'\n      devname: '{{ devname }}'\n      ids: '{{ locate_ids | default(pd_id) | default(omit) }}'\n<\/code><\/pre>\n<p>Hvis en logik er sv\u00e6r at implementere i playbooks, flytter vi den til et Ansible-modul eller filter. Scripts kan skrives i b\u00e5de Python og ethvert andet sprog. <\/p>\n<p>De er nemme og hurtige at skrive. For eksempel best\u00e5r modulet til belysning af disken, hvis eksempel er givet ovenfor, af 265 linjer.<\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/08e0384bfad24f3ee61e0643ca087852.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI bunden findes biblioteket. Til dette projekt skrev vi en separat applikation, en slags abstraktion over hardware og software RAID, der udf\u00f8rer de relevante foresp\u00f8rgsler. <\/p>\n<p><img decoding=\"async\" alt=\"Automatisering af diskudskiftninger med Ansible\" src=\"\/wp-content\/uploads\/2019\/06\/0edda3182026ce6279bd84c99613e3d6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAnsible's st\u00e6rkeste sider er enkelhed og forst\u00e5elige playbooks. Jeg mener, at man b\u00f8r bruge dem og ikke generere skr\u00e6mmende yaml-filer og et stort antal betingelser, shell-kode og loops.<\/p>\n<p>Hvis du \u00f8nsker at gentage vores erfaring med Ansible API, skal du have to ting i mente:<\/p>\n<ul>\n<li>Playbook_executor kan slet ikke overf\u00f8re en timeout til playbook'en. Der er en timeout for ssh-sessioner, men der er ingen timeout for playbook. Hvis vi fors\u00f8ger at afmontere en disk, der ikke l\u00e6ngere findes i systemet, vil playbook'en k\u00f8re uendeligt, s\u00e5 vi m\u00e5tte indkapsle k\u00f8rsel i en separat wrapper og dr\u00e6be den efter timeout.\n<\/li>\n<li>Ansible arbejder p\u00e5 basis af fork-processer, s\u00e5 dets API er ikke tr\u00e5dsikkert. Vi k\u00f8rer alle vores playbooks i en enkelt tr\u00e5d.\n<\/li>\n<\/ul>\n<p>\nSom resultat lykkedes det os at automatisere udskiftningen af omkring 80 % af diskene. Generelt er hastigheden for udskiftning steget med det dobbelte. I dag ser administratoren blot p\u00e5 h\u00e6ndelsen og beslutter, om disken skal skiftes eller ej, og derefter foretager han blot \u00e9t klik.<\/p>\n<p>Men nu begynder vi at st\u00f8de p\u00e5 et andet problem: nogle nye administratorer ved ikke, hvordan man skifter diske. \ud83d\ude42<br \/>\n<br \/>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/odnoklassniki\/blog\/452110\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432\u0435\u0434\u0443\u0449\u0438\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u043c \u0432 \u041e\u041a \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e \u0437\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u043e\u0440\u0442\u0430\u043b\u0430. \u0425\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0432\u044b\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0437\u0430\u043c\u0435\u043d\u044b \u0434\u0438\u0441\u043a\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c, \u043a\u0430\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u043b\u0438 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u043b\u0438 \u0435\u0433\u043e \u0431\u043e\u0442\u043e\u043c. \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430 \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0435\u0439 \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u0430 HighLoad+ 2018 \u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u043f\u043e \u0437\u0430\u043c\u0435\u043d\u0435 \u0434\u0438\u0441\u043a\u043e\u0432 \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26233,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-34841","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/avtomatizatsiya-zameny-diskov-s-pomoshhyu-ansible\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0437\u0430\u043c\u0435\u043d\u044b \u0434\u0438\u0441\u043a\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Ansible | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/avtomatizatsiya-zameny-diskov-s-pomoshhyu-ansible\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:00:43+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:00:43+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47 Automatisering af diskudskiftning med Ansible | ProHoster","description":"Hej alle.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/avtomatizatsiya-zameny-diskov-s-pomoshhyu-ansible","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0437\u0430\u043c\u0435\u043d\u044b \u0434\u0438\u0441\u043a\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Ansible | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442.","og:url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/avtomatizatsiya-zameny-diskov-s-pomoshhyu-ansible","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:00:43+00:00","article:modified_time":"2019-10-31T19:00:43+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"34841","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 20:48:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:14:05","updated":"2026-01-21 20:48:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/34841","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=34841"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/34841\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/26233"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=34841"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=34841"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=34841"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}