Proxmox LXC設定

LXC是輕量級的容器,Proxmox 直接提供了這功能,等於是可以拿 LXC 來當 VM,這樣可以更壓榨硬體的效能出來。

這邊主要是紀錄用的時候遇到的一些狀況:

  1. Tailscale
  2. podman

Tailscale

因為我 Proxmox 網路設定是用NAT,再加上沒有第二張網卡,所以就簡單用 Tailscale 讓外部可以連到 Proxmox 裡面的 LXC 跟 VM。VM 用 tailscale 沒什麼問題,但 LXC 就遇到不能用的情況。

這邊要在 lxc 容器設定 (Proxmox 主機裡的 /etc/pve/lxc/<id>.conf 裡加上以下內容

lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file

podman

podman 本身就容器,等於是容器裡的容器,這邊要處理 rootless 的情況,一樣,在 lxc 容器設定 (Proxmox 主機裡的 /etc/pve/lxc/<id>.conf 加上以下內容

lxc.idmap: u 0 100000 165536
lxc.idmap: g 0 100000 165536

還有 /etc/subuid

root:100000:200000

/etc/subgid

root:100000:200000

參考資料

helm images

適用情境,客戶是離線環境,沒辦法直接拉 container image,所以要先知道 helm chart 裏面用到的 container image,用這指令,就可以找到所有 helm chart 所使用到的 image,再用 skopeo/podman pull/docker pull 拉取下來,存為 tarball ,並帶到客戶端。

專案網址:https://github.com/nikhilsbhat/helm-images

安裝

安裝好 helm 以後,可以用以下指令安裝

helm plugin install https://github.com/nikhilsbhat/helm-images

使用

簡單說,就是拿 helm install 的指令來用,並改為 helm images get。

所以在配置好 helm repo 以後,就可以用 helm images 取得

例如 redis-operator

helm images get redis redis-operator/redis-operator

又例如 zabbix operator

helm images get zabbix zabbix-chart-7.0/zabbix-helm-chrt

就可以取得 container images 的網址。


題外話,應該要來熟悉一下 skopeo 怎麼用才是。

使用systemctl 啟用podman出現Failed to connect to bus

在使用 sudo/su 切換身份以後,用以下指令去啟用/啟動 podman 服務,會出現以下錯誤

Failed to connect to bus: No such file or directory

查了以後,才知道是少了 DBUS 環境變數的問題:https://stackoverflow.com/questions/73814619/permission-denied-trying-to-use-rootless-podman-docker-compose-traefik-with

這個時候,只要查到 DBUS 的 socket 路徑,再去 export DBUS 環境變數即可

export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
$ systemctl --user enable --now podman

啟用以後,會有 podman.sock 檔案,這個檔案的位置跟 root 身份的位置不一樣,會是在

/run/user/$UID/podman/podman.sock

這邊是要特別注意的。

終端機快速複製檔案內容到剪貼簿

資料來源:How to copy and paste within a terminal in macOS or Linux?

在 MacOS 下,可以用 pbcopy/pbpaste

cat file.txt | pbcopy
pbpaste | tee foo.txt

在 Linux 下,要用 xsel,主要是參數 –input 跟 –output

# 複製到剪貼簿
cat file.txt | xsel --clipboard --input
xsel --clipboard --output | tee foo.txt

若要讓指令一致,可以用 alias

alias pbcopy='xsel --clipboard --input'
alias pbpaste='xsel --clipboard --output'

為 yum repository 指定 proxy

要設定讓 yum 可以使用指定的 proxy 伺服器,可以在 /etc/yum.conf 的 [main] 區段裡增加 proxy 設定即可

[main]
proxy=http://<proxy_server>:3128

那如果是個別的 repository 要使用不同的 proxy 伺服器,可以怎麼做呢?
原本以為會很麻煩的,但意想不到簡單,因為有支援此設定。
就在 repository 的區段裡增加 proxy 設定就可以:

[repo]
name=baseos
baseurl=http://yumrepo.example.com/baseos
enabled=1
gpgcheck=0
proxy=http://<proxy_server>:3128

參考資料

bash script取亂數

在 bash script 裡,可以用 ${RANDOM} 取亂數,例如

echo "random number: ${RANDOM}"

就會出現一個隨機的數字。

那如果想限制在 20~40 這個範圍內的話,可以怎麼做呢?這時候可以用 bash 的 % ,取餘數的運算子來做,例如

echo "random number(0~10): $((20 + RANDOM % 20))"

參考資料

BIND+DNS over HTTPs

說明一下為什麼會要這樣作。

因為環境關係,DNS protocol 出不去,只有 A 主機可以透過 HTTP 出去。

因此方案如下:

  1. A 電腦安裝 squid,其他主機可將 HTTP proxy 設定為 A 主機,這樣 HTTP 請求就可透過 A 主機出去。
  2. 環境內原有 B 主機已經安裝 BIND,此主機就安裝 cloudflare 提供的 cloudflared ,使用 DNS over HTTPs 方式,讓 DNS 查詢可以用 HTTP 請求,透過 A 主機去查詢。

安裝與設定

cloudflared 蠻好安裝的,就一個執行檔,下載以後,改個權限就可以執行了 (安裝方式)

那如果要用 systemd 來啟動,也很容易,安裝方式裡就有提供範例:

[Unit]
Description=DNS over HTTPS (DoH) proxy client
Wants=network-online.target nss-lookup.target
Before=nss-lookup.target

[Service]
Environment=http_proxy=http://<proxy>:3128
Environment=https_proxy=http://<proxy>:3128
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
DynamicUser=yes
ExecStart=/usr/local/bin/cloudflared proxy-dns --port 5533

[Install]
WantedBy=multi-user.target

設定好,用 firewall-cmd 設定好防火牆 (TCP 5533) 以後,就可以去調整 BIND 的設定 /etc/named.conf

修改既有的 forwarder 設定

forwarders { 127.0.0.1 port 5533; };

重新啟動 named 以後,就可以試試看了。

流程大致如下

--[DNS查詢]--> B 主機(53/UDP) ----> B 主機(5533/TCP) --[HTTP]--> A 主機(3128/TCP) --> 外部

參考資料

找昨天到現在有更動的檔案

需求是要找到從昨天到現在有變更的檔案,一時也想不出來怎麼做,利用 Google 找了一下,大多都是利用 find 的 -newer 參數。

find 的 -newer 參數要帶入的是一個檔案,表示會以這個檔案為基準來進行比對。

所以假設是要找 2023-11-11 之後的檔案,就先利用 touch 來建立一個基準檔案,其修改日期為 2023-11-11:

touch --date "2023-11-11" /tmp/base

然後再用

find . -newer /tmp/base -print

就可以找出在 /tmp/base 之後變更的檔案了。

find 也有一個 -newerXY 的參數,這個 XY 可以是以下內容

  1. a – 檔案的存取時間
  2. B – 檔案的建立時間
  3. c – 檔案 inode 的變更時間
  4. m – 檔案的修改時間
  5. t – 參數的內容是時間

那要找比 2023-11-11 要新的檔案,就用以下指令

find . -type f -newermt 2023-11-11

要找特定一天的,就用以下指令

find . -type f -newermt 2023-11-11 ! -newermt 2023-11-12

參考資料

還原git簽出檔案的修改時間

執行 git clone 以後取得的修改時間是當下執行的時間,所以其實是沒辦法去判斷哪個檔案是七天前修改的,或是十天前修改的。

Stackoverflow 上有人問了相同的問題:Git clone changes file modification time – Stack Overflow

有人就回答了,其實 git 裡面沒有保留檔案修改時間的資訊,但可以有個 tricky 的方法,就是透過 git log 的資訊來變更檔案的修改日期:

git ls-tree -r --name-only HEAD | while read filename; do
  unixtime=$(git log -1 --format="%at" -- "${filename}")
  touchtime=$(date -d @$unixtime +'%Y%m%d%H%M.%S')
  touch -t ${touchtime} "${filename}"
done

這邊主要用到幾個指令,說明如下

  • git ls-tree 是取出檔案名稱
  • git log -1 --format 是取出檔案提交的日期,這邊取出的是 timestamp 值
  • date -d 將 timestamp 值,轉換為日期時間格式。
  • touch -t 依據指定的日期格式去設定檔案的修改日期。

這邊要注意,目錄的修改時間不會被更動到。

透過以上的腳本,就可以還原git簽出檔案的修改時間,然後再搭配 find 指令來找出七天前修改的檔案了。

測試指定的套件會影響哪些套件

若是想知道指定的套件會影響哪些套件,這時候可以怎麼做呢?

我第一個是想到可以用 rpm ,用 man rpm 可以查到 rpm 有以下參數

  • –provides
  • –requires
  • –whatprovides
  • –whatrequires

所以就試試看

rpm -q --whatrequires libweb

但結果卻不如預期,上網找到這篇 centos – Why does rpm –whatrequires fail to report dependencies? – Unix & Linux Stack Exchange

才知道正確用法是這樣,要先用 rpm -q --provides libwebp 去查到 libwebp 有提供什麼capability,然後再用 rpm -q --whatrequires <capability> 去找。

例如 libwebp

[root@workstation ~]# rpm -q --provides libwebp
libwebp = 1.0.0-5.el8
libwebp(x86-64) = 1.0.0-5.el8
libwebp.so.7()(64bit)
libwebpdecoder.so.3()(64bit)
libwebpdemux.so.2()(64bit)
libwebpmux.so.3()(64bit)
[root@workstation ~]# rpm -q --whatrequires "libwebp.so.7()(64bit)"
libwebp-1.0.0-5.el8.x86_64
gd-2.2.5-7.el8.x86_64
ImageMagick-libs-6.9.12.50-2.el8.x86_64

這樣就可以找到,但若是如此,就要寫腳本了。因為 libwebp 有提供多個 capability ,需要逐一去查才行。

有沒有更快的方法呢?

centos – Why does rpm –whatrequires fail to report dependencies? – Unix & Linux Stack Exchange 裡面有提到可以用 rpm -e --test ,直接模擬看看移除。

rpm -e --test libwebp 2>&1 | grep needed | awk '{print $6}' | sort | uniq

這樣就可以很快找出來了。