Klaster OKD 4.19 (OpenShift) – Serwer GitLab pod Argo CD i OKD

Rola maszyny gitlab.okdlab.local w klastrze OKD OpenShift 4.19

Maszyna gitlab będzie pełniła rolę silnika bazo danowego dla aplikacji OpenShift na klastrze OKD 4.19.

LPNazwa DNSAdres ipvCPUvRAMvHDDSystem OperacyjnyFunkcja
1dns1.okdlab.local192.168.40.1022 GB16 GBFedora Server 43DNS dla klastra
2proxy.okdlab.local192.168.40.1522 GB16 GBFedora Server 43HAProxy / Load balancer / instalacja
3storage.okdlab.local192.168.40.2022 GB16/64/128 GBFedora Server 43Storage NFS dla klastra, registry OpenShift
4database-1.okdlab.local192.168.40.2524 GB32 GBFedora Server 43Serwer baz danych PostgreSQL
5database-2.okdlab.local192.168.40.2624 GB32 GBFedora Server 43Serwer baz danych MariaDB
6bastion.okdlab.local192.168.40.3044 GB128 GBFedora Server 43Instalacja i zarządzanie klastrem OKD
7gitlab.okdlab.local192.168.40.3548 GB128 GBFedora Server 43Gitlab
8jenkins.okdlab.local192.168.40.37816 GB256 GBFedora Server 43Jenkins
9bootstrap.testcluster.okdlab.local192.168.40.50416 GB128 GBCentosOS Stream 9Bootstrap node
10control-plane-1.testcluster.okdlab.local192.168.40.51416 GB128 GBCentosOS Stream 9Master node
11control-plane-2.testcluster.okdlab.local192.168.40.52416 GB128 GBCentosOS Stream 9Master node
12control-plane-3.testcluster.okdlab.local192.168.40.53416 GB128 GBCentosOS Stream 9Master node
13compute-1.testcluster.okdlab.local192.168.40.61416 GB256 GBCentosOS Stream 9Worker node
14compute-2.testcluster.okdlab.local192.168.40.62416 GB256 GBCentosOS Stream 9Worker node
15compute-3.testcluster.okdlab.local192.168.40.63416 GB256 GBCentosOS Stream 9Worker node

Serwer GitLab będzie oparty na systemie Debian 13 pobranym stąd https://ftp.icm.edu.pl/pub/Linux/debian-cd/13.3.0/amd64/iso-cd/debian-13.3.0-amd64-netinst.iso
Na potrzeby homelab i aplikacji OpenShift zdefiniowano parametry:

  • 128 GB vHDD
  • 4 x vCPU
  • 8 GB vRAM

W oknie instalatora podajemy parametry:

time & date Europe/Warsaw

ipv4 192.168.40.35/24 , brama 192.168.40.1 , dns: 192.168.40.10 , search domains: okdlab.local

włączamy konto roota

wybieramy minimalny zestaw narzędzi SSH Server oraz standard system utilities

installation destination domyślnie

Aktualizacja systemu i instalacja podstawowych narzędzi

sudo apt update
sudo apt full-upgrade -y
sudo reboot

sudo apt update
sudo apt install -y \
  nano mc htop curl fastfetch git screen wget ncdu nmap \
  sysstat vnstat atop iftop
  
 sudo apt install -y sshfs
 sudo apt install -y nfs-common
 sudo apt install -y cifs-utils

Ustawienia swap

sudo swapoff /dev/mapper/gitlab--vg-swap_1
# usunąć z /etc/fstab
/dev/mapper/gitlab--vg-swap_1 none swap sw 0 0
sudo sed -i '\|/dev/mapper/gitlab--vg-swap_1|d' /etc/fstab

# Usuń LV swap_1 z LVM
sudo lvremove -y /dev/gitlab-vg/swap_1
# Rozszerz LV root o 100% wolnego miejsca
sudo lvextend -l +100%FREE /dev/gitlab-vg/root
# Rozszerz system plików root (online)
sudo resize2fs /dev/gitlab-vg/root

# przygotowanie swapa w pliku
sudo fallocate -l 1G /var/swap
sudo chmod 600 /var/swap
sudo mkswap /var/swap
sudo swapon /var/swap
echo '/var/swap none swap defaults 0 0' | sudo tee -a /etc/fstab

# w razie długiego uruchamiania
cat /etc/initramfs-tools/conf.d/resume 2>/dev/null || echo "brak pliku resume"
RESUME=/dev/mapper/gitlab--vg-swap_1
echo "RESUME=none" | sudo tee /etc/initramfs-tools/conf.d/resume
# Przebuduj initramfs
sudo update-initramfs -u -k all

Ustawienia fastfetch

# wyłaczenie banera po połaczeniu
> /etc/motd

sudo nano /root/.bashrc
# Dopisz na końcu

# --- fastfetch banner on interactive SSH login (root) ---
if [[ $- == *i* ]] && [[ -n "$SSH_CONNECTION" || -n "$SSH_TTY" ]] && command -v fastfetch >/dev/null 2>&1; then
  if [[ -t 1 ]]; then
    fastfetch
  fi
fi

Weryfikacja błędów przy starcie serwera dmesg

sudo dmesg -T --level=err,warn

echo "blacklist snd_hda_intel" | sudo tee /etc/modprobe.d/blacklist-audio.conf
echo "blacklist pciehp"        | sudo tee /etc/modprobe.d/blacklist-pciehp.conf
echo "blacklist shpchp"        | sudo tee /etc/modprobe.d/blacklist-shpchp.conf

sudo update-initramfs -u
sudo reboot

Tuned na Debian 13

sudo apt install -y tuned
sudo systemctl enable --now tuned
sudo tuned-adm profile throughput-performance
# Weryfikacja:
sudo tuned-adm active
sudo tuned-adm list

Usunięcie quiet / „ładnego bootowania” w Debian

sudo nano /etc/default/grub
# Znajdź np.:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
# I zmień np. na:
GRUB_CMDLINE_LINUX_DEFAULT=""

Sprawdzenie ustawień strefy czasowej i synchronizacji czasu

sudo timedatectl set-timezone Europe/Warsaw
journalctl -u systemd-timesyncd --since "1 hour ago" --no-pager

# przed zmianami
root@gitlab:~# timedatectl timesync-status
       Server: 149.156.70.60 (2.debian.pool.ntp.org)
Poll interval: 2min 8s (min: 32s; max 34min 8s)
         Leap: normal
      Version: 4
      Stratum: 2
    Reference: 959C464B
    Precision: 1us (-25)
Root distance: 22.468ms (max: 5s)
       Offset: -2.870ms
        Delay: 15.786ms
       Jitter: 3.893ms
 Packet count: 3
    Frequency: +25.176ppm

# zmiana 
sudo mkdir -p /etc/systemd/timesyncd.conf.d
sudo nano /etc/systemd/timesyncd.conf.d/10-ntp.conf
# wkleić
[Time]
NTP=0.pl.pool.ntp.org 1.pl.pool.ntp.org 2.pl.pool.ntp.org 3.pl.pool.ntp.org
FallbackNTP=

sudo systemctl restart systemd-timesyncd

# po zmianach
       Server: 91.212.242.20 (0.pl.pool.ntp.org)
Poll interval: 1min 4s (min: 32s; max 34min 8s)
         Leap: normal
      Version: 4
      Stratum: 2
    Reference: C292FB64
    Precision: 2us (-19)
Root distance: 40.931ms (max: 5s)
       Offset: -2.037ms
        Delay: 10.939ms
       Jitter: 0
 Packet count: 1
    Frequency: +9.257ppm

Ustawienia historii poleceń użytkownika root

sudo nano /root/.bash_profile

# Load ~/.bashrc if present (interactive settings)
if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

sudo nano /root/.bashrc

# -------------------------------
# Root bash history - extended + timestamps + safe append
# -------------------------------

# Where to store history
export HISTFILE="$HOME/.bash_history"

# Make history very long (in memory + on disk)
export HISTSIZE=200000
export HISTFILESIZE=500000

# Timestamp format: "2026-02-19 15:10:15 "
# NOTE: timestamp is stored internally and shown by `history`
export HISTTIMEFORMAT="%F %T "

# Append (do not overwrite) and keep clean history behavior
shopt -s histappend          # append to HISTFILE, don't overwrite
shopt -s cmdhist             # multi-line commands as one entry

# Avoid useless duplicates + ignore commands starting with space
# ignoreboth = ignorespace + ignoredups
export HISTCONTROL="ignoreboth:erasedups"

# Optional: ignore some noisy commands (tweak to taste)
export HISTIGNORE="ls:ll:la:pwd:cd:cd -:exit:history:clear:reset:fg:bg:jobs"

# Save after EVERY command, and also reload new lines from disk.
# This is important when you have multiple root SSH sessions.
PROMPT_COMMAND='history -a; history -n'

# (Optional but often useful) Add "checkwinsize" so terminal size updates
shopt -s checkwinsize

Instalacja GitLab CE na Debian 13

Zainstaluj GitLab z EXTERNAL_URL

# Pakiety bazowe
sudo apt update
sudo apt -y full-upgrade
sudo apt -y install curl ca-certificates tzdata openssh-server perl
sudo systemctl enable --now ssh

# Dodaj repo GitLab
curl -fsSL https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash

# Na start ustawimy HTTPS i domenę:
sudo EXTERNAL_URL="https://gitlab.okdlab.local" apt -y install gitlab-ce
# Po instalacji:
sudo gitlab-ctl status

W razie błędu jak poniżej

There was an error running gitlab-ctl reconfigure:

letsencrypt_certificate[gitlab.okdlab.local] (letsencrypt::http_authorization line 6) had an error: Acme::Client::Error::RejectedIdentifier: acme_certificate[staging] (letsencrypt::http_authorization line 60) had an error: Acme::Client::Error::RejectedIdentifier: Invalid identifiers requested :: Cannot issue for "gitlab.okdlab.local": Domain name does not end with a valid public suffix (TLD)

Wyłaczamy obsługę Letsencrypt

sudo nano /etc/gitlab/gitlab.rb

# ustawić te 2 linie
letsencrypt['enable'] = false
letsencrypt['auto_renew'] = false

i generujemy certyfikat z SAN (potrzebny dla Argo CD i bastion git push) self-signed dla GitLab ,zamiast 192.168.40.35 wpisać adres ip gitlaba.

sudo mkdir -p /etc/gitlab/ssl
sudo chmod 700 /etc/gitlab/ssl

# Ustal IP GitLaba (żeby dać SAN = DNS + IP)
ip -4 addr show | egrep -o 'inet 192\.168\.40\.[0-9]+' | awk '{print $2}' | head -n1

sudo nano /etc/gitlab/ssl/gitlab.okdlab.local-openssl.cnf

[ req ]
default_bits       = 4096
prompt             = no
default_md         = sha256
distinguished_name = dn
req_extensions     = req_ext

[ dn ]
C  = PL
ST = OKDLab
L  = OKDLab
O  = OKDLab
OU = DevOps
CN = gitlab.okdlab.local

[ req_ext ]
subjectAltName = @alt_names
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

[ alt_names ]
DNS.1 = gitlab.okdlab.local
IP.1 = 192.168.40.35
cd /etc/gitlab/ssl

# Wygeneruj klucz i cert (self-signed z SAN)
sudo openssl req -x509 -nodes -days 825 -newkey rsa:4096 \
  -keyout gitlab.okdlab.local.key \
  -out gitlab.okdlab.local.crt \
  -config gitlab.okdlab.local-openssl.cnf \
  -extensions req_ext

# Sprawdź, czy SAN jest obecny
openssl x509 -in /etc/gitlab/ssl/gitlab.okdlab.local.crt -noout -text | egrep -i 'Subject:|Subject Alternative|DNS:|IP Address'

# Upewnij się, że GitLab ma wyłączony Let’s Encrypt i wskazuje na te pliki
sudo nano /etc/gitlab/gitlab.rb
#U pewnij się, że masz:
external_url "https://gitlab.okdlab.local"
nginx['ssl_certificate'] = "/etc/gitlab/ssl/gitlab.okdlab.local.crt"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/gitlab.okdlab.local.key"

Zastosowanie konfiguracji i dokończenie instalacji

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart
sudo gitlab-ctl status

sudo gitlab-ctl status
run: alertmanager: (pid 18947) 16s; run: log: (pid 18720) 48s
run: gitaly: (pid 17521) 705s; run: log: (pid 16528) 839s
run: gitlab-exporter: (pid 18904) 18s; run: log: (pid 18632) 67s
run: gitlab-kas: (pid 16959) 830s; run: log: (pid 16988) 827s
run: gitlab-workhorse: (pid 17498) 705s; run: log: (pid 17201) 749s
run: logrotate: (pid 15916) 854s; run: log: (pid 15930) 853s
run: nginx: (pid 18886) 19s; run: log: (pid 17229) 745s
run: node-exporter: (pid 18896) 19s; run: log: (pid 18605) 75s
run: postgres-exporter: (pid 18959) 16s; run: log: (pid 18761) 43s
run: postgresql: (pid 16580) 836s; run: log: (pid 16829) 833s
run: prometheus: (pid 18923) 17s; run: log: (pid 18687) 55s
run: puma: (pid 18835) 33s; run: log: (pid 17079) 761s
run: redis: (pid 16264) 848s; run: log: (pid 16479) 845s
run: redis-exporter: (pid 18909) 18s; run: log: (pid 18656) 63s
run: sidekiq: (pid 18775) 40s; run: log: (pid 17132) 755s

Sprawdzenie jakie jest hasło roota

sudo cat /etc/gitlab/initial_root_password

Weryfikacja czy działa HTTPS

curl -kI https://gitlab.okdlab.local

HTTP/2 302
server: nginx
date: Thu, 18 Feb 2026 17:15:11 GMT
content-type: text/html; charset=utf-8
content-length: 0
location: https://gitlab.okdlab.local/users/sign_in
cache-control: no-cache
content-security-policy:
nel: {"max_age": 0}
permissions-policy: interest-cohort=()
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-gitlab-meta: {"correlation_id":"01KHV42E1CRJ183T93RA1PW197","version":"1"}
x-permitted-cross-domain-policies: none
x-request-id: 01KHV42E1CRJ183T93RA1PW197
x-runtime: 0.070672
x-ua-compatible: IE=edge
x-xss-protection: 1; mode=block
strict-transport-security: max-age=63072000
referrer-policy: strict-origin-when-cross-origin

Utworzenie projektu i repo w GitLab

Obecnie repo aplikacji zawiera wszystko. W repo są Dockerfile, index.php, helm/, kustomize/overlays/…/values-*.yaml

Plusy:

jedno repo, mniej żonglowania
prosto na start

Minusy:

Argo CD ma dostęp do repo z kodem (czasem nie chcesz)
częściej będziesz robił commity “mieszane” (kod + deploy)


Polecanym stylem jest Repo kodu + Repo wdrożeń

healthlog-gui (kod)
healthlog-gui-deploy (helm/values/argo app)

Plusy:

czyste GitOps (Argo czyta tylko deploy repo)
pipeline aktualizuje deploy repo (tag obrazu) w kontrolowany sposób

Minusy:

dwa repo zamiast jednego
Na tym etapie wdrażany jest styl 1 czyli mieszane repo.

.
├── argocd
│   ├── app-healthlog-gui-dev.yaml
│   ├── app-healthlog-gui-prod.yaml
│   └── project-healthlog.yaml
├── argocd-bootstrap
│   └── bootstrap-app.yaml
├── Dockerfile
├── helm
│   ├── Chart.yaml
│   ├── templates
│   │   ├── configmap.yaml
│   │   ├── deployment.yaml
│   │   ├── route.yaml
│   │   ├── secret.yaml
│   │   └── service.yaml
│   └── values.yaml
├── index.php
└── kustomize
    ├── base
    │   └── kustomization.yaml
    └── overlays
        ├── dev
        │   ├── kustomization.yaml
        │   └── values-dev.yaml
        └── prod
            ├── kustomization.yaml
            └── values-prod.yaml

Logujemy się na stronie https://gitlab.okdlab.local/

  • Username: root
  • Password: hasło jest w pliku
sudo cat /etc/gitlab/initial_root_password

Tworzymy nową grupę np. DEV OPS https://gitlab.okdlab.local/admin/groups/new

Tworzymy nowego użytkownika się na stronie https://gitlab.okdlab.local/admin/users/new

  • Name: Jan Kowalski
  • Username: jan.kowalski
  • Email: [email protected]
  • Password: (po założeniu w edycji ustawiamy dowolne hasło)

Dodajemy nowego użytkownika do grupy DEV OPS

W Group members grupy DEV OPS ustawiamy rolę Maintainer (na czas tworzenie pierwszego commita, poźniej rola może być Developer) dla nowego użytkownika się na stronie

Po zalogowaniu się do GitLab na nowego użytkownika tworzymy nowy projekt o nazwie: healthlog-gui na stronie https://gitlab.okdlab.local/projects/new#blank_project

Odznaczamy: Initialize repository with README

Dodanie cert GitLaba do zaufanych w systemie na bastionie.

# na maszynie bastion
scp [email protected]:/etc/gitlab/ssl/gitlab.okdlab.local.crt /tmp/gitlab.okdlab.local.crt
sudo cp /tmp/gitlab.okdlab.local.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust

# Sprawdź, czy system ufa certowi
curl -I https://gitlab.okdlab.local

# w raazie problemów
# fatal: unable to access 'https://gitlab.okdlab.local/dev-ops/healthlog-gui.git/': SSL certificate problem: self-signed certificate
# * SSL certificate problem: self-signed certificate

mkdir -p "$HOME/.certs"

echo | openssl s_client -connect gitlab.okdlab.local:443 -servername gitlab.okdlab.local 2>/dev/null \
  | openssl x509 -outform PEM > "$HOME/.certs/gitlab-okdlab-ca.crt"

chmod 0644 "$HOME/.certs/gitlab-okdlab-ca.crt"

ls -l "$HOME/.certs/gitlab-okdlab-ca.crt"
head -n 2 "$HOME/.certs/gitlab-okdlab-ca.crt"
tail -n 2 "$HOME/.certs/gitlab-okdlab-ca.crt"
curl --cacert "$HOME/.certs/gitlab-okdlab-ca.crt" -Iv https://gitlab.okdlab.local 2>&1 | egrep -i 'verify|error'
cd /repo/git/healthlog-gui

git config --local http.sslCAInfo "$HOME/.certs/gitlab-okdlab-ca.crt"
git config --local http.sslVerify true

git config --local --get http.sslCAInfo
git push

Przygotowanie pliku .gitignore z plikami i katalogami, które git ma ignorować podczas git push

cd /repo/git/healthlog-gui

cat > .gitignore <<'EOF'
# OS/editor
.DS_Store
*.swp
*.swo
*.bak
.idea/
.vscode/

# Logs
*.log

# Local env
.env
EOF

Utworzenie pierwszego brancha

cd /repo/git/healthlog-gui

git init -b main
git config --local user.name "Jan Kowalski"
git config --local user.email "[email protected]"
git remote add origin https://gitlab.okdlab.local/dev-ops/healthlog-gui.git
git add .
git commit -m "Initial import: healthlog gui (code + helm + env values)"
git push -u origin main

Konfiguracja pod Argo CD + OKD 4.19 (repo access + token)

Jako root dodajemy nowego użytkownika o nazwie np. argocd.
W edycji ustawiamy mu hasło np. 1234abcd.

Dodajemy rolę przynajmniej Reporter użytkownikowi argocd w repo healthlog-gui

Logujemy się użytkownikiem argocd do GitLab-a. W menu User settings -> Personal access tokens tworzymy nowy token dostępowy (PAT). Koniecznie z uprawnieniami read_repository. Kopiujemy token do pliku tymczasowego.

glpat-_PrgXNpNHAimlj1YpTYIUm86MQp1OjUH.01.0w08mf9og

Zapisywanie poświadczeń do GitLab Personal Access Token + Git Credential Manager / libsecret

Jako zalogowany do GitLab użytkownik generujemy PAT w menu https://gitlab.okdlab.local/-/user_settings/personal_access_tokens?page=1&state=active&sort=expires_asc

glpat-Hu2GNPewuet36xGnXcSXvW86MQp1OjMH.01.0w0go3fxv
sudo dnf install -y git-credential-libsecret libsecret
git config --global credential.helper /usr/libexec/git-core/git-credential-libsecret

# po pierwszym commit zostanie zapisane hasło i login na stałe, np.
git add kustomize/overlays/dev/values-dev.yaml
git commit -m "dev: deploy image <tag>"
git push

Zapisywanie poświadczeń do GitLab cache w pamięci

# Potem 1 raz podajesz login+PAT i przez 8h masz spokój.
git config --global credential.helper 'cache --timeout=28800'

Zapisywanie poświadczeń do GitLab SSH zamiast HTTPS

ssh-keygen -t ed25519 -C "[email protected]"
at ~/.ssh/id_ed25519.pub

W GitLab: User Settings → SSH Keys → Add

Zmień remote w repo na SSH

git remote -v
git remote set-url origin [email protected]:dev-ops/healthlog-gui.git
ssh -T [email protected]
git push