建 ACI 并在單 Pod 中運(yùn)行:rkt 的 PostgreSQL + Play Framework 組合鏡像示例深度解析)
容器運(yùn)行時(shí)云原生網(wǎng)絡(luò)【免費(fèi)下載鏈接】rkt[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.項(xiàng)目地址https://gitcode.com/gh_mirrors/rk/rkt點(diǎn)擊查看免費(fèi)下載本指南基于 rkt 倉(cāng)庫(kù)Documentation/examples/build-container目錄下的完整示例講解如何用 acbuild 從零構(gòu)建兩個(gè) ACI應(yīng)用容器鏡像——一個(gè)基于 Alpine 的 PostgreSQL 數(shù)據(jù)庫(kù)鏡像與一個(gè)連接該數(shù)據(jù)庫(kù)的 Play Framework 示例應(yīng)用并將二者放入同一個(gè) rkt Pod 中協(xié)同運(yùn)行。讀完本文你將掌握 ACI 鏡像的掛載點(diǎn)mount point設(shè)計(jì)、pre-start 初始化鉤子、--volume卷綁定與組合 Pod 啟動(dòng)的完整實(shí)戰(zhàn)方法。示例全景兩個(gè) ACI 組合成一個(gè)完整應(yīng)用棧該示例目錄以構(gòu)建容器為主題提供兩個(gè)可獨(dú)立構(gòu)建、又可組合運(yùn)行的 ACI 鏡像PostgreSQL 鏡像example.com/postgres提供數(shù)據(jù)庫(kù)服務(wù)并負(fù)責(zé)初始化數(shù)據(jù)Play Framework 示例應(yīng)用example.com/play-example:17.10一個(gè)極簡(jiǎn) Web 應(yīng)用每被訪問(wèn)一次就把計(jì)數(shù)器寫(xiě)入 PostgreSQL 并回顯該頁(yè)面已被檢索 N 次。Play 示例應(yīng)用依賴(lài) PostgreSQL 數(shù)據(jù)庫(kù)因此兩個(gè)鏡像被設(shè)計(jì)為可在同一個(gè) Pod中運(yùn)行rkt 的 Pod 天然共享網(wǎng)絡(luò)命名空間應(yīng)用通過(guò)127.0.0.1即可訪問(wèn)同 Pod 內(nèi)的數(shù)據(jù)庫(kù)無(wú)需暴露公網(wǎng)端口。這種一個(gè) Pod 承載完整應(yīng)用棧的組合方式正是 rkt Pod 模型的核心使用場(chǎng)景。構(gòu)建工具鏈acbuild 與 ACI 鏡像示例中的兩個(gè)構(gòu)建腳本都依賴(lài) [containers/build] 項(xiàng)目提供的acbuild命令行工具需要獲取其最新 release。acbuild 的工作方式與 Dockerfile 類(lèi)似但產(chǎn)物是符合 appc 規(guī)范的 ACI 鏡像它以acbuild begin開(kāi)始一次構(gòu)建、以acbuild write寫(xiě)出.aci文件中間通過(guò)一系列acbuild --debug子命令聲明依賴(lài)、執(zhí)行命令、設(shè)置環(huán)境變量與掛載點(diǎn)。兩個(gè)腳本開(kāi)頭都有相同的守護(hù)式寫(xiě)法#!/usr/bin/env bash set -e if [ $EUID -ne 0 ]; then echo This script uses functionality which requires root privileges exit 1 fiset -e保證任何一步失敗即中止EUID檢查強(qiáng)制以 root 運(yùn)行容器構(gòu)建需要特權(quán)操作。同時(shí)使用trap注冊(cè)退出鉤子確保中途出錯(cuò)時(shí)也能干凈地結(jié)束構(gòu)建trap { export EXT$?; acbuild --debug end exit $EXT; } EXITPostgreSQL ACI 的構(gòu)建與初始化邏輯構(gòu)建腳本位于 Documentation/examples/build-container/postgres/build-postgres.sh逐段解讀如下?;?Alpine 起步并安裝軟件PGDATA/var/lib/postgresql/data # Start the build with an empty ACI acbuild --debug begin # Name the ACI acbuild --debug set-name example.com/postgres # Based on alpine acbuild --debug dep add quay.io/coreos/alpine-sh # Install postgres and bash acbuild --debug run -- apk update acbuild --debug run -- apk add postgresql bash腳本使用begin此處未指定來(lái)源從空鏡像起步、set-name命名 ACI、dep add添加 Alpine 基礎(chǔ)依賴(lài)、run在容器內(nèi)執(zhí)行apk安裝 PostgreSQL 與 bash。目錄、掛載點(diǎn)與用戶身份# Create postgres data directory acbuild --debug run -- mkdir -p $PGDATA acbuild --debug run -- chown -R postgres:postgres $PGDATA # Create postgres run directory acbuild --debug run -- mkdir -p /var/run/postgresql acbuild --debug run -- chown -R postgres:postgres /var/run/postgresql # Add a mount point for postgres data acbuild --debug mount add data $PGDATA # Add a mount point for custom initialization data acbuild --debug mount add custom-sql /customize.sql這里定義了鏡像的兩個(gè)關(guān)鍵掛載點(diǎn)掛載點(diǎn)名稱(chēng)容器內(nèi)路徑用途data/var/lib/postgresql/data即$PGDATAPostgreSQL 數(shù)據(jù)目錄用于持久化數(shù)據(jù)庫(kù)文件custom-sql/customize.sql可選的自定義初始化 SQL 腳本掛載后由 pre-start 鉤子執(zhí)行隨后設(shè)置用戶與運(yùn)行環(huán)境# Set PGDATA env variable acbuild --debug environment add PGDATA $PGDATA # Set user and group acbuild --debug set-user postgres acbuild --debug set-group postgres # Set postgres user, group, and test-db acbuild --debug environment add POSTGRES_USER rkt acbuild --debug environment add POSTGRES_PASSWORD rkt acbuild --debug environment add POSTGRES_DB rkt默認(rèn)創(chuàng)建名為rkt的數(shù)據(jù)庫(kù)用戶名與密碼同樣為rkt。這些環(huán)境變量與 Docker 官方 postgres 鏡像的約定保持一致可被 pre-start 腳本消費(fèi)也可在rkt run時(shí)通過(guò)--set-env覆蓋后文詳述。pre-start 初始化鉤子與端口# Add pre-start hook that will set up the database acbuild --debug copy postgres-prestart.sh /root/postgres-prestart.sh acbuild --debug set-event-handler pre-start /root/postgres-prestart.sh postgres # Add postgres port acbuild --debug port add postgres tcp 5432 # Run postgres server acbuild --debug set-exec postgres三個(gè)關(guān)鍵點(diǎn)pre-start 鉤子通過(guò)set-event-handler pre-start注冊(cè)Pod 啟動(dòng)前會(huì)以postgres用戶執(zhí)行初始化腳本下文展開(kāi)端口聲明port add postgres tcp 5432聲明容器監(jiān)聽(tīng) TCP 5432PostgreSQL 默認(rèn)端口這是 ACI 清單中可選的端口聲明默認(rèn)執(zhí)行命令set-exec postgres定義容器啟動(dòng)后的主進(jìn)程即直接運(yùn)行postgres服務(wù)。最終write --overwrite postgres-latest-linux-amd64.aci寫(xiě)出產(chǎn)物。pre-start 初始化腳本默認(rèn)建庫(kù)與數(shù)據(jù)復(fù)用Documentation/examples/build-container/postgres/postgres-prestart.sh 改編自 Docker 官方 postgres 鏡像的入口腳本MIT 許可但刻意不在結(jié)尾使用exec $——因?yàn)樗?pre-start 鉤子而非主進(jìn)程主進(jìn)程由set-exec postgres另行啟動(dòng)。腳本的核心邏輯如下用戶身份切換若以 root 身份啟動(dòng)且主參數(shù)為postgres則創(chuàng)建/修復(fù)$PGDATA與/var/run/postgresql的屬主與權(quán)限chmod 700/775隨后以su postgres重新執(zhí)行自身數(shù)據(jù)目錄探測(cè)關(guān)鍵復(fù)用邏輯檢查$PGDATA/PG_VERSION是否存在# look specifically for PG_VERSION, as it is expected in the DB dir if [ ! -s $PGDATA/PG_VERSION ]; then若該文件不存在說(shuō)明是全新數(shù)據(jù)目錄執(zhí)行initdb --usernamepostgres初始化并依據(jù)POSTGRES_PASSWORD決定認(rèn)證方式有密碼用md5無(wú)密碼則輸出警告并回退到trust警告文本明確提示在 rkt 默認(rèn)配置下可訪問(wèn)該端口的基本是同系統(tǒng)上的任意其他容器應(yīng)通過(guò)rkt run --set-env POSTGRES_PASSWORD...顯式設(shè)置密碼若PG_VERSION已存在則跳過(guò)全部初始化直接復(fù)用現(xiàn)有數(shù)據(jù)目錄——這正是 README 所述若掛載中存在 PostgreSQL 數(shù)據(jù)目錄則直接使用的實(shí)現(xiàn)依據(jù)建庫(kù)與授權(quán)按POSTGRES_DB默認(rèn)rkt創(chuàng)建數(shù)據(jù)庫(kù)按POSTGRES_USER創(chuàng)建/修改用戶并授予超級(jí)權(quán)限自定義 SQL若容器內(nèi)存在/customize.sql即custom-sql掛載點(diǎn)的內(nèi)容則通過(guò)psql -f /customize.sql執(zhí)行if [ -f /customize.sql ]; then echo Using file /customize.sql to configure database ${psql[]} -f /customize.sql fi收尾以pg_ctl -m fast停止臨時(shí)實(shí)例并通過(guò)sed將postgresql.conf的listen_addresses改為*使服務(wù)監(jiān)聽(tīng)所有接口。Play Framework 應(yīng)用 ACI構(gòu)建腳本位于 Documentation/examples/build-container/play-example/build-play-example.sh它從 Docker 鏡像ubuntu:17.10起步。構(gòu)建過(guò)程# Start the build with an empty ACI acbuild --debug begin docker://ubuntu:17.10 ... # Name the ACI acbuild --debug set-name example.com/play-example # Install java, psql, and git acbuild --debug run -- apt-get update acbuild --debug run -- apt-get -y install openjdk-8-jre openjdk-8-jdk git postgresql # Clone play example repo acbuild --debug run -- git clone https://github.com/ics-software-engineering/play-example-postgresql.git /play-example acbuild --debug run -- apt-get -y autoremove --purge git acbuild --debug run -- chown -R postgres:postgres /play-example STAGE_DIR/play-example/target/universal/stage/ TARGET_BIN${STAGE_DIR}/bin/play-example-postgresql # Build example acbuild --debug run -- /bin/bash -c cd /play-example su postgres -c ./activator stage要點(diǎn)安裝openjdk-8運(yùn)行/編譯 Java與postgresql提供psql客戶端克隆 Play 示例應(yīng)用源碼后立即autoremove --purge git移除構(gòu)建期工具避免把不必要的軟件帶入最終鏡像使用activator stage將應(yīng)用打成可直接執(zhí)行的發(fā)布目錄target/universal/stage/與 PostgreSQL 鏡像一致set-user/set-group同樣設(shè)置為postgres。啟動(dòng)編排等待數(shù)據(jù)庫(kù)就緒# Copy wait for postgres script acbuild --debug copy wait-for-postgres.sh /wait-for-postgres.sh # Run postgres server acbuild --debug set-exec /wait-for-postgres.sh 127.0.0.1 ${TARGET_BIN}由于兩個(gè) App 位于同一 Pod、共享網(wǎng)絡(luò)棧Play 應(yīng)用直接以127.0.0.1作為數(shù)據(jù)庫(kù)地址。但 Pod 內(nèi)兩個(gè) App 的啟動(dòng)并無(wú)嚴(yán)格順序保證因此主命令被替換為 Documentation/examples/build-container/play-example/wait-for-postgres.sh 這個(gè)先等待、再執(zhí)行的編排腳本host$1 shift cmd$ until psql -h $host -U postgres -c \q; do 2 echo Postgres is unavailable - sleeping sleep 10 done 2 echo Postgres is up - executing command exec $cmd腳本不斷用psql -h 127.0.0.1 -U postgres -c \q探測(cè) PostgreSQL 是否已就緒每 10 秒重試一次一旦連通便exec正式的應(yīng)用啟動(dòng)命令。這種輪詢式健康檢查是組合 Pod 中解決依賴(lài)服務(wù)未啟動(dòng)問(wèn)題的常用手段。自定義 SQL為 Play 應(yīng)用準(zhǔn)備賬號(hào)與數(shù)據(jù)庫(kù)Documentation/examples/build-container/play-example/custom.sql 內(nèi)容如下CREATE ROLE root SUPERUSER LOGIN; CREATE DATABASE play_example_postgresql;它創(chuàng)建了 Play 應(yīng)用所需的超級(jí)用戶root與數(shù)據(jù)庫(kù)play_example_postgresql。該文件在運(yùn)行階段通過(guò)--volume custom-sql,kindhost,source$PWD/play-example/custom.sql以宿主卷形式掛載進(jìn) PostgreSQL 鏡像的/customize.sql由 pre-start 鉤子在數(shù)據(jù)庫(kù)初始化階段執(zhí)行——這就是 README 所說(shuō)play 示例的 SQL 定制腳本的傳遞鏈路。構(gòu)建鏡像命令與預(yù)期產(chǎn)物在Documentation/examples/build-container目錄下以特權(quán) shell 依次執(zhí)行兩個(gè)構(gòu)建腳本# (cd postgres ./build-postgres.sh) [...] # (cd play-example ./build-play-example.sh) [...]兩個(gè)腳本均以 root 運(yùn)行內(nèi)部已做EUID校驗(yàn)構(gòu)建完成后每個(gè)目錄各產(chǎn)出對(duì)應(yīng)的 ACI 文件# ls */*.aci play-example/play-latest-linux-amd64.aci postgres/postgres-latest-linux-amd64.aci在單個(gè) Pod 中運(yùn)行兩個(gè)應(yīng)用啟動(dòng)命令逐參數(shù)解析README 給出的啟動(dòng)命令是# rkt --insecure-optionsimage \ run \ --volume custom-sql,kindhost,source$PWD/play-example/custom.sql \ postgres/postgres-latest-linux-amd64.aci \ play-example/play-latest-linux-amd64.aci各參數(shù)含義--insecure-optionsimage跳過(guò)對(duì)鏡像的簽名驗(yàn)證允許運(yùn)行未簽名的本地構(gòu)建鏡像本地acbuild write產(chǎn)出的 ACI 沒(méi)有可信簽名默認(rèn)校驗(yàn)會(huì)失敗run創(chuàng)建并啟動(dòng)一個(gè) Pod兩個(gè).aci作為兩個(gè) App 放入同一 Pod共享網(wǎng)絡(luò)與資源--volume custom-sql,kindhost,source$PWD/play-example/custom.sql把宿主上的custom.sql以宿主卷形式提供給 Pod卷名custom-sql與 PostgreSQL ACI 清單中聲明的掛載點(diǎn)同名因此 rkt 會(huì)自動(dòng)將其掛載到鏡像內(nèi)的/customize.sql。這里體現(xiàn)了 rkt 卷機(jī)制的一個(gè)關(guān)鍵約定--volume只聲明卷具體的掛載路徑由 ACI 清單中的掛載點(diǎn)mount point決定。詳見(jiàn) Documentation/subcommands/run.md 與 rkt/run.go 中run子命令的語(yǔ)法說(shuō)明--volume NAME,kindhost,sourceSOURCE_PATH,readOnlyBOOL,recursiveBOOL其中NAME與source宿主路徑必填readOnly默認(rèn)falserecursive在 coreos 與 KVM stage1 下默認(rèn)true、在 fly stage1 下默認(rèn)false。若某個(gè)掛載點(diǎn)在鏡像清單中已聲明、但運(yùn)行期未提供對(duì)應(yīng)卷rkt 會(huì)自動(dòng)為其創(chuàng)建隱式empty卷。若 ACI 未聲明掛載點(diǎn)還可使用--mount volumeNAME,targetPATH顯式將卷綁定到指定路徑--mount放在 App 名之前對(duì)所有 App 生效放在某個(gè) App 之后僅對(duì)其生效。驗(yàn)證運(yùn)行結(jié)果Pod 啟動(dòng)并完成數(shù)據(jù)庫(kù)初始化后先通過(guò)rkt list獲取 Pod 的 IP示例中為172.16.28.26# rkt list UUID APP IMAGE NAME STATE CREATED STARTED NETWORKS a94b94eb postgres example.com/postgres running 11 seconds ago 11 seconds ago default:ip4172.16.28.26 play-example example.com/play-example:17.10注意兩個(gè) App 共享同一個(gè) Pod UUIDa94b94eb且共用默認(rèn)網(wǎng)絡(luò)分配的 IP172.16.28.26。由于同一 Pod 內(nèi)網(wǎng)絡(luò)共享Play 應(yīng)用正是通過(guò)127.0.0.1訪問(wèn)數(shù)據(jù)庫(kù)的。Play 框架應(yīng)用默認(rèn)監(jiān)聽(tīng) 9000 端口直接對(duì)該 IP 發(fā)起 HTTP 請(qǐng)求即可驗(yàn)證計(jì)數(shù)功能# curl 172.16.28.26:9000 [...] This page has been retrieved 0 times. [...] # curl 172.16.28.26:9000 [...] This page has been retrieved 1 times. [...]每次訪問(wèn)頁(yè)面回顯的檢索次數(shù)都會(huì) 1且該計(jì)數(shù)值持久化在 PostgreSQL 中——完整驗(yàn)證了PostgreSQL 初始化 → 掛載自定義 SQL 建庫(kù) → Play 應(yīng)用寫(xiě)入并讀取計(jì)數(shù)的整條鏈路。小結(jié)與延伸閱讀這個(gè)示例濃縮了 rkt 日常使用的三塊核心能力ACI 構(gòu)建acbuild begin/run/copy/environment/mount/set-event-handler/write一套命令即可產(chǎn)出可分發(fā)、可校驗(yàn)的鏡像卷與持久化通過(guò)掛載點(diǎn)聲明 --volume宿主卷實(shí)現(xiàn)數(shù)據(jù)庫(kù)數(shù)據(jù)目錄的持久化與自定義初始化 SQL 的注入組合 Pod 編排多 App 共享 Pod 網(wǎng)絡(luò)棧配合 pre-start 鉤子與等待服務(wù)就緒腳本解決啟動(dòng)順序問(wèn)題。進(jìn)一步閱讀可參考倉(cāng)庫(kù)內(nèi)的相關(guān)資料卷掛載的完整語(yǔ)法與empty/host兩類(lèi)卷 Documentation/subcommands/run.mdrun子命令的全部參數(shù)說(shuō)明--volume、--mount、--set-env等 rkt/run.goPod 清單格式與掛載點(diǎn)、事件鉤子的規(guī)范定義 Documentation/pod-manifest.md 與 Documentation/aci-hosting.md鏡像獲取、校驗(yàn)與存儲(chǔ)的通用行為 Documentation/image-fetching-behavior.md。贊分享容器運(yùn)行時(shí)云原生網(wǎng)絡(luò)【免費(fèi)下載鏈接】rkt[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.項(xiàng)目地址https://gitcode.com/gh_mirrors/rk/rkt點(diǎn)擊查看免費(fèi)下載相關(guān)推薦rkt 快速上手指南構(gòu)建 ACI 鏡像并運(yùn)行你的第一個(gè)容器化應(yīng)用rkt 快速上手指南構(gòu)建 ACI 鏡像并運(yùn)行你的第一個(gè)容器化應(yīng)用 本篇指南以 rktApp Container 規(guī)范的參考實(shí)現(xiàn)為背景帶你從零開(kāi)始體驗(yàn)完整容器運(yùn)行時(shí)云原生網(wǎng)絡(luò)理解 rkt 的 App Container 基礎(chǔ)ACI 鏡像、Pod 執(zhí)行單元與 appc 規(guī)范實(shí)現(xiàn)驗(yàn)證理解 rkt 的 App Container 基礎(chǔ)ACI 鏡像、Pod 執(zhí)行單元與 appc 規(guī)范實(shí)現(xiàn)驗(yàn)證 導(dǎo)讀 本文以 rkt 官方文檔 Documenta容器運(yùn)行時(shí)云原生網(wǎng)絡(luò)rkt export 實(shí)戰(zhàn)指南將已退出 Pod 導(dǎo)出為 ACI 鏡像rkt export 實(shí)戰(zhàn)指南將已退出 Pod 導(dǎo)出為 ACI 鏡像 rkt export 子命令負(fù)責(zé)把一個(gè) 已經(jīng)退出exited的單應(yīng)用 Pod 的根文容器運(yùn)行時(shí)云原生網(wǎng)絡(luò)上一篇大麥自動(dòng)搶票腳本上手指南配置說(shuō)明與常見(jiàn)問(wèn)題排查下一篇如何快速啟動(dòng)eShopOnAbp項(xiàng)目5分鐘搭建完整電商微服務(wù)系統(tǒng)創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考