Odczytywanie logów
$ show logging flash
# lub
$ show logging buffered level warnings
# lub w nowych wersjach
$ show info-center logfile 4
Odczytywanie logów
$ show logging flash
# lub
$ show logging buffered level warnings
# lub w nowych wersjach
$ show info-center logfile 4
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>
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.
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.
# 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
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.
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
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)
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.
Aby przenieś VM na inny serwer Proxmox musimy zrobić kopie VM.
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
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)"