跳到主要内容

容器的选择和安装

容器选择

选Podman 还是 Docker?

在现代软件开发和部署中,容器技术已经成为不可或缺的工具。它提供了一种轻量级、可移植的方式来运行应用程序,确保环境的一致性和提高资源利用率。在众多的容器技术中,Docker曾经是绝对的领导者,但近年来,Podman逐渐崭露头角,成为了开发者们关注的焦点。那么,在选择容器技术时,我们应该如何在Podman和Docker之间做出选择呢?

Docker:容器化的开创者

Docker自2013年发布以来,迅速成为了容器化领域的标准。它提供了一套完整的工具链来创建、管理和分发容器镜像。Docker的成功在于其简单易用的CLI命令、广泛的社区支持和丰富的生态系统。

Docker的优点:

成熟的生态系统:Docker拥有广泛的社区支持和丰富的第三方工具,可以与Kubernetes等编排工具无缝集成。 丰富的镜像库:Docker Hub提供了大量的官方和社区维护的镜像,方便用户快速启动应用。 广泛的行业应用:许多企业已经将Docker作为其容器化解决方案的标准。

Docker的缺点:

守护进程依赖:Docker需要一个后台守护进程来管理容器,这可能会引发安全性和资源管理方面的问题。 root权限问题:Docker通常需要root权限来运行,这在某些安全敏感的环境中是一个问题。

Podman:无守护进程的选择

Podman是一个开源的容器管理工具,旨在提供与Docker类似的用户体验,但不需要后台守护进程。Podman的设计理念是增强安全性和灵活性,特别是在需要无root权限运行容器的场景中。

Podman的优点:

无守护进程:Podman不需要后台守护进程,这意味着它可以在更严格的安全环境中运行。 rootless容器:Podman支持无root权限运行容器,增强了安全性和用户隔离。 与Docker兼容:Podman提供了与Docker CLI兼容的命令,使得从Docker迁移到Podman变得更加容易。

Podman的缺点:

生态系统较小:虽然Podman正在快速发展,但其生态系统和社区支持仍不如Docker成熟。 学习曲线:对于习惯了Docker的用户来说,Podman的某些特性可能需要一些时间来适应。

最终选择

Docker拥有成熟的生态系统和广泛的社区支持,在个人的单站点用例中,Docker可能是更好的选择。

容器安装

以Debian12为例,参考Docker官方文档来进行安装Docker。

  1. 设置 Docker's apt 仓库:
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
  1. 安装 Docker 相关的包:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
  1. 验证Docker安装成功:
docker ps -a

使用普通用户可能会遇到权限错误,执行下面命令,把当前用户加入docker用户组

sudo gpasswd -a $USER docker
sudo newgrp docker

配置Docker

创建配置文件夹

每个人都有自己的配置习惯,根据我的经验,可以配置两个文件夹

  1. 存放compose文件的文件夹 (/home/username/compose)
  2. 存放持久化数据的文件夹 (/home/username/docker)

使用个人用户登录服务器,在用户目录下创建如下两个文件夹(可自定义):

mkdir /home/username/compose
mkdir /home/username/docker

创建docker子网

在大部分情况下,容器均使用bridge的网络模式,所以创建一个统一的子网,用来管理内网地址是有必要的,统一配置子网的好处有:

  1. 方便容器间通信
  2. 方便进行反向代理

创建一个名为npm_default,网段为172.20.0.0/24的子网(名字和网段均可以自定义):

docker network create --subnet=172.20.0.0/24 npm_default

这样会有172.20.0.2 - 172.20.0.254 共计253个内网ip可以自定义使用,个人项目完全足够了。

如果配置了UFW防火墙,请将172.20.0.0/24 加入 UFW 白名单:

sudo ufw allow from 172.20.0.0/24

示例

后续所有docker compose文件都 统一命名为 compose.yml,敏感的环境变量统一放在.env文件中。

例如创建一个hello-world的容器的步骤如下:

1. 在compose文件夹中创建对应的文件夹

mkdir ~/compose/hello-world

2. 创建 compose.yml 文件 和 .env 文件

cd ~/compose/hello-world
touch compose.yml
touch .env

3. 编辑和配置上述两个文件:

这里指定了容器的网络为brige模式,固定配置内网ip为172.20.0.2,挂载了两个文件夹到容器内部,限制了资源使用 0.5CPU300M内存。

值得注意的是,ports端口映射部分被注释掉了,这是故意而为的。目的是不再占用宿主机的端口,在对其进行反向代理时,只需要代理127.20.0.2:80端口即可。

compose.yml:

networks:
default:
external: true
name: ${DOCKER_MY_NETWORK}
services:
hello-world:
container_name: hello-world
image: hello-world:latest
# ports:
# - "80:80"
environment:
TZ: ${TZ}
OTHER_ENV: ${OTHER_ENV}
# Volumes store your data between container upgrades
volumes:
- ${DOCKER_HOME}/hello-world/data:/data
- ${DOCKER_HOME}/hello-world/conf:/conf
restart: unless-stopped
networks:
default:
ipv4_address: 172.20.0.2
deploy:
resources:
limits:
cpus: "0.5"
memory: 300M

其中的.env文件内容中的变量和compose.yml中使用的变量需要一一对应

.env:

DOCKER_HOME=/home/username/docker
TZ=Asia/Shanghai
DOCKER_MY_NETWORK=npm_default

4. 启动容器

配置完成后,只需要在~/compose/hello-world下运行

docker compose up -d