分类 Docker 相关 下的文章

如何做一个最小的docker image?

当我们想做一个docker image 的时候, 经常想把它做的足够小, 不仅能够节省磁盘空间, 还能减少不必要的依赖, 加快启动, 减少可能出现的漏洞. 那么有哪些最精简的base image 呢?


  1. 如果你的app的所有依赖都是静态编译的, 那么你可以使用 scratch, 顾名思义, 它是一张白纸, 我们只能使用kernel 提供的服务. 它没有shell, 没有libc, 没有各种实用命令, 用户/组, 没有包管理器, 啥都没有.
  2. 如果你 busybox 提供的实用工具已经能满足, 那么你可以使用 busybox. busybox 是嵌入式linux上的瑞士军刀, 它把其它Linux 上常见的一些实用工具在一个很小的可执行文件内全部实现, 虽然选项更少, 但是基本能完成大部分常见功能.
  3. 如果你在 busybox的基础上还需要 libc库和包管理工具(package repo), 那么可以使用 alpine. alpine 在busybox的基础上, 增加了 musl libc 和 包管理器.
  4. 或者你可以尝试一下 https://github.com/GoogleContainerTools/distroless.

exec user process caused: exec format error

今天开发的app 做了一个新的docker image, 发布到K8S之后, 就报下面的错:

standard_init_linux.go:228: exec user process caused: exec format error

还以为自己写的代码配置出错了, 想登上去看看, 发现进程压根就没起来.

Google 一把, 有人说是entrypoint的shell 文件的 shebang 不对, 我这里没有这个问题.

后来看到有人说是可执行格式的错误, 发现还真是.
首先, 我在本地Mac Pro (ARM) 上去执行这个image, 很正常的执行起来了, 然后我在另外一个Ubuntu 上面执行这个image, 就给我报下面的错误了:

WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64) and no specific platform was requested

所以, 很明显, 这个image 是给 ARM64/v8 用的. 用 docker image inspect <img>去查看, 能看到这个image 是给什么平台机构的.
arch.png

我的 docker build 环境是 MAC ARM 机器, 之前一直没有错, 今天为啥出错了, 原因很有可能是我今天重启了 Docker Desktop.

去看 docker 官方文档: https://docs.docker.com/engine/reference/commandline/build/ 发现他们最近(20220914) 对于 docker build 新加了一个参数 (--platform)
platform.png

到它 change 去看, 发现最新的 v141
https://docs.docker.com/engine/api/version-history/#v140-api-changes

所以, 要在 Mac Pro ARM 芯片上做 x86_64/amd64 的image, 要给一个新参数 --platform linux/amd64

最简单的基于 nginx 的下载服务器

有时候, 有些地方不能从互联网下载东西, 但是可以上传一些内部的 docker image, 比如 生产环境, 一般是连不上外网的, 及时使用代理, 很有可能也不允许下载很大的东西. 这个时候, 可以做个 docker image 上传上去, 然后供生产环境使用. 下面是一个基于 nginx 的最简单 web 服务器.

需要2个文件, 里面的 mat.zip 和 那个 jdk 的 exe 是我需要下载的东西.
Dockerfile (去除下面的所有注释)

FROM alpine
RUN apk update
RUN apk --no-cache add nginx   #安装 nginx
ADD nginx.conf /etc/nginx/nginx.conf  #复制本地的配置文件
RUN mkdir -p /run/nginx  #建立 nginx pid 文件需要的文件夹
ADD mat.zip /usr/share/nginx/www/  #复制本地需要复制的文件1 例子
ADD jdk-8u171-windows-x64.exe /usr/share/nginx/www/  #复制本地需要复制的文件2 例子
RUN chmod 755 /usr/share/nginx/www/*  #更改文件读权限
EXPOSE 80  #暴露80端口
CMD ["nginx", "-g", "daemon off;"]  #启动 nginx

nginx.conf

events {
  worker_connections 1024;
}

http {
  include /etc/nginx/mime.types;
  index index.html;
  default_type application/octet-stream;
  sendfile     on;

  server {
    location / {
      root /usr/share/nginx/www;
      index not_a_file;
      autoindex on;
      types {}
    }
  }
}

打包: docker build -t repo.tianxiaohui.com/xiatian/test:0.1 .
上传: docker push repo.tianxiaohui.com/xiatian/test:0.1
下载: docker pull repo.tianxiaohui.com/xiatian/test:0.1
运行: docker run -p 9191:80 repo.tianxiaohui.com/xiatian/test:0.1
使用: http://container.tianxiaophui.com:9191/

docker cgroup - [docker cookbook] 读书笔记 2

Control Groups (cgroups) provide resource limitations and accounting for containers. From the Linux Kernel documentation:

Control Groups provide a mechanism for aggregating/partitioning sets
of tasks, and all their future children, into hierarchical groups with
specialized behaviour.

In simple terms, they can be compared to the ulimit shell command or the setrlimit system call. Instead of setting the resource limit to a single process, cgroups allow the limiting of resources to a group of processes.

Control groups are split into different subsystems, such as CPU, CPU sets, memory block I/O, and so on. Each subsystem can be used independently or can be grouped with others. The features that cgroups provide are:

  1. Resource limiting: For example, one cgroup can be bound to specific
    CPUs, so all processes in that group would run off given CPUs only
  2. Prioritization: Some groups may get a larger share of CPUs
  3. Accounting: You can measure the resource usage of different
    subsystems for billing
  4. Control: Freezing and restarting groups

Some of the subsystems that can be managed by cgroups are as follows:

  • blkio: It sets I/O access to and from block devices such as disk,
    SSD, and so on
  • Cpu: It limits access to CPU
  • Cpuacct: It generates CPU resource utilization
  • Cpuset: It assigns the CPUs on a multicore system to tasks in a
    cgroup
  • Devices: It devises access to a set of tasks in a cgroup
  • Freezer: It suspends or resumes tasks in a cgroup
  • Memory: It sets limits on memory use by tasks in a cgroup

There are multiple ways to control work with cgroups. Two of the most popular ones are accessing the cgroup virtual filesystem manually and accessing it with the libcgroup library.