容器的选择和安装
容器选择
选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。
- 设置 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
- 安装 Docker 相关的包:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
- 验证Docker安装成功:
docker ps -a
使用普通用户可能会遇到权限错误,执行下面命令,把当前用户加入docker
用户组
sudo gpasswd -a $USER docker
sudo newgrp docker
配置Docker
创建配置文件夹
每个人都有自己的配置习惯,根据我的经验,可以配置两个文件夹
- 存放compose文件的文件夹 (
/home/username/compose
) - 存放持久化数据的文件夹 (
/home/username/docker
)
使用个人用户登录服务器,在用户目录下创建如下两个文件夹(可自定义):
mkdir /home/username/compose
mkdir /home/username/docker
创建docker子网
在大部分情况下,容器均使用bridge的网络模式,所以创建一个统一的子网,用来管理内网地址是有必要的,统一配置子网的好处有:
- 方便容器间通信
- 方便进行反向代理
创建一个名为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.5CPU
和 300M
内存。
值得注意的是,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