{"id":1193,"date":"2019-04-01T14:55:54","date_gmt":"2019-04-01T13:55:54","guid":{"rendered":"http:\/\/www.fotoandnet.de\/wp\/?p=1193"},"modified":"2019-04-08T18:09:32","modified_gmt":"2019-04-08T17:09:32","slug":"installing-glusterfs-on-odroid-hc2","status":"publish","type":"post","link":"http:\/\/www.fotoandnet.de\/wp\/?p=1193","title":{"rendered":"Installing GlusterFS on Odroid-HC2"},"content":{"rendered":"\n<p>Das GlusterFS lebt davon, dass es unterscheiden kann welches Ver\u00e4nderung im Filesystem zu welchem Zeitpunkt, auf welchem Node zu erst stattgefunden hat. Andernfalls k\u00f6nnte es ja nicht die Aktualit\u00e4t beurteilen. Aus diesem Grund ist es, laut Anleitung, sehr wichtig ein durchgehend zeitsynchrones Setup zu pflegen. An der Installation und Nutzung von NTP f\u00fchrt also kein Weg vorbei. Also zu erst mal NTP installieren und aktivieren.   <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: All hosts install ntp\n  hosts: glusterfs\n  become: yes\n  \n  tasks:\n    - name: install ntp\n      pacman:\n        name: ntp\n        update_cache: yes<\/code><\/pre>\n\n\n\n<p>Und ausrollen, mittlerweile traue ich mich es auch gleich auf den ganzen Node-Stapel auszurollen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@barney ~]$ ansible-playbook ntp.yml\n\nPLAY [All hosts install ntp] *******************************************************************************************************************************\n\nTASK [Gathering Facts] *************************************************************************************************************************************\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\n\nTASK [install ntp] *****************************************************************************************************************************************\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\n\nPLAY RECAP *************************************************************************************************************************************************\n192.168.2.xx               : ok=2    changed=1    unreachable=0    failed=0   \n192.168.2.xx               : ok=2    changed=1    unreachable=0    failed=0   \n192.168.2.xx               : ok=2    changed=1    unreachable=0    failed=0   \n192.168.2.xx               : ok=2    changed=1    unreachable=0    failed=0   \n192.168.2.xx               : ok=2    changed=1    unreachable=0    failed=0   \n192.168.2.xx               : ok=2    changed=1    unreachable=0    failed=0   \n\n[ansible@barney ~]$ <\/code><\/pre>\n\n\n\n<p>Der n\u00e4chste Schritt ist also NTP Server f\u00fcr die interne Uhr der Gluster-Nodes zu nutzen. Ich hab mir folgendes Playbook zusammen geschrieben.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Build NTP config\n  hosts: glusterfs\n  become: yes\n  \n  tasks:\n    - name: Stop service ntpd, if started\n      service:\n        name: ntpd\n        state: stopped\n\n    - name: delete orginal config\n      file:\n        path: \/etc\/ntp.conf\n        state: absent\n\n    - name: Touch on \/etc\/ntp.conf\n      file:\n        path: \/etc\/ntp.conf\n        state: touch\n        mode: \"u=rw,g=r,o=r\"\n\n    - name: insert ntp.conf\n      blockinfile:\n        path: \/etc\/ntp.conf\n        block: |\n          #Associate to PTB's NTP pool\n          server 0.arch.pool.ntp.org\n          server 1.arch.pool.ntp.org\n          server 2.arch.pool.ntp.org\n          server 3.arch.pool.ntp.org\n\n          # By default, the server allows:\n          # - all queries from the local host\n          # - only time queries from remote hosts, protected by rate limiting and kod\n          restrict default kod limited nomodify nopeer noquery notrap\n          restrict 127.0.0.1\n          restrict ::1\n\n          # Location of drift file\n          driftfile \/var\/lib\/ntp\/ntp.drift\n\n    - name: Start service ntpd, if not started\n      service:\n        name: ntpd\n        state: started\n\n    - name: Enable service ntpd, and not touch the state\n      service:\n        name: ntpd\n        enabled: yes\n\n    - name: set timezone to Europe\/Berlin\n      timezone:\n        name: Europe\/Berlin<\/code><\/pre>\n\n\n\n<p>Ein Kontrolle, mit einigen Minuten abstand zum ausgef\u00fchrten Playbook, zeigt auch, dass die NTP Server erreicht werden.  <em>Leider war es mir nicht m\u00f6glich die Zeitserver der PTB in Deutschland zu nutzen. Auf deren Website standen zwar die FQDNs, welche aber weder auf NTP Anfragen noch auf Ping reagierten..<\/em><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS1 ~]$ ntpq -p\n     remote           refid      st t when poll reach   delay   offset  jitter\n==============================================================================\n+217.79.179.106  192.53.103.108   2 u   38   64  177   12.028   -1.624   5.113\n+eta.h6g-server. 205.46.178.169   2 u   39   64  177   15.882   -0.296   5.146\n*89.163.128.33 ( 192.53.103.104   2 u   37   64  177   13.343   -6.665   5.282\n+mx.pingless.com 130.149.17.21    2 u   35   64  177    8.285   -6.129   4.892\n[ansible@GFS1 ~]$ \n<\/code><\/pre>\n\n\n\n<p>Die Uhrzeit sollte also \u00fcber alle Nodes dann Synchron sein, nachdem ich das Playbook auf alle Gluster Nodes geworfen habe. Was ich gleich mal mache.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@barney ~]$ ansible-playbook ntp-config.yml\n\nPLAY [Build NTP config] ************************************************************************************************************************************\n\nTASK [Gathering Facts] *************************************************************************************************************************************\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\n\nTASK [Stop service ntpd, if started] ***********************************************************************************************************************\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nchanged: [192.168.2.xx]\nok: [192.168.2.xx]\n\nTASK [delete orginal config] *******************************************************************************************************************************\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\n\nTASK [Touch on \/etc\/ntp.conf] ******************************************************************************************************************************\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\n\nTASK [insert ntp.conf] *************************************************************************************************************************************\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\n\nTASK [Start service ntpd, if not started] ******************************************************************************************************************\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\n\nTASK [Enable service ntpd, and not touch the state] ********************************************************************************************************\nok: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\n\nTASK [set timezone to Europe\/Berlin] ***********************************************************************************************************************\nok: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\nchanged: [192.168.2.xx]\n\nPLAY RECAP *************************************************************************************************************************************************\n192.168.2.xx               : ok=8    changed=5    unreachable=0    failed=0   \n192.168.2.xx               : ok=8    changed=6    unreachable=0    failed=0   \n192.168.2.xx               : ok=8    changed=6    unreachable=0    failed=0   \n192.168.2.xx               : ok=8    changed=6    unreachable=0    failed=0   \n192.168.2.xx               : ok=8    changed=6    unreachable=0    failed=0   \n192.168.2.xx               : ok=8    changed=6    unreachable=0    failed=0   \n\n[ansible@barney ~]$ \n<\/code><\/pre>\n\n\n\n<p>Nachdem nun die Uhrzeit klar ist, geht es weiter mit dem aktivieren des GlusterfS Daemon, ohne welchen ein GlusterFS nicht funktioniert.<\/p>\n\n\n\n<p>Daf\u00fcr habe ich mir folgendes Playbook ausgedacht.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Start GlusterFS Daemon\n  hosts: glusterfs\n  become: yes\n  \n  tasks:\n    - name: Start GlusterFS Daemon, if not started\n      service:\n        name: glusterd\n        state: started\n\n    - name: Enable GlusterFS Daemon service, and not touch the state\n      service:\n        name: glusterd\n        enabled: yes\n<\/code><\/pre>\n\n\n\n<p>Dieses Playbook lief ebenfalls durch ohne Fehlermeldungen. Ich hab mit den GlusterFS Boardmitteln mal lokal auf Node GFS2 probiert, ob die anderen Nodes im Gluster-Service erreichbar sind.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS2 ~]$ sudo gluster peer probe gfs1\npeer probe: success. \n\n[ansible@GFS2 ~]$ sudo gluster peer probe gfs2                    \npeer probe: success. Probe on localhost not needed\n\n[ansible@GFS2 ~]$ sudo gluster peer probe gfs3\npeer probe: success. \n\n[ansible@GFS2 ~]$ sudo gluster peer probe gfs4\npeer probe: success. \n\n[ansible@GFS2 ~]$ sudo gluster peer probe gfs5\npeer probe: success. \n\n[ansible@GFS2 ~]$ sudo gluster peer probe gfs6\npeer probe: success. \n\n[ansible@GFS2 ~]$ <\/code><\/pre>\n\n\n\n<p>Auf allen Nodes wurde der GlusterFS Daemon erfolgreich gestartet. Da ich von Hause aus sehr mistrauisch bin, habe ich den selben Test nach einem reboot ebenso nochmal durchgef\u00fchrt. Das Ergebnis war das selbe.<\/p>\n\n\n\n<p>Nachdem also der GlusterFS Daemon sauber l\u00e4uft, geht es daran die einzelnen Nodes als Peers per Playbook bekannt zu machen. Das Playbook daf\u00fcr habe ich wie folgt formuliert.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\n- name: Start GlusterFS Daemon\n  hosts: glusterfs\n  become: yes\n  \n  tasks:\n    - name: Create a trusted storage pool\n      gluster_peer:\n            state: present\n            nodes:\n                 - GFS1\n                 - GFS2\n                 - GFS3\n                 - GFS4\n                 - GFS5\n                 - GFS6<\/code><\/pre>\n\n\n\n<p>Beim Ausrollen ist mir aufgefallen, dass es scheinbar nur notwendig ist, es gegen einen GlusterFS Node laufen zu lassen, da dieser dann wohl die Peers untereinander informiert. Anders kann ich mir das erfolgreiche Setup trotz der vielen Fehlermeldungen nicht recht erkl\u00e4ren. Sei es drum, das Playbook ist durchgelaufen.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@barney ~]$ ansible-playbook gluster-peers.yml \n\nPLAY [Start GlusterFS Daemon] ******************************************************************************************************************************\n\nTASK [Gathering Facts] *************************************************************************************************************************************\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\nok: [192.168.2.xx]\n\nTASK [Create a trusted storage pool] ***********************************************************************************************************************\nfatal: [192.168.2.xx]: FAILED! => {\"changed\": false, \"msg\": \"peer probe: failed: GFS1 is either already part of another cluster or having volumes configured\\n\", \"rc\": 1}\nfatal: [192.168.2.xx]: FAILED! => {\"changed\": false, \"msg\": \"peer probe: failed: GFS1 is either already part of another cluster or having volumes configured\\n\", \"rc\": 1}\nfatal: [192.168.2.xx]: FAILED! => {\"changed\": false, \"msg\": \"peer probe: failed: GFS1 is either already part of another cluster or having volumes configured\\n\", \"rc\": 1}\nfatal: [192.168.2.xx]: FAILED! => {\"changed\": true, \"msg\": \"peer probe: failed: GFS3 is either already part of another cluster or having volumes configured\\n\", \"rc\": 1}\nfatal: [192.168.2.xx]: FAILED! => {\"changed\": false, \"msg\": \"peer probe: failed: GFS1 is either already part of another cluster or having volumes configured\\n\", \"rc\": 1}\nchanged: [192.168.2.xx]\n        to retry, use: --limit @\/home\/ansible\/gluster-peers.retry\n\nPLAY RECAP *************************************************************************************************************************************************\n192.168.2.xx               : ok=2    changed=1    unreachable=0    failed=0   \n192.168.2.xx               : ok=1    changed=0    unreachable=0    failed=1   \n192.168.2.xx               : ok=1    changed=0    unreachable=0    failed=1   \n192.168.2.xx               : ok=1    changed=0    unreachable=0    failed=1   \n192.168.2.xx               : ok=1    changed=0    unreachable=0    failed=1   \n192.168.2.xx               : ok=1    changed=0    unreachable=0    failed=1   \n\n[ansible@barney ~]$<\/code><\/pre>\n\n\n\n<p>Aber wie bereits geschrieben geht es den Peers gut, denn die Abfrage des Glsuer Peer Status sieht richtig gut aus. Einmal auf GFS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS1 ~]$ sudo gluster peer status\nNumber of Peers: 5\n\nHostname: GFS2\nUuid: a8e86d86-d13d-45d6-97a1-b46619a4dfea\nState: Peer in Cluster (Connected)\n\nHostname: GFS3\nUuid: a9696e90-0707-4de4-8430-479e7d3af8ac\nState: Peer in Cluster (Connected)\n\nHostname: GFS4\nUuid: e01c2d0a-6491-4250-b531-5895be4788f0\nState: Peer in Cluster (Connected)\n\nHostname: GFS5\nUuid: c26b3841-ff62-456a-b1d9-8e2842291535\nState: Peer in Cluster (Connected)\n\nHostname: GFS6\nUuid: 67604b4f-85ba-47d5-96e4-a9dee66569ae\nState: Peer in Cluster (Connected)\n\n[ansible@GFS1 ~]$ <\/code><\/pre>\n\n\n\n<p>Und einmal zur Sicherheit auch noch auf GFS6:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS6 ~]$ sudo gluster peer status\nNumber of Peers: 5\n\nHostname: GFS1\nUuid: 48851509-5126-4d70-918d-841fc185ce21\nState: Peer in Cluster (Connected)\n\nHostname: GFS2\nUuid: a8e86d86-d13d-45d6-97a1-b46619a4dfea\nState: Peer in Cluster (Connected)\n\nHostname: GFS3\nUuid: a9696e90-0707-4de4-8430-479e7d3af8ac\nState: Peer in Cluster (Connected)\n\nHostname: GFS4\nUuid: e01c2d0a-6491-4250-b531-5895be4788f0\nState: Peer in Cluster (Connected)\n\nHostname: GFS5\nUuid: c26b3841-ff62-456a-b1d9-8e2842291535\nState: Peer in Cluster (Connected)\n\n[ansible@GFS6 ~]$ <\/code><\/pre>\n\n\n\n<p>Die Peers sehen sich und haben eine Verbindung untereinander. Weiter geht es mit dem eigentlichen interessanten Teil, das Aufsetzen des Node \u00fcbergreifenden GlusterFWS Volumes.<\/p>\n\n\n\n<p>Leider gelingt mir dieses zur Zeit nicht mit Ansible, was eigentlich sehr schade ist &#8211; da ich es umbedingt nutzen wollte. Auf der anderen Seite ist es nicht notwendigerweise mit Ansible einfacher, da die gesammte GlusterFS Konfiguration nur auf einem Node erfolgt und der verteilt es dann an die anderen Node Clustermember. Hier jetzt also die Zeilen zum Aufsetzen des GlusterFS Volumes auf der Bash von gfs1:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS1 ~]$ sudo gluster volume create GV0 disperse 4 redundancy 2 transport tcp gfs1:\/export\/sda1 gfs2:\/export\/sda1 gfs3:\/export\/sda1 gfs4:\/export\/sda1 gfs5:\/export\/sda1 gfs6:\/export\/sda1 force \nvolume create: GV0: success: please start the volume to access data\n\n[ansible@GFS1 ~]$ <\/code><\/pre>\n\n\n\n<p>Da mich nach so einem Befehl immer brennend die Auswirkung interessiert, hier die Kontrolle des Ergebnis.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS1 ~]$ sudo gluster volume info\n \nVolume Name: GV0\nType: Disperse\nVolume ID: a917ef77-f247-4460-a3bb-bf4a7cb1fad9\nStatus: Created\nSnapshot Count: 0\nNumber of Bricks: 1 x (4 + 2) = 6\nTransport-type: tcp\nBricks:\nBrick1: gfs1:\/export\/sda1\nBrick2: gfs2:\/export\/sda1\nBrick3: gfs3:\/export\/sda1\nBrick4: gfs4:\/export\/sda1\nBrick5: gfs5:\/export\/sda1\nBrick6: gfs6:\/export\/sda1\nOptions Reconfigured:\ntransport.address-family: inet\nnfs.disable: on\n\n[ansible@GFS1 ~]$<\/code><\/pre>\n\n\n\n<p>Solange das Volume nur angelegt (Created) ist, findet noch keine Replikation zwischen den Nodes statt. Daf\u00fcr muss das Volume erst gestartet werden.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS1 ~]$ sudo gluster volume start GV0  \nvolume start: GV0: success\n[ansible@GFS1 ~]$<\/code><\/pre>\n\n\n\n<p>Anschlie\u00dfend \u00e4ndert sich der Status von Created zu Started. Jetzt sollte das GlusterFS Volume erreichbar sein.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[ansible@GFS1 ~]$ sudo gluster volume info\n \nVolume Name: GV0\nType: Disperse\nVolume ID: a917ef77-f247-4460-a3bb-bf4a7cb1fad9\nStatus: Started\nSnapshot Count: 0\nNumber of Bricks: 1 x (4 + 2) = 6\nTransport-type: tcp\nBricks:\nBrick1: gfs1:\/export\/sda1\nBrick2: gfs2:\/export\/sda1\nBrick3: gfs3:\/export\/sda1\nBrick4: gfs4:\/export\/sda1\nBrick5: gfs5:\/export\/sda1\nBrick6: gfs6:\/export\/sda1\nOptions Reconfigured:\ntransport.address-family: inet\nnfs.disable: on\n\n[ansible@GFS1 ~]$ sudo gluster volume status\nStatus of volume: GV0\nGluster process                             TCP Port  RDMA Port  Online  Pid\n------------------------------------------------------------------------------\nBrick gfs1:\/export\/sda1                     49152     0          Y       1746 \nBrick gfs2:\/export\/sda1                     49152     0          Y       916  \nBrick gfs3:\/export\/sda1                     49152     0          Y       678  \nBrick gfs4:\/export\/sda1                     49152     0          Y       681  \nBrick gfs5:\/export\/sda1                     49152     0          Y       671  \nBrick gfs6:\/export\/sda1                     49152     0          Y       679  \nSelf-heal Daemon on localhost               N\/A       N\/A        Y       1767 \nSelf-heal Daemon on GFS2                    N\/A       N\/A        Y       937  \nSelf-heal Daemon on GFS3                    N\/A       N\/A        Y       699  \nSelf-heal Daemon on GFS4                    N\/A       N\/A        Y       702  \nSelf-heal Daemon on GFS5                    N\/A       N\/A        Y       692  \nSelf-heal Daemon on GFS6                    N\/A       N\/A        Y       700  \n \nTask Status of Volume GV0\n------------------------------------------------------------------------------\nThere are no active volume tasks\n \n[ansible@GFS1 ~]$ <\/code><\/pre>\n\n\n\n<p>Ich hab das GlusterFS Volume GV0 mal probeweise gemountet. Das geht sehr einfach von einem anderen Linux Arch, welcher nicht als Peer defineriert sein muss. Okay, ich habe jetzt auch keine Security features aktiviert. Was wichtig ist, dass der Client der in den GlusterFS mounten m\u00f6chte die Nodes per DNS genauso aufl\u00f6sen k\u00f6nnen muss, wie die GlusterFS Peers untereinander. Dann geht das mounten auch recht einfach von der Hand.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[eric@Wintermute ~]$ sudo mount -t glusterfs gfs6:GV0 \/media\/GV0\/\n\n[eric@Wintermute ~]$ df -aH \/media\/GV0\nDateisystem    Gr\u00f6\u00dfe Benutzt Verf. Verw% Eingeh\u00e4ngt auf\ngfs6:GV0         10T    111G  9,9T    2% \/media\/GV0\n\n[eric@Wintermute ~]$ ls -la \/media\/GV0\/\ninsgesamt 4\ndrwxr-xr-x  3 root root   24  1. Apr 20:10 .\ndrwxr-xr-x 10 root root 4096  1. Apr 21:13 ..\n\n[eric@Wintermute ~]$ <\/code><\/pre>\n\n\n\n<p>Ich hoffe, ich konnte etwas Licht in das GlusterFS Thema bringen. <\/p>\n\n\n\n<p>:o)<br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das GlusterFS lebt davon, dass es unterscheiden kann welches Ver\u00e4nderung im Filesystem zu welchem Zeitpunkt, auf welchem Node zu erst stattgefunden hat. Andernfalls k\u00f6nnte es ja nicht die Aktualit\u00e4t beurteilen. Aus diesem Grund ist&#46;&#46;&#46;<\/p>\n","protected":false},"author":2,"featured_media":1158,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[55,62,61],"class_list":["post-1193","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","tag-ansible","tag-disperse","tag-glusterfs"],"_links":{"self":[{"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=\/wp\/v2\/posts\/1193","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1193"}],"version-history":[{"count":15,"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=\/wp\/v2\/posts\/1193\/revisions"}],"predecessor-version":[{"id":1212,"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=\/wp\/v2\/posts\/1193\/revisions\/1212"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=\/wp\/v2\/media\/1158"}],"wp:attachment":[{"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1193"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1193"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fotoandnet.de\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1193"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}