667 lines
89 KiB
HTML
667 lines
89 KiB
HTML
<!doctype html><html lang=zh-cn dir=ltr class=scroll-smooth data-default-appearance=light data-auto-appearance=true><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><meta name=theme-color content="#ffffff"><title>MinIO对象存储部署:S3兼容的私有化存储方案 · 华禹 个人博客</title><meta name=title content="MinIO对象存储部署:S3兼容的私有化存储方案 · 华禹 个人博客"><script type=text/javascript src=http://blog.hys.my/js/appearance.min.8a082f81b27f3cb2ee528df0b0bdc39787034cf2cc34d4669fbc9977c929023c.js integrity="sha256-iggvgbJ/PLLuUo3wsL3Dl4cDTPLMNNRmn7yZd8kpAjw="></script><link type=text/css rel=stylesheet href=http://blog.hys.my/css/main.bundle.min.100caa677b4bc416cdd884107b203b4869f9b413a19aa57d12069fb826f1abe9.css integrity="sha256-EAyqZ3tLxBbN2IQQeyA7SGn5tBOhmqV9EgafuCbxq+k="><script defer type=text/javascript id=script-bundle src=http://blog.hys.my/js/main.bundle.min.ad7c1061b54aa5c79b6614847630c72567108bdf84dbf18d025ed692b0074cfe.js integrity="sha256-rXwQYbVKpcebZhSEdjDHJWcQi9+E2/GNAl7WkrAHTP4=" data-copy data-copied></script><meta name=description content="
|
||
|
||
MinIO 是目前最成熟的 S3 兼容私有化对象存储方案。它用 Go 语言编写,单个二进制文件部署,没有外部依赖,性能在同类产品中领先。MinIO 完整实现了 S3 API(包括 Select、Encryption、Versioning、Object Lock 等),绝大多数 S3 SDK 和工具可以零修改对接。
|
||
|
||
"><link rel=canonical href=http://blog.hys.my/posts/minio/><link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png><link rel=icon type=image/png sizes=32x32 href=/favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=/favicon-16x16.png><link rel=manifest href=/site.webmanifest><meta property="og:url" content="http://blog.hys.my/posts/minio/"><meta property="og:site_name" content="华禹 个人博客"><meta property="og:title" content="MinIO对象存储部署:S3兼容的私有化存储方案"><meta property="og:description" content="MinIO 是目前最成熟的 S3 兼容私有化对象存储方案。它用 Go 语言编写,单个二进制文件部署,没有外部依赖,性能在同类产品中领先。MinIO 完整实现了 S3 API(包括 Select、Encryption、Versioning、Object Lock 等),绝大多数 S3 SDK 和工具可以零修改对接。"><meta property="og:locale" content="zh_cn"><meta property="og:type" content="article"><meta property="article:section" content="posts"><meta property="article:published_time" content="2026-04-18T10:00:00+08:00"><meta property="article:modified_time" content="2026-04-18T10:00:00+08:00"><meta property="article:tag" content="MinIO"><meta property="article:tag" content="对象存储"><meta property="article:tag" content="S3"><meta property="article:tag" content="部署指南"><meta property="article:tag" content="私有化存储"><meta name=twitter:card content="summary"><meta name=twitter:title content="MinIO对象存储部署:S3兼容的私有化存储方案"><meta name=twitter:description content="MinIO 是目前最成熟的 S3 兼容私有化对象存储方案。它用 Go 语言编写,单个二进制文件部署,没有外部依赖,性能在同类产品中领先。MinIO 完整实现了 S3 API(包括 Select、Encryption、Versioning、Object Lock 等),绝大多数 S3 SDK 和工具可以零修改对接。"><script type=application/ld+json>{"@context":"https://schema.org","@type":"Article","articleSection":"最近笔记","name":"MinIO对象存储部署:S3兼容的私有化存储方案","headline":"MinIO对象存储部署:S3兼容的私有化存储方案","abstract":"MinIO 是目前最成熟的 S3 兼容私有化对象存储方案。它用 Go 语言编写,单个二进制文件部署,没有外部依赖,性能在同类产品中领先。MinIO 完整实现了 S3 API(包括 Select、Encryption、Versioning、Object Lock 等),绝大多数 S3 SDK 和工具可以零修改对接。","inLanguage":"zh-cn","url":"http:\/\/blog.hys.my\/posts\/minio\/","author":{"@type":"Person","name":"华禹"},"copyrightYear":"2026","dateCreated":"2026-04-18T10:00:00\u002b08:00","datePublished":"2026-04-18T10:00:00\u002b08:00","dateModified":"2026-04-18T10:00:00\u002b08:00","keywords":["MinIO","对象存储","S3","部署指南","私有化存储"],"mainEntityOfPage":"true","wordCount":"9057"}</script><script type=application/ld+json>{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","item":"http://blog.hys.my/","name":"Home","position":1},{"@type":"ListItem","item":"http://blog.hys.my/posts/","name":"最近笔记","position":2},{"@type":"ListItem","item":"http://blog.hys.my/categories/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/","name":"技术文档","position":3},{"@type":"ListItem","name":"Min Io对象存储部署: S3兼容的私有化存储方案","position":4}]}</script><meta name=author content="华禹"><link href=mailto:hello@your_domain.com rel=me><link href=https://link-to-some-website.com/ rel=me><link href=https://www.amazon.com/hz/wishlist/ls/wishlist-id rel=me><link href=https://www.apple.com rel=me><link href=https://xing.com/profile/username rel=me></head><body class="m-auto flex h-screen max-w-7xl flex-col bg-neutral px-6 text-lg leading-7 text-neutral-900 dark:bg-neutral-800 dark:text-neutral sm:px-14 md:px-24 lg:px-32"><div id=the-top class="absolute flex self-center"><a class="-translate-y-8 rounded-b-lg bg-primary-200 px-3 py-1 text-sm focus:translate-y-0 dark:bg-neutral-600" href=#main-content><span class="pe-2 font-bold text-primary-600 dark:text-primary-400">↓</span></a></div><header class="py-6 font-semibold text-neutral-900 dark:text-neutral sm:py-10 print:hidden"><nav class="flex items-start justify-between sm:items-center"><div class="z-40 flex flex-row items-center"><a class="decoration-primary-500 hover:underline hover:decoration-2 hover:underline-offset-2" rel=me href=/>华禹 个人博客</a></div><label id=menu-button for=menu-controller class="block sm:hidden"><input type=checkbox id=menu-controller class=hidden><div class="cursor-pointer hover:text-primary-600 dark:hover:text-primary-400"><span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M0 96C0 78.33 14.33 64 32 64H416c17.7.0 32 14.33 32 32 0 17.7-14.3 32-32 32H32C14.33 128 0 113.7.0 96zM0 256c0-17.7 14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32H32c-17.67.0-32-14.3-32-32zM416 448H32c-17.67.0-32-14.3-32-32s14.33-32 32-32H416c17.7.0 32 14.3 32 32s-14.3 32-32 32z"/></svg></span></div><div id=menu-wrapper class="invisible fixed inset-0 z-30 m-auto h-full w-full cursor-default overflow-auto bg-neutral-100/50 opacity-0 backdrop-blur-sm transition-opacity dark:bg-neutral-900/50"><ul class="mx-auto flex w-full max-w-7xl list-none flex-col overflow-visible px-6 py-6 text-end sm:px-14 sm:py-10 sm:pt-10 md:px-24 lg:px-32"><li class=mb-1><span class="cursor-pointer hover:text-primary-600 dark:hover:text-primary-400"><span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></span></li><li class="group mb-1"><a href=/ title=Home onclick=close_menu()><span class="decoration-primary-500 group-hover:underline group-hover:decoration-2 group-hover:underline-offset-2">首页</span></a></li><li class="group mb-1"><a href=/posts/ title=最近笔记 onclick=close_menu()><span class="decoration-primary-500 group-hover:underline group-hover:decoration-2 group-hover:underline-offset-2">学习笔记</span></a></li><li class="group mb-1"><a href title onclick=close_menu()><span class="decoration-primary-500 group-hover:underline group-hover:decoration-2 group-hover:underline-offset-2">我的简历</span></a></li><li class="group mb-1"><button id=search-button-m0 title>
|
||
<span class="group-dark:hover:text-primary-400 transition-colors group-hover:text-primary-600"><span class="icon relative inline-block px-1 align-text-bottom"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></span></button></li></ul></div></label><ul class="hidden list-none flex-row text-end sm:flex"><li class="group mb-1 sm:mb-0 sm:me-7 sm:last:me-0"><a href=/ title=Home><span class="decoration-primary-500 group-hover:underline group-hover:decoration-2 group-hover:underline-offset-2">首页</span></a></li><li class="group mb-1 sm:mb-0 sm:me-7 sm:last:me-0"><a href=/posts/ title=最近笔记><span class="decoration-primary-500 group-hover:underline group-hover:decoration-2 group-hover:underline-offset-2">学习笔记</span></a></li><li class="group mb-1 sm:mb-0 sm:me-7 sm:last:me-0"><a href title><span class="decoration-primary-500 group-hover:underline group-hover:decoration-2 group-hover:underline-offset-2">我的简历</span></a></li><li class="group mb-1 sm:mb-0 sm:me-7 sm:last:me-0"><button id=search-button-m1 title>
|
||
<span class="group-dark:hover:text-primary-400 transition-colors group-hover:text-primary-600"><span class="icon relative inline-block px-1 align-text-bottom"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></span></button></li></ul></nav></header><div class="relative flex grow flex-col"><main id=main-content class=grow><article><header class=max-w-prose><h1 class="mb-8 mt-0 text-4xl font-extrabold text-neutral-900 dark:text-neutral">MinIO对象存储部署:S3兼容的私有化存储方案</h1><div class="mb-10 text-base text-neutral-500 dark:text-neutral-400 print:hidden"><div class="flex flex-row flex-wrap items-center"><time datetime="2026-04-18 10:00:00 +0800 +0800"></time><span class="px-2 text-primary-500">·</span><span title></span></div><div class="my-1 flex flex-wrap text-xs leading-relaxed text-neutral-500 dark:text-neutral-400"><a href=http://blog.hys.my/categories/%E6%8A%80%E6%9C%AF%E6%96%87%E6%A1%A3/ class="mx-1 my-1 rounded-md border border-neutral-200 px-1 py-[1px] hover:border-primary-300 hover:text-primary-700 dark:border-neutral-600 dark:hover:border-primary-600 dark:hover:text-primary-400">技术文档</a>
|
||
<a href=http://blog.hys.my/categories/%E5%AD%98%E5%82%A8%E6%96%B9%E6%A1%88/ class="mx-1 my-1 rounded-md border border-neutral-200 px-1 py-[1px] hover:border-primary-300 hover:text-primary-700 dark:border-neutral-600 dark:hover:border-primary-600 dark:hover:text-primary-400">存储方案</a>
|
||
<a href=http://blog.hys.my/tags/minio/ class="mx-1 my-1 rounded-md border border-neutral-200 px-1 py-[1px] hover:border-primary-300 hover:text-primary-700 dark:border-neutral-600 dark:hover:border-primary-600 dark:hover:text-primary-400">MinIO</a>
|
||
<a href=http://blog.hys.my/tags/%E5%AF%B9%E8%B1%A1%E5%AD%98%E5%82%A8/ class="mx-1 my-1 rounded-md border border-neutral-200 px-1 py-[1px] hover:border-primary-300 hover:text-primary-700 dark:border-neutral-600 dark:hover:border-primary-600 dark:hover:text-primary-400">对象存储</a>
|
||
<a href=http://blog.hys.my/tags/s3/ class="mx-1 my-1 rounded-md border border-neutral-200 px-1 py-[1px] hover:border-primary-300 hover:text-primary-700 dark:border-neutral-600 dark:hover:border-primary-600 dark:hover:text-primary-400">S3</a>
|
||
<a href=http://blog.hys.my/tags/%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/ class="mx-1 my-1 rounded-md border border-neutral-200 px-1 py-[1px] hover:border-primary-300 hover:text-primary-700 dark:border-neutral-600 dark:hover:border-primary-600 dark:hover:text-primary-400">部署指南</a>
|
||
<a href=http://blog.hys.my/tags/%E7%A7%81%E6%9C%89%E5%8C%96%E5%AD%98%E5%82%A8/ class="mx-1 my-1 rounded-md border border-neutral-200 px-1 py-[1px] hover:border-primary-300 hover:text-primary-700 dark:border-neutral-600 dark:hover:border-primary-600 dark:hover:text-primary-400">私有化存储</a></div></div></header><section class="prose mt-0 flex max-w-full flex-col dark:prose-invert lg:flex-row"><div class="min-h-0 min-w-0 max-w-prose grow"><h2 id=一概述 class="relative group">一、概述 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#%e4%b8%80%e6%a6%82%e8%bf%b0 aria-label>#</a></span></h2><h3 id=11-背景介绍 class="relative group">1.1 背景介绍 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#11-%e8%83%8c%e6%99%af%e4%bb%8b%e7%bb%8d aria-label>#</a></span></h3><p>非结构化数据的爆发式增长让传统文件存储和块存储越来越力不从心。图片、视频、日志、备份文件这类对象动辄 TB 甚至 PB 级别,传统 NAS 在扩展性和并发访问上存在天花板,而块存储(如 Ceph RBD、EBS)虽然性能好,但不适合海量小文件和 HTTP 直接访问的场景。</p><p>对象存储通过扁平化的命名空间(Bucket + Object Key)取代了目录树结构,天然适合海量非结构化数据。AWS S3 定义了事实上的对象存储 API 标准,但公有云存储在数据主权、网络延迟和长期成本上并不总是最优解。</p><p>MinIO 是目前最成熟的 S3 兼容私有化对象存储方案。它用 Go 语言编写,单个二进制文件部署,没有外部依赖,性能在同类产品中领先。MinIO 完整实现了 S3 API(包括 Select、Encryption、Versioning、Object Lock 等),绝大多数 S3 SDK 和工具可以零修改对接。</p><p><strong>三种存储类型的核心差异:</strong></p><table><thead><tr><th>对比维度</th><th>块存储</th><th>文件存储</th><th>对象存储</th></tr></thead><tbody><tr><td>访问方式</td><td>设备级(/dev/sdb)</td><td>文件路径(POSIX)</td><td>HTTP API(REST)</td></tr><tr><td>数据单位</td><td>固定大小块</td><td>文件 + 目录树</td><td>对象 + 元数据</td></tr><tr><td>扩展性</td><td>纵向为主</td><td>受限于 NAS 控制器</td><td>水平无限扩展</td></tr><tr><td>典型场景</td><td>数据库、虚拟机磁盘</td><td>共享文件、NFS 挂载</td><td>图片视频、备份、日志归档</td></tr><tr><td>元数据</td><td>无</td><td>有限(权限、时间戳)</td><td>丰富(自定义 KV)</td></tr></tbody></table><p>S3 API 兼容性原理:MinIO 在 HTTP 层实现了与 AWS S3 相同的 REST 接口规范,包括签名认证(AWS Signature V4)、分段上传(Multipart Upload)、预签名 URL 等。客户端只需将 endpoint 从 <code>s3.amazonaws.com</code> 改为 MinIO 地址,其余代码不需要任何改动。</p><h3 id=12-技术特点 class="relative group">1.2 技术特点 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#12-%e6%8a%80%e6%9c%af%e7%89%b9%e7%82%b9 aria-label>#</a></span></h3><ul><li><strong>S3 完整兼容</strong>:支持 S3 API 的绝大多数功能,包括 Multipart Upload、Versioning、Object Lock、Server-Side Encryption、S3 Select</li><li><strong>纠删码(Erasure Coding)</strong>:数据被切分为数据块和校验块分散存储,在不做完整副本的前提下提供冗余,磁盘利用率远高于三副本方案</li><li><strong>零依赖部署</strong>:单个 Go 二进制文件,不依赖数据库、ZooKeeper 或其他外部组件</li><li><strong>高性能</strong>:充分利用多核 CPU 和 NVMe SSD,单集群可达数十 GB/s 吞吐</li><li><strong>Bucket Notification</strong>:支持 Webhook、Kafka、AMQP、Redis 等事件通知,便于构建数据管道</li><li><strong>Identity Management</strong>:集成 LDAP、OpenID Connect、Keycloak 等外部身份源</li></ul><h3 id=13-适用场景 class="relative group">1.3 适用场景 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#13-%e9%80%82%e7%94%a8%e5%9c%ba%e6%99%af aria-label>#</a></span></h3><ul><li>应用系统的图片、视频、文档等非结构化数据存储,替代 NFS 共享目录</li><li>数据库备份、日志归档的统一存储后端,配合生命周期策略自动清理过期数据</li><li>AI/ML 训练数据集存储,利用 S3 API 与 PyTorch、TensorFlow 数据加载器直接对接</li><li>私有化 Docker Registry 或 Helm Chart 仓库的后端存储</li><li>替代公有云 S3,满足数据主权合规要求(金融、医疗、政务场景)</li></ul><h3 id=14-环境要求 class="relative group">1.4 环境要求 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#14-%e7%8e%af%e5%a2%83%e8%a6%81%e6%b1%82 aria-label>#</a></span></h3><table><thead><tr><th>组件</th><th>版本要求</th><th>说明</th></tr></thead><tbody><tr><td>操作系统</td><td>Ubuntu 22.04+ / CentOS 8+</td><td>推荐 Ubuntu 22.04 LTS</td></tr><tr><td>MinIO Server</td><td>RELEASE.2025-xx</td><td>使用最新稳定版,避免旧版已知 Bug</td></tr><tr><td>MinIO Client (mc)</td><td>RELEASE.2025-xx</td><td>与 Server 版本保持同期</td></tr><tr><td>硬件配置</td><td>4C8G 起步</td><td>生产环境建议 8C16G,纠删码集群每节点至少 4 块磁盘</td></tr><tr><td>磁盘</td><td>XFS 格式化</td><td>MinIO 强烈推荐 XFS,ext4 在大量小文件场景下性能衰减明显</td></tr><tr><td>网络</td><td>节点间万兆网络</td><td>纠删码集群的数据分片需要节点间高带宽</td></tr></tbody></table><hr><h2 id=二详细步骤 class="relative group">二、详细步骤 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#%e4%ba%8c%e8%af%a6%e7%bb%86%e6%ad%a5%e9%aa%a4 aria-label>#</a></span></h2><h3 id=21-单节点部署 class="relative group">2.1 单节点部署 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#21-%e5%8d%95%e8%8a%82%e7%82%b9%e9%83%a8%e7%bd%b2 aria-label>#</a></span></h3><h4 id=211-下载安装 class="relative group">2.1.1 下载安装 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#211-%e4%b8%8b%e8%bd%bd%e5%ae%89%e8%a3%85 aria-label>#</a></span></h4><pre tabindex=0><code># 下载 MinIO 二进制文件
|
||
wget https://dl.min.io/server/minio/release/linux-amd64/minio
|
||
chmod +x minio
|
||
sudo mv minio /usr/local/bin/
|
||
|
||
# 验证版本
|
||
minio --version
|
||
</code></pre><h4 id=212-创建数据目录和系统用户 class="relative group">2.1.2 创建数据目录和系统用户 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#212-%e5%88%9b%e5%bb%ba%e6%95%b0%e6%8d%ae%e7%9b%ae%e5%bd%95%e5%92%8c%e7%b3%bb%e7%bb%9f%e7%94%a8%e6%88%b7 aria-label>#</a></span></h4><pre tabindex=0><code># 创建专用系统用户,不允许登录
|
||
sudo useradd -r -s /sbin/nologin minio-user
|
||
|
||
# 创建数据目录(生产环境应使用独立磁盘挂载点)
|
||
sudo mkdir -p /data/minio
|
||
sudo chown minio-user:minio-user /data/minio
|
||
</code></pre><h4 id=213-环境变量配置 class="relative group">2.1.3 环境变量配置 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#213-%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f%e9%85%8d%e7%bd%ae aria-label>#</a></span></h4><pre tabindex=0><code># /etc/default/minio - MinIO 环境变量配置
|
||
# 管理员账号(至少 3 个字符)
|
||
MINIO_ROOT_USER=minioadmin
|
||
# 管理员密码(至少 8 个字符,生产环境务必修改)
|
||
MINIO_ROOT_PASSWORD=Change-Me-2025!
|
||
# 数据存储路径
|
||
MINIO_VOLUMES="/data/minio"
|
||
# 监听地址,0.0.0.0 表示所有网卡
|
||
MINIO_OPTS="--address :9000 --console-address :9001"
|
||
</code></pre><h4 id=214-systemd-服务配置 class="relative group">2.1.4 systemd 服务配置 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#214-systemd-%e6%9c%8d%e5%8a%a1%e9%85%8d%e7%bd%ae aria-label>#</a></span></h4><pre tabindex=0><code># /etc/systemd/system/minio.service
|
||
[Unit]
|
||
Description=MinIO Object Storage
|
||
Documentation=https://min.io/docs
|
||
After=network-online.target
|
||
Wants=network-online.target
|
||
|
||
[Service]
|
||
User=minio-user
|
||
Group=minio-user
|
||
EnvironmentFile=/etc/default/minio
|
||
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
|
||
Restart=always
|
||
RestartSec=5
|
||
LimitNOFILE=65536
|
||
# 禁止 OOM Killer 杀掉 MinIO 进程
|
||
OOMScoreAdjust=-500
|
||
TasksMax=infinity
|
||
TimeoutStopSec=infinity
|
||
SendSIGKILL=no
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
</code></pre><pre tabindex=0><code># 启动服务
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now minio
|
||
|
||
# 验证状态
|
||
sudo systemctl status minio
|
||
curl -s http://localhost:9000/minio/health/live
|
||
# 预期返回空 body,HTTP 200
|
||
</code></pre><p>单节点模式没有纠删码保护,任何磁盘故障都会导致数据丢失,仅适合开发测试环境。</p><h3 id=22-纠删码多节点集群部署 class="relative group">2.2 纠删码多节点集群部署 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#22-%e7%ba%a0%e5%88%a0%e7%a0%81%e5%a4%9a%e8%8a%82%e7%82%b9%e9%9b%86%e7%be%a4%e9%83%a8%e7%bd%b2 aria-label>#</a></span></h3><h4 id=221-纠删码原理 class="relative group">2.2.1 纠删码原理 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#221-%e7%ba%a0%e5%88%a0%e7%a0%81%e5%8e%9f%e7%90%86 aria-label>#</a></span></h4><p>MinIO 的纠删码基于 Reed-Solomon 算法。以 4 节点、每节点 4 块磁盘(共 16 块)为例,默认配置下数据被切分为 8 个数据块 + 8 个校验块。这意味着集群可以容忍任意 8 块磁盘同时故障而不丢数据,磁盘利用率 50%(对比三副本的 33%)。</p><p>纠删码集合(Erasure Set)的大小由磁盘总数决定。MinIO 自动计算最优的纠删码集合划分,管理员不需要手动配置。</p><h4 id=222-集群规划 class="relative group">2.2.2 集群规划 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#222-%e9%9b%86%e7%be%a4%e8%a7%84%e5%88%92 aria-label>#</a></span></h4><p>节点</p><p>IP</p><p>磁盘</p><p>挂载点</p><p>minio-1</p><p>192.168.10.11</p><p>4 × NVMe SSD</p><p>/data/disk{1..4}</p><p>minio-2</p><p>192.168.10.12</p><p>4 × NVMe SSD</p><p>/data/disk{1..4}</p><p>minio-3</p><p>192.168.10.13</p><p>4 × NVMe SSD</p><p>/data/disk{1..4}</p><p>minio-4</p><p>192.168.10.14</p><p>4 × NVMe SSD</p><p>/data/disk{1..4}</p><h4 id=223-所有节点磁盘准备 class="relative group">2.2.3 所有节点磁盘准备 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#223-%e6%89%80%e6%9c%89%e8%8a%82%e7%82%b9%e7%a3%81%e7%9b%98%e5%87%86%e5%a4%87 aria-label>#</a></span></h4><pre tabindex=0><code># 在每个节点上执行(以 disk1 为例,disk2-4 同理)
|
||
# 使用 XFS 格式化,MinIO 官方推荐
|
||
sudo mkfs.xfs /dev/nvme0n1
|
||
sudo mkfs.xfs /dev/nvme1n1
|
||
sudo mkfs.xfs /dev/nvme2n1
|
||
sudo mkfs.xfs /dev/nvme3n1
|
||
|
||
# 创建挂载点
|
||
sudo mkdir -p /data/disk{1,2,3,4}
|
||
|
||
# 写入 fstab 持久化挂载
|
||
# noatime 减少元数据写入,提升性能
|
||
cat <<'EOF' | sudo tee -a /etc/fstab
|
||
/dev/nvme0n1 /data/disk1 xfs defaults,noatime 0 2
|
||
/dev/nvme1n1 /data/disk2 xfs defaults,noatime 0 2
|
||
/dev/nvme2n1 /data/disk3 xfs defaults,noatime 0 2
|
||
/dev/nvme3n1 /data/disk4 xfs defaults,noatime 0 2
|
||
EOF
|
||
|
||
sudo mount -a
|
||
sudo chown minio-user:minio-user /data/disk{1,2,3,4}
|
||
</code></pre><h4 id=224-集群环境变量 class="relative group">2.2.4 集群环境变量 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#224-%e9%9b%86%e7%be%a4%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f aria-label>#</a></span></h4><pre tabindex=0><code># /etc/default/minio - 4节点纠删码集群配置(所有节点相同)
|
||
MINIO_ROOT_USER=minioadmin
|
||
MINIO_ROOT_PASSWORD=Change-Me-2025!
|
||
|
||
# 纠删码集群卷定义
|
||
# {1...4} 是 MinIO 的展开语法(三个点),不是 bash 的 {1..4}(两个点)
|
||
MINIO_VOLUMES="http://minio-{1...4}.example.com:9000/data/disk{1...4}"
|
||
|
||
# 服务器发现用的域名(可选,用于自动 TLS 证书)
|
||
MINIO_SERVER_URL="https://minio.example.com:9000"
|
||
|
||
MINIO_OPTS="--address :9000 --console-address :9001"
|
||
</code></pre><p><strong>关键说明</strong>:<code>{1...4}</code> 是 MinIO 自己的展开语法,三个点,不要和 bash 的 <code>{1..4}</code> 搞混。MinIO 会在内部展开为 <code>minio-1.example.com</code> 到 <code>minio-4.example.com</code>。</p><pre tabindex=0><code># 配置 DNS 解析(或 /etc/hosts)
|
||
cat <<'EOF' | sudo tee -a /etc/hosts
|
||
192.168.10.11 minio-1.example.com
|
||
192.168.10.12 minio-2.example.com
|
||
192.168.10.13 minio-3.example.com
|
||
192.168.10.14 minio-4.example.com
|
||
EOF
|
||
|
||
# 在所有节点上启动
|
||
sudo systemctl enable --now minio
|
||
</code></pre><h4 id=225-集群健康检查 class="relative group">2.2.5 集群健康检查 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#225-%e9%9b%86%e7%be%a4%e5%81%a5%e5%ba%b7%e6%a3%80%e6%9f%a5 aria-label>#</a></span></h4><pre tabindex=0><code># 存活检查
|
||
curl -s http://minio-1.example.com:9000/minio/health/live
|
||
|
||
# 集群就绪检查(所有节点在线才返回 200)
|
||
curl -s http://minio-1.example.com:9000/minio/health/cluster
|
||
|
||
# 查看集群信息(需要 mc 客户端)
|
||
mc admin info myminio
|
||
</code></pre><h3 id=23-tls-证书配置 class="relative group">2.3 TLS 证书配置 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#23-tls-%e8%af%81%e4%b9%a6%e9%85%8d%e7%bd%ae aria-label>#</a></span></h3><p>MinIO 支持自动加载 <code>~/.minio/certs/</code> 目录下的证书文件。</p><pre tabindex=0><code># 创建证书目录
|
||
sudo mkdir -p /home/minio-user/.minio/certs
|
||
sudo mkdir -p /home/minio-user/.minio/certs/CAs
|
||
|
||
# 复制证书文件(文件名必须是 public.crt 和 private.key)
|
||
sudo cp /path/to/fullchain.pem /home/minio-user/.minio/certs/public.crt
|
||
sudo cp /path/to/privkey.pem /home/minio-user/.minio/certs/private.key
|
||
|
||
# 如果使用自签名 CA,将 CA 证书放入 CAs 目录
|
||
sudo cp /path/to/ca.crt /home/minio-user/.minio/certs/CAs/
|
||
|
||
# 修正权限
|
||
sudo chown -R minio-user:minio-user /home/minio-user/.minio
|
||
sudo chmod 600 /home/minio-user/.minio/certs/private.key
|
||
|
||
# 重启 MinIO 加载证书
|
||
sudo systemctl restart minio
|
||
</code></pre><p>启用 TLS 后,MinIO 自动监听 HTTPS。环境变量中的 <code>http://</code> 需要改为 <code>https://</code>,mc 客户端连接时也需要使用 <code>https://</code>。</p><p>对于纠删码集群,每个节点都需要配置证书。如果使用内部 CA 签发,所有节点的 CAs 目录都要放入 CA 证书,否则节点间 TLS 握手会失败。</p><h3 id=24-mc-客户端操作 class="relative group">2.4 mc 客户端操作 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#24-mc-%e5%ae%a2%e6%88%b7%e7%ab%af%e6%93%8d%e4%bd%9c aria-label>#</a></span></h3><h4 id=241-安装与配置 class="relative group">2.4.1 安装与配置 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#241-%e5%ae%89%e8%a3%85%e4%b8%8e%e9%85%8d%e7%bd%ae aria-label>#</a></span></h4><pre tabindex=0><code># 下载 mc 客户端
|
||
wget https://dl.min.io/client/mc/release/linux-amd64/mc
|
||
chmod +x mc
|
||
sudo mv mc /usr/local/bin/
|
||
|
||
# 配置别名(alias)
|
||
mc alias set myminio https://minio.example.com:9000 minioadmin 'Change-Me-2025!'
|
||
|
||
# 验证连接
|
||
mc admin info myminio
|
||
</code></pre><h4 id=242-常用操作 class="relative group">2.4.2 常用操作 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#242-%e5%b8%b8%e7%94%a8%e6%93%8d%e4%bd%9c aria-label>#</a></span></h4><pre tabindex=0><code># Bucket 操作
|
||
mc mb myminio/my-bucket # 创建 Bucket
|
||
mc ls myminio # 列出所有 Bucket
|
||
mc rb myminio/old-bucket --force # 删除 Bucket(含内容)
|
||
|
||
# 对象操作
|
||
mc cp localfile.tar.gz myminio/my-bucket/ # 上传文件
|
||
mc cp myminio/my-bucket/file.tar.gz ./ # 下载文件
|
||
mc ls myminio/my-bucket --recursive # 递归列出对象
|
||
mc rm myminio/my-bucket/old-file.log # 删除对象
|
||
mc cat myminio/my-bucket/config.yaml # 查看对象内容
|
||
|
||
# 批量操作
|
||
mc cp --recursive ./logs/ myminio/my-bucket/logs/ # 递归上传目录
|
||
mc mirror ./data myminio/my-bucket/data # 目录镜像同步
|
||
|
||
# 管理操作
|
||
mc admin user add myminio app-user App-Pass-2025! # 创建用户
|
||
mc admin policy attach myminio readwrite --user app-user # 绑定策略
|
||
mc admin trace myminio # 实时请求追踪(调试用)
|
||
</code></pre><hr><h2 id=三示例代码和配置 class="relative group">三、示例代码和配置 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#%e4%b8%89%e7%a4%ba%e4%be%8b%e4%bb%a3%e7%a0%81%e5%92%8c%e9%85%8d%e7%bd%ae aria-label>#</a></span></h2><h3 id=31-bucket-policy-配置 class="relative group">3.1 Bucket Policy 配置 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#31-bucket-policy-%e9%85%8d%e7%bd%ae aria-label>#</a></span></h3><h4 id=311-公开只读策略 class="relative group">3.1.1 公开只读策略 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#311-%e5%85%ac%e5%bc%80%e5%8f%aa%e8%af%bb%e7%ad%96%e7%95%a5 aria-label>#</a></span></h4><p>适用于静态资源 CDN 回源场景,允许匿名用户读取指定 Bucket 的所有对象:</p><pre tabindex=0><code>{
|
||
"Version": "2012-10-17",
|
||
"Statement": [
|
||
{
|
||
"Effect": "Allow",
|
||
"Principal": {"AWS": ["*"]},
|
||
"Action": ["s3:GetObject"],
|
||
"Resource": ["arn:aws:s3:::static-assets/*"]
|
||
}
|
||
]
|
||
}
|
||
</code></pre><pre tabindex=0><code># 应用策略
|
||
mc anonymous set-json public-read.json myminio/static-assets
|
||
</code></pre><h4 id=312-应用专用读写策略 class="relative group">3.1.2 应用专用读写策略 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#312-%e5%ba%94%e7%94%a8%e4%b8%93%e7%94%a8%e8%af%bb%e5%86%99%e7%ad%96%e7%95%a5 aria-label>#</a></span></h4><p>限制特定用户只能访问指定 Bucket 前缀:</p><pre tabindex=0><code>{
|
||
"Version": "2012-10-17",
|
||
"Statement": [
|
||
{
|
||
"Effect": "Allow",
|
||
"Action": [
|
||
"s3:PutObject",
|
||
"s3:GetObject",
|
||
"s3:DeleteObject",
|
||
"s3:ListBucket"
|
||
],
|
||
"Resource": [
|
||
"arn:aws:s3:::app-data",
|
||
"arn:aws:s3:::app-data/uploads/*"
|
||
]
|
||
}
|
||
]
|
||
}
|
||
</code></pre><pre tabindex=0><code># 创建自定义策略并绑定用户
|
||
mc admin policy create myminio app-rw-policy app-rw-policy.json
|
||
mc admin policy attach myminio app-rw-policy --user app-user
|
||
</code></pre><h3 id=32-生命周期管理脚本 class="relative group">3.2 生命周期管理脚本 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#32-%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f%e7%ae%a1%e7%90%86%e8%84%9a%e6%9c%ac aria-label>#</a></span></h3><pre tabindex=0><code>#!/bin/bash
|
||
set -euo pipefail
|
||
# minio-lifecycle.sh - MinIO Bucket 生命周期管理脚本
|
||
# 功能:为指定 Bucket 配置对象过期策略,自动清理过期数据
|
||
# 用法:./minio-lifecycle.sh <bucket-name> <prefix> <expire-days>
|
||
|
||
# ============ 参数定义 ============
|
||
MINIO_ALIAS="myminio"
|
||
BUCKET_NAME="${1:?用法: $0 <bucket-name> <prefix> <expire-days>}"
|
||
PREFIX="${2:?请指定对象前缀,例如 logs/}"
|
||
EXPIRE_DAYS="${3:?请指定过期天数,例如 30}"
|
||
|
||
# ============ 参数校验 ============
|
||
if ! [[ "$EXPIRE_DAYS" =~ ^[0-9]+$ ]] || [ "$EXPIRE_DAYS" -lt 1 ]; then
|
||
echo "[错误] 过期天数必须为正整数: $EXPIRE_DAYS"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 mc 客户端是否可用
|
||
if ! command -v mc &>/dev/null; then
|
||
echo "[错误] mc 客户端未安装,请先安装 MinIO Client"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查 Bucket 是否存在
|
||
if ! mc ls "${MINIO_ALIAS}/${BUCKET_NAME}" &>/dev/null; then
|
||
echo "[错误] Bucket 不存在: ${BUCKET_NAME}"
|
||
exit 1
|
||
fi
|
||
|
||
# ============ 配置生命周期规则 ============
|
||
RULE_ID="auto-expire-${PREFIX//\//-}-${EXPIRE_DAYS}d"
|
||
|
||
echo "[信息] 正在为 ${BUCKET_NAME}/${PREFIX} 配置 ${EXPIRE_DAYS} 天过期策略..."
|
||
|
||
# 添加生命周期规则
|
||
mc ilm rule add "${MINIO_ALIAS}/${BUCKET_NAME}" \
|
||
--prefix "${PREFIX}" \
|
||
--expire-days "${EXPIRE_DAYS}" \
|
||
--tags "managed-by=lifecycle-script"
|
||
|
||
echo "[信息] 生命周期规则配置完成"
|
||
|
||
# ============ 验证配置 ============
|
||
echo "[信息] 当前生命周期规则:"
|
||
mc ilm rule ls "${MINIO_ALIAS}/${BUCKET_NAME}"
|
||
|
||
# ============ 统计待清理对象 ============
|
||
echo "[信息] 统计 ${PREFIX} 下超过 ${EXPIRE_DAYS} 天的对象数量..."
|
||
OLDER_THAN="${EXPIRE_DAYS}d"
|
||
OBJECT_COUNT=$(mc find "${MINIO_ALIAS}/${BUCKET_NAME}/${PREFIX}" \
|
||
--older-than "${OLDER_THAN}" 2>/dev/null | wc -l || true)
|
||
|
||
echo "[信息] 预计将在下次扫描周期清理约 ${OBJECT_COUNT} 个过期对象"
|
||
echo "[完成] 脚本执行结束"
|
||
</code></pre><h3 id=33-nginx-反向代理--https-卸载 class="relative group">3.3 Nginx 反向代理 + HTTPS 卸载 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#33-nginx-%e5%8f%8d%e5%90%91%e4%bb%a3%e7%90%86--https-%e5%8d%b8%e8%bd%bd aria-label>#</a></span></h3><pre tabindex=0><code># /etc/nginx/conf.d/minio.conf
|
||
# MinIO 反向代理配置 - HTTPS 卸载 + 负载均衡
|
||
|
||
# MinIO API 后端(9000 端口)
|
||
upstream minio_api {
|
||
# 最少连接数负载均衡
|
||
least_conn;
|
||
server 192.168.10.11:9000;
|
||
server 192.168.10.12:9000;
|
||
server 192.168.10.13:9000;
|
||
server 192.168.10.14:9000;
|
||
}
|
||
|
||
# MinIO Console 后端(9001 端口)
|
||
upstream minio_console {
|
||
least_conn;
|
||
server 192.168.10.11:9001;
|
||
server 192.168.10.12:9001;
|
||
server 192.168.10.13:9001;
|
||
server 192.168.10.14:9001;
|
||
}
|
||
|
||
# S3 API 入口
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name minio.example.com;
|
||
|
||
# TLS 证书
|
||
ssl_certificate /etc/nginx/ssl/minio.example.com.crt;
|
||
ssl_certificate_key /etc/nginx/ssl/minio.example.com.key;
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||
|
||
# 允许大文件上传(5GB 分段上传)
|
||
client_max_body_size 5G;
|
||
|
||
# 关闭缓冲,避免大文件上传时 Nginx 占用过多内存
|
||
proxy_buffering off;
|
||
proxy_request_buffering off;
|
||
|
||
location / {
|
||
proxy_pass http://minio_api;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
|
||
# S3 签名依赖 Host 头,必须透传
|
||
proxy_set_header Host $http_host;
|
||
|
||
# 长连接支持
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Connection "";
|
||
|
||
# 超时设置(大文件上传需要较长超时)
|
||
proxy_connect_timeout 300s;
|
||
proxy_read_timeout 300s;
|
||
proxy_send_timeout 300s;
|
||
}
|
||
}
|
||
|
||
# Console 管理界面入口
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name console.minio.example.com;
|
||
|
||
ssl_certificate /etc/nginx/ssl/minio.example.com.crt;
|
||
ssl_certificate_key /etc/nginx/ssl/minio.example.com.key;
|
||
ssl_protocols TLSv1.2 TLSv1.3;
|
||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||
|
||
# Console 上传文件也需要较大 body 限制
|
||
client_max_body_size 5G;
|
||
|
||
# 限制 Console 访问来源(可选)
|
||
# allow 10.0.0.0/8;
|
||
# deny all;
|
||
|
||
location / {
|
||
proxy_pass http://minio_console;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
|
||
proxy_http_version 1.1;
|
||
|
||
# WebSocket 支持(Console 实时日志需要)
|
||
proxy_set_header Upgrade $http_upgrade;
|
||
proxy_set_header Connection "upgrade";
|
||
}
|
||
}
|
||
|
||
# HTTP 跳转 HTTPS
|
||
server {
|
||
listen 80;
|
||
server_name minio.example.com console.minio.example.com;
|
||
return 301 https://$host$request_uri;
|
||
}
|
||
</code></pre><pre tabindex=0><code># 验证 Nginx 配置
|
||
sudo nginx -t
|
||
|
||
# 重载配置
|
||
sudo systemctl reload nginx
|
||
</code></pre><h3 id=34-minio-环境变量配置完整参考 class="relative group">3.4 MinIO 环境变量配置完整参考 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#34-minio-%e7%8e%af%e5%a2%83%e5%8f%98%e9%87%8f%e9%85%8d%e7%bd%ae%e5%ae%8c%e6%95%b4%e5%8f%82%e8%80%83 aria-label>#</a></span></h3><pre tabindex=0><code># /etc/default/minio - 生产环境完整配置参考
|
||
|
||
# ============ 认证 ============
|
||
MINIO_ROOT_USER=minioadmin
|
||
MINIO_ROOT_PASSWORD=Change-Me-2025!
|
||
|
||
# ============ 存储 ============
|
||
MINIO_VOLUMES="http://minio-{1...4}.example.com:9000/data/disk{1...4}"
|
||
|
||
# ============ 网络 ============
|
||
# 对外暴露的 URL(经过负载均衡器后的地址)
|
||
MINIO_SERVER_URL="https://minio.example.com"
|
||
# Console 对外 URL
|
||
MINIO_BROWSER_REDIRECT_URL="https://console.minio.example.com"
|
||
|
||
# ============ 区域 ============
|
||
MINIO_SITE_REGION="cn-east-1"
|
||
|
||
# ============ 日志 ============
|
||
# 审计日志推送到 Webhook
|
||
# MINIO_AUDIT_WEBHOOK_ENABLE_target1="on"
|
||
# MINIO_AUDIT_WEBHOOK_ENDPOINT_target1="http://logstash:8080/minio-audit"
|
||
|
||
# ============ 启动参数 ============
|
||
MINIO_OPTS="--address :9000 --console-address :9001"
|
||
</code></pre><hr><h2 id=四最佳实践和注意事项 class="relative group">四、最佳实践和注意事项 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#%e5%9b%9b%e6%9c%80%e4%bd%b3%e5%ae%9e%e8%b7%b5%e5%92%8c%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9 aria-label>#</a></span></h2><h3 id=41-最佳实践 class="relative group">4.1 最佳实践 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#41-%e6%9c%80%e4%bd%b3%e5%ae%9e%e8%b7%b5 aria-label>#</a></span></h3><h4 id=411-纠删码选择与硬件规划 class="relative group">4.1.1 纠删码选择与硬件规划 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#411-%e7%ba%a0%e5%88%a0%e7%a0%81%e9%80%89%e6%8b%a9%e4%b8%8e%e7%a1%ac%e4%bb%b6%e8%a7%84%e5%88%92 aria-label>#</a></span></h4><p>MinIO 的纠删码(Erasure Coding)直接决定集群的容错能力和可用存储比例,选型需在冗余度与空间利用率之间权衡:</p><p>配置</p><p>数据盘:校验盘</p><p>最大容忍故障盘数</p><p>存储利用率</p><p>适用场景</p><p>EC:4</p><p>12:4</p><p>4</p><p>75%</p><p>开发测试、非关键业务</p><p>EC:8</p><p>8:8</p><p>8</p><p>50%</p><p>金融合规、医疗影像等高可靠场景</p><p>EC:16</p><p>16:16</p><p>16</p><p>50%</p><p>超大规模归档,极端容灾需求</p><p>生产环境默认 EC:N/2 即可满足多数需求。若业务对存储成本敏感且可接受较低冗余,可通过 <code>--parity</code> 参数降低校验盘数量。</p><p>磁盘类型选择:</p><p>磁盘类型</p><p>随机读写 IOPS</p><p>顺序吞吐</p><p>单位成本</p><p>推荐场景</p><p>NVMe SSD</p><p>500K+</p><p>3-7 GB/s</p><p>高</p><p>元数据密集、小文件高并发</p><p>SATA SSD</p><p>50-90K</p><p>500-550 MB/s</p><p>中</p><p>混合负载、中等并发</p><p>HDD (7200rpm)</p><p>100-200</p><p>150-200 MB/s</p><p>低</p><p>大文件归档、冷数据存储</p><p>JBOD vs RAID 对比:</p><p>方案</p><p>优势</p><p>劣势</p><p>建议</p><p>JBOD 直通</p><p>MinIO 纠删码直接管理磁盘,单盘故障仅影响该盘数据修复</p><p>无硬件级缓存加速</p><p><strong>生产环境强烈推荐</strong></p><p>硬件 RAID</p><p>有 BBU 写缓存可提升小 IO 性能</p><p>RAID 重建期间整组性能下降,写放大严重,与纠删码功能重叠</p><p>仅在遗留硬件无法关闭 RAID 时使用</p><h4 id=412-安全加固 class="relative group">4.1.2 安全加固 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#412-%e5%ae%89%e5%85%a8%e5%8a%a0%e5%9b%ba aria-label>#</a></span></h4><p><strong>IAM Policy 最小权限原则</strong>:为每个应用创建独立 Service Account,绑定精确到 Bucket + 前缀的 Policy:</p><pre tabindex=0><code>{
|
||
"Version": "2012-10-17",
|
||
"Statement": [
|
||
{
|
||
"Effect": "Allow",
|
||
"Action": ["s3:GetObject", "s3:PutObject"],
|
||
"Resource": ["arn:aws:s3:::app-data/uploads/*"]
|
||
},
|
||
{
|
||
"Effect": "Deny",
|
||
"Action": ["s3:DeleteBucket", "s3:PutBucketPolicy"],
|
||
"Resource": ["arn:aws:s3:::*"]
|
||
}
|
||
]
|
||
}
|
||
</code></pre><p><strong>禁用匿名访问</strong>:默认情况下 MinIO 不允许匿名访问,但需确认没有人为设置 public Policy:</p><pre tabindex=0><code># 检查所有 Bucket 的匿名策略
|
||
mc anonymous list myminio --recursive
|
||
|
||
# 如发现异常,立即移除
|
||
mc anonymous set none myminio/bucket-name
|
||
</code></pre><p><strong>启用 Object Lock(对象锁定)</strong>:对合规性要求高的场景,在创建 Bucket 时启用:</p><pre tabindex=0><code># 创建时必须指定 --with-lock,事后无法追加
|
||
mc mb myminio/compliance-data --with-lock
|
||
|
||
# 设置默认保留策略:合规模式,保留 365 天
|
||
mc retention set --default COMPLIANCE 365d myminio/compliance-data
|
||
</code></pre><p><strong>审计日志</strong>:将操作审计日志推送至外部系统,便于安全审计和事件溯源:</p><pre tabindex=0><code># 配置审计日志 Webhook
|
||
mc admin config set myminio audit_webhook:elk \
|
||
endpoint="http://logstash:8080/minio-audit" \
|
||
queue_size=10000
|
||
|
||
# 重启生效
|
||
mc admin service restart myminio
|
||
</code></pre><h4 id=413-多租户隔离 class="relative group">4.1.3 多租户隔离 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#413-%e5%a4%9a%e7%a7%9f%e6%88%b7%e9%9a%94%e7%a6%bb aria-label>#</a></span></h4><p>MinIO 不提供原生的"租户"概念,但可通过 IAM User + Bucket + Policy 组合实现逻辑隔离:</p><pre tabindex=0><code># 为租户 A 创建专属用户
|
||
mc admin user add myminio tenant-a-svc 'T3nantA-P@ss!'
|
||
|
||
# 创建租户专属 Bucket
|
||
mc mb myminio/tenant-a-data
|
||
|
||
# 编写隔离策略:仅允许访问自己的 Bucket
|
||
cat > /tmp/tenant-a-policy.json << 'POLICY'
|
||
{
|
||
"Version": "2012-10-17",
|
||
"Statement": [
|
||
{
|
||
"Effect": "Allow",
|
||
"Action": ["s3:*"],
|
||
"Resource": [
|
||
"arn:aws:s3:::tenant-a-data",
|
||
"arn:aws:s3:::tenant-a-data/*"
|
||
]
|
||
}
|
||
]
|
||
}
|
||
POLICY
|
||
|
||
# 创建并绑定策略
|
||
mc admin policy create myminio tenant-a-policy /tmp/tenant-a-policy.json
|
||
mc admin policy attach myminio tenant-a-policy --user tenant-a-svc
|
||
</code></pre><p>对于大规模多租户场景(50+ 租户),建议部署多个独立 MinIO 集群通过 Kubernetes Operator 管理,避免单集群 IAM 策略过于复杂导致管理成本上升。</p><h4 id=414-版本控制与对象锁定 class="relative group">4.1.4 版本控制与对象锁定 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#414-%e7%89%88%e6%9c%ac%e6%8e%a7%e5%88%b6%e4%b8%8e%e5%af%b9%e8%b1%a1%e9%94%81%e5%ae%9a aria-label>#</a></span></h4><p><strong>Versioning(版本控制)</strong> 为 Bucket 内每个对象保留完整的历史版本,误删或误覆盖时可快速回滚:</p><pre tabindex=0><code># 启用版本控制
|
||
mc version enable myminio/app-data
|
||
|
||
# 查看对象的所有版本
|
||
mc ls --versions myminio/app-data/config.json
|
||
|
||
# 恢复到指定版本(通过 version-id 复制回原路径)
|
||
mc cp --version-id "a1b2c3d4-xxxx" myminio/app-data/config.json myminio/app-data/config.json
|
||
</code></pre><p><strong>WORM 合规模式</strong>:Object Lock 提供两种保留模式:</p><p>模式</p><p>特点</p><p>适用场景</p><p>GOVERNANCE</p><p>拥有 <code>s3:BypassGovernanceRetention</code> 权限的用户可提前解除锁定</p><p>内部数据保护,允许管理员紧急操作</p><p>COMPLIANCE</p><p>任何人(包括 root)在保留期内都无法删除或修改</p><p>金融监管、医疗合规、法律存证</p><p>⚠️ COMPLIANCE 模式一旦设置,保留期内无法缩短或解除,务必确认保留时长后再操作。</p><h3 id=42-注意事项 class="relative group">4.2 注意事项 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#42-%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9 aria-label>#</a></span></h3><h4 id=421-配置注意事项 class="relative group">4.2.1 配置注意事项 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#421-%e9%85%8d%e7%bd%ae%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9 aria-label>#</a></span></h4><p>⚠️ <strong>警告</strong>:以下配置错误在生产事故中出现频率极高,务必逐项检查。</p><ul><li>❗ <strong>纠删码集合大小不可变更</strong>:集群初始化后,Erasure Set 的磁盘数量无法修改。扩容只能以 Server Pool 为单位追加,不能向已有 Pool 中添加单个节点或磁盘。</li><li>❗ <strong>MINIO_VOLUMES 格式严格</strong>:花括号展开语法 <code>{1...4}</code> 中是三个点而非两个,写错不会报语法错误但会导致节点发现异常。</li><li>❗ <strong>时钟同步是硬性要求</strong>:分布式模式下节点间时钟偏差超过 15 秒会导致签名校验失败,所有节点必须配置 NTP/Chrony。</li><li>❗ <strong>TLS 证书路径固定</strong>:MinIO 只从 <code>${HOME}/.minio/certs/</code> 或 <code>/etc/minio/certs/</code> 读取证书,自定义路径需通过 <code>--certs-dir</code> 指定。</li><li>❗ <strong>内存预留</strong>:MinIO 在纠删码模式下每个 Erasure Set 约占用 2-3 GB 内存,16 组 Erasure Set 的集群至少预留 48 GB。</li></ul><h4 id=422-常见错误 class="relative group">4.2.2 常见错误 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#422-%e5%b8%b8%e8%a7%81%e9%94%99%e8%af%af aria-label>#</a></span></h4><p>错误现象</p><p>原因分析</p><p>解决方案</p><p><code>Unable to initialize backend: format.json not found</code></p><p>磁盘未格式化或挂载点不正确</p><p>检查 <code>lsblk</code> 确认挂载,确保目录为空且属主为 minio-user</p><p><code>Signature does not match</code></p><p>节点间时钟偏差过大</p><p>部署 Chrony 并执行 <code>chronyc makestep</code> 强制同步</p><p><code>Healing required</code></p><p> 持续不消失</p><p>磁盘存在坏块或 IO 错误</p><p><code>mc admin heal myminio --recursive</code></p><p> 并检查 <code>dmesg</code> 中的磁盘错误</p><p><code>Drive already being healed</code></p><p>多个 heal 任务冲突</p><p>等待当前 heal 完成,通过 <code>mc admin heal myminio --status</code> 查看进度</p><p><code>Server not initialized, please try again</code></p><p>集群节点数不满足最小法定数</p><p>检查所有节点网络连通性,确保至少 N/2+1 个节点在线</p><p>Console 登录后白屏</p><p><code>MINIO_BROWSER_REDIRECT_URL</code></p><p> 与实际访问地址不匹配</p><p>修正环境变量为实际的负载均衡器地址</p><h4 id=423-兼容性问题 class="relative group">4.2.3 兼容性问题 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#423-%e5%85%bc%e5%ae%b9%e6%80%a7%e9%97%ae%e9%a2%98 aria-label>#</a></span></h4><ul><li><strong>版本兼容</strong>:MinIO 采用滚动发布,版本号格式为 <code>RELEASE.YYYY-MM-DDTHH-MM-SSZ</code>。升级时必须逐版本滚动,不支持跨大版本跳跃升级。升级前务必阅读对应版本的 Release Notes。</li><li><strong>S3 API 兼容</strong>:MinIO 兼容 AWS S3 API 的绝大部分操作,但 <code>S3 Select</code> 仅支持 CSV/JSON/Parquet 格式,<code>S3 Inventory</code> 和 <code>S3 Analytics</code> 暂不支持。</li><li><strong>客户端 SDK 兼容</strong>:AWS SDK(boto3、aws-sdk-js 等)可直接对接 MinIO,只需修改 endpoint 和关闭 virtual-hosted-style(使用 path-style)。部分旧版 SDK 的分片上传实现可能与 MinIO 存在兼容问题,建议使用 MinIO 官方 SDK 或 AWS SDK 最新版本。</li></ul><hr><h2 id=五故障排查和监控 class="relative group">五、故障排查和监控 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#%e4%ba%94%e6%95%85%e9%9a%9c%e6%8e%92%e6%9f%a5%e5%92%8c%e7%9b%91%e6%8e%a7 aria-label>#</a></span></h2><h3 id=51-故障排查 class="relative group">5.1 故障排查 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#51-%e6%95%85%e9%9a%9c%e6%8e%92%e6%9f%a5 aria-label>#</a></span></h3><h4 id=511-日志查看 class="relative group">5.1.1 日志查看 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#511-%e6%97%a5%e5%bf%97%e6%9f%a5%e7%9c%8b aria-label>#</a></span></h4><pre tabindex=0><code># 查看 MinIO 服务日志(systemd 部署)
|
||
sudo journalctl -u minio.service -f --no-pager
|
||
|
||
# 仅查看最近 1 小时的错误日志
|
||
sudo journalctl -u minio.service --since "1 hour ago" | grep -i "error\|fatal\|panic"
|
||
|
||
# 通过 mc 实时查看服务端日志(需要管理员权限)
|
||
mc admin logs myminio
|
||
|
||
# 仅查看特定 Bucket 的操作日志
|
||
mc admin logs myminio --bucket app-data
|
||
|
||
# 查看审计日志(如已配置 Webhook,从 ELK 等系统查询)
|
||
mc admin trace myminio --call s3 --verbose
|
||
</code></pre><h4 id=512-常见问题排查 class="relative group">5.1.2 常见问题排查 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#512-%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98%e6%8e%92%e6%9f%a5 aria-label>#</a></span></h4><p><strong>问题一:单盘故障恢复</strong></p><p>磁盘故障是分布式存储最常见的硬件问题。MinIO 在纠删码保护范围内可自动降级运行,但需尽快替换故障盘:</p><pre tabindex=0><code># 1. 确认故障盘位置
|
||
mc admin info myminio --json | jq '.info.servers[].disks[] | select(.state != "ok")'
|
||
|
||
# 输出示例:
|
||
# { "endpoint": "/data/disk3", "state": "offline", "totalspace": 0 }
|
||
|
||
# 2. 物理替换磁盘后,格式化并挂载到原路径
|
||
mkfs.xfs /dev/sdX
|
||
mount /dev/sdX /data/disk3
|
||
|
||
# 3. 确保目录属主正确
|
||
chown minio-user:minio-user /data/disk3
|
||
|
||
# 4. MinIO 自动检测到新盘并开始 healing
|
||
mc admin heal myminio --recursive --status
|
||
</code></pre><p><strong>问题二:节点替换流程</strong></p><pre tabindex=0><code># 1. 确认待替换节点状态
|
||
mc admin info myminio
|
||
|
||
# 2. 新节点部署完成后,使用相同的 MINIO_VOLUMES 配置启动
|
||
# 关键:新节点的主机名/IP 必须与原节点一致(或更新 DNS 解析)
|
||
|
||
# 3. 启动后观察 healing 进度
|
||
mc admin heal myminio --recursive --status
|
||
# 输出中关注 Items healed / Items pending 的比例
|
||
</code></pre><p><strong>问题三:性能瓶颈定位</strong></p><pre tabindex=0><code># 实时追踪 S3 API 调用延迟
|
||
mc admin trace myminio --call s3 --verbose --filter-response-time 500ms
|
||
|
||
# 查看各节点磁盘 IO 状态
|
||
mc admin speedtest myminio --duration 30s
|
||
|
||
# 检查网络带宽是否成为瓶颈(节点间测试)
|
||
iperf3 -c minio-2.example.com -t 10 -P 4
|
||
</code></pre><h4 id=513-mc-admin-诊断工具 class="relative group">5.1.3 mc admin 诊断工具 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#513-mc-admin-%e8%af%8a%e6%96%ad%e5%b7%a5%e5%85%b7 aria-label>#</a></span></h4><p><code>mc admin</code> 提供了一套完整的集群诊断命令,排障时按以下顺序逐步排查:</p><pre tabindex=0><code># 集群整体健康状态概览
|
||
mc admin info myminio
|
||
|
||
# 生成诊断报告包(包含配置、日志、系统信息)
|
||
# 提交工单或社区求助时附带此文件
|
||
mc admin inspect myminio
|
||
|
||
# 查看集群配置差异(多节点配置不一致是常见问题源)
|
||
mc admin config get myminio | head -50
|
||
|
||
# 查看实时 API 调用链路(类似 strace 效果)
|
||
mc admin trace myminio --all --verbose
|
||
|
||
# 磁盘级别健康检查
|
||
mc admin scanner status myminio
|
||
</code></pre><h3 id=52-性能监控 class="relative group">5.2 性能监控 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#52-%e6%80%a7%e8%83%bd%e7%9b%91%e6%8e%a7 aria-label>#</a></span></h3><h4 id=521-关键指标监控 class="relative group">5.2.1 关键指标监控 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#521-%e5%85%b3%e9%94%ae%e6%8c%87%e6%a0%87%e7%9b%91%e6%8e%a7 aria-label>#</a></span></h4><p>MinIO 原生支持 Prometheus 指标暴露,生成抓取配置:</p><pre tabindex=0><code># 生成 Prometheus 抓取配置
|
||
mc admin prometheus generate myminio
|
||
|
||
# 输出示例(添加到 prometheus.yml 的 scrape_configs 中):
|
||
# - job_name: minio-job
|
||
# bearer_token: <token>
|
||
# metrics_path: /minio/v2/metrics/cluster
|
||
# scheme: http
|
||
# static_configs:
|
||
# - targets: ['minio-1:9000','minio-2:9000','minio-3:9000','minio-4:9000']
|
||
</code></pre><h4 id=522-监控指标说明 class="relative group">5.2.2 监控指标说明 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#522-%e7%9b%91%e6%8e%a7%e6%8c%87%e6%a0%87%e8%af%b4%e6%98%8e aria-label>#</a></span></h4><p>指标名称</p><p>正常范围</p><p>告警阈值</p><p>说明</p><p><code>minio_node_disk_free_bytes</code></p><p>>20% 总容量</p><p><10%</p><p>磁盘剩余空间,低于阈值需扩容</p><p><code>minio_s3_requests_errors_total</code></p><p><0.1% 请求量</p><p>>1%</p><p>S3 错误请求数,突增说明客户端或权限异常</p><p><code>minio_s3_ttfb_seconds</code></p><p><200ms (p99)</p><p>>500ms</p><p>首字节延迟,反映存储后端响应速度</p><p><code>minio_node_disk_used_bytes</code></p><p>线性增长</p><p>增速突变</p><p>磁盘使用量,突增可能是异常写入</p><p><code>minio_heal_objects_total</code></p><p>0</p><p>>0 持续 1h</p><p>待修复对象数,持续不为零说明有磁盘问题</p><p><code>minio_node_process_cpu_total</code></p><p><70%</p><p>>85%</p><p>CPU 使用率,纠删码计算密集时会升高</p><h4 id=523-prometheus--grafana-告警配置 class="relative group">5.2.3 Prometheus + Grafana 告警配置 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#523-prometheus--grafana-%e5%91%8a%e8%ad%a6%e9%85%8d%e7%bd%ae aria-label>#</a></span></h4><pre tabindex=0><code># prometheus-rules.yml - MinIO 告警规则
|
||
groups:
|
||
- name: minio-alerts
|
||
rules:
|
||
# 磁盘空间不足告警
|
||
- alert: MinioDiskSpaceLow
|
||
expr: (minio_node_disk_free_bytes / minio_node_disk_total_bytes) < 0.1
|
||
for: 10m
|
||
labels:
|
||
severity: critical
|
||
annotations:
|
||
summary: "MinIO 磁盘空间不足 ({{ $labels.instance }})"
|
||
description: "节点 {{ $labels.server }} 磁盘 {{ $labels.disk }} 剩余空间低于 10%"
|
||
|
||
# S3 请求错误率告警
|
||
- alert: MinioHighErrorRate
|
||
expr: rate(minio_s3_requests_errors_total[5m]) / rate(minio_s3_requests_total[5m]) > 0.01
|
||
for: 5m
|
||
labels:
|
||
severity: warning
|
||
annotations:
|
||
summary: "MinIO S3 错误率超过 1%"
|
||
|
||
# 节点离线告警
|
||
- alert: MinioNodeOffline
|
||
expr: minio_cluster_nodes_offline_total > 0
|
||
for: 2m
|
||
labels:
|
||
severity: critical
|
||
annotations:
|
||
summary: "MinIO 集群存在离线节点"
|
||
description: "当前离线节点数: {{ $value }}"
|
||
</code></pre><h3 id=53-备份与恢复 class="relative group">5.3 备份与恢复 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#53-%e5%a4%87%e4%bb%bd%e4%b8%8e%e6%81%a2%e5%a4%8d aria-label>#</a></span></h3><h4 id=531-mc-mirror-备份脚本 class="relative group">5.3.1 mc mirror 备份脚本 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#531-mc-mirror-%e5%a4%87%e4%bb%bd%e8%84%9a%e6%9c%ac aria-label>#</a></span></h4><pre tabindex=0><code>#!/bin/bash
|
||
set -euo pipefail
|
||
|
||
# MinIO 增量备份脚本
|
||
# 通过 mc mirror 将源集群数据同步到备份集群
|
||
# 建议通过 crontab 每日执行:0 2 * * * /opt/scripts/minio-backup.sh
|
||
|
||
SOURCE_ALIAS="myminio"
|
||
TARGET_ALIAS="backup-minio"
|
||
BUCKETS=("app-data" "user-uploads" "logs-archive")
|
||
LOG_DIR="/var/log/minio-backup"
|
||
DATE=$(date +%Y%m%d-%H%M%S)
|
||
|
||
mkdir -p "${LOG_DIR}"
|
||
|
||
for bucket in "${BUCKETS[@]}"; do
|
||
echo "[${DATE}] 开始备份 Bucket: ${bucket}" | tee -a "${LOG_DIR}/backup-${DATE}.log"
|
||
|
||
# --watch 不加,单次同步;--overwrite 覆盖已存在但内容不同的对象
|
||
mc mirror --overwrite --remove \
|
||
"${SOURCE_ALIAS}/${bucket}" \
|
||
"${TARGET_ALIAS}/${bucket}-backup" \
|
||
2>&1 | tee -a "${LOG_DIR}/backup-${DATE}.log"
|
||
|
||
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
|
||
echo "[ERROR] Bucket ${bucket} 备份失败" | tee -a "${LOG_DIR}/backup-${DATE}.log"
|
||
# 发送告警(根据实际告警通道修改)
|
||
curl -s -X POST "http://alertmanager:9093/api/v1/alerts" \
|
||
-H "Content-Type: application/json" \
|
||
-d "[{\"labels\":{\"alertname\":\"MinioBackupFailed\",\"bucket\":\"${bucket}\"}}]"
|
||
fi
|
||
done
|
||
|
||
echo "[${DATE}] 备份任务完成" | tee -a "${LOG_DIR}/backup-${DATE}.log"
|
||
|
||
# 清理 30 天前的备份日志
|
||
find "${LOG_DIR}" -name "backup-*.log" -mtime +30 -delete
|
||
</code></pre><h4 id=532-站点复制site-replication class="relative group">5.3.2 站点复制(Site Replication) <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#532-%e7%ab%99%e7%82%b9%e5%a4%8d%e5%88%b6site-replication aria-label>#</a></span></h4><p>Site Replication 是 MinIO 原生的多站点同步方案,支持 Bucket、对象、IAM 策略的双向实时同步,适用于异地容灾:</p><pre tabindex=0><code># 前置条件:所有站点必须使用相同的 root 凭证,且均为空集群或数据完全一致
|
||
|
||
# 1. 添加站点复制关系(在任意一个站点执行)
|
||
mc admin replicate add \
|
||
site1-minio \
|
||
site2-minio \
|
||
site3-minio
|
||
|
||
# 2. 查看复制状态
|
||
mc admin replicate status site1-minio
|
||
|
||
# 3. 查看复制延迟指标
|
||
mc admin replicate metrics site1-minio
|
||
|
||
# 注意事项:
|
||
# - 站点复制会同步 IAM 用户、策略、Bucket 配置
|
||
# - 已有数据的集群加入复制前需确保数据一致
|
||
# - 网络中断后会自动追赶同步,但长时间中断可能导致队列积压
|
||
</code></pre><h4 id=533-恢复流程 class="relative group">5.3.3 恢复流程 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#533-%e6%81%a2%e5%a4%8d%e6%b5%81%e7%a8%8b aria-label>#</a></span></h4><ol><li><p><strong>停止服务</strong>:<code>sudo systemctl stop minio</code></p></li><li><p><strong>替换故障磁盘</strong>:物理更换后格式化挂载到原路径</p></li><li><p><strong>验证数据完整性</strong>:</p><pre tabindex=0><code># 启动服务
|
||
sudo systemctl start minio
|
||
|
||
# 触发全量 heal 检查
|
||
mc admin heal myminio --recursive
|
||
|
||
# 持续观察 heal 进度直到完成
|
||
watch -n 5 'mc admin heal myminio --recursive --status'
|
||
</code></pre></li><li><p><strong>从备份恢复(如需要)</strong>:</p><pre tabindex=0><code># 从备份集群恢复指定 Bucket
|
||
mc mirror backup-minio/app-data-backup myminio/app-data
|
||
|
||
# 验证对象数量一致
|
||
mc ls --summarize --recursive myminio/app-data
|
||
</code></pre></li></ol><hr><h2 id=六总结 class="relative group">六、总结 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#%e5%85%ad%e6%80%bb%e7%bb%93 aria-label>#</a></span></h2><h3 id=61-技术要点回顾 class="relative group">6.1 技术要点回顾 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#61-%e6%8a%80%e6%9c%af%e8%a6%81%e7%82%b9%e5%9b%9e%e9%a1%be aria-label>#</a></span></h3><ul><li>✅ <strong>纠删码是核心</strong>:理解 Erasure Set 的划分逻辑和校验盘配比,直接决定集群的容错能力和存储效率</li><li>✅ <strong>JBOD 优于 RAID</strong>:让 MinIO 自身管理磁盘冗余,避免硬件 RAID 带来的写放大和故障域耦合</li><li>✅ <strong>安全不是事后补救</strong>:IAM 最小权限、禁用匿名访问、Object Lock 应在集群初始化阶段就规划到位</li><li>✅ <strong>监控先于故障</strong>:Prometheus 指标 + Grafana 看板 + 告警规则三件套是生产环境的底线要求</li><li>✅ <strong>备份要自动化</strong>:mc mirror 脚本 + Site Replication 双管齐下,RPO 和 RTO 才有保障</li><li>✅ <strong>扩容按 Pool 为单位</strong>:不能向已有 Erasure Set 添加磁盘,扩容前做好容量规划</li></ul><h3 id=62-进阶学习方向 class="relative group">6.2 进阶学习方向 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#62-%e8%bf%9b%e9%98%b6%e5%ad%a6%e4%b9%a0%e6%96%b9%e5%90%91 aria-label>#</a></span></h3><p><strong>MinIO vs Ceph RGW 对比</strong>:</p><p>维度</p><p>MinIO</p><p>Ceph RGW</p><p>部署复杂度</p><p>单二进制,分钟级部署</p><p>需要 MON/OSD/MDS/RGW 多组件,小时级部署</p><p>运维成本</p><p>低,配置项少,升级简单</p><p>高,组件多,调优参数复杂</p><p>S3 兼容性</p><p>覆盖主流 API,部分高级特性缺失</p><p>覆盖面更广,支持 Swift API</p><p>小文件性能</p><p>优秀,元数据轻量</p><p>一般,RADOS 层开销较大</p><p>大文件吞吐</p><p>优秀,纠删码计算高效</p><p>优秀,可通过调优追平</p><p>纠删码灵活性</p><p>Erasure Set 固定,扩容按 Pool</p><p>可在线调整 EC Profile</p><p>块存储/文件存储</p><p>不支持,纯对象存储</p><p>支持 RBD/CephFS,统一存储</p><p>社区生态</p><p>活跃,云原生方向发力</p><p>成熟,企业级部署案例丰富</p><p>适用场景</p><p>纯对象存储、云原生、S3 网关</p><p>需要统一存储、混合负载</p><ol><li><p><strong>Kubernetes Operator 部署</strong>:通过 MinIO Operator 在 K8s 上管理多租户集群,结合 CSI Driver 实现 PV 动态供给</p><ul><li>学习资源:MinIO Operator 文档</li><li>实践建议:先在测试集群部署单租户,熟悉 Tenant CRD 后再扩展到多租户</li></ul></li><li><p><strong>数据生命周期管理(ILM)</strong>:通过 Lifecycle Rule 自动将冷数据迁移到低成本存储层或自动过期删除</p><ul><li>学习资源:MinIO Object Lifecycle Management</li><li>实践建议:从日志类 Bucket 开始配置 Expiration 规则,逐步扩展到 Transition 规则</li></ul></li><li><p><strong>事件通知集成</strong>:将 Bucket 事件推送到 Kafka/NATS/Webhook,构建数据驱动的处理管道</p><ul><li>学习资源:MinIO Bucket Notifications</li></ul></li></ol><h3 id=63-参考资料 class="relative group">6.3 参考资料 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#63-%e5%8f%82%e8%80%83%e8%b5%84%e6%96%99 aria-label>#</a></span></h3><ul><li>MinIO 官方文档 - 最权威的配置和运维参考</li><li>MinIO GitHub - 源码、Issue 和 Release Notes</li><li>MinIO Blog - 架构设计思路和性能测试报告</li><li>Awesome MinIO - 社区工具和集成方案汇总</li></ul><hr><h2 id=附录 class="relative group">附录 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#%e9%99%84%e5%bd%95 aria-label>#</a></span></h2><h3 id=a-命令速查表 class="relative group">A. 命令速查表 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#a-%e5%91%bd%e4%bb%a4%e9%80%9f%e6%9f%a5%e8%a1%a8 aria-label>#</a></span></h3><pre tabindex=0><code># ========== 集群管理 ==========
|
||
mc alias set myminio http://minio:9000 admin password # 添加集群别名
|
||
mc admin info myminio # 查看集群状态
|
||
mc admin service restart myminio # 重启服务
|
||
mc admin update myminio # 在线升级
|
||
mc admin speedtest myminio --duration 30s # 性能测试
|
||
|
||
# ========== Bucket 操作 ==========
|
||
mc mb myminio/new-bucket # 创建 Bucket
|
||
mc mb myminio/locked-bucket --with-lock # 创建带 Object Lock 的 Bucket
|
||
mc rb myminio/empty-bucket # 删除空 Bucket
|
||
mc ls myminio # 列出所有 Bucket
|
||
|
||
# ========== 对象操作 ==========
|
||
mc cp localfile.tar.gz myminio/bucket/path/ # 上传文件
|
||
mc cp myminio/bucket/path/file.tar.gz ./ # 下载文件
|
||
mc cp --recursive ./dir/ myminio/bucket/dir/ # 递归上传目录
|
||
mc rm myminio/bucket/path/file.tar.gz # 删除对象
|
||
mc ls --summarize --recursive myminio/bucket # 统计对象数量和大小
|
||
|
||
# ========== 同步与备份 ==========
|
||
mc mirror source-minio/bucket target-minio/bucket # 增量同步
|
||
mc mirror --watch source-minio/bucket target-minio/bucket # 持续同步(守护模式)
|
||
|
||
# ========== 用户与策略 ==========
|
||
mc admin user add myminio username password # 创建用户
|
||
mc admin user list myminio # 列出用户
|
||
mc admin policy create myminio policy-name policy.json # 创建策略
|
||
mc admin policy attach myminio policy-name --user user # 绑定策略
|
||
|
||
# ========== 诊断与排障 ==========
|
||
mc admin logs myminio # 实时日志
|
||
mc admin trace myminio --all # API 调用追踪
|
||
mc admin heal myminio --recursive # 触发数据修复
|
||
mc admin heal myminio --recursive --status # 查看修复进度
|
||
mc admin prometheus generate myminio # 生成监控配置
|
||
</code></pre><h3 id=b-配置参数详解 class="relative group">B. 配置参数详解 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#b-%e9%85%8d%e7%bd%ae%e5%8f%82%e6%95%b0%e8%af%a6%e8%a7%a3 aria-label>#</a></span></h3><p>MinIO 通过环境变量进行配置,以下为生产环境常用参数:</p><p>环境变量</p><p>默认值</p><p>说明</p><p><code>MINIO_ROOT_USER</code></p><p>minioadmin</p><p>超级管理员用户名,长度 3-128 字符</p><p><code>MINIO_ROOT_PASSWORD</code></p><p>minioadmin</p><p>超级管理员密码,长度 8-128 字符</p><p><code>MINIO_VOLUMES</code></p><p>无</p><p>存储路径,分布式模式使用 <code>http://host:port/path</code> 格式</p><p><code>MINIO_OPTS</code></p><p>无</p><p>启动参数,如 <code>--address :9000 --console-address :9001</code></p><p><code>MINIO_SERVER_URL</code></p><p>自动检测</p><p>对外暴露的 S3 API 地址,经过负载均衡器时必须设置</p><p><code>MINIO_BROWSER_REDIRECT_URL</code></p><p>自动检测</p><p>Console 对外地址,反向代理场景必须设置</p><p><code>MINIO_SITE_REGION</code></p><p>无</p><p>区域标识,S3 兼容性需要时设置(如 <code>cn-east-1</code>)</p><p><code>MINIO_SITE_NAME</code></p><p>无</p><p>站点名称,Site Replication 场景使用</p><p><code>MINIO_STORAGE_CLASS_STANDARD</code></p><p>EC:N/2</p><p>标准存储类的纠删码校验盘数量</p><p><code>MINIO_STORAGE_CLASS_RRS</code></p><p>EC:2</p><p>低冗余存储类的校验盘数量</p><p><code>MINIO_PROMETHEUS_AUTH_TYPE</code></p><p>jwt</p><p>Prometheus 指标端点认证方式,可选 <code>jwt</code> 或 <code>public</code></p><p><code>MINIO_SCANNER_SPEED</code></p><p>default</p><p>后台扫描速度,可选 <code>fastest</code>/<code>fast</code>/<code>default</code>/<code>slow</code>/<code>slowest</code></p><p><code>MINIO_BATCH_REPLICATION_WORKERS</code></p><p>4</p><p>批量复制并发数,带宽充足时可适当调高</p><h3 id=c-术语表 class="relative group">C. 术语表 <span class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100"><a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700" style=text-decoration-line:none!important href=#c-%e6%9c%af%e8%af%ad%e8%a1%a8 aria-label>#</a></span></h3><p>术语</p><p>英文</p><p>解释</p><p>纠删码</p><p>Erasure Coding</p><p>将数据分片并生成校验片,允许在部分分片丢失时恢复完整数据</p><p>纠删集</p><p>Erasure Set</p><p>MinIO 中纠删码的最小管理单元,由固定数量的磁盘组成</p><p>服务器池</p><p>Server Pool</p><p>一组配置相同的 MinIO 节点,扩容以 Pool 为单位追加</p><p>对象锁定</p><p>Object Lock</p><p>防止对象在保留期内被删除或覆盖的 WORM 保护机制</p><p>站点复制</p><p>Site Replication</p><p>MinIO 原生的多站点双向同步方案,支持对象和 IAM 同步</p><p>生命周期管理</p><p>ILM (Information Lifecycle Management)</p><p>基于规则自动迁移、过期或删除对象</p><p>首字节延迟</p><p>TTFB (Time To First Byte)</p><p>从发起请求到收到第一个字节的耗时,衡量存储响应速度</p><p>数据修复</p><p>Healing</p><p>MinIO 自动检测并修复损坏或缺失的数据分片的过程</p><p>版本控制</p><p>Versioning</p><p>为同一对象保留多个历史版本,支持误操作回滚</p><p>服务账户</p><p>Service Account</p><p>绑定到 IAM 用户的访问凭证,用于应用程序接入</p></div></section><footer class="max-w-prose pt-8 print:hidden"><div class=flex><picture class="!mb-0 !mt-0 me-4 w-24 h-auto rounded-full"><img width=480 height=480 class="!mb-0 !mt-0 me-4 w-24 h-auto rounded-full" alt=华禹 loading=lazy decoding=async src=http://blog.hys.my/img/author.png></picture><div class=place-self-center><div class="text-[0.6rem] uppercase leading-3 text-neutral-500 dark:text-neutral-400"></div><div class="font-semibold leading-6 text-neutral-800 dark:text-neutral-300">华禹</div><div class="text-sm text-neutral-700 dark:text-neutral-400">北京理工大学医学技术学院研究生<br>AI食品营养量化初创公司联合创始人</div><div class="text-2xl sm:text-lg"><div class="flex flex-wrap text-neutral-400 dark:text-neutral-500"><a class="px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400" style=will-change:transform href=mailto:hello@your_domain.com target=_blank aria-label=Email rel="me noopener noreferrer"><span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 512 512"><path fill="currentColor" d="M207.8 20.73c-93.45 18.32-168.7 93.66-187 187.1-27.64 140.9 68.65 266.2 199.1 285.1 19.01 2.888 36.17-12.26 36.17-31.49l1e-4-.6631c0-15.74-11.44-28.88-26.84-31.24-84.35-12.98-149.2-86.13-149.2-174.2.0-102.9 88.61-185.5 193.4-175.4 91.54 8.869 158.6 91.25 158.6 183.2v16.16c0 22.09-17.94 40.05-40 40.05s-40.01-17.96-40.01-40.05v-120.1c0-8.847-7.161-16.02-16.01-16.02l-31.98.0036c-7.299.0-13.2 4.992-15.12 11.68-24.85-12.15-54.24-16.38-86.06-5.106-38.75 13.73-68.12 48.91-73.72 89.64-9.483 69.01 43.81 128 110.9 128 26.44.0 50.43-9.544 69.59-24.88 24 31.3 65.23 48.69 109.4 37.49C465.2 369.3 496 324.1 495.1 277.2V256.3c0-149.2-133.9-265.632-287.3-235.57zM239.1 304.3c-26.47.0-48-21.56-48-48.05s21.53-48.05 48-48.05 48 21.56 48 48.05-20.6 48.05-48 48.05z"/></svg>
|
||
</span></a><a class="px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400" style=will-change:transform href=https://link-to-some-website.com/ target=_blank aria-label=Link rel="me noopener noreferrer"><span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 640 512"><path fill="currentColor" d="M172.5 131.1c55.6-55.59 148-55.59 203.6.0 50 50 57.4 129.7 16.3 187.2L391.3 319.9C381 334.2 361 337.6 346.7 327.3c-14.4-10.3-17.8-30.3-7.5-44.6L340.3 281.1C363.2 249 359.6 205.1 331.7 177.2c-31.4-31.4-82.5-31.4-114 0L105.5 289.5c-31.51 30.6-31.51 82.5.0 114C133.3 431.4 177.3 435 209.3 412.1L210.9 410.1C225.3 400.7 245.3 404 255.5 418.4 265.8 432.8 262.5 452.8 248.1 463.1L246.5 464.2c-58.4 41.1-136.3 34.5-186.29-15.4-56.469-56.5-56.469-148.1.0-204.5L172.5 131.1zM467.5 380c-56.5 56.5-148 56.5-204.5.0-50-50-56.5-128.8-15.4-186.3L248.7 192.1C258.1 177.8 278.1 174.4 293.3 184.7 307.7 194.1 311.1 214.1 300.8 229.3L299.7 230.9C276.8 262.1 280.4 306.9 308.3 334.8c31.4 31.4 82.5 31.4 114 0L534.5 222.5c31.5-31.5 31.5-83.4.0-114C506.7 80.63 462.7 76.99 430.7 99.9L429.1 101C414.7 111.3 394.7 107.1 384.5 93.58 374.2 79.2 377.5 59.21 391.9 48.94L393.5 47.82C451 6.731 529.8 13.25 579.8 63.24c56.5 56.46 56.5 148.06.0 204.46L467.5 380z"/></svg>
|
||
</span></a><a class="px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400" style=will-change:transform href=https://www.amazon.com/hz/wishlist/ls/wishlist-id target=_blank aria-label=Amazon rel="me noopener noreferrer"><span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 448 512"><path fill="currentColor" d="M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5.0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2.0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1.0 27.1-6.5 43.1z"/></svg>
|
||
</span></a><a class="px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400" style=will-change:transform href=https://www.apple.com target=_blank aria-label=Apple rel="me noopener noreferrer"><span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 384 512"><path fill="currentColor" d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8.0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg>
|
||
</span></a><a class="px-1 transition-transform hover:scale-125 hover:text-primary-700 dark:hover:text-primary-400" style=will-change:transform href=https://xing.com/profile/username target=_blank aria-label=Xing rel="me noopener noreferrer"><span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 384 512"><path fill="currentColor" d="M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7.0-12.1-7.5-8.5-14.4l69-121.3c.2.0.2-.1.0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H1e2c7.3.0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6.0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z"/></svg></span></a></div></div></div></div><div class=pt-8><hr class="border-dotted border-neutral-300 dark:border-neutral-600"><div class="flex justify-between pt-3"><span><a class="group flex" href=http://blog.hys.my/posts/android-firefox/><span class="me-2 text-neutral-700 transition-transform group-hover:-translate-x-[2px] group-hover:text-primary-600 dark:text-neutral dark:group-hover:text-primary-400"><span class="ltr:inline rtl:hidden">←</span><span class="ltr:hidden rtl:inline">→</span></span>
|
||
<span class="flex flex-col"><span class="mt-[0.1rem] leading-6 group-hover:underline group-hover:decoration-primary-500">使用Docker容器在服务器上运行安卓和Firefox,实现自建云手机和指纹浏览器</span>
|
||
<span class="mt-[0.1rem] text-xs text-neutral-500 dark:text-neutral-400"><time datetime="2026-04-18 10:00:00 +0800 +0800"></time>
|
||
</span></span></a></span><span><a class="group flex text-right" href=http://blog.hys.my/posts/ds2api/><span class="flex flex-col"><span class="mt-[0.1rem] leading-6 group-hover:underline group-hover:decoration-primary-500">DS2API说明文档</span>
|
||
<span class="mt-[0.1rem] text-xs text-neutral-500 dark:text-neutral-400"><time datetime="2026-04-18 10:00:00 +0800 +0800"></time>
|
||
</span></span><span class="ms-2 text-neutral-700 transition-transform group-hover:-translate-x-[-2px] group-hover:text-primary-600 dark:text-neutral dark:group-hover:text-primary-400"><span class="ltr:inline rtl:hidden">→</span><span class="ltr:hidden rtl:inline">←</span></span></a></span></div></div></footer></article></main><div class="pointer-events-none absolute bottom-0 end-0 top-[100vh] w-12" id=to-top hidden=true><a href=#the-top class="pointer-events-auto sticky top-[calc(100vh-5.5rem)] flex h-12 w-12 items-center justify-center rounded-full bg-neutral/50 text-xl text-neutral-700 backdrop-blur hover:text-primary-600 dark:bg-neutral-800/50 dark:text-neutral dark:hover:text-primary-400" aria-label title>↑</a></div><footer class="py-10 print:hidden"><div class="flex items-center justify-between"><div><p class="text-sm text-neutral-500 dark:text-neutral-400">©
|
||
2026
|
||
华禹</p><p class="text-xs text-neutral-500 dark:text-neutral-400"></p></div><div class="flex flex-row items-center"></div></div></footer><div id=search-wrapper class="invisible fixed inset-0 z-50 flex h-screen w-screen cursor-default flex-col bg-neutral-500/50 p-4 backdrop-blur-sm dark:bg-neutral-900/50 sm:p-6 md:p-[10vh] lg:p-[12vh]" data-url=http://blog.hys.my/><div id=search-modal class="top-20 mx-auto flex min-h-0 w-full max-w-3xl flex-col rounded-md border border-neutral-200 bg-neutral shadow-lg dark:border-neutral-700 dark:bg-neutral-800"><header class="relative z-10 flex flex-none items-center justify-between px-2"><form class="flex min-w-0 flex-auto items-center"><div class="flex h-8 w-8 items-center justify-center text-neutral-400"><span class="icon relative inline-block px-1 align-text-bottom"><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" class="svg-inline--fa fa-search fa-w-16" role="img" viewBox="0 0 512 512"><path fill="currentColor" d="M505 442.7 405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9.0 208 0S0 93.1.0 208s93.1 208 208 208c48.3.0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9.0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7.0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7.0 128 57.2 128 128 0 70.7-57.2 128-128 128z"/></svg></span></div><input type=search id=search-query class="mx-1 flex h-12 flex-auto appearance-none bg-transparent focus:outline-dotted focus:outline-2 focus:outline-transparent" placeholder tabindex=0></form><button id=close-search-button class="flex h-8 w-8 items-center justify-center text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400" title>
|
||
<span class="icon relative inline-block px-1 align-text-bottom"><svg viewBox="0 0 320 512"><path fill="currentColor" d="M310.6 361.4c12.5 12.5 12.5 32.75.0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3 54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75.0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75.0-45.25s32.75-12.5 45.25.0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25.0s12.5 32.75.0 45.25l-105.4 105.4L310.6 361.4z"/></svg></span></button></header><section class="flex-auto overflow-auto px-2"><ul id=search-results></ul></section></div></div></div></body></html> |