蚊章汇 - 镜像
type: channel
link: https://linuxcn.bwsl.wang/tag/%E9%95%9C%E5%83%8F/
items: 使用 mkosi 构建 RHEL 和 RHEL UBI 镜像
items: 如何使用 Watchtower 自动更新正在运行的 Docker 容器
items: 什么是容器镜像？
items: 一次 Docker 镜像的逆向工程
items: 修改磁盘镜像来创建基于树莓派的家庭实验室
items: 如何构建 Fedora 容器镜像
items: PiShrink：使树莓派镜像更小
items: 清华大学开源软件镜像站推出一键使用服务，将来或支持 42 操作系统
items: 如何打造更小巧的容器镜像
items: 如何分析并探索 Docker 容器镜像的内容

使用 mkosi 构建 RHEL 和 RHEL UBI 镜像
type: item
date: 2023-11-28T07:22:00+08:00
description: mkosi 是一个轻量级工具，用于从发行版软件包构建镜像。本文介绍如何使用 mkosi 从 RHEL 和 RHEL 通用基础镜像 Universal Base Image （UBI）的软件包构建镜像。RHEL UBI 是 RHEL 的一个子集，可以在没有订阅的情况下免费使用。mkosi 特性mkosi 支持一些输出格式，但最重要的是 可发现磁盘镜像 Discoverable Disk Images （DDI）。同一个 DDI 可用于引导容器、或运行在虚拟机、抑或是复制到 U 盘以引导真实物理机，然后从 U 盘复制到磁盘以引导系统。该镜像具有标准化的布局和描述其用途的元数据。mkosi 依赖其他工具来完成大部分工作：使用 systemd-repart 在磁盘镜像上创建分区，使用 mkfs.btrfs / mkfs.ext4 / mkfs.xfs 等创建文件系统，并使用 dnf / apt / pacman / zypper 下载和解压包。mkosi 支持一系列发行版：Debian 和 Ubuntu、Arch Linux、openSUSE，当然还包括 Fedora、CentOS Stream 及其衍生版本，以及最近的 RHEL UBI 和 RHEL 。由于实际的“重活”是由其他工具完成的，mkosi 可以进行交叉构建。这意味着可以使用一个发行版构建各种其他发行版的镜像。唯一的要求是主机上安装了相应的工具。Fedora 有原生的 apt、pacman 和 zypper，因此它为使用 mkosi 构建任何其他发行版提供了良好的基础。它还有一些有趣的功能：镜像可以由非特权用户创建，或者在没有设备文件的容器中创建，特别是没有对回环设备的访问权限。它还可以在没有特权的情况下将这些镜像启动为虚拟机（使用 qemu）。配置是声明性的，非常容易创建。使用 systemd-repart 创建磁盘分区，并使用 repart.d 配置文件定义应该如何完成此操作。有关更多详细信息，请参见 Daan DeMeyer 在 All Systems Go 大会上的两个演讲：《systemd-repart: Building Discoverable Disk Images》 和 《mkosi: Building Bespoke Operating System Images》。项目目标mkosi 的一个目标是允许对软件项目进行针对不同发行版的测试。它将为一个发行版创建一个镜像（使用该发行版的软件包），然后将软件项目编译并安装到该镜像中，插入不属于软件包的额外文件。但是，首个阶段，即从软件包创建镜像的过程，本身就是有用的。这是我们将首先展示的内容。我们 [1] 最近添加了对 RHEL 和 RHEL UBI 的支持。让我们从 RHEL UBI 开始，利用发行版软件包创建镜像。请注意，下面的示例要求 mkosi 19，而且不适用于更早的版本。带有 Shell 的基本 RHEL UBI 镜像$ mkdir -p mkosi.cache $ mkosi \ -d rhel-ubi \ -t directory \ -p bash,coreutils,util-linux,systemd,rpm \ --autologin 上面的命令指定了发行版 rhel-ubi，输出格式 directory，并请求安装软件包 bash、coreutils、…、rpm。rpm 通常不需要放到镜像内部，但在这里用于内省会很有用。我们还启用了以 root 用户自动登录。在启动构建之前，我们创建了缓存目录 mkosi.cache。当存在缓存目录时，mkosi 会自动使用它来持久化下载的 RPM 包。这将使相同软件包集合的后续调用速度更快。然后，我们可以使用 systemd-nspawn 将此镜像作为容器启动：$ sudo mkosi \ -d rhel-ubi \ -t directory \ boot systemd 252-14.el9_2.3 running in system mode (+PAM +AUDIT +SELINUX -APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS -FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY +P11KIT -QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified) Detect…

如何使用 Watchtower 自动更新正在运行的 Docker 容器
type: item
date: 2022-08-14T01:17:15+08:00
description: 使用 Watchtower 自动更新 Docker 容器基础镜像对开发运维人员来说，保持 Docker 容器为最新版本是重要工作之一。手动更新 Docker 容器是一项耗时的工作。这篇文章解释了 Watchtower 是什么，如何安装它，以及在 Linux 中如何 使用 Watchtower 自动更新正在运行的 Docker 容器 。Watchtower 是什么？Watchtower 是一款自由开源的应用，用来监控运行中的 Docker 容器，并且当它发现基础镜像被更改后，可以自动的更新容器。若 Watchtower 发现一个运行中的容器需要更新，它会以发送 SIGTERM 信号的方式，优雅的结束运行中容器的运行。它会下载新镜像，然后以最初部署时使用的方式，重启容器。所有文件会在后台自动下载，因此不需要用户的介入。在这份指南中，我们将会明白如何在类 Unix 系统中使用 Watchtower 自动更新正在运行的 Docker 容器。我已经在 CentOS 和 Ubuntu 中测试了这份指南，所有的 Linux 发行版中操作过程都一样。在 Linux 中安装 Watchtower可以通过 Docker 镜像的方式下载 Watchtower 。因此，部署它是小事一桩。在你的 Linux 中安装 Docker 镜像，然后运行 Watchtower 立即开始监控 Docker 容器。参考下方指导在基于 PRM 和 DEB 包管理系统中安装 Docker如何在 CentOS 中安装 Docker如何在 Ubuntu 中安装 Docker适用于 Linux 的 Docker 桌面初学者手册安装 Docker 后，你可以使用以下命令以 root 用户身份部署 Watchtower 容器：# docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower 如果你已经安装了 Docker 桌面版，以普通用户运行 Watchtower 容器。$ docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower 该命令会拉取最新版的 watchtower 镜像，并运行 watchtower 容器。输出样例：Unable to find image 'containrrr/watchtower:latest' locally latest: Pulling from containrrr/watchtower 1045b2f97fda: Pull complete 35a104a262d3: Pull complete 1a0671483169: Pull complete Digest: sha256:bbf9794a691b59ed2ed3089fec53844f14ada249ee5e372ff0e595b73f4e9ab3 Status: Downloaded newer image for containrrr/watchtower:latest 91c104ef0e9896e8cd5ff30d9f13e728dbfad66443830ec2ac85dde6d7d37564 使用 Watchtower 自动更新 Docker 容器在你的系统上，Watchtower 正在和其他容器一起运行。你可以使用一下命令查看运行中的 Docker 容器列表：$ docker ps 输出样例：CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 91c104ef0e98 containrrr/watchtower "/watchtower" 14 minutes ago Up 14 minutes 8080/tcp watchtower f90b462b0712 bitnami/wordpress-nginx:6 "/opt/bitnami/script…" 19 minutes ago Up 19 minutes 0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp ostechnix-wordpress-1 正如上方输出所示，watchtower 容器正在和名为 ostechnix-wordpress-1 的容器一起运行。从现在开始，watchtower 会每隔几分钟会检查该容器。如果 Watchtower 发现该容器的基础镜像的任何变化，它会优雅的关闭 ostechnix-wordpress-1 容器，…

什么是容器镜像？
type: item
date: 2021-09-08T23:27:42+08:00
description: 容器镜像包含一个打包的应用，以及它的依赖关系，还有它在启动时运行的进程信息。容器是当今 IT 运维的一个关键部分。 容器镜像 container image 包含了一个打包的应用，以及它的依赖关系，还有它在启动时运行的进程信息。你可以通过提供一组特殊格式的指令来创建容器镜像，可以是提交给 注册中心 Registry ，或者是作为 Dockerfile 保存。例如，这个 Dockerfile 为 PHP Web 应用创建了一个容器：FROM registry.access.redhat.com/ubi8/ubi:8.1 RUN yum --disableplugin=subscription-manager -y module enable php:7.3 \ && yum --disableplugin=subscription-manager -y install httpd php \ && yum --disableplugin=subscription-manager clean all ADD index.php /var/www/html RUN sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf \ && sed -i 's/listen.acl_users = apache,nginx/listen.acl_users =/' /etc/php-fpm.d/www.conf \ && mkdir /run/php-fpm \ && chgrp -R 0 /var/log/httpd /var/run/httpd /run/php-fpm \ && chmod -R g=u /var/log/httpd /var/run/httpd /run/php-fpm EXPOSE 8080 USER 1001 CMD php-fpm & httpd -D FOREGROUND 这个文件中的每条指令都会在容器镜像中增加一个 层 layer 。每一层只增加与下面一层的区别，然后，所有这些堆叠在一起，形成一个只读的容器镜像。它是如何工作的？你需要知道一些关于容器镜像的事情，按照这个顺序理解这些概念很重要：联合文件系统写入时复制（COW）叠加文件系统快照器联合文件系统 联合文件系统 Union File System （UnionFS）内置于 Linux 内核中，它允许将一个文件系统的内容与另一个文件系统的内容合并，同时保持“物理”内容的分离。其结果是一个统一的文件系统，即使数据实际上是以分支形式组织。这里的想法是，如果你有多个镜像有一些相同的数据，不是让这些数据再次复制过来，而是通过使用一个叫做 层 layer 的东西来共享。每一层都是一个可以在多个容器中共享的文件系统，例如，httpd 基础层是 Apache 的官方镜像，可以在任何数量的容器中使用。想象一下，由于我们在所有的容器中使用相同的基础层，我们节省了多少磁盘空间。这些镜像层总是只读的，但是当我们用这个镜像创建一个新的容器时，我们会在它上面添加一个薄的可写层。这个可写层是你创建、修改、删除或进行每个容器所需的其他修改的地方。写时复制（COW）当你启动一个容器时，看起来好像这个容器有自己的整个文件系统。这意味着你在系统中运行的每个容器都需要自己的文件系统副本。这岂不是要占用大量的磁盘空间，而且还要花费大量的时间让容器启动？不是的，因为每个容器都不需要它自己的文件系统副本!容器和镜像使用 写时复制 copy-on-write （COW）机制来实现这一点。写时复制策略不是复制文件，而是将同一个数据实例分享给多个进程，并且只在一个进程需要修改或写入数据时进行复制。所有其他进程将继续使用原始数据。Docker 对镜像和容器都使用了写时复制的机制。为了做到这一点，在旧版本中，镜像和运行中的容器之间的变化是通过 图驱动 graph driver 来跟踪的，现在则是通过 快照器 snapshotter 来跟踪。在运行中的容器中执行任何写操作之前，要修改的文件的副本被放在容器的可写层上。这就是发生 写 的地方。现在你知道为什么它被称为“写时复制”了么。这种策略既优化了镜像磁盘空间的使用，也优化了容器启动时间的性能，并与 UnionFS 一起工作。叠加文件系统 叠加文件系统 Overlay File System 位于现有文件系统的顶部，结合了上层和下层的目录树，并将它们作为一个单一的目录来呈现。这些目录被称为 层 layer 。下层保持不被修改。每一层只增加与下一层的差异（计算机术语为 “diff”），这种统一的过程被称为 联合挂载 union mount 。最低的目录或镜像层被称为 下层目录 lowerdir ，上…

一次 Docker 镜像的逆向工程
type: item
date: 2021-04-02T05:55:31+08:00
description: 这要从一次咨询的失误说起：政府组织 A 让政府组织 B 开发一个 Web 应用程序。政府机构 B 把部分工作外包给某个人。后来，项目的托管和维护被外包给一家私人公司 C。C 公司发现，之前外包的人（已经离开很久了）构建了一个自定义的 Docker 镜像，并将其成为系统构建的依赖项，但这个人没有提交原始的 Dockerfile。C 公司有合同义务管理这个 Docker 镜像，可是他们他们没有源代码。C 公司偶尔叫我进去做各种工作，所以处理一些关于这个神秘 Docker 镜像的事情就成了我的工作。幸运的是，Docker 镜像的格式比想象的透明多了。虽然还需要做一些侦查工作，但只要解剖一个镜像文件，就能发现很多东西。例如，这里有一个 Prettier 代码格式化 的镜像可供快速浏览。首先，让 Docker 守护进程 daemon 拉取镜像，然后将镜像提取到文件中：docker pull tmknom/prettier:2.0.5 docker save tmknom/prettier:2.0.5 > prettier.tar 是的，该文件只是一个典型 tarball 格式的归档文件：$ tar xvf prettier.tar 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/ 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/VERSION 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/json 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/ a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/VERSION a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/json a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/ d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/VERSION d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/json d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tar manifest.json repositories 如你所见，Docker 在命名时经常使用 哈希 hash 。我们看看 manifest.json。它是以难以阅读的压缩 JSON 写的，不过 JSON 瑞士军刀 jq 可以很好地打印 JSON：$ jq . manifest.json [ { "Config": "88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json", "RepoTags": [ "tmknom/prettier:2.0.5" ], "Layers": [ "a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar", "d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tar", "6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar" ] } ] 请注意，这三个 层 Layer 对应三个以哈希命名的目录。我们以后再看…

修改磁盘镜像来创建基于树莓派的家庭实验室
type: item
date: 2020-06-03T20:34:48+08:00
description: 使用树莓派或其它单板机创建一个“家庭私有云”。构建一个家庭实验室可以是一个有趣的方式，可以让你学习的新概念和实验新技术时还能自娱自乐。得益于以 树莓派 为首的单板计算机（SBC）的流行，在舒适的家里就可以轻松构建一个多计算机实验室。比起试图在主流的云服务商建立的相同配置，创建一个“家庭私有云”以花更少的钱来体验到云原生技术，也是一个极好的方法。这篇文章阐述如何修改树莓派或其它的单板机的磁盘镜像，预配置主机的 SSH，并禁用首次启动时强制竞选交互配置的服务。这是一个让你的设备“即启动，即运行”的极好方法，类似于云端实例。之后，你可以使用自动化的流程通过 SSH 连接来进行更专业和更深入的配置。此外, 当向你的实验室添加更多的树莓派时，修改磁盘镜像可以来让你只需要将该镜像写到一个 SD 卡、放入树莓派中就可以了！解压缩和挂载镜像对于这个项目，你需要修改一个服务器磁盘镜像。在测试期间，我使用 Fedora Server 31 ARM。在你下载该磁盘镜像并验证其校验和之后，你需要将其解压缩并挂载其到宿主机的文件系统的某个位置上，以便你可以根据需要修改它。你可以使用 xz 命令通过 --decompress 参数来解压缩 Fedora 服务器镜像：xz --decompress Fedora-Server-armhfp-X-y.z-sda.raw.xz这会留下一个解压缩后的原始磁盘镜像（它会自动地替换 .xz 压缩文件）。这个原始磁盘镜像就像它听起来的那样：一个包含格式化后安装好的磁盘上的所有数据的文件。这包含分区信息、启动分区、root 分区以及其它分区。你需要挂载你打算在其中进行修改的分区，但是要做到这一点，你需要知道磁盘镜像中的分区起始位置和扇区大小，这样你才可以挂载该文件正确的扇区。幸运的是，你可以在一个磁盘镜像上使用 fdisk 命令，就像在实际磁盘上使用一样容易。使用 --list 或 -l 参数来查看分区的列表和其信息：# 使用 fdisk 来列出原始镜像文件的分区： $ fdisk -l Fedora-Server-armhfp-31-1.9-sda.raw Disk Fedora-Server-armhfp-X-y.z-sda.raw: 3.2 GiB, 3242196992 bytes, 6332416 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xdaad9f57 Device Boot Start End Sectors Size Id Type Fedora-Server-armhfp-X-y.z-sda.raw1 8192 163839 155648 76M c W95 F Fedora-Server-armhfp-X-y.z-sda.raw2 * 163840 1163263 999424 488M 83 Linux Fedora-Server-armhfp-X-y.z-sda.raw3 1163264 6047743 4884480 2.3G 83 Linux你需要的所有信息都可在上面的输出中获得。第 3 行表示扇区大小（包括逻辑和物理的）：512 字节 / 512 字节。设备列表显示的是原始磁盘镜像中的分区。第一个，Fedora-Server-armhfp-X-y.z-sda.raw1 毫无疑问是引导程序分区，因为它是第一个，很小（仅仅 76MB），而且类型被标识为 c，即 W95 FAT32（LBA），这是一个从 SD 卡启动的 FAT32 分区。第二个分区也不是非常大，只有 488MB。这个分区是一个 Linux 原生类型分区（Id 83），它可能是包含内核和 initramfs 的 Linux 启动分区。第三个分区可能是你需要的东西：它有 2.3GB 大小，所以在它其中应该有发行版的主要部分，并且它是一个 Linux 原生分区类型，这也是在预料之中的。这个分区应该包含了你需要修改的分区和数据。第三个分区从扇区 1163264 开始（在 fdisk 的输出中被显示为 Start 列），所以你的挂载偏移量是 595591168，计算方法是将扇区大小（512）乘以起始扇区（1163264）（即 512 * 1163264）。这意味着你需要以偏移量 595591168 挂载该文件，才能挂载到正确位置。装备了这些信息，现在你可以将第三个分区挂载到你的家目录中了：$ mkdir ~/…

如何构建 Fedora 容器镜像
type: item
date: 2019-09-10T20:23:23+08:00
description: 随着容器和容器技术的兴起，现在所有主流的 Linux 发行版都提供了容器基础镜像。本文介绍了 Fedora 项目如何构建其基本镜像，同时还展示了如何使用它来创建分层图像。基础和分层镜像在看如何构建 Fedora 容器 基础镜像 base image 之前，让我们定义基础镜像和 分层镜像 layered image 。定义基础镜像的简单方法是没有父镜像层的镜像。但这具体意味着什么呢？这意味着基础镜像通常只包含操作系统的根文件系统基础镜像（rootfs）。基础镜像通常提供安装软件以创建分层镜像所需的工具。分层镜像在基础镜像上添加了一组层，以便安装、配置和运行应用。分层镜像在 Dockerfile 中使用 FROM 指令引用基础镜像：FROM fedora:latest如何构建基础镜像Fedora 有一整套用于构建容器镜像的工具。其中包括 podman，它不需要以 root 身份运行。构建 rootfs基础镜像主要由一个 tarball) 构成。这个 tarball 包含一个 rootfs。有不同的方法来构建此 rootfs。Fedora 项目使用 kickstart) 安装方式以及 imagefactory 来创建这些 tarball。在创建 Fedora 基础镜像期间使用的 kickstart 文件可以在 Fedora 的构建系统 Koji 中找到。Fedora-Container-Base 包重新组合了所有基础镜像的构建版本。如果选择了一个构建版本，那么可以访问所有相关文件，包括 kickstart 文件。查看 示例，文件末尾的 %packages 部分定义了要安装的所有软件包。这就是让软件放在基础镜像中的方法。使用 rootfs 构建基础镜像rootfs 完成后，构建基础镜像就很容易了。它只需要一个包含以下指令的 Dockerfile：FROM scratch ADD layer.tar / CMD ["/bin/bash"]这里的重要部分是 FROM scratch 指令，它会创建一个空镜像。然后，接下来的指令将 rootfs 添加到镜像，并设置在运行镜像时要执行的默认命令。让我们使用 Koji 内置的 Fedora rootfs 构建一个基础镜像：$ curl -o fedora-rootfs.tar.xz https://kojipkgs.fedoraproject.org/packages/Fedora-Container-Base/Rawhide/20190902.n.0/images/Fedora-Container-Base-Rawhide-20190902.n.0.x86_64.tar.xz $ tar -xJvf fedora-rootfs.tar.xz 51c14619f9dfd8bf109ab021b3113ac598aec88870219ff457ba07bc29f5e6a2/layer.tar $ mv 51c14619f9dfd8bf109ab021b3113ac598aec88870219ff457ba07bc29f5e6a2/layer.tar layer.tar $ printf "FROM scratch\nADD layer.tar /\nCMD [\"/bin/bash\"]" > Dockerfile $ podman build -t my-fedora . $ podman run -it --rm my-fedora cat /etc/os-release需要从下载的存档中提取包含 rootfs 的 layer.tar 文件。这在 Fedora 生成的镜像已经可以被容器运行时使用才需要。因此，使用 Fedora 生成的镜像，获得基础镜像会更容易。让我们看看它是如何工作的：$ curl -O https://kojipkgs.fedoraproject.org/packages/Fedora-Container-Base/Rawhide/20190902.n.0/images/Fedora-Container-Base-Rawhide-20190902.n.0.x86_64.tar.xz $ podman load --input Fedora-Container-Base-Rawhide-20190902.n.0.x86_64.tar.xz $ podman run -it --rm localhost/fedora-container-base-rawhide-20190902.n.0.x86_64:latest cat /etc/os-release构建分层镜像要构建使用 Fedora 基础镜像的分层镜像，只需在 FROM 行指令中指定 fedora：FROM fedora…

PiShrink：使树莓派镜像更小
type: item
date: 2019-05-24T20:44:14+08:00
description: 树莓派不需要过多介绍。它是一款小巧、价格实惠，只有信用卡大小的电脑，它可以连接到显示器或电视。我们可以连接一个标准的键盘和鼠标，并将其用作一台成熟的台式计算机来完成日常任务，如互联网浏览、播放视频/玩游戏、文字处理和电子表格制作等。它主要是为学校的计算机科学教学而开发的。如今，树莓派被广泛用于大学、中小型组织和研究所来教授编码。如果你有一台树莓派，你可能需要了解一个名为 PiShrink 的 bash 脚本，该脚本可使树莓派镜像更小。PiShrink 将自动缩小镜像，然后在启动时将其调整为 SD 卡的最大大小。这能更快地将镜像复制到 SD 卡中，同时缩小的镜像将更好地压缩。这对于将大容量镜像放入 SD 卡非常有用。在这个简短的指南中，我们将学习如何在类 Unix 系统中将树莓派镜像缩小到更小。安装 PiShrink要在 Linux 机器上安装 PiShrink，请先使用以下命令下载最新版本：$ wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh接下来，将下载的 PiShrink 变成二进制可执行文件：$ chmod +x pishrink.sh最后，移动到目录：$ sudo mv pishrink.sh /usr/local/bin/使树莓派镜像更小你可能已经知道，Raspbian 是所有树莓派型号的官方操作系统。树莓派基金会为 PC 和 Mac 开发了树莓派桌面版本。你可以创建一个 live CD，并在虚拟机中运行它，甚至也可以将其安装在桌面上。树莓派也有少量非官方​​操作系统镜像。为了测试，我从官方下载页面下载了官方的 Raspbian 系统。解压下载的系统镜像：$ unzip 2019-04-08-raspbian-stretch-lite.zip上面的命令将提取当前目录中 2019-04-08-raspbian-stretch-lite.zip 文件的内容。让我们看下提取文件的实际大小：$ du -h 2019-04-08-raspbian-stretch-lite.img 1.7G 2019-04-08-raspbian-stretch-lite.img如你所见，提取的树莓派系统镜像大小为 1.7G。现在，使用 PiShrink 缩小此文件的大小，如下所示：$ sudo pishrink.sh 2019-04-08-raspbian-stretch-lite.img示例输出：Creating new /etc/rc.local rootfs: 39795/107072 files (0.1% non-contiguous), 239386/428032 blocks resize2fs 1.45.0 (6-Mar-2019) resize2fs 1.45.0 (6-Mar-2019) Resizing the filesystem on /dev/loop1 to 280763 (4k) blocks. Begin pass 3 (max = 14) Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Begin pass 4 (max = 3728) Updating inode references XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX The filesystem on /dev/loop1 is now 280763 (4k) blocks long. Shrunk 2019-04-08-raspbian-stretch-lite.img from 1.7G to 1.2G正如你在上面的输出中看到的，树莓派镜像的大小已减少到 1.2G。你还可以使用 -s 标志跳过该过程的自动扩展部分。$ sudo pishrink.sh -s 2019-04-08-raspbian-stretch-lite.img newpi.img这将创建一个源镜像文件（即 2019-04-08-raspbian-stretch-lite.img）的副本到一个新镜像文件（newpi.img）并进行处理。有关更多详细信息，请查看最后给出的官方 GitHub 页面。就是这些了。希望本文有用。还有更多好东西，敬请期待！资源：PiShrink 的 GitHub 仓库树莓派网站via: https://www.ostechnix.com/pishrink-make-raspberry-pi-images-smaller/作者：sk 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推…

清华大学开源软件镜像站推出一键使用服务，将来或支持 42 操作系统
type: item
date: 2019-05-02T01:38:00+08:00
description: 清华大学开源软件镜像站 是国内著名的开源软件镜像站，在去年某个节日推出了“一键使用 TUNA”服务，并发布了一篇热情洋溢的公告，特此将此服务及公告分享给大家： XD# 号外：现推出“一键使用TUNA”服务2018-04-01 TUNA Staff随着 TUNA 协会的现代化建设进入新时代，镜像站面临的主要矛盾已经转化为用户日益增长的高速下载需要和各类软件不简单不直观的配置之间的矛盾。只有正确认识这一主要矛盾，才能确定正确的战略、策略、政策和办法，促进矛盾解决，推动 TUNA 协会进步。必须认识到，TUNA 主要矛盾的变化，是关系全局的历史性变化，对协会工作提出了许多新要求。在新任会长 Xavier Yao (a.k.a. Pero) 的带领下，TUNA 协会的同学们勇于担当，攻坚克难，开发出了适应时代潮流、贴合用户需要的新一代工具“一键使用 TUNA” 脚本，又名 oh-my-tuna 。它目前支持更改下列软件的配置，将其直接指向 TUNA 镜像站：AnacondaArch LinuxTeX Live (by tlmgr)Debian GNU/LinuxHomebrewPyPIUbuntu Linux您可以选择仅更改当前用户的配置，也可以更改全局配置。如果不满意，随时可以撤销这些更改。这一切，只需要一行命令：python oh-my-tuna.py ！项目托管在 TUNA 主页 上，您也可以访问 GitHub 阅读源码、获取更详细的说明，也欢迎各位对本项目作出贡献！在将来，我们的目标是将其支持的系统/软件范围进一步扩展到（包括且不限于）：TUNA 镜像的尽可能多的系统/软件Macrohard TM Windoge TM42TUNA 成员要紧密团结在会长周围，高举开源精神伟大旗帜，锐意进取，埋头苦干，为实现推进镜像站建设、完成 Linux 发行版统一、维护开源界和平与促进共同发展三大历史任务，为决胜全面建成中国最好的镜像站、夺取新时代开源精神伟大胜利、实现社区伟大复兴的开源梦、实现用户对高速下载的向往继续奋斗！

如何打造更小巧的容器镜像
type: item
date: 2019-03-28T07:07:29+08:00
description: 五种优化 Linux 容器大小和构建更小的镜像的方法。Docker 近几年的爆炸性发展让大家逐渐了解到容器和容器镜像的概念。尽管 Linux 容器技术在很早之前就已经出现，但这项技术近来的蓬勃发展却还是要归功于 Docker 对用户友好的命令行界面以及使用 Dockerfile 格式轻松构建镜像的方式。纵然 Docker 大大降低了入门容器技术的难度，但构建一个兼具功能强大、体积小巧的容器镜像的过程中，有很多技巧需要了解。第一步：清理不必要的文件这一步和在普通服务器上清理文件没有太大的区别，而且要清理得更加仔细。一个小体积的容器镜像在传输方面有很大的优势，同时，在磁盘上存储不必要的数据的多个副本也是对资源的一种浪费。因此，这些技术对于容器来说应该比有大量专用内存的服务器更加需要。清理容器镜像中的缓存文件可以有效缩小镜像体积。下面的对比是使用 dnf 安装 Nginx 构建的镜像，分别是清理和没有清理 yum 缓存文件的结果：# Dockerfile with cache FROM fedora:28 LABEL maintainer Chris Collins <collins.christopher@gmail.com> RUN dnf install -y nginx ----- # Dockerfile w/o cache FROM fedora:28 LABEL maintainer Chris Collins <collins.christopher@gmail.com> RUN dnf install -y nginx \ && dnf clean all \ && rm -rf /var/cache/yum ----- [chris@krang] $ docker build -t cache -f Dockerfile . [chris@krang] $ docker images --format "{{.Repository}}: {{.Size}}" | head -n 1 cache: 464 MB [chris@krang] $ docker build -t no-cache -f Dockerfile-wo-cache . [chris@krang] $ docker images --format "{{.Repository}}: {{.Size}}" | head -n 1 no-cache: 271 MB从上面的结果来看，清理缓存文件的效果相当显著。和清除了元数据和缓存文件的容器镜像相比，不清除的镜像体积接近前者的两倍。除此以外，包管理器缓存文件、Ruby gem 的临时文件、nodejs 缓存文件，甚至是下载的源码 tarball 最好都全部清理掉。层：一个潜在的隐患很不幸（当你往下读，你会发现这是不幸中的万幸），根据容器中的层的概念，不能简单地向 Dockerfile 中写一句 RUN rm -rf /var/cache/yum 就完事儿了。因为 Dockerfile 的每一条命令都以一个层的形式存储，并一层层地叠加。所以，如果你是这样写的：RUN dnf install -y nginx RUN dnf clean all RUN rm -rf /var/cache/yum你的容器镜像就会包含三层，而 RUN dnf install -y nginx 这一层仍然会保留着那些缓存文件，然后在另外两层中被移除。但缓存实际上仍然是存在的，当你把一个文件系统挂载在另外一个文件系统之上时，文件仍然在那里，只不过你见不到也访问不到它们而已。在上一节的示例中，你会看到正确的做法是将几条命令链接起来，在产生缓存文件的同一条 Dockerfile 指令里把缓存文件清理掉：RUN dnf install -y nginx \ && dnf clean all \ && rm -rf /var/cache/yum这样就把几条命令连成了一条命令，在最终的镜像中只占用一个层。这样只会浪费一点缓存的好处，稍微多耗费一点点构建容器镜像的时间，但被清理掉的缓存文件就不会留存在最终的镜像中了。作为一个折衷方法，只需要把一些相关的命令（例如 yum install 和 yum clean all、下载文件、解压文件、移除 tarball 等等）连接成一个命令，就可以在最终的容器镜像中节省出大量体积，你也能够利用 Docker 的缓存加快开发速度。层还有一个更隐蔽的特性。每一层都记录了文件的更改，这里的更改并不仅仅已有的文件累加起来，而是包括文件属性在内的所有更改。因此即使是对文件使用了 chmod 操作也会被在新的层创建文件的副本。下面是一次 docker images 命令的输出内容。其中容器镜像 layer_tes…

如何分析并探索 Docker 容器镜像的内容
type: item
date: 2018-11-04T07:46:57+08:00
description: 或许你已经了解到 Docker 容器镜像是一个轻量、独立、含有运行某个应用所需全部软件的可执行包，这也是为什么容器镜像会经常被开发者用于构建和分发应用。假如你很好奇一个 Docker 镜像里面包含了什么东西，那么这篇简要的指南或许会帮助到你。今天，我们将学会使用一个名为 Dive 的工具来分析和探索 Docker 镜像每层的内容。通过分析 Docker 镜像，我们可以发现在各个层之间可能重复的文件并通过移除它们来减小 Docker 镜像的大小。Dive 工具不仅仅是一个 Docker 镜像分析工具，它还可以帮助我们来构建镜像。Dive 是一个用 Go 编程语言编写的自由开源工具。安装 Dive首先从该项目的 发布页 下载最新版本，然后像下面展示的那样根据你所使用的发行版来安装它。假如你正在使用 Debian 或者 Ubuntu，那么可以运行下面的命令来下载并安装它。$ wget https://github.com/wagoodman/dive/releases/download/v0.0.8/dive_0.0.8_linux_amd64.deb$ sudo apt install ./dive_0.0.8_linux_amd64.deb在 RHEL 或 CentOS 系统中$ wget https://github.com/wagoodman/dive/releases/download/v0.0.8/dive_0.0.8_linux_amd64.rpm$ sudo rpm -i dive_0.0.8_linux_amd64.rpmDive 也可以使用 Linuxbrew 包管理器来安装。$ brew tap wagoodman/dive$ brew install dive至于其他的安装方法，请参考 Dive 项目的 GitHub 网页。分析并探索 Docker 镜像的内容要分析一个 Docker 镜像，只需要运行加上 Docker 镜像 ID 的 dive 命令就可以了。你可以使用 sudo docker images 来得到 Docker 镜像的 ID。$ sudo dive ea4c82dcd15a上面命令中的 ea4c82dcd15a 是某个镜像的 ID。然后 dive 命令将快速地分析给定 Docker 镜像的内容并将它在终端中展示出来。正如你在上面的截图中看到的那样，在终端的左边一栏列出了给定 Docker 镜像的各个层及其详细内容，浪费的空间大小等信息。右边一栏则给出了给定 Docker 镜像每一层的内容。你可以使用 Ctrl+空格 来在左右栏之间切换，使用 UP/DOWN 光标键来在目录树中进行浏览。下面是 dive 的快捷键列表：Ctrl+空格 —— 在左右栏之间切换空格 —— 展开或收起目录树Ctrl+A —— 文件树视图：展示或隐藏增加的文件Ctrl+R —— 文件树视图：展示或隐藏被移除的文件Ctrl+M —— 文件树视图：展示或隐藏被修改的文件Ctrl+U —— 文件树视图：展示或隐藏未修改的文件Ctrl+L —— 层视图：展示当前层的变化Ctrl+A —— 层视图：展示总的变化Ctrl+/ —— 筛选文件Ctrl+C —— 退出在上面的例子中，我使用了 sudo 权限，这是因为我的 Docker 镜像存储在 /var/lib/docker/ 目录中。假如你的镜像保存在你的家目录 （$HOME）或者在其他不属于 root 用户的目录，你就没有必要使用 sudo 命令。你还可以使用下面的单个命令来构建一个 Docker 镜像并立刻分析该镜像：$ dive build -t <some-tag>Dive 工具仍处于 beta 阶段，所以可能会存在 bug。假如你遇到了 bug，请在该项目的 GitHub 主页上进行报告。好了，这就是今天的全部内容。现在你知道如何使用 Dive 工具来探索和分析 Docker 容器镜像的内容以及利用它构建镜像。希望本文对你有所帮助。更多精彩内容即将呈现，请保持关注！干杯！via: https://www.ostechnix.com/how-to-analyze-and-explore-the-contents-of-docker-images/作者：SK 选题：lujun9972 译者：FSSlc 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出