如何通過 Overlay2 或 Bind 進行ISO 重新構建
導讀 | 自從換了新工作之後,則開始負責 超融合產品[3] 叢集部署相關工作,因此也會接觸很多映象,不過這個映象是作業系統的 ISO 映象而不是容器映象 。雖然兩者都統稱為映象,但兩者有著本質的區別。 |
筆者之前在位元組跳動的時候是負責 PaaS 容器雲平臺的私有化部署相關的工作,所以經常會和一些容器映象打交道,對容器映象也有一些研究,之前還寫過不少部落格文章。比如 深入淺出容器映象的一生[1]、overlay2 在打包釋出流水線中的應用[2] 等等。
首先兩者構建的方式有本質的很大的區別,ISO 映象一般使用 mkisofs 或者 genisoimage 等 將一個包含作業系統安裝所有檔案目錄構建為一個 ISO 映象;而容器映象構建則是根據 Dockerfile 檔案使用相應的容器映象構建工具來一層一層構建;
另外 ISO 映象掛載後是隻讀的,這就意味著如果想要修改 ISO 映象中的一個檔案(比如 kickstart 檔案),則需要先將 ISO 映象中的所有內容複製到一個可以讀寫的目錄中,在這個讀寫的目錄中進行修改和重新構建 ISO 操作。
╭─root@esxi-debian-devbox ~/build ╰─# mount -o loop CentOS-7-x86_64-Minimal-2009.iso /mnt/iso mount: /mnt/iso: WARNING: device write-protected, mounted read-only. ╭─root@esxi-debian-devbox ~/build ╰─# touch /mnt/iso/kickstart.cfg touch: cannot touch '/mnt/iso/kickstart.cfg': Read-only file system
在日常工作中經常會對一些已有的 ISO 映象進行重新構建,重新構建 ISO 的效率根據不同的方式也會有所不同,本文就整理了三種不同重新構建 ISO 映象的方案供大家參考。
以下是按照 RedHat 官方文件 WORKING WITH ISO IMAGES[4] 中的操作步驟進行 ISO 重新構建。
- 首先我們下載一個 ISO 檔案,這裡以 CentOS-7-x86_64-Minimal-2009.iso[5] 為例,下載好之後將它掛載到本地 /mnt/iso 目錄下;
╭─root@esxi-debian-devbox ~/build ╰─# mount -o loop CentOS-7-x86_64-Minimal-2009.iso /mnt/iso mount: /mnt/iso: WARNING: device write-protected, mounted read-only.
- 將 ISO 裡的所有檔案複製到另一個目錄
╭─root@esxi-debian-devbox ~/build ╰─# rsync -avrut --force /mnt/iso/ /mnt/build/
- 進入到該目錄下修改或新增檔案,然後重新構建 ISO 映象
# 使用 genisoimage 構建 ISO 映象,在 CentOS 上可以使用 mkisofs 命令,引數上會有一些差異
╭─root@esxi-debian-devbox ~/build ╰─# genisoimage -U -r -v -T -J -joliet-long -V "CentOS 7 x86_64" -volset "CentOS 7 x86_64" -A "CentOS 7 x86_64" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -no-emul-boot -o /mnt/CentOS-7-x86_64-Minimal-2009-dev.iso . Total translation table size: 124658 Total rockridge attributes bytes: 55187 Total directory bytes: 100352 Path table size(bytes): 140 Done with: The File(s) Block(s) 527985 Writing: Ending Padblock Start Block 528101 Done with: Ending Padblock Block(s) 150 Max brk space used a4000 528251 extents written (1031 MB) # 給 ISO 映象生成 md5 校驗 ╭─root@esxi-debian-devbox ~/build ╰─# implantisomd5 /mnt/CentOS-7-x86_64-Minimal-2009-dev.iso Inserting md5sum into iso image... md5 = 9ddf5277bcb1d8679c367dfa93f9b162 Inserting fragment md5sums into iso image... fragmd5 = f39e2822ec1ae832a69ae399ea4bd3e891eeb31e9deb9c536f529c15bbeb frags = 20 Setting supported flag to 0
對於 ISO 映象比較小或者該操作不是很頻繁的情況下按照這種方式是最省事兒的,但如果是 ISO 映象比較大,或者是在 CI/CD 流水線中頻繁地重新構建映象,每次都要 cp 複製原 ISO 映象的內容確實比較浪費時間。那有沒有一個更加高效的方法呢 ?️
經過一番摸索,折騰出來兩種可以避免使用 cp 複製這種佔用大量 IO 操作的構建方案,可以根據不同的場景進行選擇。
熟悉 docker 映象的應該都知道映象是隻讀的,使用映象的時候則是通過聯合掛載的方式將映象的每一層 layer 掛載為只讀層,將容器實際執行的目錄掛載為讀寫層,而容器執行期間在讀寫層的所有操作不會影響到映象原有的內容。容器映象掛載的方式使用最多的是 overlay2 技術,在 overlay2 在打包釋出流水線中的應用[6] 和 ?深入淺出容器映象的一生 中我們曾對它進行過比較深入的研究和使用,對 overlay2 技術感興趣的可以翻看一下這兩篇部落格,本文就不再詳解其中的技術原理了,只對使用 overlay2 技術重新構建 ISO 映象的可行性進行一下分析。
- 首先是建立 overlay2 掛載所需要的幾個目錄
╭─root@esxi-debian-devbox ~ ╰─# mkdir -p /mnt/overlay2/{lower,upper,work,merged} ╭─root@esxi-debian-devbox ~ ╰─# cd /mnt/overlay2
- 接著將 ISO 映象掛載到 overlay2 的只讀層 lower 目錄
╭─root@esxi-debian-devbox /mnt/overlay2 ╰─# mount -o loop /root/build/CentOS-7-x86_64-Minimal-2009.iso lower mount: /mnt/overlay2/lower: WARNING: device write-protected, mounted read-only.
- 使用 mount 命令掛載 overlay2 檔案系統,掛載點為 merged 目錄
╭─root@esxi-debian-devbox /mnt/overlay2 ╰─# mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workdir=work merged ╭─root@esxi-debian-devbox /mnt/overlay2 ╰─# cd merged
- 新增一個 kickstart.cfg 檔案,然後重新構建 ISO 映象
╭─root@esxi-debian-devbox /mnt/overlay2/merged ╰─# echo '# this is a kickstart config file' > kickstart.cfg ╭─root@esxi-debian-devbox /mnt/overlay2/merged ╰─# genisoimage -U -r -v -T -J -joliet-long -V "CentOS 7 x86_64" -volset "CentOS 7 x86_64" -A "CentOS 7 x86_64" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -no-emul-boot -o /mnt/CentOS-7-x86_64-Minimal-2009-dev.iso . Total translation table size: 124658 Total rockridge attributes bytes: 55187 Total directory bytes: 100352 Path table size(bytes): 140 Done with: The File(s) Block(s) 527985 Writing: Ending Padblock Start Block 528101 Done with: Ending Padblock Block(s) 150 Max brk space used a4000 528251 extents written (1031 MB)
- 掛載新的 ISO 映象驗證後發現確實可行
╭─root@esxi-debian-devbox /mnt/overlay2/merged ╰─# mount -o loop /mnt/CentOS-7-x86_64-Minimal-2009-dev.iso /mnt/newiso mount: /mnt/newiso: WARNING: device write-protected, mounted read-only. ╭─root@esxi-debian-devbox /mnt/overlay2/merged ╰─# cat /mnt/newiso/kickstart.cfg # this is a kickstart config file
前面講到了使用 overlay2 的方式避免複製原映象內容進行重新構建映象的方案,但是 overlay2 對於不是很熟悉的人來講還是比較複雜,光 lowerdir、upperdir、workdir、mergeddir 這四個資料夾的作用和原理就把人直接給整不會了。那麼還有沒有更為簡單一點的方式呢?
別說還真有,只不過這種方式的用途比較侷限。如果僅僅是用於修改 ISO 中的一個檔案或者目錄,可以將該檔案或目錄以 bind 掛載的方式將它掛載到 ISO 目錄目錄對應的檔案上。
原理就是雖然 ISO 目錄本身是隻讀的,但它裡面的檔案和目錄是可以作為一個掛載點的。也就是說我把檔案 A 掛載到檔案 B,並不是在修改檔案 B,這就是 Unix/Linux 檔案系統十分奇妙的地方。同樣運用 bind 掛載的還有 docker 的 volume 以及 pod 的 volume 也是運用同樣的原理,以 bind 的方式將宿主機上的目錄或檔案掛載到容器執行對應的目錄上。對於修改只讀 ISO 裡的檔案/目錄我們當然也可以這樣做。廢話不多說來實踐驗證一下:
- 首先依舊是將 ISO 映象掛載到 /mn/iso 目錄
╭─root@esxi-debian-devbox ~/build ╰─# mount -o loop CentOS-7-x86_64-Minimal-2009.iso /mnt/iso mount: /mnt/iso: WARNING: device write-protected, mounted read-only.
- 接著建立一個 /mnt/files/ks.cfg 檔案,並寫入我們需要的內容
╭─root@esxi-debian-devbox ~/build ╰─# mkdir -p /mnt/files ╭─root@esxi-debian-devbox ~/build ╰─# echo '# this is a kickstart config file' > /mnt/files/ks.cfg
- 接著以 mount --bind 的方式掛載新建的檔案到 ISO 的 EULA 檔案
╭─root@esxi-debian-devbox /mnt/build ╰─# mount --bind /mnt/files/ks.cfg /mnt/iso/EULA ╭─root@esxi-debian-devbox /mnt/build ╰─# cat /mnt/iso/EULA # this is a kickstart config file
可以看到原來 ISO 檔案中的 EULA 檔案已經被成功替換成了我們修改的檔案,然後再重新構建一下該 ISO 映象
╭─root@esxi-debian-devbox /mnt/iso ╰─# genisoimage -U -r -v -T -J -joliet-long -V "CentOS 7 x86_64" -volset "CentOS 7 x86_64" -A "CentOS 7 x86_64" -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -no-emul-boot -o /mnt/CentOS-7-x86_64-Minimal-2009-dev.iso . 然後我們再重新掛載新的 ISO 檔案驗證一下是否可以
╭─root@esxi-debian-devbox /mnt/iso ╰─# mkdir /mnt/newiso ╭─root@esxi-debian-devbox /mnt/iso ╰─# mount -o loop /mnt/CentOS-7-x86_64-Minimal-2009-dev.iso /mnt/newiso mount: /mnt/newiso: WARNING: device write-protected, mounted read-only. ╭─root@esxi-debian-devbox /mnt/iso ╰─# cat /mnt/newiso/EULA # this is a kickstart config file
驗證通過,確實可以!不過這種方式很侷限,比較適用於修改單個檔案如 kickstart.cfg,如果是要新增檔案那還是使用上文提到的 overlay2 的方式更為方便一些。
雖然 ISO 映象和容器映象二者有著本質的差別,但對於只讀和聯合掛載的這些特性二者可以相互借鑑滴。
不止如此 overlay2 這種聯合掛載的特性,還可以用在其他地方。比如我有一個公共的 NFS 共享伺服器,共享著一些目錄,所有人都可以以 root 使用者並以讀寫的許可權進行 NFS 掛載。這種情況下很難保障一些重要的檔案和資料被誤刪。這時候就可以使用 overlay2 的方式將一些重要的檔案資料掛載為 overlay2 的 lowerdir 只讀層,保證這些資料就如容器映象一樣,每次掛載使用的時候都作為一個只讀層。所有的讀寫操作都在 overlay2 的 merged 那一層,不會真正影響到只讀層的內容。
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2903967/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何通過CRM進行遠端支援?
- 如何通過閱讀文件,構建概念模型?模型
- 通過 Spring 框架如何進行JDBC操作呢?Spring框架JDBC
- 通過串列埠進行通訊 :串列埠
- HelloWorld:通過demo,構建黑盒模型模型
- 看 Amazon 如何通過 Nitro System 構建技術優勢
- 看 AWS 如何通過 Nitro System 構建競爭優勢
- 通過qq進行ip定位
- [Flutter翻譯]通過重新編譯Flutter引擎對Flutter應用進行逆向工程。Flutter編譯
- Oracle通過rman進行克隆,你知道如何做嗎?Oracle
- [新手開發記錄] 測試通過之後進行重構
- 如何批次對檔案進行重新命名?
- Go通過cobra快速構建命令列應用Go命令列
- 記錄一篇關於條件查詢語句的用法:1.通過QueryWrapper進行條件構造2.通過Example進行條件構造APP
- ES 24 - 如何通過Elasticsearch進行聚合檢索 (分組統計)Elasticsearch
- Mac系統如何通過自帶的工具進行磁碟修復Mac
- 筆記六:通過 Analyzer 進行分詞筆記分詞
- 通過JNI對C++進行封裝C++封裝
- 通過進攻心態進行有效的網路防禦
- 于振:如何通過倉儲,對實體進行持久化處理?持久化
- 執行時的頁面構建過程
- 使用Angular CLI進行Build (構建) 和 ServeAngularUI
- 如何重新架構 JPVideoPlayer架構IDE
- 介紹下JSP如何進行自動重新整理JS
- ES 筆記六:通過 Analyzer 進行分詞筆記分詞
- 通過nginx進行udp報文負載均衡NginxUDP負載
- 如何進行有效的績效溝通?
- 使用UDP如何進行網路通訊UDP
- 教你如何通過自媒體變現!(建議收藏)
- 【進階5-1期】重新認識建構函式、原型和原型鏈函式原型
- 通過silky框架在.net平臺構建微服務應用框架微服務
- 通過vue-cli3構建一個SSR應用程式Vue
- 通過Gradle自動實現Android元件化模組構建GradleAndroid元件化
- win10通過映象檔案進行升級Win10
- C#如何開發透過USB進行串列埠通訊的Androud上位機C#串列埠
- 國企如何進行資料中臺建設?
- 如何透過建構函式和JPQL生成DTO?函式
- 利用fastlane進行專案的自動化構建AST