Artikkelissa kuvataan yksinkertaisen web-liikenteen kuormanjaon toteutus Saltilla käyttäen nginx:ää sekä web-palvelimena että kuormanjakajana. Kirjoitus on kotitehtäväpalautus Haaga-Helian Tero Karvisen kurssille ICT4TN011 Linuxin keskitetty hallinta.

Tehtävänanto on seuraavanlainen:

Tee oma Salt-tila ja esittele se viimeisellä tunnilla. Mieti jokin hyödyllinen tarkoitus tekemällesi tilalle. Ehkä jotain, mitä voit hyödyntää kotona tai töissä.

1 Lähtötilanne

Teen harjoituksen Digitalocean.com virtuaalipalvelimella jotta vältyn VirtualBoxin kanssa puljaamiselta ja voin tehdä harjoitukset joko työkoneella (MacBook Pro) tai kotikoneella (iMac) helposti ilman linuxin asennusta kumpaankaan. Haaga-Helian opiskelijana saa Githubin Student Developer Pack:n kautta 100$ krediittiä DigitalOceanin palveluun, joten tämä on käytännössä ilmaista.

Lähtötilanteessa on tehtynä jo seuraavaa:

  • Virtuaalikoneet 3kpl on luotu DigitalOceanin web-käyttöliittymän kautta Lontoon palvelinkeskukseen. Käyttöjärjestelmänä DigitalOceanin asentama Ubuntu 14.04 x64.
    • gru.jkw.fi (178.62.126.210)
    • kevin.jkw.fi (46.101.19.106)
    • bob.jkw.fi (178.62.108.191)
  • Olen luonut palvelimille omat käyttäjätunnukseni (jkw) ja asentanut julkiset avaimeni tiedostoon (~/.ssh/authorized_keys) jotta pääsen yhdistämään palvelimille ssh:lla ilman salasanan syöttämistä.
  • Ensimmäinen kotitehtävä on tehty eli:
    • salt-master on asennettu koneelle gru
    • salt-minion on asennettu koneille kevin ja bob
  • Yhteys koneiden välillä toimii, masterilta voi ajaa saltin “reseptejä” minion-koneille komentamalla esimerkiksi salt '*' state.sls nginx
  • Palvelimille on asennettu uusimmat päivitykset (sudo apt-get update && sudo apt-get dist-upgrade) ja palvelimet on sen jälkeen uudelleenkäynnistetty.

2 Kuormanjako-minion

Aloitin tekemällä DigitalOceaniin vielä yhden minionin: margo.jkw.fi (IP: 46.101.95.127), jolle asensin Saltin ensimmäisestä kotitehtävästä tutulla tavalla. Kun yhteys masteriin toimi, aloitin tekemällä oman Salt-tilan kuormanjakalle.

Seurasin DigitalOceanin ohjetta How to Use Nginx as a Front-end Proxy Server and Software Load Balancer. Aloitin tuttuun tapaan luomalla tilalleni hakemiston /srv/salt/balancer ja sinne tiedoston init.sls. Tiedoston sisältö:

nginx:
  pkg:
    - installed
  service.running:
    - enable: True

/etc/nginx/sites-enabled/default:
  file.managed:
    - source: salt://balancer/margo.jkw.fi

Lisäksi loin tuon hallitun default tiedoston templaten /srv/salt/balancer/margo.jkw.fi:

server {

  listen 80;
  server_name margo.jkw.fi www.margo.jkw.fi;

  location / {
     proxy_pass  http://appcluster;
     include /etc/nginx/proxy_params;
  }

}

upstream appcluster {
   server kevin.jkw.fi:80;
   server bob.jkw.fi:80;
}

Oleellisimpana nginx:n default asetustiedostossa määritellään kuormanjaon käytettävissä olevat osoitteet (koneet) portteineen. Tässä tapauksessa on yksi kuormanjakaja joka käyttää hyväkseen kahta palvelinta.

Tässä kohtaa olisi ehdottomasti kehittämisen varaa, nyt kuormanjakajan käytössä olevat web-palvelimet määritellään “käsin” tuohon asetustiedostoon, vaikka varmasti ne kannattaisi ohjelmallisesti jostain Saltin käytössä olevista tiedoista. Siis että kun webservers-ryhmään lisättäisiin vielä yksi palvelin, päivittyisi se automaattisesti myös tähän nginx-asetustiedostoon.

3 Web-palvelin minionit

Palvelimille on asennettu nginx ja simppeli oletus index.html joka näyttää graineista haettuna, mikä palvelin on kyseessä.

/srv/salt/nginx/init.sls

nginx:

  pkg:
    - installed
  service.running:
    - enable: True

php5-fpm:
  pkg:
    - installed

/usr/share/nginx/html/index.html:
  file.managed:
    - source: salt://nginx/index.html.jinja
    - template: jinja

/srv/salt/ginx/index.html.jinja

<!DOCTYPE html>
<html>
  <head>
    <title>Welcome to nginx!</title>
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    <p>This is being served from:</p> <b>{{ grains['fqdn'] }}</b>
  </body>
</html>

Näin siis bob.jkw.fi näyttää tältä:

bob.jkw.fi

Ja kevin.jkw.fi tältä:

kevin.jkw.fi

Tarkoituksena on että osoitteessa margo.jkw.fi näkyy vuorotellen / satunnaisesti joko tuo kevin.jkw.fi tai bob.jkw.fi.

4 Testaus

Tilojen ajaminen toimi ensimmäisellä yrittämällä ja kuormanjako toimii mainiosti:

margo.jkw.fi

Testasin myös suorituskykyä apachebanchillä, tekemällä 100000 pyyntöä 100 rinnakkain. Osasin odottaa että suorituskyky ei tälläisellä simppelillä sivulla parannu, koska palvelimen ei tarvitse juurikaan tehdä töitä sivun näyttämiseksi. Mutta silti tulokset olivat hieman yllättävät:

Ilman kuormanjakajaa yhdellä palvelimella:

ab -n 100000 -c 10 http://bob.jkw.fi/
Time taken for tests:   16.127 seconds
Requests per second:    6200.72 [#/sec] (mean)

Kuormanjako kahdelle palvelimelle:

ab -n 100000 -c 10 http://margo.jkw.fi/
Time taken for tests:   19.619 seconds
Requests per second:    5097.09 [#/sec] (mean)

Toistin testejä muutaman kerran ja tulos pysyi samansuuntaisena. Kuormanjako hidasti toimintaa. Oikeastaan tämä on ihan loogista, kun yhdellä palvelimella tapahtuu vain yksi pyyntö, tapahtuu kuormanjakoa käyttäen ensin pyyntö kuormanjakajalle ja sieltä vielä varsinaiselle palvelimelle.

Jos sivulla olisi jotain dynaamista / laskentaa vaativaa, olisi tilanne varmasti toinen. Nyt kuormanjako hidastaa koska tilanne on niin simppeli, että suurin osa ajasta ei mene “palvelimen tekemään työhön” vaan http-liikenteeseen.