用 acbuild 构建 ACI 并在单 Pod 中运行:rkt 的 PostgreSQL + Play Framework 组合镜像示例深度解析
容器运行时云原生网络【免费下载链接】rkt[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.项目地址https://gitcode.com/gh_mirrors/rk/rkt点击查看免费下载本指南基于 rkt 仓库Documentation/examples/build-container目录下的完整示例讲解如何用 acbuild 从零构建两个 ACI应用容器镜像——一个基于 Alpine 的 PostgreSQL 数据库镜像与一个连接该数据库的 Play Framework 示例应用并将二者放入同一个 rkt Pod 中协同运行。读完本文你将掌握 ACI 镜像的挂载点mount point设计、pre-start 初始化钩子、--volume卷绑定与组合 Pod 启动的完整实战方法。示例全景两个 ACI 组合成一个完整应用栈该示例目录以构建容器为主题提供两个可独立构建、又可组合运行的 ACI 镜像PostgreSQL 镜像example.com/postgres提供数据库服务并负责初始化数据Play Framework 示例应用example.com/play-example:17.10一个极简 Web 应用每被访问一次就把计数器写入 PostgreSQL 并回显该页面已被检索 N 次。Play 示例应用依赖 PostgreSQL 数据库因此两个镜像被设计为可在同一个 Pod中运行rkt 的 Pod 天然共享网络命名空间应用通过127.0.0.1即可访问同 Pod 内的数据库无需暴露公网端口。这种一个 Pod 承载完整应用栈的组合方式正是 rkt Pod 模型的核心使用场景。构建工具链acbuild 与 ACI 镜像示例中的两个构建脚本都依赖 [containers/build] 项目提供的acbuild命令行工具需要获取其最新 release。acbuild 的工作方式与 Dockerfile 类似但产物是符合 appc 规范的 ACI 镜像它以acbuild begin开始一次构建、以acbuild write写出.aci文件中间通过一系列acbuild --debug子命令声明依赖、执行命令、设置环境变量与挂载点。两个脚本开头都有相同的守护式写法#!/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检查强制以 root 运行容器构建需要特权操作。同时使用trap注册退出钩子确保中途出错时也能干净地结束构建trap { export EXT$?; acbuild --debug end exit $EXT; } EXITPostgreSQL ACI 的构建与初始化逻辑构建脚本位于 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此处未指定来源从空镜像起步、set-name命名 ACI、dep add添加 Alpine 基础依赖、run在容器内执行apk安装 PostgreSQL 与 bash。目录、挂载点与用户身份# 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这里定义了镜像的两个关键挂载点挂载点名称容器内路径用途data/var/lib/postgresql/data即$PGDATAPostgreSQL 数据目录用于持久化数据库文件custom-sql/customize.sql可选的自定义初始化 SQL 脚本挂载后由 pre-start 钩子执行随后设置用户与运行环境# 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默认创建名为rkt的数据库用户名与密码同样为rkt。这些环境变量与 Docker 官方 postgres 镜像的约定保持一致可被 pre-start 脚本消费也可在rkt run时通过--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三个关键点pre-start 钩子通过set-event-handler pre-start注册Pod 启动前会以postgres用户执行初始化脚本下文展开端口声明port add postgres tcp 5432声明容器监听 TCP 5432PostgreSQL 默认端口这是 ACI 清单中可选的端口声明默认执行命令set-exec postgres定义容器启动后的主进程即直接运行postgres服务。最终write --overwrite postgres-latest-linux-amd64.aci写出产物。pre-start 初始化脚本默认建库与数据复用Documentation/examples/build-container/postgres/postgres-prestart.sh 改编自 Docker 官方 postgres 镜像的入口脚本MIT 许可但刻意不在结尾使用exec $——因为它是 pre-start 钩子而非主进程主进程由set-exec postgres另行启动。脚本的核心逻辑如下用户身份切换若以 root 身份启动且主参数为postgres则创建/修复$PGDATA与/var/run/postgresql的属主与权限chmod 700/775随后以su postgres重新执行自身数据目录探测关键复用逻辑检查$PGDATA/PG_VERSION是否存在# look specifically for PG_VERSION, as it is expected in the DB dir if [ ! -s $PGDATA/PG_VERSION ]; then若该文件不存在说明是全新数据目录执行initdb --usernamepostgres初始化并依据POSTGRES_PASSWORD决定认证方式有密码用md5无密码则输出警告并回退到trust警告文本明确提示在 rkt 默认配置下可访问该端口的基本是同系统上的任意其他容器应通过rkt run --set-env POSTGRES_PASSWORD...显式设置密码若PG_VERSION已存在则跳过全部初始化直接复用现有数据目录——这正是 README 所述若挂载中存在 PostgreSQL 数据目录则直接使用的实现依据建库与授权按POSTGRES_DB默认rkt创建数据库按POSTGRES_USER创建/修改用户并授予超级权限自定义 SQL若容器内存在/customize.sql即custom-sql挂载点的内容则通过psql -f /customize.sql执行if [ -f /customize.sql ]; then echo Using file /customize.sql to configure database ${psql[]} -f /customize.sql fi收尾以pg_ctl -m fast停止临时实例并通过sed将postgresql.conf的listen_addresses改为*使服务监听所有接口。Play Framework 应用 ACI构建脚本位于 Documentation/examples/build-container/play-example/build-play-example.sh它从 Docker 镜像ubuntu:17.10起步。构建过程# 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要点安装openjdk-8运行/编译 Java与postgresql提供psql客户端克隆 Play 示例应用源码后立即autoremove --purge git移除构建期工具避免把不必要的软件带入最终镜像使用activator stage将应用打成可直接执行的发布目录target/universal/stage/与 PostgreSQL 镜像一致set-user/set-group同样设置为postgres。启动编排等待数据库就绪# 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}由于两个 App 位于同一 Pod、共享网络栈Play 应用直接以127.0.0.1作为数据库地址。但 Pod 内两个 App 的启动并无严格顺序保证因此主命令被替换为 Documentation/examples/build-container/play-example/wait-for-postgres.sh 这个先等待、再执行的编排脚本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探测 PostgreSQL 是否已就绪每 10 秒重试一次一旦连通便exec正式的应用启动命令。这种轮询式健康检查是组合 Pod 中解决依赖服务未启动问题的常用手段。自定义 SQL为 Play 应用准备账号与数据库Documentation/examples/build-container/play-example/custom.sql 内容如下CREATE ROLE root SUPERUSER LOGIN; CREATE DATABASE play_example_postgresql;它创建了 Play 应用所需的超级用户root与数据库play_example_postgresql。该文件在运行阶段通过--volume custom-sql,kindhost,source$PWD/play-example/custom.sql以宿主卷形式挂载进 PostgreSQL 镜像的/customize.sql由 pre-start 钩子在数据库初始化阶段执行——这就是 README 所说play 示例的 SQL 定制脚本的传递链路。构建镜像命令与预期产物在Documentation/examples/build-container目录下以特权 shell 依次执行两个构建脚本# (cd postgres ./build-postgres.sh) [...] # (cd play-example ./build-play-example.sh) [...]两个脚本均以 root 运行内部已做EUID校验构建完成后每个目录各产出对应的 ACI 文件# ls */*.aci play-example/play-latest-linux-amd64.aci postgres/postgres-latest-linux-amd64.aci在单个 Pod 中运行两个应用启动命令逐参数解析README 给出的启动命令是# 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各参数含义--insecure-optionsimage跳过对镜像的签名验证允许运行未签名的本地构建镜像本地acbuild write产出的 ACI 没有可信签名默认校验会失败run创建并启动一个 Pod两个.aci作为两个 App 放入同一 Pod共享网络与资源--volume custom-sql,kindhost,source$PWD/play-example/custom.sql把宿主上的custom.sql以宿主卷形式提供给 Pod卷名custom-sql与 PostgreSQL ACI 清单中声明的挂载点同名因此 rkt 会自动将其挂载到镜像内的/customize.sql。这里体现了 rkt 卷机制的一个关键约定--volume只声明卷具体的挂载路径由 ACI 清单中的挂载点mount point决定。详见 Documentation/subcommands/run.md 与 rkt/run.go 中run子命令的语法说明--volume NAME,kindhost,sourceSOURCE_PATH,readOnlyBOOL,recursiveBOOL其中NAME与source宿主路径必填readOnly默认falserecursive在 coreos 与 KVM stage1 下默认true、在 fly stage1 下默认false。若某个挂载点在镜像清单中已声明、但运行期未提供对应卷rkt 会自动为其创建隐式empty卷。若 ACI 未声明挂载点还可使用--mount volumeNAME,targetPATH显式将卷绑定到指定路径--mount放在 App 名之前对所有 App 生效放在某个 App 之后仅对其生效。验证运行结果Pod 启动并完成数据库初始化后先通过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注意两个 App 共享同一个 Pod UUIDa94b94eb且共用默认网络分配的 IP172.16.28.26。由于同一 Pod 内网络共享Play 应用正是通过127.0.0.1访问数据库的。Play 框架应用默认监听 9000 端口直接对该 IP 发起 HTTP 请求即可验证计数功能# 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. [...]每次访问页面回显的检索次数都会 1且该计数值持久化在 PostgreSQL 中——完整验证了PostgreSQL 初始化 → 挂载自定义 SQL 建库 → Play 应用写入并读取计数的整条链路。小结与延伸阅读这个示例浓缩了 rkt 日常使用的三块核心能力ACI 构建acbuild begin/run/copy/environment/mount/set-event-handler/write一套命令即可产出可分发、可校验的镜像卷与持久化通过挂载点声明 --volume宿主卷实现数据库数据目录的持久化与自定义初始化 SQL 的注入组合 Pod 编排多 App 共享 Pod 网络栈配合 pre-start 钩子与等待服务就绪脚本解决启动顺序问题。进一步阅读可参考仓库内的相关资料卷挂载的完整语法与empty/host两类卷 Documentation/subcommands/run.mdrun子命令的全部参数说明--volume、--mount、--set-env等 rkt/run.goPod 清单格式与挂载点、事件钩子的规范定义 Documentation/pod-manifest.md 与 Documentation/aci-hosting.md镜像获取、校验与存储的通用行为 Documentation/image-fetching-behavior.md。赞分享容器运行时云原生网络【免费下载链接】rkt[Project ended] rkt is a pod-native container engine for Linux. It is composable, secure, and built on standards.项目地址https://gitcode.com/gh_mirrors/rk/rkt点击查看免费下载相关推荐rkt 快速上手指南构建 ACI 镜像并运行你的第一个容器化应用rkt 快速上手指南构建 ACI 镜像并运行你的第一个容器化应用 本篇指南以 rktApp Container 规范的参考实现为背景带你从零开始体验完整容器运行时云原生网络理解 rkt 的 App Container 基础ACI 镜像、Pod 执行单元与 appc 规范实现验证理解 rkt 的 App Container 基础ACI 镜像、Pod 执行单元与 appc 规范实现验证 导读 本文以 rkt 官方文档 Documenta容器运行时云原生网络rkt export 实战指南将已退出 Pod 导出为 ACI 镜像rkt export 实战指南将已退出 Pod 导出为 ACI 镜像 rkt export 子命令负责把一个 已经退出exited的单应用 Pod 的根文容器运行时云原生网络上一篇大麦自动抢票脚本上手指南配置说明与常见问题排查下一篇如何快速启动eShopOnAbp项目5分钟搭建完整电商微服务系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

4PAM通信仿真:MATLAB代码到Simulink模型迁移调试全记录

4PAM通信仿真:MATLAB代码到Simulink模型迁移调试全记录

做通信仿真这几年,我一直有个习惯:先拿MATLAB脚本把算法跑通,再挪到Simulink里搭模型。这次手搓4PAM的发射接收链路,本来以为就是个“搬砖活”,结果硬是从代码到模型折腾了一整天,编译报错、波形不显示、误…

2026/9/25 3:53:03 阅读更多 →
医疗器械包装验证方案全解析:密封强度、微生物屏障与加速老化避坑指南

医疗器械包装验证方案全解析:密封强度、微生物屏障与加速老化避坑指南

简介:一份面向医疗器械研发、注册与质量控制人员的包装完整性验证方案文档,对应 YY/T0681.1、YY/T0313 等标准要求,可直接用于包装系统符合性评价与试验记录整理。文档共 1 个 doc 文件,压缩包大小约 80KB,虽体量不大&…

2026/9/25 3:53:03 阅读更多 →
2026低空经济风口已至!襄阳想学无人机怎么选?星辰航空真实学员案例告诉你答案

2026低空经济风口已至!襄阳想学无人机怎么选?星辰航空真实学员案例告诉你答案

最近低空经济热度持续走高,无人机测绘、电力巡检、商业航拍、农田植保等岗位需求不断增加,不少襄阳本地朋友都在问:襄阳无人机培训哪家好?襄阳无人机培训哪家靠谱?襄阳无人机培训哪家专业?襄阳无人机培训哪…

2026/9/25 3:53:03 阅读更多 →

最新新闻

低功耗电压检测电路:MOS管开关控制电阻分压,将待机电流降至nA级

低功耗电压检测电路:MOS管开关控制电阻分压,将待机电流降至nA级

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:59:53 阅读更多 →
Arduino IDE安装ESP8266卡在99%?换源与离线包方案彻底解决

Arduino IDE安装ESP8266卡在99%?换源与离线包方案彻底解决

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:59:53 阅读更多 →
Flowbite 搜索输入框组件完全指南:从基础搜索栏到语音搜索与高级筛选

Flowbite 搜索输入框组件完全指南:从基础搜索栏到语音搜索与高级筛选

UI组件前端 【免费下载链接】flowbite Open-source UI component library and front-end development framework based on Tailwind CSS 项目地址: https://gitcode.com/gh_mirrors/fl/flowbite 点击查看 免费下载 搜索框是每个站点的“入口级”交互组件。本篇基于…

2026/9/25 4:59:53 阅读更多 →
ESP32-C3 当管家:软件模拟 SWD 实现 RP2040 固件下载与日志采集

ESP32-C3 当管家:软件模拟 SWD 实现 RP2040 固件下载与日志采集

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:59:53 阅读更多 →
产线烧录良率排查全攻略:从硬件连接到固件格式的链路诊断

产线烧录良率排查全攻略:从硬件连接到固件格式的链路诊断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:59:53 阅读更多 →
从 Codex CLI 到知识库:TaoToken 统一 Key 驱动的 AI 代理个人知识管理全流程

从 Codex CLI 到知识库:TaoToken 统一 Key 驱动的 AI 代理个人知识管理全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 4:58:52 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →