ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ARM64离线部署tendis 2.7.0:镜像与配置齐步走

ARM64离线部署tendis 2.7.0:镜像与配置齐步走 简介面向需要在ARM64架构CPU上离线部署Tendis 2.7.0单机版的运维与开发人员这份基于docker-compose的部署工具解决离线环境下软件分发和安装配置的痛点。资源包共19个文件压缩后体积约310.27MB主要包含shell控制脚本、conf/tpl配置模板、docker-compose yaml编排文件、Dockerfile以及ARM64离线镜像包templates目录提供可复用的配置模板可按实际环境调整端口、密码、数据目录等参数。该工具完整覆盖部署、启动、停止、卸载、检测等操作支持数据目录、端口、密码灵活配置并可将Tendis配置与数据目录持久化到宿主机避免容器重建导致数据丢失适合国产化替代或ARM64服务器上的生产/测试环境搭建。目前已有282人学习下载对于需要快速掌握ARM64容器化部署Tendis的团队是一套结构清晰、值得参考的离线落地实践。1. ARM64 离线部署 tendis 2.7.0真正难的不是 docker-compose而是镜像与配置齐步走ARM64 服务器在机房里已经是常态私有化交付现场经常是机器到位了网络策略还没放开。tendis 2.7.0 作为兼容 Redis 协议、把数据落到 RocksDB 的存储组件单机版部署要解决的其实是三个问题镜像拿不到、镜像架构和 CPU 不匹配、容器启动缺配置。docker-compose 本身只是编排层它不会帮你绕过这些前置条件。把 tendis 单机版做成一个可以整体拷贝的离线部署工具目录里一次性放好镜像 tar、compose 文件、tendis 配置、install.sh 脚本和校验清单目标节点拷进去之后执行一条命令即可完成从docker load到健康检查的全过程。这套做法对经常接触 ARM64 交付的平台工程师和运维是有直接参考价值的下面按造包、编排、脚本、验证四个阶段展开。2. 先预备离线镜像确认 ARM64 架构后再打包 tendis 2.7.02.1 在联网构建机上用 --platform 拉取并导出镜像离线部署工具的第一步是在能联网的构建机上把 tendis 2.7.0 的 arm64 镜像生成出来。构建机可以是同为 ARM64 的机器也可以在 x86_64 机器上直接拉取 ARM64 镜像层只要镜像仓库的 manifest 里存在linux/arm64平台分支。常见做法是先检查 manifest再拉取导出命令如下docker manifest inspect tendis:2.7.0 | grep -E architecture|os docker pull --platform linux/arm64 tendis:2.7.0 docker save tendis:2.7.0 -o images/tendis-2.7.0-arm64.tar第一行做架构预检确认仓库里确实有 arm64 分支。如果 manifest 里 architecture 是 amd64继续拉取导出入不了离线包。第二行是关键--platform linux/arm64让 Docker 在 manifest list 中选择 arm64 分支不受构建机自身 CPU 架构影响。第三行把完整镜像层导出为 tar。docker save的产物在离线节点上用docker load恢复。如果镜像体积大建议压缩传输docker save tendis:2.7.0 | gzip -1 images/tendis-2.7.0-arm64.tar.gz。-1是低压缩级别离线节点加载时受磁盘和 CPU 瓶颈影响压缩级别太高会拖慢docker load。目标节点上若已有同名同 tag 镜像docker load不会报错但会留下悬空层脚本里一般在 load 前先查docker images -q tendis:2.7.0存在就跳过。注意manifest 里是 arm64 和运行时能跑是两码事。如果发布方编译时启用了 ARMv8.2 特性老款 ARMv8.0 的 CPU 启动时会报 Illegal instruction这个坑跟镜像 tar 本身没有关系尽量选择带明确基线版本的镜像。2.2 没有现成 ARM64 镜像时走 buildx 或源码打包项目组只提供 amd64 版 tendis 镜像的情况很常见。此时可以在构建机上用docker buildx构建 ARM64 镜像但要清楚 buildx 在 x86 主机执行 arm64 的 RUN 指令时依赖 qemu 模拟 arm64 内核的 binfmt 机制编译大项目会明显变慢而且容易在依赖本地 x86 二进制时碰壁。更可控的做法是把准备好的 tendis 二进制、配置和数据目录一起塞进多架构基础镜像。我封装工具时会在仓库里留一个 build-helper 目录Dockerfile 框架如下FROM --platform$BUILDPLATFORM debian:bullseye-slim AS prep ARG TARGETARCH COPY tendis-${TARGETARCH}-2.7.0.tar.gz /tmp/ FROM debian:bullseye-slim COPY --fromprep /tmp/tendis-${TARGETARCH}-2.7.0.tar.gz /tmp/ RUN tar xzf /tmp/tendis-${TARGETARCH}-2.7.0.tar.gz -C /usr/local/tendis \ useradd -r tendis chown -R tendis:tendis /usr/local/tendis USER tendis EXPOSE 16379 ENTRYPOINT [/usr/local/tendis/bin/tendis]构建执行的是docker buildx build --platform linux/arm64 --output typeoci,desttendis-2.7.0-arm64.tar .关键点是ARG TARGETARCH由 buildx 自动注入COPY tendis-${TARGETARCH}-2.7.0.tar.gz会按目标平台选择对应二进制的文件名。生成的 OCI tar 在离线节点上可以用skopeo copy oci-archive:tendis-2.7.0-arm64.tar docker-daemon:tendis:2.7.0导入。真正把 tendis 2.7.0 源码交叉编译成 ARM64 二进制涉及 RocksDB 版本、编译选项、透明大页取舍不是几行 Dockerfile 能覆盖的。离线部署工具要把这部分隔离到造包阶段让部署的人只消费最终的镜像 tar。2.3 离线工具分发目录的结构与体积预估整个离线工具建议设计成一个目录直接压缩成单个归档分发。具体结构如下路径作用部署时状态docker-compose.yml容器编排声明 tendis 服务原位使用conf/tendis.conftendis 启动配置读入容器只读挂载images/tendis-2.7.0-arm64.tardocker load的镜像归档load 后可留可删scripts/install.sh一键部署主入口原地执行checksum.sha256整个工具包的完整性校验开跑前校验这个结构解决离线交付里“东西不全”的问题。很多时候离线部署失败不是镜像或者配置写错而是复制过程中丢文件所以工具包根目录一定要放 checksuminstall.sh 第一步做校验不通过就不允许继续执行。3. docker-compose 编排与 tendis 配置端口、数据目录和资源边界3.1 单机版最小的 docker-compose.yml 写法离线环境里 docker-compose 只需要保证一件事不依赖网络、不依赖构建、容器能自行恢复。最小可用的 compose 文件如下version: 3.8 services: tendis: image: tendis:2.7.0 container_name: tendis-single restart: unless-stopped ports: - 127.0.0.1:16379:16379 volumes: - ./data:/data:rw - ./conf/tendis.conf:/tc/tendis.conf:ro command: - /usr/local/tendis/bin/tendis - -f - /tc/tendis.conf environment: - TZAsia/Shanghai ulimits: nofile: soft: 1024000 hard: 1024000参数说明restart: unless-stopped保证节点重启后 Docker daemon 自动把容器拉起这是离线节点无人值守的第一道保险。ports只绑定127.0.0.1单机部署默认不开远程访问。如果同一台机器其他容器要访问可以放到同一个自定义 network绑定宿主机端口是给 redis-cli 和运维探针用的。command里写绝对路径避免镜像没设默认启动入口时 compose 去猜命令。nofile软硬限制都调到 1024000处理连接数堆积时的 too many open files。特意保留version: 3.8是为了兼容还在用 docker-compose v1 的旧节点新版 Docker 会忽略该字段不影响执行。3.2 tendis 配置文件挂载进容器而不是打进镜像tendis 配置建议放conf/tendis.conf再挂载改配置不用重建镜像离线改错也能直接改回原文件。单机版里我常用的最小配置如下port 16379 bind 0.0.0.0 protected-mode no daemonize no dir /data pidfile /data/tendis.pid logfile /data/tendis.log maxmemory 10737418240关键点daemonize no必须保持 no。容器里 PID 1 必须是 tendis 进程本身daemonize 后容器启动完就退出compose 会按 restart 策略反复拉起重启。dir /data对应 compose 挂载的宿主机数据目录RocksDB 的数据文件写在这里容器重建不丢。logfile /data/tendis.log落盘保存方便 docker logs 之外做历史排查。如果镜像构建时把日志直接输出到 stdout这里会出现双写按现场需要二选一。protected-mode no配合bind 0.0.0.0使用。部署环境是隔离内网时这样写没问题如果要跨网段访问建议再叠加一条requirepass。3.3 ARM64 节点上资源限制参数的选型ARM64 服务器内存分配策略和 x86 有差异尤其开启了大页内存和 NUMA 的机器资源边界最好写进 compose。docker compose v2 单独执行up时顶层的mem_limit、memswap_limit、cpuset是直接生效的示例mem_limit: 8g memswap_limit: 8g cpuset: 0-3 pids_limit: 4096参数速查表参数与 x86 的主要差别典型取值mem_limitARM 机型内存密度高按可用内存 70% 留余量8gmemswap_limit与 mem_limit 相等禁用 swap 兜底8gcpuset固定到大核区间避免大小核调度抖动0-3pids_limit限制 fork 进程数防句柄泄漏4096这里最容易出事的是 RocksDB block cache。tendis 启动后即使没有请求也会按maxmemory配置预留相当一部分内存作为 block cachemem_limit设得太紧进程会在 compaction 或后台写盘期间被内核 OOM 杀掉现象是容器一直重启但不报配置错误。3.4 compose 文件离线执行时最容易踩的两个坑第一个坑是 compose 里残留build段。离线目录里只要还有 Dockerfiledocker compose up就会优先尝试构建构建时找不到基础镜像就卡住。工具脚本应该在启动前用docker compose config --quiet做校验。第二个坑是命令差异。部分机器只有docker-composev1部分只有docker composev2。脚本不能写死常见做法是探测后赋值变量if docker compose version /dev/null 21; then COMPOSE_CMDdocker compose elif docker-compose version /dev/null 21; then COMPOSE_CMDdocker-compose else echo docker compose not found; exit 1 fi这个探测要放在 install.sh 的统一入口处后续所有执行都使用同一个$COMPOSE_CMD避免 v1/v2 参数差异引发二次问题。4. 一键部署脚本镜像加载、compose up 与健康检查的顺序不能乱4.1 脚本主流程和前置条件检查一键部署脚本由前置检查、镜像加载、compose 启动、健康检查四个阶段组成。顺序颠倒会让错误解释变得困难比如先启动 compose 再加载镜像离线节点上 compose 会直接去远程仓库拉取然后长时间卡住。前置检查 checklist 如下uname -m必须是 aarch64 或 arm64docker version可连通daemon 处于运行状态镜像 tar 存在且 checksum 匹配端口未被占用数据目录可写且磁盘剩余空间足够。脚本核心片段#!/usr/bin/env bash set -Eeuo pipefail cd $(dirname $0) ROOT_DIR$(pwd) IMAGE_NAMEtendis:2.7.0 IMAGE_TARimages/tendis-2.7.0-arm64.tar PORT16379 precheck() { local arch$(uname -m) if [[ ${arch} ! aarch64 ${arch} ! arm64 ]]; then echo arch not supported: ${arch}; exit 1 fi if ! docker version /dev/null 21; then echo docker daemon not ready; exit 1 fi if ss -lnt | grep -q [:.]${PORT} ; then echo port ${PORT} already in use; exit 1 fi }参数解释set -Eeuo pipefail的-E让 ERR trap 覆盖函数内部错误-u防止未定义变量把路径拼坏。端口检查用ss -lnt新装离线系统经常没有 netstatss 由 iproute2 提供基本是内核标配。架构检查放在最前面也能顺带把 qemu 模拟 arm64 的场景挡在流程外。qemu-user 模拟出的 aarch64 在uname -m里同样显示 aarch64所以这个检查只是保证宿主机确实是 ARM64不能代替对模拟部署的判断。4.2 镜像加载、compose up 与健康检查的代码骨架load_image() { if docker images --format {{.Repository}}:{{.Tag}} | grep -q ${IMAGE_NAME}; then echo image already loaded, skip return 0 fi docker load -i ${IMAGE_TAR} echo image loaded: ${IMAGE_NAME} } start_compose() { ${COMPOSE_CMD} config --quiet ${COMPOSE_CMD} up -d --no-build echo tendis container started } wait_tendis_online() { local i0 while (( i 30 )); do if (exec 3/dev/tcp/127.0.0.1/${PORT}) 2/dev/null; then exec 3- 3- echo tendis on ${PORT} is accepting connections return 0 fi sleep 2 (( i )) done return 1 } trap echo deploy failed; docker ps -a --filter nametendis-single; docker logs --tail 100 tendis-single ERR main() { precheck load_image start_compose wait_tendis_online } main $逻辑说明docker compose config --quiet在 up 前检查编排文件。--quiet是 v2 参数v1 用docker-compose config -q由 COMPOSE_CMD 分支保证命令正确。--no-build必须保留。离线目录里一旦存在构建文件没有这个参数就会触发网络依赖。/dev/tcp是 bash 内置的 TCP 通道在没有 nc、curl 的最小系统里也能做端口探测。它只能验证 TCP accept协议层面的 ping 放到部署后验证阶段处理。ERR trap 打印容器列表和最近 100 行日志失败现场保留在终端不需要重新翻日志。4.3 失败时的三类错误信号与排查方法4.3.1 exec format error容器显示 Exiteddocker logs输出exec format error优先怀疑镜像平台标签。确认命令docker image inspect tendis:2.7.0 --format {{.Architecture}} {{.Os}}正常输出为arm64 linux。显示amd64时说明构建机打包阶段--platform linux/arm64没有生效或者是后续有人用错误架构重新打了镜像。替换正确架构的镜像即可。4.3.2 容器反复重启且 ExitCode 为 137ExitCode 137 通常是 OOM 或被 kill。先查 OOMKilled 字段docker inspect tendis-single --format {{.State.OOMKilled}} {{.State.ExitCode}}OOMKilled 为 true 时按第 3.3 节调大 mem_limit或减小配置里 maxmemory 预留空间。宿主机的 dmesg 一般保留out of memory记录cgroup v2 环境下用journalctl -k查看。4.3.3 端口 bind 冲突的时序问题预检查已经查过端口监听但 docker-proxy 占用端口时 ss 不一定直接显示尤其是 ipv4、ipv6 绑定并存时。推荐两条命令复合确认ss -lntp | grep 16379 docker ps -a --filter publish16379第二条更直接能列出所有声明过该端口映射的容器失败提示里给出已占用容器的名称排错路径会短很多。5. 部署后的验证与加固redis-cli、systemd 与离线包的 checksum5.1 部署完先做三个协议级验证镜像和配置都到位后不能用“端口能通”当作成功标准。tendis 兼容 Redis 协议最省事的验证就是 redis-clidocker exec tendis-single redis-cli -p 16379 ping docker exec tendis-single redis-cli -p 16379 info server ss -lnt | grep 16379第一行验证读写通道第二行确认启动后的版本与编译平台。如果镜像里没内置 redis-cli改用docker exec tendis-single sh -c redis-cli -p 16379 ping或者从宿主机 redis-cli 连接127.0.0.1:16379。info 输出里顺带确认run_id避免多台机器之间复制工具包后误部署了旧配置。5.2 将部署工具托管到 systemd离线节点经常按需重启compose 的 restart 策略能拉起容器但工具目录的加载顺序最好交给 systemd 统一管理。unit 文件放在/etc/systemd/system/tendis-deploy.service[Unit] Descriptiontendis offline deploy service Requiresdocker.service Afterdocker.service network-online.target [Service] Typeoneshot RemainAfterExityes WorkingDirectory/opt/tendis-offline ExecStart/opt/tendis-offline/scripts/install.sh start ExecStop/opt/tendis-offline/scripts/install.sh stop ExecReload/opt/tendis-offline/scripts/install.sh reload [Install] WantedBymulti-user.targetTypeoneshot配合RemainAfterExityes让 install.sh 结束后 unit 保持 activesystemctl restart才能正确走 stop、start 流程。ExecStart 等路径写绝对路径不能依赖 systemd 服务环境里的相对路径。5.3 用 checksum 和冷备闭环一个单机版工具离线包会在多台 ARM64 节点间复制镜像 tar 被截断或覆盖的情况并不少见。工具包分发时生成校验清单find . -type f -exec sha256sum {} \; checksum.sha256install.sh 的 precheck 里校验通过后再执行后续步骤。这样可以把“镜像损坏”和“容器启动失败”两类问题快速区分开避免在错误方向上反复抓日志。最后的备份环节也建议固定成一条命令单机版 tendis 的数据都在/data下备份时先docker stop做一次冷备再用tar czf style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;" />
返回列表