## Red Host
### Q1:
- Network Manager file configuraton:
- /etc/NetworkManager/system-connections/enp0s3.nmconnection
- nmtui
```bash=
# nmtui
# ping -c 4 10.20.1.254
# ping -c 4 server.example.com
```
- 指令補充:
```bash=
# nmcli device
# nmcli connection modify enp3s0 ipv4.addresses 10.20.1.1/24
# nmcli connection modify enp3s0 ipv4.method manual
# nmcli connection modify enp3s0 ipv4.gateway 10.20.1.254
# nmcli connection modify enp3s0 ipv4.dns 10.20.1.254
# nmcli connection down enp3s0
# nmcli connection up enp3s0
# ip addr show
# cat /etc/resolv.conf
# cat /etc/NetworkManager/system-connections/enp0s3.nmconnection
```
### Q2:
```bash=
#vim /etc/yum.repos.d/exam.repo
[BaseOS]
name=BaseOS
baseurl=http://server.example.com/BaseOS
gpgcheck=0
enabled=1
[AppStream]
name=AppStream
baseurl=http://server.example.com/AppStream
gpgcheck=0
enabled=1
# yum clean all
# yum repolist
# yum list all
```
### Q3:
- 安裝 web site 服務
```bash=
# yum install httpd
# systemctl enable --now httpd
# systemctl status httpd -l
```
- 設定 SELinux for Web 目錄
```bash=
# vim /etc/sysconfig/selinux
SELINUX=enforcing
# mkdir -p /var/www/html
# semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
# restorecon -Rvv /var/www/html
# ls -dZ /var/www/html
```
- 設定 SELinux for Web port
```bash=
# semanage port -l | grep http
# semanage port -a -t http_port_t -p tcp 72
# semanage port -l | grep http
```
- 設定防火牆規則
```bash=
# firewall-cmd --list-all
# firewall-cmd --add-port=72/tcp
# firewall-cmd --add-port=72/tcp --permanent
# firewall-cmd --list-all
```
- 調整 httpd 服務設定
```bash=
# vim /etc/httpd/conf/httpd.conf
Listen 72
# vim /var/www/html/test.html
Hello World
# restorecon -Rvv /var/www/html
# systemctl restart httpd
# systemctl status httpd
# getsebool -a | grep http
# setsebool -P httpd_can_network_connect 1
# curl http://red.example.com:72/test.html
```
- SELinux 補充說明
- 啟動模組設定檔:/etc/config/selinux -- 改動之後,需要重開機
| 常見指令 | 參數 | 說明 |
| -------- | -------- | -------- |
| setenforce | 0: permissive 1: enforcing | 開啟或是暫時關閉 |
| getenforce || 查詢現在是否有使用 SELinux 模組|
| semanage | fcontext, port, -a -t -l | 調整 SELinux 權限類型|
| restorecon | -Rvv | 回復原規則設定 |
| setsebool | -P , 0 , 1| 設定服務的規則是否開啟 |
| getsebool | -a | 查詢服務的規則狀況 |
### Q4
- 使用者與群組常用的指令:
| 對象 | 新增 | 修改 | 刪除 |查詢 |
| :------ | :------ | :------ | :------ | :------ |
| User | useradd | usermod, passwd | userdel | id, who, whoami |
| Group | groupadd | groupmod, gpasswd | groupdel | id, who, whoami |
- 解題
```bash=
# groupadd admin
# useradd peter
# usermod -aG admin peter
# useradd james
# usermod -aG admin james
# useradd -s /bin/nologin tom
# grep admin /etc/group
# grep peter /etc/passwd
# grep james /etc/passwd
# grep tom /etc/passwd
```
### Q5
- 週期工作:
- at : 在指定的時間上,做單一工作
- cron : 週期性重複的工作
- 週期工作指令
| 服務名稱 | 新增 | 修改 | 刪除 | 查詢 |
| -------- | -------- | -------- | -------- | -------- |
| atd | at | | atrm | atq |
| crond | crontab -e | crontab -e | crontab -r| crontab -l|
- 常用檔案(白名單、黑名單)
| 服務名稱 | Allow | Deny | 預設檔案 |
| -------- | -------- | -------- | -------- |
| atd | /etc/at.allow | /etc/at.deny | /etc/at.deny (無任帳號) |
| crond | /etc/cron.allow | /etc/cron.deny | 無預設檔案 |
- crontab 檔案內容格式
- 分 時 日 月 週 <工作指令>
- 解題:
```bash=
# su - peter
$ crontab -e
32 16 * * * /bin/echo "Hello Linux"
$ crontab -l
$ exit
# crontab -l -u peter
```
### Q6
- 指令備註:
| 指令名稱 | 說明 |
| -------- | -------- |
| mkdir | 建立目錄 |
| touch | 建立檔案 |
| chown,chgrp | 設定檔案或目錄的使用者與群組設定 |
| chmod | 修改檔案或目錄權限 |
```bash=
# mkdir /opt/math
# chown :admin /opt/math
# chmod g+s /opt/math
# su - peter
$ cd /opt/math
$ touch test
$ ls -al
$ exit
#
```
### Q7
- 解題:喬治克隆尼在賣錶
```bash=
# vim /etc/chrony.conf
server server.example.com iburst
# systemctl enable --now chronyd
# systemctl status chronyd
# chronyc tracking
# chronyc sources -v
# date 101010102022
# chronyc makestep
```
### Q8
- 補充說明:
- autofs 是自動掛載服務,需要自行安裝
- nfs-utils 是讓掛載指令可以識別 nfs 檔案系統,協助 autofs 自動掛載
- 解題:
```bash=
# yum install autofs nfs-utils
# vim /etc/auto.master
/test /etc/auto.exam
# vim /etc/auto.exam
* -fstype=nfs,vers=4.2,rw,soft server.example.com:/test/&
# systemctl enable --now autofs
# useradd -u 1030 -m -d /test/kenny kenny (考試時不用新增)
# passwd kenny (考試時不用做這一項)
# su - kenny
$ cd /test/kenny
$ ls -al
$ exit
#
```
### Q9
- 補充說明:
- 帳號記錄檔:/etc/passwd
- 密碼檔案:/etc/shadow
- 解題:
```bash=
# useradd --uid 3456 alex
# passwd alex
# id alex
# cat /etc/passwd | grep alex
# cat /etc/shadow | grep alex
```
### Q10
- 補充說明: find 指令的查詢是依據檔案的屬性為參數,進行查詢的工作
- 解題:
```bash=
# mkdir /root/alex
# find / -name alex -type f -exec cp -ap {} /root/alex \;
# ls -al /root/alex
```
### Q11
- 解題:
```bash=
# grep apple /usr/share/dict/words > /root/lines
# less /root/lines
```
### Q12
- 解題:
```bash=
# tar jcvf /root/hello.tar.bz2 /usr/local
# tar jtf /root/hello.tar.bz2
```
### Q13
- Container 重要觀念:(以下摘錄自鳥哥的 Linux 私房菜)
- 容器化技術 (Containerization):在核心層級執行一組被獨立出來的程式,這個程式會被獨自隔離,且這個程式雖然可以取得系統的所有資源,然而這個程式只能看到屬於他自己的部份而已,又名為作業系統層虛擬化 (Operating system-level virtualization)。
- 因為容器使用了原有系統的資源,因此所需要的獨立的資源相對小很多!但是 container 只能運作與母系統相同的作業系統環境 (因為共用核心資源!)
- 虚擬機與容器比較圖
- 容器重要名詞:
- 映像檔 (image):映像檔就是一個唯讀的模板。
- 一個映像檔可以包含一個完整的作業系統環境,而內容卻只安裝使用者需要的應用程式。
- 容器 (container):容器就是從映像檔執行起來的軟體實體。
- 容器可以被啟動、開始、停止、刪除等等。
- 每個容器都是獨立且互相隔離的。
- 倉庫 (registry):放置 image 的倉庫,分成公有與私有。
- 開放式的倉庫(不論公有或是私有),可以不用登入該倉庫,即可下載 image。
- Podman:
- 指令的使用方式與 docker 完全相同
- Podman指令圖
- [Containerfile](https://www.jinnsblog.com/2018/12/docker-dockerfile-guide.html):
- 基本上 Dockerfile 是由一行一行的指令列所組成,一行指令對Image來說就是一層的資料層(Layer),一個Image 就是靠這樣一層一層的資料累加上去,最後才編譯出客製化映像檔。
- Containerfile 與 Dockerfile 相同,可客製化一個符合需求的映像檔。
- 檔案所使用的規格與指令名稱與 docker 相同。
- Containerfile 亦可使用 docker 來執行,建立自已的映像檔。
- Containerfile 內容指令:
- FROM:指定這個映像檔要以哪一個Image為基底來建構,必需是「第一個」指令行。
- MAINTAINER:映像檔維護者,通常是以 Email 格式來署名
- LABEL:設定映像檔的Metadata資訊
- RUN:執行指定的指令
- 如果想要執行的指令很長,可以利用\符號來換行
- 每一個RUN就會新增一層資料層,為了減少不必要的資料層,可以利用&&來串連多個命令
- CMD:設定映像檔啟動成為 Container 時,預設要執行的指令
- Dockerfile 中只能有一行CMD,若有多行CMD,則只有最後一行會生效
- 若在建立 Container 時有帶執行的命令,則CMD的指令會被蓋掉
- ENTRYPOINT:和CMD一樣,用來設定映像檔啟動Container時要執行的指令,但不同的是,ENTRYPOINT一定會被執行,而不會有像CMD覆蓋的情況發生
- Dockerfile 中只能有一行 ENTRYPOINT,若有多行 ENTRYPOINT,則只有最後一行會生效
- COPY:複製本地端的檔案/目錄到映像檔的指定位置中
- 指令的來源位置可以多個
- 如果目的位置是目錄的話,記得最後要以/結尾
- 目的位置可以是絕對路徑或者相對於WORKDIR定義值的相對路徑
- 若目的位置不存在,會自動建立
- ADD:和COPY一樣,可將本地端的檔案/目錄加到映像檔的指定位置內
- ADD的來源路徑支援URL,COPY則不支援URL
- 若來源檔案是壓縮檔(副檔名為gzip、bzip2、xz),則使用ADD加入檔案時會自動解壓縮,而COPY不會
- EXPOSE:宣告在映像檔中預設要使用(對外)的連接埠
- ENV:設定環境變數
- VOLUME:建立本機或來自其他容器的掛載點
- WORKDIR:設定工作目錄
- 如果目錄不存在,系統會幫忙自動建立
- USER:指定運行Container時的用戶名稱或UID
- ARG:設定在建置映像檔時可傳入的參數
- ONBUILD:若這個映像檔是作為其他映像檔的基底時,便需要定義ONBUILD指令
- 解題:
- 先以 root 登入系統,進行 podman 套件安裝
- 注意防火牆與 SELinux 設定
- 以 root 身份執行
```bash=
# yum install podman wget
# mkdir /opt/www
# chown alex /opt/www
# semanage fcontext -a -t container_file_t "/opt/www(/.*)?"
# restorecon -Rvv /opt/www
```
- alex 身份執行
```bash=
$ wget http://server.example.com/Containerfile
$ podman build -f Containerfile -t website --tls-verify=false
$ podman images
$ podman run localhost/website
$ podman ps -a
$ podman stop <Container_ID>
$ podman start <Container_ID>
```
### Q14
- Service 服務:
- 常駐在記體體中的程序,且可以提供一些系統或網路功能。
- 系統運作的 Service 統稱為 daemon 。
- Systemd (System Daemon 系統服務):
- 平行處理所有服務,加速開機流程
- 全部就是僅有一隻 systemd 服務搭配 systemctl 指令來處理,無須其他額外的指令來支援。
- 服務相依性的自我檢查
- 依 daemon 功能分類,共分為 service, socket, target, path, snapshot, timer 等多種不同的類型(type)。
- 將多個 daemons 集合成為一個群組,成為一個所謂的 target 項目,這個項目主要在設計操作環境的建置
- 向下相容舊有的 init 服務腳本
- systemd 將每個服務視為一個 unit (單位),並且分類到不同的 type。
- systemd 的設定檔放置目錄
- /usr/lib/systemd/system/:每個服務最主要的啟動腳本設定
- /run/systemd/system/:系統執行過程中所產生的服務腳本,這些腳本的優先序要比 /usr/lib/systemd/system/ 高
- /etc/systemd/system/:管理員依據主機系統的需求所建立的執行腳本,執行優先序比 /run/systemd/system/ 高
- 透過 systemctl 管理服務:
- start:立刻啟動服務
- stop:立刻關閉服務
- restart:立刻關閉服務後,再立即啟動服務
- reload:不關閉服務的情況下,重新載入設定檔,讓設定生效
- enable:設定下次開機時,服務會被啟動
- disable:設定下次開機時,該項服務不會被啟動
- status:目前服務的狀態,會列出有沒有正在執行、開機預設執行否、登錄等資訊等!
- is-active:目前有沒有正在運作中
- is-enabled:開機時有沒有預設要啟用服務
- 透過 systemctl 管理不同的操作環境 (target unit)
- target 分類:
- graphical.target:文字加上圖形界面,包含 multi-user.target 項目
- multi-user.target:純文字模式
- rescue.target:在無法使用 root 登入的情況下,systemd 在開機時會多加一個額外的暫時系統,與原本的系統無關。這時可以取得 root 的權限來維護系統,但是因為是額外系統,因此需要使用 chroot 的方式來取得原有系統及其目錄架構。
- emergency.target:緊急處理系統的錯誤,還是需要使用 root 登入,在無法使用 rescue.target 時,可以嘗試使用這種模式
- shutdown.target:關機
- getty.target:可以設定需要幾個 tty,如果想要降低 tty 的項目,可以修改這個東西的設定檔
- 常用指令參數:
- get-default:取得目前的 target
- set-default:設定 target 成為預設的操作模式
- isolate:切換到指定的 target
- 其它常用指令:
- systemctl poweroff:系統關機
- systemctl reboot:重新開機
- systemctl suspend:進入暫停模式
- systemctl hibernate:進入休眠模式
- systemctl rescue:強制進入救援模式
- systemctl emergency:強制進入緊急救援模式
- systemd 的設定檔內容常用參數:
- [Unit]:unit 本身的說明,以及與其他相依 daemon 的設定
- Description:輸出簡易說明,可使用 systemctl status 輸出
- Documentation:提供進一步的文件,提供的文件可以是如下的資料:
- Documentation=http://www....
- Documentation=man:sshd(8)
- Documentation=file:/etc/ssh/sshd_config
- After:此 unit 是在哪個 daemon 啟動之後才啟動,但並沒有強制要求該服務一定要啟動後,此 unit 才能啟動。
- Before:某服務啟動前,先啟動這個服務,但沒有強制要求。
- Requires:明確的定義此 unit 需要在哪個 daemon 啟動後才能夠啟動。
- Wants:與 Requires 剛好相反,定義該 unit 啟動之後最好還要啟動某項服務,但並沒有明確的規範。
- Conflicts: 如果某服務有啟動,則該 unit 不能啟動,但如果該 unit 有啟動,則某項服務就不啟動。
- [Service]:主要在規範服務啟動的腳本、環境設定檔檔名、重新啟動的方式等等。
- Type:該 daemon 啟動方式,有底下幾種類型
- simple:預設值,這個 daemon 主要由 ExecStart 接的指令串來啟動,啟動後常駐於記憶體中。
- forking:由 ExecStart 啟動的程序透過 spawns 延伸出其他子程序來作為此 daemon 的主要服務。原生的父程序在啟動結束後就會終止運作。傳統的 unit 服務大多屬於這種項目
- oneshot:與 simple 類似,不過這個程序在工作完成後就結束,不會常駐在記憶體中。
- dbus:與 simple 類似,但這個 daemon 必須要在取得一個 D-Bus 的名稱後,才會繼續運作,因此設定這個項目時,通常也要設定 BusName= 。
- idle:與 simple 類似,在執行這個 daemon 時,必須所有的工作都順利執行完畢後才會執行。這類的 daemon 通常是開機到最後才執行即可的服務!
- EnvironmentFile:可以指定啟動腳本的環境設定檔,可以使用 Environment= 後面接多個不同的 Shell 變數。
- ExecStart:實際執行此 daemon 的指令或腳本程式。
- ExecStop:關閉此服務時所進行的指令。
- ExecReload:與 systemctl reload 有關的指令行為
- Restart:當設定 Restart=1 時,則當此 daemon 服務終止後,會再次的啟動此服務。
- RemainAfterExit:當設定為 RemainAfterExit=1 時,則當這個 daemon 所屬的所有程序都終止之後,此服務會再嘗試啟動。
- TimeoutSec:若這個服務在啟動或者是關閉時,因為某些緣故導致無法順利『正常啟動或正常結束』的情況下,則需要要等多久才進入『強制結束』的狀態!
- KillMode:有 process, control-group, none 三種
- process:在該 daemon 終止時,只會終止主要的程序。
- control-group:在該 daemon 終止時,則由此 daemon 所產生的其他 control-group 的程序,也都會被關閉。
- none: 在該 daemon 終止時,則沒有程序會被關閉。
- RestartSec:如果這個服務被關閉,然後需要重新啟動時,大概要 sleep 多少時間再重新啟動。預設是 100ms (毫秒)。
- [Install]:將此 unit 服務分類到哪個 target
- WantedBy:表示這個 unit 分類在哪一個 target,通常是是 multi-user.target。
- Also:當這個 unit 被 enable 時,Also 後面接的 unit 也將會 enable 。
- Alias:進行一個連結的別名。當 systemctl enable 相關的服務時,則此服務會進行連結檔的建立。
- 一般使用者可自行設定服務,但 systemd 無法監控與管理
- 如果要納入 systemd 服務管理,須要設定使用者的 loginctl 要開啟
- 一般使用者的設定檔,放置於 ~/.config/systemd/user 下
- 解題:
- 以 alex 帳號登入
```bash=
$ loginctl show-user alex
$ loginctl enable-linger alex
$ loginctl show-user alex
$ mkdir -p ~/.config/systemd/user
$ cd ~/.config/systemd/user
$ cd /opt/www
$ wget http://server.example.com/website2.html
$ mv website2.html index.html
$ cd -
$ podman images
$ podman run -d --rm --name website2 -v /opt/www:/var/www/html:Z -p 8080:8080 -p 8443:8443 localhost/website
$ curl http://localhost:8080
$ podman ps -a
$ podman generate systemd --name website2 --new --files
$ cat /home/alex/.config/systemd/user/container-website2.service
$ podman stop website2
$ podman ps -a
$ systemctl --user daemon-reload
$ systemctl --user start container-website2.service
$ systemctl --user enable container-website2.service
$ podman ps
$ curl http://localhost:8080
$ su -
# firewall-cmd --add-port=8080/tcp
# firewall-cmd --add-port=8443/tcp
# firewall-cmd --runtime-to-permanent
# firewall-cmd --list-all
```
### Q15
- 補充說明:此題有修正內容
- 解題:
```bash=
# touch /root/goodyear
# vim /usr/local/bin/goodyear
#!/bin/bash
# find /usr -size -10M -perm /g=s -exec cp -ap {} /root/usr \; (此行不用做)
find /usr -size -10M -perm /g=s > /root/goodyear
# chmod +x /usr/local/bin/goodyear
# restorecon -Rvv /usr/local/bin/goodyear
# /usr/local/bin/goodyear
# ls /root/goodyear
# cat /root/goodyear
```
## Blue Host
### Q1
- 開機流程 

- 載入 BIOS 的硬體資訊與進行自我測試,並依據設定取得第一個可開機的裝置;
- 讀取並執行第一個開機裝置內 MBR 的 boot Loader (亦即是 grub2, spfdisk 等程式);
- 依據 boot loader 的設定載入 Kernel ,Kernel 會開始偵測硬體與載入驅動程式;
- 載入 kernel file 與 initramfs 檔案在記憶體內解壓縮
- initramfs 會在記憶體模擬出系統根目錄,提供 kernel 相關的驅動程式模組
- 核心裝置驅動程式完整的驅動硬體
- 在硬體驅動成功後,Kernel 會主動呼叫 systemd 程式,並以 default.target 流程開機;
- systemd 執行 sysinit.target 初始化系統及 basic.target 準備作業系統;
- systemd 啟動 multi-user.target 下的本機與伺服器服務;
- systemd 執行 multi-user.target 下的 /etc/rc.d/rc.local 檔案;
- systemd 執行 multi-user.target 下的 getty.target 及登入服務;
- systemd 執行 graphical 需要的服務
- 開機選單:grub2 設定檔
- 檔案:/boot/grub2/grub.cfg(該檔案不建議直接編修)
- set timeout=5 倒數計時5秒
- set root='hd0,msdos2' 設定啟動的磁區
- set default_kernelopts="..." 預設的開機 kernel 參數設定
- 檔案:/etc/default/grub (可編修修的檔案)
- GRUB_TIMEOUT=5 指定預設倒數讀秒的秒數
- GRUB_DEFAULT=saved 指定預設由哪一個選單來開機,預設開機選單之意
- GRUB_DISABLE_SUBMENU=true 是否要隱藏次選單,通常是藏起來的好!
- GRUB_TERMINAL_OUTPUT="console" 指定資料輸出的終端機格式,預設是透過文字終端機
- GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet" 就是在 default_kernelopts 內的核心參數
- GRUB_DISABLE_RECOVERY="true" 取消救援選單的製作
- 轉換指令:grub2-mkconfig -o /boot/grub2/grub.cfg
- 解題:
```bash=
重新開機
在五秒內按空白鍵或是上下方向鍵
在第一項選單上,按下「e」按鍵
選擇 linux 項目,在末端加上 rd.break
按下 Ctrl+x 按鍵,進入開機項目
# mount
# mount -o remount,rw /sysroot
# chroot /sysroot
# passwd root
# touch /.autorelabel
# exit
# mount -o remount,ro /sysroot
# exit
```
### Q2:
- 解題:
```bash=
#vim /etc/yum.repos.d/exam.repo
[BaseOS]
name=BaseOS
baseurl=http://server.example.com/BaseOS
gpgcheck=0
enabled=1
[AppStream]
name=AppStream
baseurl=http://server.example.com/AppStream
gpgcheck=0
enabled=1
# yum clean all
# yum repolist
# yum list all
```
### Q3:
- LVM 原理:請參照 Q5
- 解題:
```bash=
# umount /dev/datastore/sql
# lvdisplay
# e2fsck -k /dev/datastore/sql
# e2fsck -f /dev/datastore/sql
# resize2fs /dev/datastore/sql 300M
# lvreduce -L 300M /dev/datastore/sql
# mkdir /mnt/sql
# mount /dev/datastore/sql /mnt/sql
# df -h
```
- 急救:
```bash=
# lvextend -L 500M /dev/datastore/sql
# resize2fs /dev/datastore/sql
# e2fsck -apk /dev/datastore/sql
# mount /dev/datastore/sql /mnt/sql
```
### Q4:
- 硬碟分割區:[引用自烏哥的Linux私房菜網站](https://linux.vbird.org/linux_basic/centos7/0130designlinux.php#partition_table)
- MBR(Master Boot Record,主要開機紀錄區):
- 主要開機記錄區(Master Boot Record, MBR):可以安裝開機管理程式的地方,有446 bytes
- 分割表(partition table):記錄整顆硬碟分割的狀態,有64 bytes

- GPT(GUID partition table,GPT 磁碟分割表):
- 磁區的定義上面,使用邏輯區塊位址(Logical Block Address, LBA)來處理。
- 第一個 LBA 稱為 LBA0 (從 0 開始編號)。
- GPT 使用了 34 個 LBA 區塊來紀錄分割資訊!
- 整個磁碟的最後 33 個 LBA 也拿來作為備份!

- 常用指令:
- MBR:fdisk
- GPT:gdisk
- SWAP 分割區:[硬碟置換空間](https://blog.gtwang.org/linux/linux-swap-space-tutorial/)
- Linux 系統將實體記憶體(RAM)分成一塊一塊的小區域,這些小區塊稱為 pages
- 在實體記憶體不足的時候,系統會透過 swapping 的動作將 page 的資料搬到預先配置好的swap中儲存,然後釋放出 page 的記憶體空間
- Linux 系統上的虛擬記憶體(virtual memory)就是包含實體記憶體與硬碟的置換空間這兩大部份
- 常用指令:
- swapon -s: 查看目前 Linux 系統上的置換空間狀態
- swapon -a: 啟動 /etc/fstab 上設定為 swap 的置換空間分割區
- mkswap <分割區代號>: mkswap 來初始化置換空間
- swapon -d <分割區代號>: 使用有支援 TRIM 的 SSD 來作為置換空間
- /etc/fstab 的設定亦可加上 discard 選項
- /dev/sda2 none swap defaults,discard 0 0
- swapoff <分割區代號>:停用交換空間
- 解題:
```bash=
# gdisk /dev/sdb
->n
-><Enter>
-><Enter>
->+512M
->8200
->p
->w
# partprobe /dev/sdb
# mkswap /dev/sdb3
# swapon /dev/sdb3
# swapon -s
# vim /etc/fstab
/dev/sdb3 swap swap defaults 0 0
# mount -a
# swapon -s
```
### Q5:
- LVM 基本原理(Logical Volume Manager)

- Physical Volume(PV,實體捲軸):作為 LVM 最基礎的物理捲軸,可以是 partition 也可以是整顆 disk。
- Volume Group(VG,捲軸群組):將許多的 PV 整合成為一個捲軸群組 (VG),這就是所謂的最大的主要大磁碟。
- Physical Extent(PE,實體範圍區塊):PE 是整個 LVM 最小的儲存區塊,系統的檔案資料都是藉由寫入 PE 來處理的。PE 如同檔案系統裡面的 block 。PE 預設需要是 2 的次方量,且最小為 4M。
- Logical Volume(LV,邏輯捲軸):利用 VG 切割出類似 partition 的 LV ,即可使用該裝置。 LV 是藉由『分配數個 PE 所組成的裝置』,因此 LV 的容量與 PE 的容量大小有關。
- LVM 指令集
|任務|PV 階段|VG 階段|LV 階段|filesystem(XFS / EXT4)|
|:---:|:---:|:---:|:---:|:---:|
|搜尋(scan)|pvscan|vgscan|lvscan|lsblk / blkid|
|建立(create)|pvcreate|vgcreate|lvcreate|mkfs.xfs / mkfs.ext4|
|列出(display)|pvdisplay|vgdisplay|lvdisplay|df, mount|
|增加(extend)||vgextend|lvextend (lvresize)|xfs_growfs / resize2fs|
|減少(reduce)||vgreduce|lvreduce (lvresize)|不支援 / resize2fs|
|刪除(remove)|pvremove|vgremove|lvremove| umount, 重新格式化|
|改變容量(resize)|||lvresize|xfs_growfs / resize2fs|
|改變屬性(attribute)|pvchange|vgchange|lvchange|/etc/fstab, remount|
- 解題:
```bash=
# fdisk -l
# gdisk /dev/sdb
-> p
-> n
-> <Enter>
-> <Enter>
-> +1G
-> 8e00
-> p
-> w
# fdisk -l
# reboot
# pvcreate /dev/sdb2
# pvdisplay
# vgcreate -s 8M world
# vgdisplay
# lvcreate -l 50 -n hello world
# lvdisplay
# mkdir /mnt/helloworld
# mkfs -t vfat /dev/world/hello
# vim /etc/fstab
/dev/world/hello /mnt/helloworld vfat defaults 0 0
# mount -a
# pvs
# vgs
# lvs
# reboot
```
### Q6:
- 系統調校(Tuned 服務)
- 調整系統效能:需進行一連串相關設定,包括核心模組、核心參數、網路參數、磁碟參數...等等
- tuned 服務:透過該項服務的動態處理,可以隨時以選定的環境 (profile) 進行效能優化
- tuned 可依下列不同情境策略,進行系統優化:
|情境策略名稱|說明|
|:---:|:---|
|accelerator-performance|在停用更高延遲的停止狀態下,基於吞吐量性能的調整|
|balanced|一般非特定調整策略,均衡使用系統|
|desktop|針對桌上型使用案例最佳化|
|hpc-compute|針對高效能運算電腦,最佳化計算工作負載|
|intel-sst|針對 Intel Speed Select Base Frequency 功能進行設定|
|latency-performance|以增加功耗為代價,優化俱決定性的效能|
|network-latency|以增加功耗為代價,優化俱決定性的效能,但聚焦在低延遲網路效能上|
|network-throughput|針對串流網路吞吐量進行優化,通常只用於舊款CPU或是40G以上的網路|
|optimize-serial-console|針對串列埠進行優化調整|
|powersave|針對電源進行低功耗優化調整|
|throughput-performance|通用的的優化調整方案,可在各種常見的伺服器工作負載中,提供出色的性能|
|virtual-guest|針對VM內部進行優化|
|virtual-host|針對VM載體主機系統進行優化|
- tuned 指令用法: tuned-adm <參數名稱>
|參數名稱|說明|
|:---:|:---:|
|list|列出情境策略功能與說明|
|active|顯示目前運作中的情境策略|
|off|關閉所有調整功能|
|profile <情境策略名稱>|切換至指定的情境策略名稱。若沒指定情境略策,則列出情境策略名稱|
|profile_info <情境策略名稱>|顯示情境策略內容。若沒指定情境略策,則列出目前使用的情境策略名稱|
|recommend|建議的情境策略|
|verify|使用檢查功能,看看環境設定有沒有問題|
|auto_profile|開啟自動選擇情境策略模式,自動切換至建議的情境模式|
|profile_mode|顯示目前所選擇的情境策略模式|
- tuned 服務啟動指令:
- systemctl enabled tuned
- systemctl start tuned
- systemctl status tuned
- systemctl stop tuned
- systemctl disabled tuned
- 解題:
```bash=
# systemctl status tuned
# systemctl enable tuned
# systemctl start tuned
# tuned-adm recommend
# tuned-adm profile virtual-guest
# tuned-adm active
```
# 其它常見考題
## Red 主機
### Q1: 設定特殊權限
- ACL(Access Control List)說明:
- 目的是在提供傳統權限之外的細部權限設定。
- 可針對單一使用者,單一檔案或目錄來進行 r,w,x 的權限規範。
- ACL 主要可以針對幾個項目來加以控制:
- 使用者 (user):針對使用者來設定權限
- 群組 (group):針對群組為對象來設定其權限
- 統一遮罩 (mask):針對各別的權限設定,進行權限過濾或是限制
- 預設屬性 (default):針對在該目錄下在建立新檔案/目錄時,規範新資料的預設權限
- ACL 必須要配合檔案系統的掛載啟動才能生效
- 一般均將 acl 參數寫入 /etc/fstab 的第四欄位中
- 目前 Linux 已支援該檔案系統參數
- ACL 指令:
- setfacl
- 設定權限用,其欄位設定為 <角色>:<使用者帳號>:<權限值>
- 可配合參數:
- -m: 修改內容
- -d: 設定成預設屬性
- -x: 移除 ACL 設定
- -b: 完全移除 ACL 屬性
- -k: 移除預設屬性
- getfacl
- 查看目前的設定值
- 解題:
```bash=
# cp /etc/fstab /var/tmp/fstab
# getfacl /var/tmp/fstab
# setfacl -m u:peter:rw- /var/tmp/fstab
# setfacl -m u:james:--- /var/tmp/fstab
# getfacl /var/tmp/fstab
# su - james
$ cat /var/tmp/fstab
$ exit
```
#### Q2: kernel 核心更新
- 解題:
```bash=
# wget https://mirror.stream.centos.org/9-stream/BaseOS/x86_64/os/Packages/kernel-5.14.0-206.el9.x86_64.rpm
(kernel kernel-core kernel-api-stablelist kernel-modules kernel-tools)
# yum localinstall kernel-*
# reboot
```
#### Q3: 撰寫一個 shell scripts 程式
- 解題:
```bash=
# vim /opt/auth.sh
#!/bin/bash
case "$1" in
apple)
echo "pineapple"
;;
pineapple)
echo "apple"
;;
*)
echo "/opt/auth.sh apple | pineapple"
esac
# chmod +x /opt/auth.sh
# /opt/auth.sh apple
```
#### Q4: 指定群組管理帳號
- 解題:
```bash=
# gpasswd admin
# gpasswd -A peter admin
# su - peter
$ newgrp admin
$ gpasswd -a alex admin
$ exit
```
#### Q5: 建立 NFS 分享目錄
- 說明:
- NFS(Network FileSystem):
- 可分享目錄給遠端的主機,進行目錄掛載存取。
- 使用遠端程序呼叫(Remote Procedure Call, RPC)協定來協助 NFS 的運作
- rpc.nfsd:管理 Client 是否能夠登入主機的權限,其中包含登入者 ID 的判別
- rpc.mountd:管理 NFS 的檔案系統
- NFS 所需安裝套件:
- nfs-utils:NFS 的主要套件
- portmap:管理 NFS 連接的 port
- 解題:
```bash=
# yum install nfs-utils
# mkdir /opt/share
# chgrp admin /opt/share
# vim /etc/exports
/opt/share 10.20.1.0/24(ro,root_squash)
# systemctl enable --now nfs-server
# systemctl enable --now nfs-utils
# systemctl status rpcbind -l
# firewall-cmd --add-service=nfs --permanent
# firewall-cmd --reload
# showmount -e localhost
```
- 由 Blue 主機連線驗證
```bash=
# yum install nfs-utils
# mount -t nfs 10.20.1.1:/opt/share /mnt
```
#### Q6: 建立客製化指令
- 解題:
```bash=
# vim /etc/bashrc
alias pstest='/usr/bin/ps -Ao pid,tt,user,fname,rsz'
# su - peter
$ pstest
$ exit
```
#### Q7: 網路 team 設定
- 解題:
```bash=
# ip link show
# nmcli conn add type team con-name team0 ifname team0 config '{"runner": {"name": "activebackup"}}'
# nmcli conn mod team0 ipv4.addresses '10.20.1.1/24'
# nmcli conn mod team0 ipv4.method manual
# nmcli conn add type team-slave con-name team0-port1 ifname enp0s3 master team0
# nmcli conn add type team-slave con-name team0-port2 ifname enp0s8 master team0
# teamdctl team0 state
# ping -I team0 10.20.1.1
# nmcli dev dis enp0s8
# nmcli con up team0-port1
```
## Blue 主機
#### Q1: 改變 LVM 大小
- 解題:
```bash=
# lvs
# lvextend -L 850MiB /dev/datastore/sql
# e2fsck -f /dev/datastore/sql
# resize2fs /dev/datastore/sql
# df -h
```
#### Q2: 建立 VDO 卷冊
- VDO 說明:
- 虛擬資料優化系統 (Virtual Data Optimizer, VDO) 是為了處理虛擬機器的磁碟裝置而設計
- VDO可以在VDO的掛載點裡面,直接透過VDO系統的管理,自行進行資料同步、資料壓縮。

- VDO 在新版的 RHEL 9 之後,已併入 LVM2 之中,所以,不會再有 vdo 指令。
- 解題前說明:
- 請先新增一個 10G 硬碟空間,以利本題的練習
- 本題不太會考,因為有核心模組上的問題
- 解題:
```bash=
# gdisk /dev/sdc
-> p
-> n
-> <Enter>
-> <Enter>
-> <Enter>
-> <Enter>
-> p
-> w
# partprobe /dev/sdc
# fdisk -l
# yum install vdo kmod-kvdo lvm2
# pvcreate /dev/sdc1
# vgcreate vdotest /dev/sdc1
# lvcreate --type vdo --name vdodata --size 1G --virtualsize 5G vdotest
# mkfs.xfs -K /dev/vdotest/vdodata
# vdostats --human-readable
# mkdir /vbred
# vim /etc/fstab
/dev/vdotest/vdodata /vbred xfs defaults 0 0
# mount -a
```
#### Q3: 新增 swap 空間
- 解題:
```bash=
# df -h
# dd if=/dev/zero of=/opt/swap.img bs=4k count=1048576
# cd /opt
# mkswap /opt/swap.img
# swapon /opt/swap.img
# swapon -s
# vim /etc/fstab
/opt/swap.img swap swap defaults 0 0
# mount -a
```
#### Q4: 建立磁碟陣列
- 解題:
```bash=
#gdisk /dev/sdc
-> p
-> n
-> <Enter>
-> <Enter>
-> +2G
-> <Enter>
-> p
-> n
-> <Enter>
-> <Enter>
-> +2G
-> <Enter>
-> p
-> w
# fdisk -l
# partprobe /dev/sdb
# mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb{2..3}
# cat /proc/mdstat
# mdadm --detail /dev/md0
# gdisk /dev/md0
-> p
-> n
-> <Enter>
-> <Enter>
-> +2G
-> <Enter>
-> p
-> w
# partprobe /dev/md0
# mkfs.xfs /dev/md0p1
# mkdir /opt/databackup
# vim /etc/fstab
/dev/md0p1 /opt/databackup xfs defaults 0 0
# mount -a
```
#### LVM 修復方式
```bash=
# lvs
# pvs -a
# fdisk -l
# vgs -P -o +devices
# lvs -P -o +devices
# cd /etc/lvm/archive
# ls (記下檔名)
# vgchange -an --partial
# vim /etc/lvm/archive/datastore_你記下的檔名.vg
(記下 pv 的 uuid 值)
# pvcreate -ff --uuid "你剛記下的 uuid 值" --restorefile /etc/lvm/archive/datastore_你記下的檔名.vg /dev/sdb1
# vgchange -an --partial
# pvs
# vgs
# vgcfgrestore datastore
# vgs
# lvs (記下錯誤訊息的內容)
# rm datastore_你記下的檔名.vg
# vim /etc/lvm/devices/system.devices
刪除錯誤訊息的那一行
# vgs
# pvs
# lvchange -ay /dev/datastore/sql
# vgchange -an --partial
(稍等一下)
# mount /dev/datastore/sql /mnt
# ls -al /mnt
```