Uke 10 - Hyperthreading og Docker

Oppgaver til mandag 3. - fredag 7. mars

I første del denne uken er det fokus på multitasking og hyperthreading. Deretter blir det kjøring av docker-containere på Linux-VMene.

Oppgavene denne uken som er merket med (Oblig), utgjør de siste oppgavene i obligatorisk innlevering nummer 2. Oblig 2 består av alle oppgaver merket (Oblig) fra og med uke 7 til og med uke 10 og har innleveringsfrist fredag 14. mars.

  1. (Oblig) På forelesning ble output fra et par kommandoer brukt til å vise at kjernene på desktop'en rex var hyperthreading og til å vise hvilke to CPU'er mellom 0 og 7 (OS sin nummerering) som var thread-siblings, dvs deler ALU. Gjør det samme på Linux-VM. Er det thread-siblings på Linux-VM?
  2. (Oblig) Kopier det RAM-intensive programmet mem.c demonstrert på forelesning
    #include <stdio.h> 
    
    int array[102400];
    
    void main(){
       int i,k;
       for(k=0;k<2000000;k++)
         {
    	for(i = 0;i < 1024;i++){
    	   array[i] = i;
    	}
         }
    }
    
    til Linux-VM, kompiler det med gcc og kjør det og ta samtidig tiden på det med time. Definer først i shellet variabelen
    TIMEFORMAT="Real:%R User:%U System:%S %P%%"
    
    for å få en ryddigere utskrift av tidsbruken. Legg gjerne denne linjen inn i .bashrc, slik at du ikke trenger å definere den på nytt hver gang du bruker time. Bruk taskset til å sørge for at to kjøringer av mem.c begge kjører på CPU nr 0. Hvor lang tid tar det før begge disse er fullført sammenlignet med om du kjører dem slik at OS bestemmer hvilken CPU de bruker? Hvordan kan det forklares?
  3. (Oblig) Ta utgangspunkt i scriptet regn som ble brukt i forelesningen til å finne ut om CPUene på desktopen rex bruker hyperthreading.
    #! /bin/bash
    
    (( max = 3000000 ))
    (( i = 0  ))
    (( sum = 0  ))
    
    while (($i < $max))
    do
            (( i += 1 ))
    	(( sum += i  ))
    done
    #echo $0, resultat: $sum
      
    Sørg først for at du kan kjøre dette og ta tiden på det som i de forrige oppgavene. På forelesningen ble kjøring og tidtaging av flere instanser av dette programmet til å avgjøre om Linux-VM har hyperthreading cores, på desktopen rex, der konklusjonen ble at det var fire hyperthreading kjerner (cores), som OS betraktet som totalt 8 CPUer. Men denne metoden er det vanskelig å bruke på Linux-VM fordi man der kun får tilgang til 2 CPUer av serverens 48 cores. Din VM er egentlig en docker-container som er startet med docker container run --cpus="2" slik at den bare får det som tilsvarer 2 CPU-er med CPU-tid. I oppgave 1 denne uken, fant du ut hvilke CPUer som er siblings. Prøv å finne ut av effekten av hyperthreading for CPUene på Linux-VM ved å samtidig kjøre regn-scriptet ved hjelp av taskset på to CPU-siblings og på to CPUer som ikke er siblings og ta tiden på dem. Utgjør dette noen forskjell utifra tiden det tar? Hva kan du konkludere utifra dette?
  4. Gjør tilsvarende forsøk med mem.c og følgende CPU-intensive C-program etter å ha kompilert dem med gcc -O:
    #include <stdio.h>
    
    int main()
    {
       float sum = 10;
       int i,j;
       for (j = 1; j < 5;j++)
       for (i = 1; i < 450000000;i++)
         {
    	sum = sum/(1.0*i);
         }
       printf("SUm: %2.6f",sum);
    }
    
    Ser du noen forskjeller i effekten av hyperthreading?
  5. (Oblig)

    I 2023 økte OsloMet sikkerheten i våre nettverk ytteligere og tillater nå kun trafikk på port 22 (ssh), 80 (http) og 443 (https) også internt innenfor VPN-nettverket. Det betyr at du ikke vil kunne kontakte webservere på porter som 8080 og 8081 fra for eksempel en browser på en laptop inne på OsloMet. I eksemplene i forelesningene brukes disse portene, men det var før disse portene generelt ble stoppet i brannmuren. Men om du følger disse eksemplene, kan du sjekke at du har fått satt opp webserveren riktig ved å bruke curl inne på din VM, med noe slikt som $ curl localhost:8081 og sjekke at webserveren gir en webside i retur. Hvis OsloMet i dette tilfellet ikke hadde stoppet trafikk på port 8081, ville du kunne sett dette fra en browser. Men hvis du starter en docker webserver med -p 80:80, vil du kunne se den i en browser, siden denne porten er åpen. I eksemplene under bruker vi noen ganger port 443 for http-trafikk. Det går helt fint selvom denne porten er tenkt brukt til https.

    Følgende er en video med gjennomgang av litt av det man skal få til i de følgende Docker-oppgavene. Se den hvis du ikke får til oppgavene under.

    På Linux-VMene er docker installert, men man må starte docker-tjenesten. Det må man være root for å gjøre og det kan gjøres med
    root@os100:~# service docker start
     * Starting Docker: docker                                                                                                                                                                                    [ OK ] 
    root@os100:~# 
    
    Test deretter at docker virker ved å som root kjøre kommandoen
    root@os100:~# docker container run hello-world
      
    som blant annet gir output Hello from Docker! Alle docker-oppgaver må gjøres som root. Når dette fungerer, kan du begynne på oppgavene som ligger på web-siden
    https://github.com/praqma-training/docker-exercises/tree/master/labs
    
    Målet denne uken er å komme igjennom assignment 1-5.

    NB! I avsnitt 03-delition, "Throw your container away", blir du bedt om å utføre rm -rf inne i en container. Pass på å ikke gjøre denne kommandoen inne på VMen, da vil denne VMen bli ubrukelig til man får lagt inn en ny bin-mappe eller bygd den på nytt.

    En fin måte å komme igjennom alle assignmentene er å gå igjennom Mike Longs slides fra 2018 og hver gang det kommer en slide med "Your turn", klikke deg inn på neste assignment og gjøre den (men du må legge til en 0 foran nummeret på oppgaven, 01 istedet for 1). Slidene ligger under filer i Canvas og heter Docker Kickstart.

    I oppgave 4-port-forward.md, vil du ikke få opp nginx-websiden med noe tilsvarende

    http://os100.vlab.cs.oslomet.no:8080
      
    Sjekk istedet at det virker med $ curl localhost:8080 . Alternativt kan du bytte ut 8080 med 443 og da vil du også kunne se websiden i en browser med
    http://os100.vlab.cs.oslomet.no:443
      

  6. (Oblig) Start et ubuntu-container og inkluder -p 443:80, slik at man kan koble til en webserver på port 443 på Linux-VM. Gå inn i containeren på kommandolinjen og installer apache2 webserver og få den til å kjøre. Prøv også å få webserveren til å starte og å endre innholdet på webserveren fra kommandolinjen på Linux-VM. Du skal nå kunne se webserveren på
    http://os100.vlab.cs.oslomet.no:443/
      
    hvor du må bytte ut os100 med din Linux-VM. Sjekk først at det virker med $ curl localhost:443 inne på VMen. Når du har fått installert apache2 og fått den til å kjøre, gå ut av containeren med CTRL-p CTRL-q (da fortsetter den å kjøre i bakgrunnen) og list kjørende containere med
    # docker container ps -a
      
    Da vil du for containeren du har installert apache i, få opp en linje som ser ut omtrent slik:
    3376df05f434 ubuntu "/bin/bash" 3 minutes ago Up 3 minutes  0.0.0.0:443->80/tcp   elegant_almeida
    
    Lag så en kopi av denne containeren med
     docker container commit 3376df05f434 apacheubuntu
    
    eventuelt ved å bruke docker export og import. Etter å ha gjort dette, kan du starte opp en ny container med apache installert ved
    # docker container run -it -d -p 80:80 apacheubuntu /bin/bash
    
    NB! Hvis du allerede har en apache2-server kjørende på VMen må du stoppe den først, ellers får du ikke lov å kjøre containeren siden port 80 allerede er i bruk. Deretter kan du starte apache i denne containeren ved å gjøre
    docker container exec IDTILNYCONTAINER /bin/bash -c "/etc/init.d/apache2 start"
    
    hvor IDTILNYCONTAINER er id til den nye containeren du nettopp startet (returneres av kommandoen du startet med, kan også sees med # docker container ps -a). Endre så /var/www/html/index.html på begge docker-instansene slik at du kan se hvem som er hvem når du åpner webserverene i en browser. Denne ene skal da sees på port 80 og den andre på port 443.
  7. Ukens utfordring! Skriv et bash-script som starter opp 9 containere med apache web-server på portnummer 8081, 8081, 8083, ..., 8089 og som har en tekst på web-siden som viser hvilken webserver det er (ligger i /var/www/html/index.html for apache). Legg merke til at docker-kommandoen returnerer docker-IDen når containeren starter.
  8. (Oblig) Anta at du på en Ubuntu 22.04 server starter 10 docker-instanser som hver kjører en Apache webserver. Med tanke på bruk av RAM og disk, hva er den vesentligste forskjellen på dette og om du istedet startet opp 10 virtuelle maskiner med Ubuntu 22.04 som kjørte hver sin Apache webserver?
  9. (Oblig) Dette er ukens konkurranse-oppgave. Noe som kan være nyttig for å løse denne oppgaven, er å bruke opsjonen -o PasswordAuthentication=no til ssh for å unngå å bli spurt om passord når man prøver å logge inn med ssh. Det kan også være nyttig å legge til -o StrictHostKeyChecking=no for å slippe å svare ja på dette.

    Logg inn som tidligere med noe tilsvarende som følgende:

    $ ssh -p 5135 s135@intel3.vlab.cs.oslomet.no
    
    s135@intel3.vlab.cs.oslomet.no's password: 
    
    s135@os5135:~$ 
    

    I hjemme-mappen for s-brukeren din ligger det nå en privat ssh-key i en fil som heter id_rsa. Denne kan du bruke til logge inn på en av de 430 s-serverene som er opprettet på serveren intel1. Problemet er at det kun er en av de 430 du kommer inn på og at du ikke vet hvilken det er (det er en helt tifeldig sammenkobling). Du kan prøve om for eksempel s-server s200 er den rette på følgende måte:

    s135@os5135:~$ ssh -i id_rsa -p 5200 s200@intel1.vlab.cs.oslomet.no
    
    s200@intel1.vlab.cs.oslomet.no's password: 
    
    men hvis du ikke har gjettet riktig vil du bli spurt om passord. Derfor må du finne en systematisk måte å prøve ut alle muligheter. Og da kan hintene i begynnelsen av oppgaven være nyttige. Når du har funnet frem til rette s-server på intel1, ligger filen med koden i hjemme-mappen intel1-serveren. For å sjekke at du har funnet det rette ordet, skriv strengen med 10 tegn inn på siden os.php uke 10 og du får beskjed om du har skrevet riktig. I tilegg blir du da med på OS-konkurransen om å finne denne koden fortest mulig!