Krótki przegląd i konfiguracja Kata Containers

Krótki przegląd i konfiguracja Kata Containers
W tym artykule omówimy zasady działania Kata Containers, a także będzie część praktyczna z ich podłączeniem do Docker.

Na temat ogólnych problemów z Dockerem i możliwych rozwiązań już zostało napisane, dziś krótko opiszę implementację Kata Containers. Kata Containers to bezpieczne środowisko uruchomieniowe (runtime) kontenerów oparte na lekkich maszynach wirtualnych. Praca z nimi przebiega tak samo jak z innymi kontenerami, ale dodatkowo zapewniają one lepszą izolację z wykorzystaniem technologii wirtualizacji sprzętu. Projekt rozpoczął się w 2017 roku, wówczas społeczność o tej samej nazwie zakończyła integrację najlepszych pomysłów z Intel Clear Containers i Hyper.sh RunV, po czym kontynuowano pracę nad wsparciem różnych architektur, w tym AMD64, ARM, IBM p- i z-series. Dodatkowo wspierana jest praca w hipernadzorcach QEMU, Firecracker, a także istnieje integracja z containerd. Kod jest dostępny na GitHub na licencji MIT.

Główne możliwości

  • Praca z oddzielnym rdzeniem, co zapewnia izolację sieci, pamięci i operacji wejścia/wyjścia, istnieje możliwość przymusowego wykorzystania izolacji sprzętowej opartej na rozszerzeniach wirtualizacji
  • Wsparcie dla standardów przemysłowych, w tym OCI (format kontenerów), Kubernetes CRI
  • Stabilna wydajność zwykłych kontenerów Linux, zwiększona izolacja bez narzutów wpływających na wydajność zwykłych maszyn wirtualnych
  • Usunięcie potrzeby uruchamiania kontenerów wewnątrz pełnoprawnych maszyn wirtualnych, standardowe interfejsy ułatwiają integrację i uruchamianie

Instalacja

Tak wiele wariantów instalacji, omówię instalację z repozytoriów na bazie systemu operacyjnego CentOS 7.
Ważne: praca Kata Containers jest wspierana tylko na sprzęcie, przekazywanie wirtualizacji nie zawsze działa, wymagana jest także obsługa sse4.1 ze strony procesora.

Instalacja Kata Containers jest dość prosta:

Instalujemy narzędzia do pracy z repozytoriami:

# yum -y install yum-utils

Wyłączamy Selinux (najlepiej go skonfigurować, ale dla uproszczenia wyłączam go):

# setenforce 0
# sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

Podłączamy repozytorium i przeprowadzamy instalację

# source /etc/os-release
# ARCH=$(arch)
# BRANCH="${BRANCH:-stable-1.10}"
# yum-config-manager --add-repo "http://download.opensuse.org/repositories/home:/katacontainers:/releases:/${ARCH}:/${BRANCH}/CentOS_${VERSION_ID}/home:katacontainers:releases:${ARCH}:${BRANCH}.repo"
# yum -y install kata-runtime kata-proxy kata-shim

Konfiguracja

Będę przeprowadzał konfigurację do pracy z dockerem, jego instalacja jest standardowa, nie będę jej opisywał szczegółowo:

# rpm -qa | grep docker
docker-ce-cli-19.03.6-3.el7.x86_64
docker-ce-19.03.6-3.el7.x86_64
# docker -v
Docker version 19.03.6, build 369ce74a3c

Wprowadzamy poprawki w daemon.json:

# cat <<EOF > /etc/docker/daemon.json
{
  "default-runtime": "kata-runtime",
  "runtimes": {
    "kata-runtime": {
      "path": "/usr/bin/kata-runtime"
    }
  }
}
EOF

Restartujemy dockera:

# service docker restart

Sprawdzenie działania

Jeśli uruchomisz kontener przed ponownym uruchomieniem dockera, możesz zobaczyć, że uname zwraca wersję jądra uruchomioną na głównym systemie:

# docker run busybox uname -a
Linux 19efd7188d06 3.10.0-1062.12.1.el7.x86_64 #1 SMP Tue Feb 4 23:02:59 UTC 2020 x86_64 GNU/Linux

Po ponownym uruchomieniu — wersja jądra wygląda następująco:

# docker run busybox uname -a
Linux 9dd1f30fe9d4 4.19.86-5.container #1 SMP Sat Feb 22 01:53:14 UTC 2020 x86_64 GNU/Linux

Inne komendy!

# time docker run busybox mount
kataShared on / type 9p (rw,dirsync,nodev,relatime,mmap,access=client,trans=virtio)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,relatime,mode=755)
cgroup on /sys/fs/cgroup/systemd type cgroup (ro,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (ro,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer)
cgroup on /sys/fs/cgroup/pids type cgroup (ro,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k)
kataShared on /etc/resolv.conf type 9p (rw,dirsync,nodev,relatime,mmap,access=client,trans=virtio)
kataShared on /etc/hostname type 9p (rw,dirsync,nodev,relatime,mmap,access=client,trans=virtio)
kataShared on /etc/hosts type 9p (rw,dirsync,nodev,relatime,mmap,access=client,trans=virtio)
proc on /proc/bus type proc (ro,relatime)
proc on /proc/fs type proc (ro,relatime)
proc on /proc/irq type proc (ro,relatime)
proc on /proc/sys type proc (ro,relatime)
tmpfs on /proc/acpi type tmpfs (ro,relatime)
tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755)
tmpfs on /sys/firmware type tmpfs (ro,relatime)

real    0m2.381s
user    0m0.066s
sys 0m0.039s

# time docker run busybox free -m
              total        used        free      shared  buff/cache   available
Mem:           1993          30        1962           0           1        1946
Swap:             0           0           0

real    0m3.297s
user    0m0.086s
sys 0m0.050s

Szybkie testowanie obciążenia

Aby ocenić straty związane z wirtualizacją, uruchamiam sysbench, jako główne przykłady wybieram tę opcję.

Uruchamianie sysbench z użyciem Docker+containerd

Test procesora

sysbench 1.0: wielowątkowy benchmark oceny systemu

Uruchamianie testu z następującymi opcjami:
Liczba wątków: 1
Inicjalizacja generatora liczb losowych na podstawie bieżącego czasu

Limit liczb pierwszych: 20000

Inicjalizacja wątków roboczych...

Wątki uruchomione!

Ogólne statystyki:
    całkowity czas:                          36.7335s
    całkowita liczba zdarzeń:              10000
    całkowity czas wykonania zdarzeń: 36.7173s
    czas odpowiedzi:
         min:                                  3.43ms
         avg:                                  3.67ms
         max:                                  8.34ms
         około 95 percentyl:               3.79ms

Sprawiedliwość wątków:
    zdarzenia (avg/stddev):           10000.0000/0.00
    czas wykonania (avg/stddev):   36.7173/0.00

Test pamięci RAM

sysbench 1.0: wielowątkowy benchmark oceny systemu

Uruchamianie testu z następującymi opcjami:
Liczba wątków: 1
Inicjalizacja generatora liczb losowych na podstawie bieżącego czasu

Inicjalizacja wątków roboczych...

Wątki uruchomione!

Operacje wykonane: 104857600 (2172673.64 ops/sek)

102400.00 MiB przesłane (2121.75 MiB/sek)

Ogólne statystyki:
    całkowity czas:                          48.2620s
    całkowita liczba zdarzeń:              104857600
    całkowity czas wykonania zdarzeń: 17.4161s
    czas odpowiedzi:
         min:                                  0.00ms
         avg:                                  0.00ms
         max:                                  0.17ms
         około 95 percentyl:               0.00ms

Sprawiedliwość wątków:
    zdarzenia (avg/stddev):           104857600.0000/0.00
    czas wykonania (avg/stddev):   17.4161/0.00

Uruchamianie sysbench z użyciem Docker+Kata Containers

Test procesora

sysbench 1.0: wielowątkowy benchmark oceny systemu

Uruchamianie testu z następującymi opcjami:
Liczba wątków: 1
Inicjalizacja generatora liczb losowych na podstawie bieżącego czasu

Limit liczb pierwszych: 20000

Inicjalizacja wątków roboczych...

Wątki uruchomione!

Ogólne statystyki:
    całkowity czas:                          36.5747s
    całkowita liczba zdarzeń:              10000
    całkowity czas wykonania zdarzeń: 36.5594s
    czas odpowiedzi:
         min:                                  3.43ms
         avg:                                  3.66ms
         max:                                  4.93ms
         około 95 percentyl:               3.77ms

Sprawiedliwość wątków:
    zdarzenia (avg/stddev):           10000.0000/0.00
    czas wykonania (avg/stddev):   36.5594/0.00

Test pamięci RAM

sysbench 1.0: wielowątkowy systemowy benchmark oceny

Uruchomienie testu z następującymi opcjami:
Liczba wątków: 1
Inicjalizacja generatora liczb losowych z aktualnego czasu

Inicjalizacja wątków roboczych...

Wątki uruchomione!

Wykonane operacje: 104857600 (2450366.94 ops/sec)

102400.00 MiB przeniesione (2392.94 MiB/sec)

Ogólne statystyki:
    całkowity czas:                          42.7926s
    całkowita liczba zdarzeń:              104857600
    całkowity czas wykonania zdarzeń: 16.1512s
    czas reakcji:
         min:                                  0.00ms
         avg:                                  0.00ms
         max:                                  0.43ms
         przybliżony  95 percentyl:               0.00ms

Sprawiedliwość wątków:
    zdarzenia (avg/stddev):           104857600.0000/0.00
    czas wykonania (avg/stddev):    16.1512/0.00

W zasadzie sytuacja jest już jasna, ale optymalniej jest uruchamiać testy kilka razy, eliminując odchylenia i uśredniając wyniki, dlatego na razie nie wykonuję więcej testów.

Wnioski

Mimo że uruchamianie takich kontenerów zajmuje około pięć do dziesięciu razy więcej czasu (typowy czas uruchomienia analogicznych poleceń przy użyciu containerd to mniej niż jedna trzecia sekundy) — działają one nadal wystarczająco szybko, jeśli weźmiemy pod uwagę absolutny czas uruchomienia (powyżej są przykłady, polecenia wykonują się średnio w trzy sekundy). Wyniki szybkiego testu CPU i RAM pokazują faktycznie identyczne wyniki, co nie może nie cieszyć, zwłaszcza biorąc pod uwagę, że izolacja jest zapewniana dzięki tak dobrze sprawdzonemu mechanizmowi, jak kvm.

Ogłoszenie

Artykuł jest przeglądowy, ale daje możliwość przetestowania alternatywnego środowiska uruchomieniowego. Niektóre obszary zastosowania nie zostały omówione, na przykład na stronie opisano możliwość uruchamiania Kubernetes na Kata Containers. Dodatkowo można przeprowadzić szereg testów dotyczących bezpieczeństwa, ustanawiania ograniczeń i innych interesujących rzeczy.

Proszę wszystkich, którzy przeczytali lub przewinęli tutaj, o udział w ankiecie, od której będą zależeć przyszłe publikacje na ten temat.

Tylko zarejestrowani użytkownicy mogą brać udział w ankiecie. Zaloguj się, proszę.

Czy powinienem dalej publikować artykuły o Kata Containers?

  • 80,0%Tak, pisz jeszcze!28

  • 20,0%Nie, nie warto…7

Zagłosowało 35 użytkowników. Wstrzymało się 7 użytkowników.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster