centos2rhel

工作有需要幫客戶將 CentOS 轉換到 Red Hat Enterprise Linux,試驗了一下。這個轉換是有條件的,必須要滿足前置條件,才能順利做轉換。

我用的環境是 CentOS 8.3 ,用以下的 playbook 來安裝 Red Hat 所提供的 convert2rhel 工具,先新增檔案,命名為 install-convert2rhel.yml ,然後把下面的內容貼進去。

---
- name: Convert CentOS to RHEL
  hosts: all
  become: yes

  tasks:
    - name: Get GPG key
      get_url:
        url: https://www.redhat.com/security/data/fd431d51.txt
        dest: /etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
        mode: '0440'

    - name: Get repo
      get_url:
        url: https://ftp.redhat.com/redhat/convert2rhel/8/convert2rhel.repo
        dest: /etc/yum.repos.d/convert2rhel.repo
        mode: '0440'

    - name: Get convert2rhel
      yum:
        name: convert2rhel
        state: latest

接著執行:ansible-playbook -i <your_ip>, -u root -k install-convert2rhel.yml

目的主機內就有 convert2rhel 指令了,先依照說明來執行看看

convert2rhel --username <redhat_account> --password <redhat_password> -a

執行結果會說需要把 CentOS 升級到 7.9 或是 8.4 才可以進行轉換,所以用 yum update -y 將 CentOS 8.3 升級到 8.4

升級完成,重新開機,再來執行一次。我這次是遇到 Python 處理編碼發生錯誤,改用

LANG=C convert2rhel --username <redhat_account> --password <redhat_password> -a

接著可以繼續往下了,依照指示回答問題以後,就順利轉換到 RHEL 了。(懶得回答可以加上 -y)

man convert2rhel 可以看到使用說明,講的還蠻清楚的。指令有提供了 –disablerepo / –enablerepo 可以關閉或啟用可能影響轉換的 repo,也可以使用 –no-rpm-va 來跳過檢查,也有提供 –activationkey 來支援 Red Hat Satellite,也可以使用 –no-rhsm 來避免註冊到 Red Hat 。

我自己是覺得使用這類的工具其實蠻需要經驗,如果主機上的軟體套件很單純的話,就還好,如果是有引用到第三方的 repo,可能就需要耐心來做狀況排除。同時,也需要事後的檢查,來確保上面的服務跟轉移前一樣。

Linux 改 hostname

目前大部分的 Linux 發行版應該都有 hostnamectl 指令了,用這個指令就可以去修改。

hostnamectl set-hostname <your-hostname>

昨天遇到一個怪狀況,怎麼改都改不了,請教 Google 大神以後,才知道 cloud-init 也有關係。

遇到這狀況,有兩個方法:

  1. 把 cloud-init 服務給關掉:systemctl disable cloud-init
  2. 修改 /etc/cloud/cloud.cfg ,把裡面的 preserve_hostname false 改為 preserve_hostname true

套用其中一種方法以後,重新開機,這樣就行了。

順便紀錄以下我以前怎麼改的,以前改要做這幾個步驟:

  1. 修改 /etc/hostname 這個檔案裡的內容
  2. 修改 /etc/hosts 裡的對應

改完以後,再重新開機。

如何在 systemd 裡啟用 rc.local

以前用 sysv 或 upstart 時,很方便,想要在開機時跑一些指令,又懶得寫啟動 sysv init script 或 upstart job 時,就寫在 rc.local 裡就好。現在幾乎各大 Linux 發行版本都改用 systemd 了,那 systemd 又該怎麼做呢?印象中之前查過兩三次了,這次再查,決定還是記錄一下好了。

主要參考這篇:How to Enable /etc/rc.local with Systemd – LinuxBabe

第一步,新增 /etc/rc.local ,然後把要執行的指令放到裡面去,並且用 chmod +x /etc/rc.local 加上執行權限。

第二步,新增 /etc/systemd/system/rc-local.service

[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target

第三步,啟用這個服務

sudo systemctl enable rc-local

硬碟空間不足?用OverlayFS來整合新硬碟空間

想到昨天還前天朋友問的,說伺服器的硬碟空間沒了,買了新的硬碟來用,有沒有辦法用一個比較便利的方法來掛載使用。我那時回答是說,得掛載到新的資料夾,再使用 symbolic link 方式去處理,今天看到 overlayfs,覺得應該可以用,就研究了一下。

主要是看了這三篇

第一篇側重於原理,第二篇很簡單,我覺得第三篇比較清楚。

是這樣的,本來看完第一篇跟第二篇,在嘗試的時候 (我是用 dd 做磁碟映像來掛載),一直遇到 wrong fs type, bad option, bad superblock on overlay 的問題,掛載不起來。看完第三篇,才知道自己錯在哪裡,就是 upperdir 必須要跟 workdir 在同個磁碟上,這樣掛載才不會有問題。

下面就開始實作,建立 olddisk,這裡把它當作是舊的 /home

dd if=/dev/zero of=olddisk bs=1024 count=1024
mkfs.ext4 olddisk

如果是真實情況的話,那麼這原本是掛載到 /home,這裡就把它改掛載到 /mnt/home。

sudo mkdir -p /mnt/home
sudo mount olddisk /mnt/home
sudo chown -R $USER:$USER /mnt/home

建立使用者目錄,盡可能模擬真實狀況,在真實狀況下,這步驟不用做

mkdir -p /mnt/home/user{1,2,3,4,5}

然後重新掛載為唯讀,模擬為以後都不去動的狀態

sudo mount -o remount,ro /mnt/home

建立 newdisk ,也就是模擬為新的硬碟

dd if=/dev/zero of=newdisk bs=1024 count=8192
mkfs.ext4 newdisk

掛載到 /mnt/newdisk

sudo mkdir -p /mnt/newdisk
sudo mount newdisk /mnt/newdisk
sudo chown -R $USER:$USER /mnt/newdisk

在新磁碟上建立兩個目錄,一個 home,一個 workdir。home 是 upperdir,workdir 還是 workdir,至於什麼是 upperdir,什麼是 workdir ,這裡就不多做說明了。

mkdir -p /mnt/newdisk/{home,workdir}

好,開始來掛載 overlay,這裡是掛載到 /home1,實際狀況會是 /home

sudo mount -t overlay none -o lowerdir=/mnt/home,upperdir=/mnt/newdisk/home,workdir=/mnt/newdisk/workdir /home1

看看 /home1

ls /home1
# 結果:
# lost+found  user1  user2  user3  user4  user5

建立新的使用者資料夾看看

mkdir -p /home1/user{6,7,8,9,10}

再來看看 /home1 有什麼變化

ls /home1
# 結果:
# lost+found  user1  user10  user2  user3  user4  user5  user6  user7  user8  user9

這時可以看到有確實的增加了 user6, user7, user8, user9, user10 這些資料夾,然後來看看新的硬碟裡怎麼樣了

ls /mnt/newdisk/home
# 結果:
# user10  user6  user7  user8  user9

這時可以看到新的使用者資料夾在這邊了,那 workdir 呢?

ls /mnt/newdisk/workdir
# 結果:
# work 

會發現只有 work,看來這是 kernel 工作用的目錄,可以忽略。那如果去原來在舊磁碟的使用者資料夾裡新增或修改檔案,會怎麼樣呢?

cd /home1/user1
touch {x,y}.md
cd /home1/user2
touch z.md

看舊磁碟上有沒有變化

ls /mnt/home/user1
# 結果:
#

會發現一樣是空的。來看看新磁碟

ls /mnt/newdisk/home/user1
# 結果:
# x.md  y.md

至此,存取一樣都在 /home1,但新的資料都會被放在新磁碟上了。

整理一下,在實際情況時的處置

  1. 接上新硬碟,分割、格式化好之後,掛載到 /mnt/newdisk ,建立兩個資料夾:home, workdir
  2. 如果 /home 是在分割區的話,先卸載,改掛載到 /oldhome;如果是跟 / 在一起的話,改個名字,例如 /oldhome
  3. 掛載:sudo mount -t overlay none -o lowerdir=/oldhome,upperdir=/mnt/newdisk/home,workdir=/mnt/newdisk/workdir /home
  4. 修改 /etc/fstab ,這樣下次開機時,才會生效。修改重點有三,一是原來的 /home,二是掛載新的磁碟,三是加入 overlay 的處理。

棄用 yaourt,改用 yay

原來 archlinux 的 yaourt 已經過時了,我參考這篇 Yaourt is Dead! Use These Alternatives for AUR in Arch Linux,換成 yay,用法跟 yaourt 差不多。最新的 AUR 替代品可以參考 Archlinux 維基:AUR_helpers ,只是官方不建議使用這些工具,還是希望大家熟悉手動建置套件的程序。

先移除 yaourt

$ sudo pacman -Rn yaourt package-query

再參考 yay 的安裝說明來安裝

git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

用法跟 yaourt 差不多

# 更新套件列表並更新目前已經安裝的套件 (包含 AUR)
yay -Syu
# 安裝套件
yay -S foo
# 尋找套件
yay -Ss foo
# 取得遠端套件資訊
yay -Si foo
# 目前系統套件狀況
yay -P --stats

搞定以後,參考 yay -P –stats 的建議,移除了 aur 沒在維護的套件。最後跟 yaourt 說聲再見,謝謝 yaourt 過去幾年的照顧。

apk add 的 –virtual

Reduce Docker image sizes using Alpine 這篇學到的,add 時加上 –virtual,是暫時性的為這次加的 package 納入群組。之後若不需要這些 package,就可以在 del 時,指定這個名稱,就可以移除前次加入的 packages。

apk add --no-cache --virtual .build-deps gcc freetype-dev musl-dev
apk del .build-deps

Serveo.net

網址:https://serveo.net/
找 ngrok alternative 時,找到這個用 ssh 指令就可以破牆,挺方便的。

例子1

Port forwarding

在 A 電腦裡輸入

ssh -R 80:localhost:3000 serveo.net

按下 yes,會拿到一個類似 https://talis.serveo.net 的網址,當從另外一台電腦連到此網址時,會連接到 A 電腦的 port 3000

P.S. 

  1. 要拿到不一樣的網址,就帶 username,例如:ssh -R 80:localhost:8888 foo@serveo.net
  2. localhost 可以替換為其他電腦,例如 192.168.1.1

例子2

ssh port forwarding

在 A 電腦裡有 SSH server,然後輸入

ssh -R myalias:22:localhost:22 serveo.net

接著在其他電腦有 ssh client 的電腦裡輸入

ssh -o ProxyCommand="ssh -W myalias:22 serveo.net" user@myalias

就可以連接到 A 電腦的 SSH server

P.S.

  1. OpenSSH client 7.3 以後可以用 -J 參數:ssh -J serveo.net user@myalias

用 autossh 自動重連

事前預備

  1. sudo adduser –system –group –disabled-password autossh
  2. sudo chsh –shell /bin/false autossh
  3. 預先使用 autossh ,執行過一次 autossh 指令

autossh + upstart

# /etc/init/autossh.conf
# http://logan.tw/posts/2014/12/15/autossh-and-ubuntu-upstart-daemon/
description "autossh daemon for ssh tunnel"
start on net-device-up IFACE=br0 # 此處需因應網路裝置來調整為 eth0, eth1 ...
stop on runlevel [01S6]

setuid autossh
respawn
respawn limit 5 60
script
#export AUTOSSH_FIRST_POLL=30
#export AUTOSSH_GATETIME=0
#export AUTOSSH_POLL=60
autossh -M 0 -R pokemon22:22:localhost:22 serveo.net
end script

autossh + systemd

# /etc/systemd/system/autossh.service
# https://gist.github.com/thomasfr/9707568
[Unit]Description=Keeps a tunnel to 'serveo.net' open
After=network-online.target

[Service]
User=autossh
# -p [PORT]
# -l [user]
# -M 0 --> no monitoring
# -N Just open the connection and do nothing (not interactive)
# LOCALPORT:IP_ON_EXAMPLE_COM:PORT_ON_EXAMPLE_COM
# ExecStart=/usr/bin/autossh -M 0 -N -q -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -p 22 -l autossh remote.example.com -L 7474:127.0.0.1:7474 -i /home/autossh/.ssh/id_rsa
ExecStart=/usr/bin/autossh -M 0 -R pokemon22:22:localhost:22 serveo.net

[Install]
WantedBy=multi-user.target

tldr

tldr = too long don’t read

覺得 man 太冗長,懶得看嗎?試試 tldr,這指令直接給你常用的範例跟簡短的說明。
tldr 專案網址:https://github.com/tldr-pages/tldr
有各種語言的客戶端,用 bash 版的是最方便的了 (適用於 zsh/bash/csh/ksh…..):https://github.com/raylee/tldr

安裝很簡單,用 curl 下載,放到 PATH ,收工。

# 下載到 ~/bin,然後確定 ~/bin 有在 PATH 裡
curl -o ~/bin/tldr https://raw.githubusercontent.com/raylee/tldr/master/tldr
# 設定自動完成
complete -W "$(tldr 2>/dev/null --list)" tldr

sudo 免輸入密碼

這篇 command line – Execute sudo without Password? – Ask Ubuntu 講的很仔細,簡單說就是用 visudo 加入

username ALL=(ALL) NOPASSWD: ALL

就可以了。

我的作法是:

  1. 新增 sudo_nopass 的 group:
    sudo groupadd sudo_nopass
  2. visudo 之後,加入:
    sudo_nopass ALL=(ALL) NOPASSWD: ALL
  3. 將 user 加入 sudo_nopass 群組:
    sudo usermod -a -G sudo_nopass user
  4. 重新登入或重開機

這樣 user 用 sudo 時,就不需要再輸入密碼了。

Linux GPS 軟體小記

最近比較常在看 GPS 軌跡,紀錄一下 Ubuntu 下有在用的軟體:

  1. gpxviewer :用來看 gpx 檔案軌跡的工具,圖資是用 OpenStreetMap 。
  2. gpsprune:用來裁剪/合併 GPS 軌跡用的工具,用 Java 寫的,圖資一樣是 OpenStreetMap。
  3. gpsbabel/gpsbabel-gui:用來轉換各種軌跡檔案的工具。常見的 gdb ,要選 garmin mapsource (gdb) ,而 gpx 則是 GPX XML。
  4. gpscorrelate:根據 gpx 軌跡檔,在照片的 exif 加入地理座標標籤的工具。這工具蠻貼心的加入了 offset 的功能,也就說 gps logger 的時間跟照片時間有差距也沒關係,可以透過這 offset 去推算。

今天還有找到 garmin-forerunner-tools 跟 garmin-plugin 是可以搭配我那隻 Garmin ForeRunner 手錶的工具,要找時間來試試看。