Palvelinten hallinta - Harjoitus 4 ============== *Disclaimer:* -------------- Tämä harjoitus on tehty osana Haaga-Helian Tietojenkäsittelyn koulutusohjelman kurssia [Palvelinten hallinta (ICT4TN022, kevät 2018)](http://www.haaga-helia.fi/fi/opinto-opas/opintojaksokuvaukset/ICT4TN022). Kurssin pitäjänä toimii [Tero Karvinen](http://terokarvinen.com/), joka on määritellyt tämän harjoituksen tehtävänkuvaukset. Tehtävien vastaukset ovat Pekka Heleniuksen (allekirjoittanut) tuottamia. *SISÄLLYSLUETTELO* -------------- - [Harjoituksen esivaatimus - kahden minion-koneen asentaminen Vagrantilla](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h4.md#harjoituksen-esivaatimus---kahden-minion-koneen-asentaminen-vagrantilla) - [b) Tee kahdella orjalla esimerkki, jossa orjat saavat eri muuttujan pilarista. Tarkista ‘pillars.items’, että kummalekin orjalle mene eri tieto. Tee jokin muu kuin tunnilla tehty sshd-esimerkki.](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h4.md#b-tee-kahdella-orjalla-esimerkki-jossa-orjat-saavat-eri-muuttujan-pilarista-tarkista-pillarsitems-ett%C3%A4-kummalekin-orjalle-mene-eri-tieto-tee-jokin-muu-kuin-tunnilla-tehty-sshd-esimerkki) - [c) Tee kahdella orjalla esimerkki, jossa toinen orja saa muuttujan pilarista ja toinen käyttää oletusarvoa (pillar.get). Tee jokin muu kuin tunnilla tehty sshd-esimerkki.](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/h4.md#c-tee-kahdella-orjalla-esimerkki-jossa-toinen-orja-saa-muuttujan-pilarista-ja-toinen-k%C3%A4ytt%C3%A4%C3%A4-oletusarvoa-pillarget-tee-jokin-muu-kuin-tunnilla-tehty-sshd-esimerkki) Harjoituksen esivaatimuksena on käyttää useampaa Minion-konetta Salt:lla. Useamman Salt-minionin luomiseen on monta eri tapaa, kuten - 1) luodaan jokaiselle minionille oma virtuaalikoneensa (Oracle VirtualBox, VMWare, Vagrant...), jotka kykenevät muodostamaan yhteyden Master-koneeseen - 2) luodaan jokaiselle minionille oma konttinsa (docker, systemd-nspawn), jotka kykenevät muodostamaan yhteyden Master-koneeseen - 3) käytetään olemassa olevia virtuaalikoneita, jotka pyörivät esimerkiksi palvelinsaleissa - 4) luodaan joko fyysiselle tai virtuaaliselle tietokoneelle useampi minion-konfiguraatio omine ID:ineen (huonoin!) Toteutetaan vaihtoehto 1) Vagrantilla. Harjoituksen esivaatimus - kahden minion-koneen asentaminen Vagrantilla -------------- Toteutetaan minion-koneet [Vagrant-virtualisoinnilla](https://en.wikipedia.org/wiki/Vagrant_(software)). Tässä vaiheessa oletetaan, että koneelta löytyy Salt-master jo valmiina (ks. mm. [harjoitus 1](https://raw.githubusercontent.com/Fincer/central-management-of-multiple-servers/master/h1.md)). Asennetaan vagrant ``` sudo apt-get -y install vagrant ``` Tietokoneelta löytyy ennestään _virtualbox_ asennettuna, mutta se voidaan asentaa myös: ``` sudo apt-get -y install virtualbox ``` Vagrant käyttää laatikoita (boxes) virtualisoitujen ympäristöjen toteuttamisessa. Käytän harjoituksessa laatikkoa [debian/jessie64](https://app.vagrantup.com/debian/boxes/jessie64). Tässä täytyy olla tarkkana, ettei käytettyjen Salt:ien versiot ja API:t rikkoonnu! Tuotantoympäristössä nämä on tarkistettava ja katsottava huolella! Luodaan kaksi Salt minion -konetta ajamalla seuraava Vagrantfile Master-koneen myöhemmin valittavassa alihakemistossa: [Vagrantfile - Multiple Salt minions](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/scripts/vagrant_salt-minions/Vagrantfile) **HUOM!** Vagrant-ratkaisu ei toimi hyvin jo-virtualisoiduissa työympäristöissä, eli Vagrantia tulisi ajaa "fyysisellä" koneella. Ladataan yllä mainittu Vagrantfile master-koneen alihakemistoon /srv/salt/vagrant_minions: ``` sudo mkdir -p /srv/salt/vagrant_minions sudo wget https://raw.githubusercontent.com/Fincer/central-management-of-multiple-servers/master/scripts/vagrant_salt-minions/Vagrantfile -O /srv/salt/vagrant_minions/Vagrantfile ``` Ladatussa Vagrantfile:ssä on jo ennestään määritetty luotavaksi kaksi Salt-minionia: minion_1 ja minion_2 laatikkotemplatella debian/jessie64. **HUOM!** Monet _vagrant_ -komennot on sidottu työhakemistoon. Ennestään luodut virtuaalikoneet tulee ne tuhota siitä hakemistosta käsin, jossa koneet on luotu (ja siis jossa Vagrantfile sijaitsee). Vagrant luo tähän hakemistoon piilohakemiston _.vagrant/machines_, johon koneet on luotu. Annetaan master-koneen normaalille ylläpitäjälle (UID: 1000, GID: 1000 ja kuuluu sudo-ryhmään) omistusoikeus kansioon /srv/salt/vagrant_minions: ``` sudo chown 1000:1000 -R /srv/salt/vagrant_minions ``` Luodaan tällä käyttäjällä tuohon hakemistoon viittaava symbolinen linkki kys. käyttäjän kotihakemistoon: ``` ln -s /srv/salt/vagrant_minions $HOME/vagrant-minions ``` **HUOM!** Edellä olevaa ei ole pakko tehdä, ja se on täysin vapaaehtoista. Halusin tehdä sen selkeyden vuoksi. Ajetaan ladattu Vagrantfile: ``` cd $HOME/vagrant-minions vagrant up ``` Testataan laatikoiden minion_1 ja minion_2 SSH-toimivuus ajamalla: ``` vagrant ssh minion_1 vagrant ssh minion_2 ``` ![vagrant-connection-test](https://raw.githubusercontent.com/Fincer/central-management-of-multiple-servers/master/images/vagrant-connection-test.png) Hyväksytään nämä minion-koneet masterilla: ``` [23/04/2018 19:24:57 - fincer: vagrant ]$ sudo salt-key -A The following keys are going to be accepted: Unaccepted Keys: minion_1 minion_2 Proceed? [n/Y] y Key for minion minion_1 accepted. Key for minion minion_2 accepted. ``` **b)** Tee kahdella orjalla esimerkki, jossa orjat saavat eri muuttujan pilarista. Tarkista ‘pillars.items’, että kummalekin orjalle mene eri tieto. Tee jokin muu kuin tunnilla tehty sshd-esimerkki. -------------- **Vastaus:** Ajetaan root-käyttäjänä (sudo-komento) seuraava shell-skripti master-koneella: [Pekka Helenius - salt_pillar_sample.sh](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/scripts/salt_pillar_sample.sh) Masterilta saatu output: ``` [23/04/2018 19:41:45 - fincer: vagrant ]$ sudo sh pillar_sample.sh base: 'minion_1': - minion-1 'minion_2': - minion-2 test_variable: 'secret like coffee shop wants to say hello to the world' test_variable: 'hidden miniart: superman vs. hulk figures' This is my pillarfile which has the following content: {{ pillar['test_variable'] }} pillar_file: file.managed: - user: 1000 - group: 1000 - name: /tmp/pillarfile_for_{{ grains['id'] }} - source: salt://files/pillarfile - makedirs: True - template: jinja minion_2: True minion_1: True **Salt -- pillar.items output** minion_2: ---------- test_variable: hidden miniart: superman vs. hulk figures minion_1: ---------- test_variable: secret like coffee shop wants to say hello to the world **Salt -- state.apply output** minion_1: ---------- ID: pillar_file Function: file.managed Name: /tmp/pillarfile_for_minion_1 Result: True Comment: File /tmp/pillarfile_for_minion_1 is in the correct state Started: 16:42:18.786164 Duration: 54.806 ms Changes: Summary for minion_1 ------------ Succeeded: 1 Failed: 0 ------------ Total states run: 1 Total run time: 54.806 ms minion_2: ---------- ID: pillar_file Function: file.managed Name: /tmp/pillarfile_for_minion_2 Result: True Comment: File /tmp/pillarfile_for_minion_2 is in the correct state Started: 16:42:18.886370 Duration: 57.26 ms Changes: Summary for minion_2 ------------ Succeeded: 1 Failed: 0 ------------ Total states run: 1 Total run time: 57.260 ms **Salt -- get file output with head command** minion_2: This is my pillarfile which has the following content: hidden miniart: superman vs. hulk figures minion_1: This is my pillarfile which has the following content: secret like coffee shop wants to say hello to the world ``` **c)** Tee kahdella orjalla esimerkki, jossa toinen orja saa muuttujan pilarista ja toinen käyttää oletusarvoa (pillar.get). Tee jokin muu kuin tunnilla tehty sshd-esimerkki. -------------- **Vastaus:** Asennetaan molemmille orjille Apache HTTP daemon seuraavaa shell-skriptiä käyttäen: [salt_pillar_apache_sample.sh](https://github.com/Fincer/central-management-of-multiple-servers/blob/master/scripts/salt_pillar_apache_sample.sh) Masterilta saatu output: ``` [24/04/2018 01:57:10 - fincer: vagrant ]$ sudo sh apache_sample.sh {% if grains['id'] == 'minion_2' %} site_data: '{{ salt['cmd.run']('uname -a') }}' {% endif %} ServerName {{ servername }} ServerAlias {{ serveralias }} ServerAdmin webmaster@localhost DocumentRoot {{ ('/var/www/html/' + grains['id'] + '/') }} ErrorLog /error.log CustomLog /access.log combined {{ pillar.get('site_data','Nothing interesting here') }} {% set servername = grains['os'].lower() + '.' + grains['id'] + '.com' %} {% set serveralias = 'www.' + grains['os'].lower() + '.' + grains['id'] + '.com' %} apache_install: pkg.installed: - pkgs: - apache2 - curl sample_page_conf: file.managed: - name: /etc/apache2/sites-available/{{ grains['id'] }}.conf - source: salt://apache/samplesite.conf - mode: 0644 - user: root - group: root - template: jinja - context: servername: {{ servername }} serveralias: {{ serveralias }} - require: - pkg: apache_install enable_sample_page: cmd.run: - name: 'a2ensite {{ grains['id'] }}.conf' - require: - file: sample_page_conf sample_page_content: file.managed: - mode: 0644 - user: root - group: root - makedirs: True - template: jinja - name: {{ ('/var/www/html/' + grains['id'] + '/index.html') }} - source: salt://apache/sampleindex.html - require: - cmd: enable_sample_page add_vhost_domain: file.append: - name: /etc/hosts - text: 127.0.0.1 {{ servername }} - require: - file: sample_page_content restart_httpd: service.running: - name: apache2.service - watch: - file: add_vhost_domain - cmd: enable_sample_page test_page: cmd.run: - name: 'curl -s {{ servername }}' - require: - service: restart_httpd **Salt -- pillar.items output** minion_1: ---------- test_variable: secret like coffee shop wants to say hello to the world minion_2: ---------- site_data: Linux fincer-laptop 4.15.10-1-ARCH #1 SMP PREEMPT Thu Mar 15 12:24:34 UTC 2018 x86_64 GNU/Linux test_variable: hidden miniart: superman vs. hulk figures **Salt -- state.apply output** minion_1: ---------- ID: apache_install Function: pkg.installed Result: True Comment: All specified packages are already installed Started: 22:59:25.325084 Duration: 273.26 ms Changes: ---------- ID: sample_page_conf Function: file.managed Name: /etc/apache2/sites-available/minion_1.conf Result: True Comment: File /etc/apache2/sites-available/minion_1.conf is in the correct state Started: 22:59:25.599368 Duration: 51.619 ms Changes: ---------- ID: enable_sample_page Function: cmd.run Name: a2ensite minion_1.conf Result: True Comment: Command "a2ensite minion_1.conf" run Started: 22:59:25.651513 Duration: 20.174 ms Changes: ---------- pid: 13401 retcode: 0 stderr: stdout: Site minion_1 already enabled ---------- ID: sample_page_content Function: file.managed Name: /var/www/html/minion_1/index.html Result: True Comment: File /var/www/html/minion_1/index.html is in the correct state Started: 22:59:25.671991 Duration: 9.937 ms Changes: ---------- ID: add_vhost_domain Function: file.append Name: /etc/hosts Result: True Comment: File /etc/hosts is in correct state Started: 22:59:25.682126 Duration: 1.011 ms Changes: ---------- ID: restart_httpd Function: service.running Name: apache2.service Result: True Comment: Service restarted Started: 22:59:25.697483 Duration: 2145.224 ms Changes: ---------- apache2.service: True ---------- ID: test_page Function: cmd.run Name: curl -s ubuntu.minion_1.com Result: True Comment: Command "curl -s ubuntu.minion_1.com" run Started: 22:59:27.842981 Duration: 9.994 ms Changes: ---------- pid: 13523 retcode: 0 stderr: stdout: Nothing interesting here Summary for minion_1 ------------ Succeeded: 7 (changed=3) Failed: 0 ------------ Total states run: 7 Total run time: 2.511 s minion_2: ---------- ID: apache_install Function: pkg.installed Result: True Comment: All specified packages are already installed Started: 22:59:25.453349 Duration: 273.908 ms Changes: ---------- ID: sample_page_conf Function: file.managed Name: /etc/apache2/sites-available/minion_2.conf Result: True Comment: File /etc/apache2/sites-available/minion_2.conf is in the correct state Started: 22:59:25.728257 Duration: 10.512 ms Changes: ---------- ID: enable_sample_page Function: cmd.run Name: a2ensite minion_2.conf Result: True Comment: Command "a2ensite minion_2.conf" run Started: 22:59:25.739209 Duration: 18.428 ms Changes: ---------- pid: 13160 retcode: 0 stderr: stdout: Site minion_2 already enabled ---------- ID: sample_page_content Function: file.managed Name: /var/www/html/minion_2/index.html Result: True Comment: File /var/www/html/minion_2/index.html is in the correct state Started: 22:59:25.757909 Duration: 8.736 ms Changes: ---------- ID: add_vhost_domain Function: file.append Name: /etc/hosts Result: True Comment: File /etc/hosts is in correct state Started: 22:59:25.766840 Duration: 0.933 ms Changes: ---------- ID: restart_httpd Function: service.running Name: apache2.service Result: True Comment: Service restarted Started: 22:59:25.779507 Duration: 2102.595 ms Changes: ---------- apache2.service: True ---------- ID: test_page Function: cmd.run Name: curl -s ubuntu.minion_2.com Result: True Comment: Command "curl -s ubuntu.minion_2.com" run Started: 22:59:27.882439 Duration: 11.578 ms Changes: ---------- pid: 13282 retcode: 0 stderr: stdout: Linux fincer-laptop 4.15.10-1-ARCH #1 SMP PREEMPT Thu Mar 15 12:24:34 UTC 2018 x86_64 GNU/Linux Summary for minion_2 ------------ Succeeded: 7 (changed=3) Failed: 0 ------------ Total states run: 7 Total run time: 2.427 s ``` Luotujen HTML-sivustojen sisältö: ``` [24/04/2018 01:59:28 - fincer: vagrant ]$ sudo salt 'minion_1' cmd.run 'curl -s ubuntu.minion_1.com' minion_1: Nothing interesting here [24/04/2018 02:00:47 - fincer: vagrant ]$ sudo salt 'minion_2' cmd.run 'curl -s ubuntu.minion_2.com' minion_2: Linux fincer-laptop 4.15.10-1-ARCH #1 SMP PREEMPT Thu Mar 15 12:24:34 UTC 2018 x86_64 GNU/Linux ```