Hajautetut ohjelmistojärjestelmät ja pilvipalvelut -kurssi

Dockerin käyttöönotto

Virtuaalikoneisiin on asennettu Docker. Docker on ohjelmisto, jolla voidaan ajaa kontteja (engl. container). Kontit ovat minimalistisia virtuaalikoneita. Ottaaksesi Dockerin käyttöön, käynnistä se komennolla sudo systemctl start docker. Komennolla sudo systemctl enable docker Docker-palvelu käynnistyy aina virtuaalikoneen käynnistymisen yhteydessä. Kontteja haetaan internetistä komennolla docker pull imagename. Haetut kontit käynnistetään komennolla docker container run imagename. Tarkempia ohjeita käyttöön on kursin TKO8971 materiaalissa ja Dockerin kotisivuilla www.docker.com.

Distributed-chat esimerkkiprojekti

Dockeriin tutustumista varten on rakennettu hajautettu chat-ohjelmisto. Voit asentaa projektin gitistä seuraavasti:

  1. Kloonaa projekti komennolla
    git clone https://gitlab.utu.fi/tech/education/distributed-systems/distributed-chat.git

  2. Vaihda kansioon komennolla: cd distributed-chat

  3. Paketoi projekti Mavenilla: mvn package install

  4. Kun projekti on rakennettu voit käynnistää palvelimen komennolla
    mvn exec:java -Dexec.args="-server"
    Portti on valinnainen, oletuksena käytetään TCP-porttia 59059.

  5. Asiakas käynnistetään komennolla
    mvn exec:java -Dexec.args="-host localhost -port 59059
    Host-parametri on pakollinen ja se voi olla palvelimen symbolinen nimi tai ip-osoite. Portti on valinnainen, oletuksena käytetään TCP-porttia 59059. Portin tulee olla sama kuin palvelimella.

Mitä jos halutaan ajaa useita palvelimia? Nykyään palvelinsovellukset halutaan usein kapseloida valmiiksi suoritusympäristöiksi, jotka voidaan ottaa käyttöön ilman monimutkaista projektin rakennusta ja konfiguraatiota esim. pilvipalvelussa. Projektin rakentamisen ja konfiguroinnin päähaaste keskitetään siis suoritusympäristön (kontti) luomisvaiheeseen, jolloin käyttöönotto on myöhemmin suoraviivaista ja käyttöönottopaikasta riippumatta. Palvelin siirretään toimimaan omassa kontissaan seuraavan luvun ohjeiden avulla.

Docker-kontin rakentaminen distributed-chat ohjelmalle

Rakenna ensin kontti-image:

$ docker build .

Kun image on rakentunut onnistuneesti ('Successfully built'), listaa syntyneet imaget:

$ docker images
REPOSITORY    TAG           IMAGE ID        CREATED         SIZE
<none>        <none>        5db05b68abd9    17 seconds ago  409MB
openjdk       11.0.5-slim   c41356b393a7    2 weeks ago     401MB

Kopioi listasta uuden imagen id. Anna imagelle tagi seuraavasti:

$ docker image tag 5db05b68abd9 distributed-chat:1.0

Tarkista että imagella on oikea nimi ja tägi. (Kohdat REPOSITORY ja TAG)

$ docker images
REPOSITORY          TAG         IMAGE ID        CREATED         SIZE
distributed-chat    1.0         5db05b68abd9    3 minutes ago   409MB
openjdk             11.0.5-slim c41356b393a7    2 weeks ago     401MB

Tee seuraavaksi imagen distributed-chat:1.0 mukainen kontti ja listat luodut kontit:

$ docker container create distributed-chat:1.0
$ docker container ls -a
CONTAINER ID    IMAGE                   ...   NAMES
8b5a62568080    distributed-chat:1.0    ...   sharp_einstein

Käynnistä kontti ja tarkasta, että lokeista, että kontti on toiminnassa (container id tässä 8b5a62568080):

$ docker container start <container id>
$ docker container logs <container id>
Starting the chat server..
Listening to port 59059 at 0.0.0.0/0.0.0.0
Shut down with ctrl-c or kill the process.

Seuraavaksi listataan dockerin verkot:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
1d61b4c9e8e9        bridge              bridge              local
3947e4c7cf11        host                host                local
f74a6e79ff90        none                null                local

Listaa bridge-verkosta tarkemmat tiedot seuraavasti:

$ docker network inspect 1d61b4c9e8e9
[
    {
        "Name": "bridge",
        "Id": "1d61b4c9e8e9b714d2d37d715d9a80337d85643880fc6af...",
        "Created": "2019-11-05T18:44:25.359992616+02:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "8b5a6256808081d657d51f2ffb207174bbccb2...": {
                "Name": "sharp_einstein",
                "EndpointID": "bb3e1299413a86f2b092dd63fdc03...",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

Listasta löydät kontin nimen perusteella (tässä tapauksessa sharp_einstein) sen käyttämän ip-osoitteen (IPv4Address). Komennolla mvn exec:java -Dexec.args="-host <kontin ip-osoite> voit käynnistää chat-asiakasohjelman.

Docker muodostaa konttien ja isäntäkoneen välille virtuaalisen verkon. Aiheesta kiinnostuneille löytyy kattava selvitys Dockerin käyttämistä erilaisista verkkotekniikoista osoittesta https://docs.docker.com/network/

Spawn-container

Virtuaalikoneessa on valmiina Dockerin lisäksi spawn-container, joka on Turun yliopiston kehittämä pieni ajonaikainen avustin Red Hatin kehittämän systemd-nspawn -järjestelmän käyttämiseksi. Spawn-kontit ovat Docker-kontteja kevyempiä, sillä niissä pohjana käytetään virtualisointialustan omaa levykuvaa. Järjestelmässä on vastaavalla tavalla image- ja container-käsitteet. Kuitenkin kontit eivät muodosta monitasoista sipulimaista rakennelmaa, vaan niiden pohjalla on aina virtualisointiympäristön levykuva, sitten sovelluskohtainen kerros ja päällä RAM-muistiin väliaikaisesti tallentuva tilapäinen kerros. Eli kontteihin ei käytön myötä tallennu mitään vaan joka käynnistys aloittaa tyhjästä. Kontteihin voi liittää mukaan ulkopuolisia liitospisteitä, mikäli halutaan säilyttää pysyvämmin dataa. Tämä edistynyt käyttö sivuutetaan tässä.

Seuraavassa esitetään Javalla toteutetun distributed-chat -palvelimen imagen tekeminen ja käyttö. Image-tiedosto käsittää siis valmiiksi rakennetun palvelinsovelluksen, mutta ei sen lopullista konfiguraatiota. Aloita siirtymällä kansioon johon distributed-chat on kloonattu. Paketoi ohjelma Mavenilla antamalla komento mvn package.

utu@utuVM:~/git/distributed-chat$ mvn package
...
...
[INFO] --- maven-source-plugin:3.1.0:jar (attach-sources) @ distributed-chat ---
[INFO] Building jar: /home/utu/git/distributed-chat/target/distributed-chat-1.0-sources.jar
[INFO] -----------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -----------------------------------------------------------------
[INFO] Total time:  4.074 s
[INFO] Finished at: 2019-12-17T13:29:50+02:00
[INFO] -----------------------------------------------------------------
utu@utuVM:~/git/distributed-chat$ 

Imaget ja kontit tallentuvat järjestelmän hakemistoon /var/local/utu/. Seuraavaksi rakennetaan image komennolla spawn-container build.

utu@utuVM:~/git/distributed-chat$ spawn-container build
Preparing to build the image from 'Spawnfile'..
Preparing to build the base image 'utuvm'..
Building image 'utuvm'..
...
...
Image 'distributed_chat' successfully built.

= distributed_chat-1.0 (Simple chat application for testing TCP socket connections)
   - base image: utuvm

Rakentamisen jälkeen image valmistellaan komennolla spawn-container --param CHATPORT=12345 --bridge br0 spawn distributed\_chat default. Tämän jälkeen viimeistellään kontin tekeminen komennolla spawn-container enable distributed\_chat default.

utu@utuVM:~/git/distributed-chat$ spawn-container --param CHATPORT=12345 --bridge br0 spawn distributed_chat default
Preparing to build the container for 'distributed_chat/default'..
 - distributed_chat/default:   -n --network-bridge=br0 
Built the container 'distributed_chat/default'.
utu@utuVM:~/git/distributed-chat$spawn-container enable distributed_chat default
Created symlink /etc/systemd/system/machines.target.wants/spawn-container@distributed_chat-default.service -> /etc/systemd/system/spawn-container@.service.
To start the service now, type:
sudo systemctl start spawn-container@distributed_chat-default.service

Nyt kontin voi käynnistää komennolla sudo systemctl start spawn-container@distributed\_chat-default.service ja komennolla sudo systemctl status spawn-container@distributed\_chat-default.service voit varmistaa, että kontti on ladattu ja aktiivinen.

utu@utuVM:~/git/distributed-chat$ sudo systemctl start spawn-container@distributed_chat-default.service
utu@utuVM:~/git/distributed-chat$ sudo systemctl status spawn-container@distributed_chat-default.service
* spawn-container@distributed_chat-default.service - Container distributed_chat/default
   Loaded: loaded (/etc/systemd/system/spawn-container@.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-12-17 13:07:34 EET; 10s ago
 Main PID: 4239 (systemd-nspawn)
    Tasks: 1 (limit: 2363)
   Memory: 2.6M
   CGroup: /machine.slice/spawn-container@distributed_chat-default.service
           |-4239 systemd-nspawn -D /tmp/tmp.N1Vy9QkgIh --register=yes -b -M distributed-chat-1576580854 -n --network

Dec 17 13:07:34 utuVM systemd[1]: Started Container distributed_chat/default.
Dec 17 13:07:34 utuVM spawn-container[4239]: CHATPORT=12345
Dec 17 13:07:34 utuVM spawn-container[4239]: Host and machine ids are equal (3423248286e34c7fb72ca87e3ffe763f): refus
Dec 17 13:07:34 utuVM spawn-container[4239]: systemd 241 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR
Dec 17 13:07:34 utuVM spawn-container[4239]: Detected virtualization systemd-nspawn.
Dec 17 13:07:34 utuVM spawn-container[4239]: Detected architecture x86-64.
Dec 17 13:07:34 utuVM spawn-container[4239]: Set hostname to <utuVM>.
Dec 17 13:07:40 utuVM spawn-container[4239]: [2B blob data]
Dec 17 13:07:40 utuVM spawn-container[4239]: Debian GNU/Linux 10 utuVM console
Dec 17 13:07:40 utuVM spawn-container[4239]: [1B blob data]

Komennolla spawn-container images listataan jo asennetut imaget. Komento spawn-container containers listaa kontit ja viimeiseksi komennolla spawn-container machines näet käynnissä olevat koneet ja niihin liitetyt ip-osoitteet.

utu@utuVM:~/git/distributed-chat$ spawn-container images
= distributed_chat-1.0 (Simple chat application for testing TCP socket connections)
   - base image: utuvm
   - 8432 kB, created 1576576052
   - checksum ok: ff14fd329d1990dc9ed7ca25818350ead985b506

= utuvm-420 (UTU-FT dev tools base squashfs OS image)
   - 1060 kB, created 1576576045
   - checksum ok: a0220abb1984a6e22c56d39bb44f85d9a6f993d5
utu@utuVM:~/git/distributed-chat$ spawn-container containers
 - distributed_chat/default:   -n --network-bridge=br0 
utu@utuVM:~/git/distributed-chat$ spawn-container machines
MACHINE                     CLASS     SERVICE        OS     VERSION ADDRESSES    
distributed-chat-1576580854 container systemd-nspawn debian 10      10.10.10.142...

1 machines listed.

Kun kontti on käynnissä, voit käynnistää chat-asiakasohjelman asiakkaan komennolla mvn exec:java -Dexec.args="-host <kontin ip-osoite>.

Chatticlientti toiminnassa