Pros and cons of Alpine as a base image

Alpine

AlpineThe operating system is a security-oriented light Linuxdistribution . It is different from the usual Linuxdistribution . It Alpineadopts musl libcand busyboxto reduce the size of the system and the consumption of runtime resources, but its functions are much busyboxmore complete, so it is more and more favored by the open source community. While keeping the weight down, Alpineit also provides its own package management tool apk. You can query package information through the https://pkgs.alpinelinux.org/packageswebsite , or you can apkdirectly query and install various software through commands.

spaces_-M5xTVjmK7ax94c8ZQcm_uploads_git-blob-acfe2b19a46d65232e6180e44e2ee7b64e26b52a_alpinelinux-logo.png

1. Advantages and disadvantages

 1.1. Advantages

  • Mirror size is small

    AlpineThe goal is to reduce the construction cost of the basic image, so that the built image occupies less space, so the bottom layer must be a dynamic link relationship. But it is special. It does not use a heavy dynamic library such as GLIBC , but uses busybox + musl libc . Compared with glibc, the musl libc library is smaller, simpler and safer, which greatly reduces the space and maintains the same corresponding function.

  • Package management tools are fast

    Containers change frequently in the cycle. New images may be built regularly, and some debugging tools may be temporarily installed in the running container. If the installation speed of the software package is very slow, it will quickly wear out our patience, and The package management tool of the Alpine image is very fast, and the software installation experience is very smooth.

 1.2. Disadvantages

  • Niche disadvantage

    Unlike common operating systems like CentOS and UbuntuAlpine , it is not maintained by a big company like Red Hat or Canonical, but is maintained by a non-commercial organization, so the number of packages is less than these distributions A lot (if you just look at the default out-of-the-box repositories, Alpine has only 10,000 packages, while Ubuntu, Debian, and Fedora all have more than 50,000).

    If you need to use a binary file linked by musl libc in the project, but the tool Alpine itself does not provide one, you need to compile and package it yourself. This process itself is a very complicated thing, and you must understand how to compile it with make . In the large stage state, it is necessary to debug when an error occurs, which is a waste of time.

  • Underlying Dependency Defects

    The bottom layer uses musl libc as a dependent library. Its small size is an advantage, but it is also a disadvantage. It cannot have a complete underlying dynamic library like glibc. In the multi-layer construction process, it may occur that the relevant dependencies cannot be found. , this problem is also a buried point that causes Alpine to generate a large number of pits as the underlying image.

    musl libc is commonly used in embedded systems, because the resources of such systems themselves are very scarce, and it is not suitable to use a large underlying library, so such small library dependencies must be used.

2. Common problems

  1. Building a Python docker container with Alpine is 50 times slower

    pythonspeed.com/articles/al…

    这是一篇博文中给出的数据验证,上面地址是他的具体情况链接, 这种情况是很好理解的,因为 Python 是一种解释型的语言,它内部的很多依赖都已经打包好了,用 PIP 可以直接进行一个引入安装,但这些都绑定了特定的 C 库,这就意味着在大多数使用 glibc 的镜像中都可以正常安装,但 Alpine 镜像就不行。如果非要在 Alpine 中安装,你需要安装很多依赖,重头构建,耗时又费力。

  2. 构建多层容器镜像时发生错误

    github.com/elastic/ela…

    Docker 的容器概念本来就是一个分层的多层文件系统,从底层开始一层一层的添加所属层来增加对于业务层的支撑,但是在这个问题中在超过 4 层就发生了构建错误......

  3. DNS 转发失败

    musl libc does not use domain or search directives in the /etc/resolv.conf file. For example, if you started your Docker daemon with --dns-search=service.consul, and then tried to resolve consul from within an Alpine Linux container, it would fail as the name consul.service.consul would not be tried. You will need to work around this by using fully qualified names.

    Another difference is parallel querying of name servers. This can be problematic if your first name server has a different DNS view (such as service discovery through DNS). For example, if you started your Docker daemon with --dns=172.17.42.1 --dns=10.0.2.15 where 172.17.42.1 is a local DNS server to resolve name for service discovery and 10.0.2.15 is for external DNS resolving, you wouldn't be able to guarantee that 172.17.42.1 will always be queried first. There will be sporadic failures.

    In both of these cases, it can help to run a local caching DNS server such as dnsmasq, that can be used for both caching and search path routing. Running dnsmasq with --server /consul/10.0.0.1 would forward queries for the .consul to 10.0.0.1.

  4. 二进制编译不兼容

    While there are binaries that will run on musl libc without needing to be recompiled, you will likely encounter binaries and applications that rely on specific glibc functionality that will fail to start up. An example of this would be Oracle Java which relies on specific symbols only found in glibc. You can often use ldd to determine the exact symbol:

    # ldd bin/java
    /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
    libjli.so => bin/../lib/amd64/jli/libjli.so (0x7f542e9a0000)
    libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f542ebb5000)
    Error relocating bin/../lib/amd64/jli/libjli.so: __rawmemchr: symbol not found
    

    In this case, the upstream would need to remove the support for this offending symbol or have the ability to compile the software natively on musl libc. Be sure to check the Alpine Linux package index to see if a suitable replacement package already exists.

3、方案替换

 如果程序仅用到了标准库或者依赖项和程序本身使用的是同一种语言,且无需调用 C 库和外部依赖,那么使用 Alpine 作为基础镜像一般是没有啥问题的。

 一旦程序需要调用外部依赖,情况就复杂了,想继续使用 Alpine 镜像,就得安装这些依赖。

  1. 依赖库有针对 Alpine 的安装说明,一般会说明需要安装哪些软件包以及如何建立依赖关系。
  2. 依赖库没有针对 Alpine 的安装说明,我们可以通过对比找到与别的发行版的软件包相匹配的 Alpine 软件包。
  3. 依赖库没有针对 Alpine 的安装说明,也没有与之对应的软件,这种情况就必须从源码开始构建。

 我们大概可以得出一个结论,Alpine 通过降低底层依赖来减少自身的一个体积成为了后续最大的问题隐患,在场景比较复杂的情况下我们就需要切换基础镜像,使用功能更加全面、体积也相对较为轻便的镜像。

 通过 Docker hub 中的镜像比对,可以选择几款替代品,虽然在相对体积上还是比不上 Alpine ,但是容器上面体积小并不是最重要的一个指标,在一定条件下一个持续稳健的容器比一个精细的容器要更加的好。

下表是仓库中最新的 Alpine 和其他基础镜像的镜像大小比对(只比较了一个操作系统下的情况)

IMAGE DIGEST OS/ARCH COMPRESSED SIZE
alpine 4ff3ca912757 linux/amd64 2.67 MB
debian 3345381beaed linux/amd64 28.3 MB
ubuntu 386bace9fb0d592 linux/amd64 29.01 MB
fedora 486fd5578f93 linux/amd64 56.2 MB

 虽然 docker 极力想要把基础镜像从 ubuntu 迁移到 alpine ,但是考虑到用户的选择问题,还是做出了妥协,从docker 官方发布的镜像的发行版中可以看出一些的端倪,可以使用 debian 作为基础镜像的替换,彼此之间的体积差异也不是很大。

Guess you like

Origin juejin.im/post/7120557446682116132