由于 Docker 在架构上的依赖比较多,存在单点故障,且依赖于特权账号运行,需要启动有 docker 服务,才能运行 docker cli。 出现了很多替代 docker,不依赖于特权账号,普通用户可以跑,也不依赖于后台服务的工具,比如 podman, img 等。
我的Mac 上面的 Docker Desktop 越来越吃 CPU,跑起来机器非常卡顿, 看了几种不同的方案,podman 跟 docker 的兼容性非常好,可以很容易迁移到 podman上,决定从 docker 迁移到 podman。
参考:
Transitioning from Docker to Podman | Red Hat Developer
开始使用
Mac 上面安装 podman, 并启动 podman machine,命令如下。 由于 podman 需要在 linux 上运行,需要启动一个 linux virtual machine,virtual machine 用 qemu 来运行。
brew install qemu
brew install podman
podman machine init --disk-size 80 --memory=4096
podman machine start
alias docker=podman
然后就可以愉快地使用 podman 命令, 或者 docker 命令来操作了。
注意: 这里初始化 podman 机器的时候, 设定了磁盘大小是 80G,内存是 4G。如果小了,后面再跑很麻烦,需要重新初始化。因此初始化的时候就设置好。根据自己机器的情况来设置,我的机器内存是 16G,从中分 4G 到 podman。
本文到此结束。 后面演示一下基于 Alpine 构建一个 nginx http server 基础镜像的手工过程(自动的过程使用 Dockerfile),手工的过程可以体验一下 docker commit 的使用。
基于 Alpine 构建一个 nginx HTTP 镜像
参考前面链接的文档,我们把 apache httpd 替换成 nginx web 服务,来构建一个静态web 服务器的镜像,并且使用镜像启动容器。 如下的内容既适用于 podman, 也适用于 docker。 前面我们做了 alias docker=podman
1). 首先拉取到 alpine 的镜像:
docker pull alpine:3.15.1
2). 接下来启动一个容器, 交互式的方式(-it)进入到容器中:
podman run -it --name nginx alpine:latest /bin/sh
3). 在容器中安装 curl, nginx, 配置 nginx 的 web root
上面命令进入到启动的 alpine 容器中之后,然后在容器中安装 curl, nginx, 创建存放静态 web 页面的目录 /data/nginx/html。
apk add curl
apk add nginx
mkdir -p /data/nginx/html/
mkdir -p /etc/nginx/conf.d/
我们把 虚拟主机的 nginx conf 配置放在 /etc/nginx/conf.d/ 目录,还是在容器中运行命令, 编辑 /etc/nginx/nginx.conf 文件:
vi /etc/ninx/nginx.conf
在 http 节点的末尾加上配置:
include /etc/nginx/conf.d/*.conf;
然后,在容器中编辑 /etc/nginx/conf.d/nginx.host.default.conf 文件, 设置 /data/nginx/html 为默认的 web 根路径。
$ vim /etc/nginx/conf.d/nginx.host.default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location / {
root /data/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /data/nginx/html;
}
}
以上配置使得 nginx 在启动的时候, 会监听本机的 localhost:80 端口,为 /data/nginx/html 目录提供静态页面的 http 访问服务。
接下来 Web 站创建一个首页文件:
echo "hello nginx" > /data/nginx/index.html
启动 nginx, 测试 web 页:
nginx
curl http://localhost
能看到输出 hello world。 在如上命令运行完之后,运行 exit 或者 Ctrl + D 退出正在运行的容器。
4). 退出容器,提交镜像
## 提交手工构建的镜像
docker commit nginx nginx:v1
## 列出镜像
docker images
能看到下面的内容
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/nginx v1 2b33eaf5cf67 6 seconds ago 12 MB
docker.io/library/alpine 3.15.1 e9adb5357e84 23 hours ago 5.86 MB
5).使用构建的镜像启动新容器,端口映射到本机
使用如下命令, 基于镜像 nginx:v1 启动容器, 把容器中的 80 端口映射到本机的 8080。
后面的 sh -c "nginx && tail -f /dev/null" 表示在容器中带参数执行 sh 这个命令。sh 里面启动 nginx 然后执行一个永远不退出的 tail -f。
podman run -p 8080:80 -dt nginx:v1 sh -c "nginx && tail -f /dev/null"
然后访问 http://localhost:8080 就能看到页面的内容 hello world 了。
使用 Dockerfile 自动构建 nginx 服务基础镜像,可以参考这里: