Docker – polecenia

Uruchomienie nowego kontenera

# docker run <nazwaKontenera>

$ docker run ubuntu

Uruchomienie kontenera w trybie interaktywnym z shellem

$ docker run -it ubuntu bash
root@a52191c360d2:/#

Wyświetlanie wszystkich kontenerów

$ docker container -a # opcja -a pokaże również kontenery nie uruchomione
lub
$ docker ps -a

Uruchomienie wyłączonego kontenera

# docker start <CONTAINER ID> | <NAMES>

$ docker ps -a
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS                      PORTS     NAMES
a52191c360d2   ubuntu                 "bash"                   9 minutes ago    Exited (0) 9 minutes ago              magical_shtern

$ docker start a52191c360d2
lub   
$ docker start magical_shtern

Zatrzymanie kontenera pracującego w tle

# docker stop <CONTAINER ID> | <NAMES>

$ docker stop a52191c360d2

Kopiowanie plików między kontenerem a lokalnym systemem plików

# docker cp <[NAZWA KONTENERA | CONTAINER ID]>:<SCIEZKA DO PLIKU W KONTENERZE> <LOKALNA SCIEZKA DO PLIKU>
lub
# docker cp <LOKALNA SCIEZKA DO PLIKU> <[NAZWA KONTENERA | CONTAINER ID]>:<SCIEZKA DO PLIKU W KONTENERZE> 

Wyświetlenie listy obrazów

$ docker image ls
REPOSITORY                           TAG       IMAGE ID       CREATED          SIZE
ubuntu                               latest    daab1c66d467   6 days ago       65.6MB

Tworzenie nowego obrazu na podstawie kontenera

# docker commit <CONTAINER ID> <NAZWA_NOWEGO_OBRAZU>

$ docker commit a52191c360d2 nowy_obraz
sha256:534f2be1cee938f127815d93323d07e02ecd8f723c4df052ed8241ecb7922511
$ docker image ls
REPOSITORY                           TAG       IMAGE ID       CREATED          SIZE
nowy_obraz                           latest    534f2be1cee9   14 seconds ago   65.6MB
ubuntu                               latest    daab1c66d467   6 days ago       65.6MB

Podgląd historii warstw w obrazie

# docker history <NAZWA OBRAZU>

$ docker history nowy_obraz

Pobranie obrazu z docker hub. Polecenie docker run <nazwa obrazu> pobiera obraz jeżeli go nie posiadamy i uruchamia kontener. Możemy pobrać obraz bez uruchamiania kontenera.

# docker push <NAZWA OBRAZU>

$ docker run alpine

Zmiana nazwy obrazu. Źródłowy obraz nie zostanie usunięty.

# docker tag <NAZWA OBRAZU> <NAZWA KONTA DOCKER>/<NOWA NAZWA OBRAZU>

Wysyłanie obrazu do docker hub. Aby to zrobić musimy posiadać na docker hub konto i się do niego zalogować. Nazwa obrazu musi być podana w formacie <NAZWA KONTA DOCKER>/<NOWA NAZWA OBRAZU>

# docker login
# docker push <NAZWA KONTA DOCKER>/<NOWA NAZWA OBRAZU>

Docker – Dockerfile

Dockerfile to plik, który pomaga utworzyć własne obrazy Dockerowe.

Dla każdego polecenia z Dockerfile jest uruchamiany nowy kontener i zapisywana nowa warstwa obrazu.

$ mcedit Dockerfile
FROM ubuntu # bazowy obraz
COPY plik.txt . # skopiuje plik do kontenera
RUN apt-get -y update && apt-get -y install nano # zainstaluje w kontenerze edytor nano

Budowanie obrazu na podstawie Dockerfile.

# docker build [--tag name:tag] <ścieżka do kontekstu> 

$ docker build --tag moj_ubuntu:1.0 . 
$ docker image ls
REPOSITORY                           TAG       IMAGE ID       CREATED              SIZE
moj_ubuntu                           1.0       de40b0f082a5   0 days ago           93.4MB

$ docker run de40b0f082a5 cat plik.txt # uruchomi nasz nowy obraz i wyświetli zawartość skopiowanego pliku plik.txt 

Ścieżka do kontekstu to folder w którym mogą się znajdować pliki, które w procesie budowy obrazu zostaną wysłane do demona Dockera. W kontekście powinny znajdować się tylko niezbędne elementy do budowy, aby nie wydłużać procesu przesyłania ich demona.

Plik Dockerfile domyślnie jest wyszukiwany w folderze kontekstu. Możemy podać inną lokalizację pliku za pomocą parametru -f.

Docker – Wolumeny i mapowanie katalogów

Przechowywanie danych w kontenerze nie jest zbyt wygodne, gdy usuniemy kontener (docker rm <id_kontenera>), zapisane dane zostaną skasowane. Aby przechowywać dane aplikacji możemy stworzyć wolumen lub mapować katalog z hosta do kontenera.

Wolumeny

# docker volume create <nazwa_wolumenu>
$ docker volume create ubuntu_data
ubuntu_data
$ docker volume ls
DRIVER    VOLUME NAME
local     ubuntu_data

Usuwanie wolumenu

$ docker volume rm ubuntu_data
ubuntu_data

Podłączenie wolumenu do kontenera.

docker run --volume <nazwa_wolumenu>:<katalog_wewnątrz_kontenera> <nazwa_obrazu> 

Podpinamy wolumen 'ubuntu_data’ do katalogu 'data’ wewnątrz kontenera. Wszystkie dane zapisane wewnątrz kontenera do katalogu 'data’, zostaną zapisane w wolumenie 'ubuntu_data’. Jeżeli wolumen nie będzie istniał zostanie utworzony przy starcie kontenera.

$ docker run --volume ubuntu_data:/data ubuntu

Mapowanie katalogu

Mapujemy katalog z hosta do kontenera

# docker run --volume <sciezka_bezwzgledna_katalogu>:<katalog_wewnątrz_kontenera> <nazwa_obrazu>
$ docker run --volume /home/user/docker:/data ubuntu

Mapujemy katalog '/home/user/docker’ do katalogu 'data’ wewnątrz kontenera. Wszystkie dane zapisane wewnątrz kontenera do katalogu 'data’, zostaną zapisane do katalogu ’ /home/user/docker’ na hoscie.

Klaster Kubernetes na Raspberry PI

Instalacja oparta jest o co najmniej dwa Raspberry PI 4, min. 4G RAM z zainstalowanym obrazem Ubuntu 20.04

Większość ustawień musi być wykonywane na każdym urządzeniu, które stworzą klaster.

Każde Raspberry powinno posiadać statyczny adres lub przydzielony na stałe DHCP.

Ustawienie nazwy na kontrolerze

$ sudo nano /etc/hostname
k8s-controller1

$ sudo nano /etc/hosts 
192.168.XX.XX k8s-controller1.jakas-domena.com.pl k8s-controller1 # nazwa domeny nie jest wymagana

$ sudo reboot

Zmiana nazwy na pozostałych PI które będą pracowały jako węzły (nody)

$ sudo nano /etc/hostname
k8s-node-01

$ sudo nano /etc/hosts 
192.168.XX.XX k8s-node-01.jakas-domena.com.pl k8s-node-01 # nazwa domeny nie jest wymagana

$ sudo reboot

Dodajemy nowe opcje bootowania na końcu linii w pliku

$ sudo nano  /boot/firmware/cmdline.txt
cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 swapaccount=1

Aktualizacja pakietów

$ sudo apt update && sudo apt dist-upgrade -y
$ sudo reboot

Dla wygody możemy dodać swojego użytkownika na którym będziemy pracować

$ sudo adduser mojaNazwaUzytkownika
# Dodajemy go do grupy sudo
$ sudo usermod -aG sudo mojaNazwaUzytkownika

Instalacja Dockera i dodanie własnego utworzonego użytkownika do grupy docker

$ curl -sSL get.docker.com | sh
$ sudo usermod -aG docker mojaNazwaUzytkownika

Dodając do pliku opcje konfigurujemy demona Docker.

$ sudo nano /etc/docker/daemon.json

{
   "exec-opts": ["native.cgroupdriver=systemd"],
   "log-driver": "json-file",
   "log-opts": {
     "max-size": "100m"
   },
   "storage-driver": "overlay2"
 }

Włączamy routing odkomentowując linijkę #net.ipv4.ip_forward=1 w pliku /etc/sysctl.conf

$ sudo nano /etc/sysctl.conf
$ sudo reboot

Sprawdzamy czy Docker działa prawidłowo

$  sudo systemctl status docker
...
 Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2021-10-23 17:24:11 UTC; 59s ago
TriggeredBy: ● docker.socket
...

$ docker run hello-world
...
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
Hello from Docker!
This message shows that your installation appears to be working correctly.
...

Dodajemy repozytoria Kubernetes i dodajemy klucz GPG

 $ sudo nano /etc/apt/sources.list.d/kubernetes.list

deb http://apt.kubernetes.io/ kubernetes-xenial main

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
OK

Instalacja Kubernetes

$ sudo apt update
 && sudo apt install kubeadm kubectl kubelet -y

Podczas instalacji czasem zdarzają się błędy. Gdy tak się zdarza powtarzamy ostatnie polecenie.

Teraz możemy zainicjalizować klaster wykonując poniższe na kontrolerze

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

Po uruchomieniu, na końcu otrzymasz dane wyjściowe, które będą zawierać polecenie kubeadm join wraz z tokenem. Zapisz je gdzieś. Będzie potrzebne przy dołączaniu węzłów. Jeżeli nasz token gdzieś się zagubi możemy go odzyskać wukonując na kontrolerze polecenie

kubeadm token create --print-join-command

Nadal tylko na kontrolerze uruchamiamy polecenia

$ mkdir -p ~.kube 
$ sudo cp /etc/kubernetes/admin.conf ~/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

Instalujemy sterowniki sieci na kontrolerze

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

po instalacji sterowników czekamy, czy wszystkie pody zostały uruchomione

$ kubectl get pods --all-namespaces

Wszystkie powinny mieć status Running. W przeciwnym wypadku czekamy chwile i powtarzamy powyższy test.

Możemy dołączać węzły robocze. Na każdym PI, który będzie pełnił taką funkcję uruchamiamy polecenie kubeadm join, które zapisaliśmy w czasie inicjalizacji klastra.

$ sudo kubeadm join 192.168.XX.XX:6443 --token xxxxxxx --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Sprawdzamy na kontrolerze czy nasze węzły robocze się dołączyły

$ kubectl get nodes
NAME              STATUS   ROLES                  AGE    VERSION
k8s-controller1   Ready    control-plane,master   65d    v1.22.1
k8s-node-01       Ready    <none>                 65d    v1.22.1
k8s-node-02       Ready    <none>                 2m1s   v1.22.2

Podłączanie dysku do VM w trybie przechodzącym przez Proxmox – Passthrough

W konsoli Proxmoxa musimy zidentyfikować dysk który chcemy dołączyć w trybie Passthrough do VM.

$ find /dev/disk/by-id/ -type l|xargs -I{} ls -l {}|grep -v -E '[0-9]$' |sort -k11|cut -d' ' -f9,10,11,12

/dev/disk/by-id/ata-WDC_WDS500G2B0A-00SM50_21060M809484 -> ../../sda
/dev/disk/by-id/wwn-0x5001b448be044ab2 -> ../../sda
/dev/disk/by-id/ata-WDC_WD5000AZRX-00A8LB0_WD-WMC1U6335427 -> ../../sdb
/dev/disk/by-id/wwn-0x50014ee602c28429 -> ../../sdb
/dev/disk/by-id/ata-WDC_WD5000AUDX-73H9TY0_WD-WCC4J0287754 -> ../../sdc
/dev/disk/by-id/wwn-0x50014ee25e260065 -> ../../sdc
/dev/disk/by-id/ata-WDC_WD5000AAKX-001CA0_WD-WCAYU9578736 -> ../../sdd
/dev/disk/by-id/wwn-0x50014ee10389e0a4 -> ../../sdd

Teraz wybieramy dyski z listy aby je dodać do konfiguracji naszej maszyny vm, wskazując id maszyny, kontroler oraz id dysku. Dla każdego dysku wybieramy nowy kontroler, który w tej vm nie używamy np: scsi2, scsi3 …..

$ qm set  111  -scsi2 /dev/disk/by-id/ata-WDC_WDS500G2B0A-00SM50_21060M809484
update VM 592: -scsi2 /dev/disk/by-id/ata-WDC_WDS500G2B0A-00SM50_21060M809484

$ qm set  111  -scsi3 /dev/disk/by-id/ata-WDC_WD5000AZRX-00A8LB0_WD-WMC1U6335427
update VM 592: -scsi3 /dev/disk/by-id/ata-WDC_WD5000AZRX-00A8LB0_WD-WMC1U6335427

$ qm set  111  -scsi4 /dev/disk/by-id/ata-WDC_WD5000AUDX-73H9TY0_WD-WCC4J0287754
update VM 592: -scsi4 /dev/disk/by-id/ata-WDC_WD5000AUDX-73H9TY0_WD-WCC4J0287754

Na podstawie: https://pve.proxmox.com/wiki/Passthrough_Physical_Disk_to_Virtual_Machine_(VM)

TrueNas – Identyfikacja i wymiana uszkodzonego dysku

Sprawdzamy w panelu TrueNas w statusie dysków który dysk mamy uszkodzony.

Następnie sprawdzamy jego numer seryjny.

$ smartctl -i /dev/sdd

=== START OF INFORMATION SECTION ===
Model Family:     Western Digital Blue
Device Model:     WDC WD5000AAKX-001CA0
Serial Number:    WD-WCAYU9578736
LU WWN Device Id: 5 0014ee 10389e0a4
Firmware Version: 15.01H15
User Capacity:    500,107,862,016 bytes [500 GB]
Sector Size:      512 bytes logical/physical
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ATA8-ACS (minor revision not indicated)
SATA Version is:  SATA 3.0, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Sat Oct 23 14:13:37 2021 CEST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

W wynikach szukamy „Serial Number”. Teraz możemy zidentyfikować dysk sprawdzając jego numer seryjny na obudowie dysku. Jeżeli chcemy i mamy możliwość wymiany dysku nie wyłączając serwera, dobrze by było w trakcje instalacji dysków, zapisać sobie jakie numery seryjne mamy w kieszeniach zainstalowane.

Po wymianie dysku w panelu zarządzania TrueNas w statusie dysków, na pozycji z wymienionym dyskiem wybieramy z menu opcję REPLACE, i w okienku wskazujemy wymieniony dysk zaznaczając FORCE.

Proxmox – Przenoszenie maszyny wirtualnej na inny serwer

Aby przenieś VM na inny serwer Proxmox musimy zrobić kopie VM.

  1. W panelu zarządzania wskazujemy maszynę do przeniesienia i wybieramy Backup, następnie przycisk Backup now. Domyślnie backup wykona się na zasobie dyskowym local.
  2. Za pomocą scp lub ftp przenosimy backup z katalogu /var/lib/vz/dump serwera źródłowego na docelowy.
  3. Na serwerze docelowym wskazujemy Backup który powinien być na zasobie dyskowym local
  4. Wybieramy plik kopi zapasowej który tam przegraliśmy, następnie przycisk Restore.

Fortigate – Zmiana adresu ip w konsoli

Konfiguracja IP statycznego

config system interface
  edit port1
    set mode static
    set ip 192.168.0.100 255.255.255.0
  next
end

Konfiguracja bramy domyślnej

config router static
  edit 1
    set device port1
    set gateway <class_ip>
  next
end

Konfiguracja IP – DHCP

config system interface
  edit port1
    set mode dhcp
  next
end

Tutel przez ssh

Aby ustawić tunel ssh do zdalnego portu lokalnego na Linuxie lub Windowsie w konsoli zestawiamy połączenie ssh poleceniem:

# ssh -L <port>:<host>:<hostport> -N -f <user@host_lub_ip> [-i <sciezka_do_klucza_prywatnego>]

Np. zostanie zestawione połączenie z adresem X.X.X.X i powiązany port 5901 z portem 5600 na naszej maszynie z której zestawiamy tunel

$ ssh -L 5600:localhost:5901 -N -f user@X.X.X.X -i e:\keys\user.pem

W Windowsie uprawnienia do klucza prywatnego powinien posiadać tylko właściciel, można to ustawić za pomocą gui lub terminala

$ icacls .\user.pem /inheritance:r
$ icacls .\user.pem /grant:r "%username%":"(R)"