<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          構(gòu)建一個(gè)世界上最小的 Redis 鏡像

          共 5456字,需瀏覽 11分鐘

           ·

          2021-10-13 20:21


          好吧,我承認(rèn)這么說可能違反了廣告法,但是……它確實(shí)挺小的。

          可以對(duì)比一組數(shù)據(jù):

          • 官方的 Redis 鏡像:105MB
          • 官方的基于 alpine 的 Redis 鏡像:32.3MB
          • 在 ubuntu 下面用默認(rèn)配置 Build 出來的 redis-server binary:13M
          • 一個(gè)什么都沒有的 alpine:latest docker 鏡像:5.6MB
          • 上圖中的 Redis 鏡像:1.69MB

          所以……可以說,確實(shí)挺小了。

          當(dāng)然生產(chǎn)環(huán)境肯定不差 100M 這點(diǎn)空間,還是帶上一些常用的工具在生產(chǎn)環(huán)境跑比較好。本文只是在玩 Nix 時(shí)候的自?shī)首詷?,沒有什么實(shí)際意義。

          這個(gè)鏡像是用 Nix build 的,實(shí)際上,就是玩了一下 Nix 網(wǎng)站上的 Cover Demo[1]。用到的手段有:

          1. 使用 Nix 來 build 這個(gè) image;
          2. 編譯的時(shí)候關(guān)閉了 systemd 的支持,Docker 里面不需要這種東西;
          3. 使用 musl 靜態(tài)鏈接編譯;
          4. 把除了 redis-server 之外的東西刪除掉;
          5. 編譯完成使用 strip -s 對(duì)最終的 binary 再次做刪減。

          具體的編譯方法

          首先在 Nix 創(chuàng)建一個(gè)文件,來編譯 Redis,這里實(shí)際上使用的 Nix 打包好的 Redis,我只是對(duì)其通過 preBuildpostInstall 做了一些操作,替換 musl 和 strip 之類的。

          [nix-shell:~]$?cat?redis-minimal.nix
          {?pkgs???import??{}
          }:
          pkgs.redis.overrideAttrs?(old:?{
          ??#?no?need?for?systemd?support?in?our?docker?image
          ??makeFlags?=?old.makeFlags?++?["USE_SYSTEMD=no"];
          ??#?build?static?binary?with?musl
          ??preBuild?=?''
          ????makeFlagsArray=(PREFIX="$out"
          ????????????????????CC="${pkgs.musl.dev}/bin/musl-gcc?-static"
          ????????????????????CFLAGS="-I${pkgs.musl.dev}/include"
          ????????????????????LDFLAGS="-L${pkgs.musl.dev}/lib")
          ??'';
          ??#?Let's?remove?some?binaries?which?we?don't?need
          ??postInstall?=?''
          ?????rm?-f?$out/bin/redis-{benchmark,check-*,cli,sentinel}
          ?????strip?-s?$out/bin/redis-server
          ??'';
          })

          然后再需要一個(gè)文件描述如何 build docker image:

          [nix-shell:~]$?cat?docker-redis-minimal.nix
          {?pkgs???import??{?system?=?"x86_64-linux";}
          }:???????????????????????????????????#?nixpkgs?package?set
          let
          ??redisMinimal?=?import?./redis-minimal.nix?{?inherit?pkgs;?};
          in
          pkgs.dockerTools.buildLayeredImage?{?#?helper?to?build?docker?image
          ??name?=?"nix-redis-minimal";????????#?give?docker?image?a?name
          ??tag?=?"latest";????????????????????#?provide?a?tag
          ??contents?=?[?redisMinimal?];???????#?use?redisMinimal?package
          }

          非常簡(jiǎn)單,以至于不需要解釋。

          然后運(yùn)行下面這個(gè)命令,build 就可以了。因?yàn)槲乙呀?jīng) build 好了,所以 Nix 不會(huì)再出現(xiàn) build 的日志。

          [nix-shell:~]$?nix-build?docker-redis-minimal.nix?-o?./result
          /nix/store/42frnm57499800z3mpwf05ab37mam1r0-docker-image-nix-redis-minimal.tar.gz

          Docker (容器) 的原理[2] 曾經(jīng)解釋過,Docker image 本質(zhì)上就是一個(gè) tar 包。我們使用 docker load -i ./result 可以 load 這個(gè) image。然后就可以運(yùn)行了:

          [nix-shell:~]$?docker?load?-i?result
          Loaded?image:?nix-redis-minimal:latest

          [nix-shell:~/export-docker-image]$?docker?images
          REPOSITORY????????????????TAG?????????????????IMAGE?ID????????????CREATED?????????????SIZE
          nix-redis-minimal?????????latest??????????????433cad4ad790????????51?years?ago????????1.69MB

          [nix-shell:~]$?docker?run?nix-redis-minimal:latest?redis-server
          1:C?19?Jul?2021?16:37:09.847?#?oO0OoO0OoO0Oo?Redis?is?starting?oO0OoO0OoO0Oo
          1:C?19?Jul?2021?16:37:09.847?#?Redis?version=5.0.7,?bits=64,?commit=00000000,?modified=0,?pid=1,?just?started
          1:C?19?Jul?2021?16:37:09.847?#?Warning:?no?config?file?specified,?using?the?default?config.?In?order?to?specify?a?config?file?use?redis-server?/path/to/redis.conf
          1:M?19?Jul?2021?16:37:09.848?*?Running?mode=standalone,?port=6379.
          1:M?19?Jul?2021?16:37:09.848?#?Server?initialized
          1:M?19?Jul?2021?16:37:09.848?#?WARNING?overcommit_memory?is?set?to?0!?Background?save?may?fail?under?low?memory?condition.?To?fix?this?issue?add?'vm.overcommit_memory?=?1'?to?/etc/sysctl.conf?and?then?reboot?or?run?the?command?'sysctl?vm.overcommit_memory=1'?for?this?to?take?effect.
          1:M?19?Jul?2021?16:37:09.848?#?WARNING?you?have?Transparent?Huge?Pages?(THP)?support?enabled?in?your?kernel.?This?will?create?latency?and?memory?usage?issues?with?Redis.?To?fix?this?issue?run?the?command?'echo?never?>?/sys/kernel/mm/transparent_hugepage/enabled'?as?root,?and?add?it?to?your?/etc/rc.local?in?order?to?retain?the?setting?after?a?reboot.?Redis?must?be?restarted?after?THP?is?disabled.

          可能你發(fā)現(xiàn)了這個(gè) image 有一些奇怪:Created 51 years ago. 其實(shí)這是對(duì)的。因?yàn)?Nix 號(hào)稱是完全 reproducible 的,但是 image 如果有一個(gè)創(chuàng)建時(shí)間的話,那么每次 build 出來的產(chǎn)物都會(huì)因?yàn)檫@個(gè)創(chuàng)建時(shí)間,而導(dǎo)致每次的產(chǎn)物 hash 都不一樣。所以 Nix 將 Docker image 產(chǎn)物的 Created 時(shí)間設(shè)置成 0 了。即 timestamp = 0.

          看看這個(gè)鏡像里面都有什么?

          讀者可以在 Docker hub[3] 上下載這個(gè)鏡像,然后使用 docker save 將它保存成 tar 再解壓,看看里面都有什么。我這里直接去解壓 Nix build 好的 image,每一層 layer 下面的 layer.tar 也都解壓到對(duì)應(yīng)的 layer 下面了。

          可以看到,里面一層只有一個(gè) redis-server 的 binary,上面一層是一個(gè) bianry 的符號(hào)鏈接。符號(hào)鏈接是 Nix 的邏輯,符號(hào)鏈接很小,就懶得去刪除了。

          [nix-shell:~/export-docker-image]$?tree
          .
          ├──?42frnm57499800z3mpwf05ab37mam1r0-docker-image-nix-redis-minimal.tar.gz
          ├──?433cad4ad790679879357e81194fa7502f7688edfe5b7ff64a4f59edfed3f84d.json
          ├──?83d967dde8785f9b8efc694109992e72f3a9ab6a1b953519e4b892633fd01b1d
          │???├──?bin
          │???│???└──?redis-server?->?/nix/store/h25xxpbif767cwhiqxk9z3gp1rbbx6fr-redis-5.0.7/bin/redis-server
          │???├──?json
          │???├──?layer.tar
          │???└──?VERSION
          ├──?8f7098124197b3823e91dd99eb3cd89853d3ec03448689f2a3f283b261551734
          │???├──?json
          │???├──?layer.tar
          │???├──?nix
          │???│???└──?store
          │???│???????└──?h25xxpbif767cwhiqxk9z3gp1rbbx6fr-redis-5.0.7
          │???│???????????└──?bin
          │???│???????????????└──?redis-server
          │???└──?VERSION
          ├──?manifest.json
          └──?repositories

          7?directories,?12?files

          體驗(yàn)這個(gè)鏡像

          我把這個(gè)鏡像放到了 Docker hub[4] 上??梢灾苯舆\(yùn)行 docker run laixintao/redis-minimal:v1 redis-server 來體驗(yàn)一下。

          Docker 在 NixOS 里面的安裝可以參考這里[5]。

          引用鏈接

          [1]

          Cover Demo: https://nixos.org/#asciinema-demo-cover

          [2]

          Docker (容器) 的原理: https://www.kawabangga.com/posts/4224

          [3]

          Docker hub: https://hub.docker.com/repository/docker/laixintao/redis-minimal

          [4]

          Docker hub: https://hub.docker.com/repository/docker/laixintao/redis-minimal

          [5]

          這里: https://nixos.wiki/wiki/Docker


          原文鏈接:https://www.kawabangga.com/posts/4411


          你可能還喜歡

          點(diǎn)擊下方圖片即可閱讀

          給工程師:關(guān)于證書(certificate)和公鑰基礎(chǔ)設(shè)施(PKI)的一切

          云原生是一種信仰???

          關(guān)注公眾號(hào)

          后臺(tái)回復(fù)?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!



          點(diǎn)擊?"閱讀原文"?獲取更好的閱讀體驗(yàn)!


          發(fā)現(xiàn)朋友圈變“安靜”了嗎?

          瀏覽 75
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品无码秘 人妻一区二区媚黑 | 在线观看内射视频 | 日韩黄色短片 | 色婷婷无码视频 | 国产精品人妻无码久久久郑州天气网 |