文章目录
- Docker 和 Podman的区别
- 安装
- 架构和特权要求
- 运行容器方面
- 安全性(root的权限)
- 镜像管理方面
- 命令方面
- Docker常用命令
- Podman常用命令
Docker 和 Podman的区别
安装
架构和特权要求
Docker使用client-server架构,其中Docker daemon(服务端)在后台以root权限运行,并通过Docker客户端与之交互。这意味着使用Docker需要root权限或者给用户添加到docker用户组中
[root@docker ~]# ps -ef |grep docker
root 5131 1 0 16:30 ? 00:00:00 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock # Docker deamon
root 5768 3870 0 18:27 pts/0 00:00:00 grep --color=auto docker
[csq@docker ~]$ sudo docker version
Client: Docker Engine - Community # 要使用这个Client需要root权限或者给用户添加到docker用户组里
Version: 26.0.1
API version: 1.45
Go version: go1.21.9
Git commit: d260a54
Built: Thu Apr 11 10:54:59 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community # 这个就是docker deamon,就是后台启用的进程
Engine:
Version: 26.0.1
API version: 1.45 (minimum version 1.24)
Go version: go1.21.9
Git commit: 60b9add
Built: Thu Apr 11 10:53:19 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.31
GitCommit: e377cd56a71523140ca6ae87e30244719194a521
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Podman是一个无守护进程的容器运行时,可以在非特权用户下运行,无需特殊权限
[csq@podman ~]$ ps -ef |grep podman # podman无守护进程(daemon)
csq 5445 5411 0 18:53 pts/0 00:00:00 grep --color=auto podman
[csq@podman ~]$ podman version
Client: Podman Engine
Version: 4.9.4-dev
API Version: 4.9.4-dev
Go Version: go1.21.7 (Red Hat 1.21.7-1.el9)
Built: Wed Mar 20 18:22:46 2024
OS/Arch: linux/amd64
运行容器方面
docker
[csq@docker ~]$ sudo docker run -it busybox # 普通用户要加上sudo才行
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
7b2699543f22: Pull complete
Digest: sha256:c3839dd800b9eb7603340509769c43e146a74c63dca3045a8e7dc8ee07e53966
Status: Downloaded newer image for busybox:latest
/ # ls
bin dev etc home lib lib64 proc root sys tmp usr var
/ #
podman
[csq@podman ~]$ podman run -it busybox # 普通用户可以直接执行
Resolved "busybox" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/busybox:latest...
Getting image source signatures
Copying blob 7b2699543f22 done |
Copying config ba5dc23f65 done |
Writing manifest to image destination
/ # ls
bin dev etc home lib lib64 proc root run sys tmp usr var
/ #
安全性(root的权限)
Docker在默认配置下需要root权限或者特权用户访问,这会增加潜在的安全风险。但可以通过配置用户命名空间和其他安全措施来提高安全性
[demo@docker ~]$ groups # demo用户在docker组里
demo docker
[demo@docker ~]$ sudo more /etc/sudoers # 不具有sudo的权限
[sudo] demo 的密码:
demo 不在 sudoers 文件中。此事将被报告。
[demo@docker ~]$ docker version # 可以执行docker命令
Client: Docker Engine - Community
Version: 26.0.1
API version: 1.45
Go version: go1.21.9
Git commit: d260a54
Built: Thu Apr 11 10:54:59 2024
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 26.0.1
API version: 1.45 (minimum version 1.24)
Go version: go1.21.9
Git commit: 60b9add
Built: Thu Apr 11 10:53:19 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.31
GitCommit: e377cd56a71523140ca6ae87e30244719194a521
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
# 将sudoers文件挂载出来,并把自己添加到sudoers当中
[demo@docker ~]$ docker run -it -v /etc/sudoers:/root/sudoers busybox sh
/ # cd /root/
~ # ls
sudoers
~ # more sudoers
Defaults !visiblepw
Defaults always_set_home
Defaults match_group_by_gid
Defaults always_query_group_plugin
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
csq ALL=(ALL) ALL
~ # vi sudoers # 将自己添加进去
demo ALL=(ALL) ALL
~ # exit
[demo@docker ~]$ sudo more /etc/sudoers # 之前不可以查看sudoer,现在就可以查看了
[sudo] demo 的密码:
Defaults !visiblepw
Defaults always_set_home
Defaults match_group_by_gid
Defaults always_query_group_plugin
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
csq ALL=(ALL) ALL
demo ALL=(ALL) ALL
配置用户命名空间
Docker提供了一种称为用户命名空间的安全功能,它使得一个容器中的进程可以运行在一个虚拟的UID/GID空间中,从而将容器中的特权进程与主机系统分离出来,提高容器的安全性
# 第一步:在Docker daemon配置文件(/etc/docker/daemon.json)中加入用户命名空间的配置
{
"userns-remap": "default"
}
# 这将配置Docker运行用户命名空间,并将容器内的UID/GID映射到主机上的一个非特权用户(default)
# 第二步:配置/etc/subuid和/etc/subgid文件,这些文件定义了用户到UID/GID的映射关系
csq:100000:65536
demo:165536:65536
# 这条配置定义了dockremap用户的UID从100000开始,分配65536个UID
# 同样的,还要为该用户分配一个GID范围
# 第三步:重启Docker daemon,使得配置生效
systemctl restart docker.service
# 此时,Docker容器应用就运行在一个特定用户空间了。
# 第四步:验证用户命名空间
[demo@docker ~]$ docker run -it -v /etc/sudoers:/root/sudoers busybox sh
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
7b2699543f22: Pull complete
Digest: sha256:c3839dd800b9eb7603340509769c43e146a74c63dca3045a8e7dc8ee07e53966
Status: Downloaded newer image for busybox:latest
/ # more /root/sudoers
more: /root/sudoers: Permission denied # 看不到了
/ #
# 如果还是希望root用户来启动容器呢,可以使用--userns=host来解决
[demo@docker ~]$ docker run -it --userns=host -v /etc/sudoers:/root/sudoers busybox sh
/ # more /root/sudoers
Defaults !visiblepw
Defaults always_set_home
Defaults match_group_by_gid
Defaults always_query_group_plugin
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
root ALL=(ALL) ALL
%wheel ALL=(ALL) ALL
csq ALL=(ALL) ALL
# 此时,容器root用户映射到宿主root用户,容器普通用户映射到宿主普通用户
# 等同于不使用User Namespace的默认情况
Podman可以在非特权用户下运行,并使用用户命名空间、Linux安全模块(如SELinux)等技术来提供更强的容器安全性
[csq@podman ~]$ podman run -it -v /etc/sudoers:/root/sudoers busybox sh
/ # cd /root/
~ # ls
sudoers
~ # more sudoers # 无法进行修改
more: sudoers: Permission denied
镜像管理方面
Docker可以通过Docker Hub等公共或私有镜像仓库来获取和分享镜像
[csq@docker ~]$ sudo docker pull nginx
[sudo] csq 的密码:
Using default tag: latest
latest: Pulling from library/nginx
13808c22b207: Pull complete
6fcdffcd79f0: Pull complete
fbf231d461b3: Pull complete
c9590dd9c988: Pull complete
b4033143d859: Pull complete
abaefc5fcbde: Pull complete
bcef83155b8b: Pull complete
Digest: sha256:9ff236ed47fe39cf1f0acf349d0e5137f8b8a6fd0b46e5117a401010e56222e1
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest # 通过Docker Hub获取镜像
与Docker兼容的Podman可以直接使用Docker镜像,但它还支持OCI(Open Container Initiative)标准的镜像
[csq@podman ~]$ podman pull nginx
? Please select an image:
▸ registry.access.redhat.com/nginx:latest # 通过上下左右来确定通过哪个registry拉取image
registry.redhat.io/nginx:latest
docker.io/library/nginx:latest
✔ docker.io/library/nginx:latest # 选择Docker Hub仓库来获取镜像
Trying to pull docker.io/library/nginx:latest...
Getting image source signatures
Copying blob abaefc5fcbde done |
Copying blob 13808c22b207 done |
Copying blob fbf231d461b3 done |
Copying blob 6fcdffcd79f0 done |
Copying blob c9590dd9c988 done |
Copying blob b4033143d859 done |
Copying blob bcef83155b8b done |
Copying config c613f16b66 done |
Writing manifest to image destination
c613f16b664244b150d1c3644cbc387ec1fe8376377f9419992280eb4a82ff3b
命令方面
命令方面的话docker和podman两个命令提供的功能大差不差
如果习惯docker,还想使用podman可以使用【alias docker=podman】命令别名
[csq@podman ~]$ alias docker=podman
Docker常用命令
管理容器(Containers):
docker create
:创建一个新的容器但不启动它。docker run
:创建并启动一个新的容器。docker start
:启动一个或多个已经创建的容器。docker stop
:停止一个或多个正在运行的容器。docker restart
:重启一个或多个容器。docker pause
:暂停一个容器的所有进程。docker unpause
:取消暂停一个容器的所有进程。docker kill
:杀死一个或多个正在运行的容器。docker rm
:删除一个或多个容器。
管理镜像(Images):
docker images
:列出本地主机上的镜像。docker pull
:从远程仓库下载一个镜像。docker build
:从Dockerfile构建一个镜像。docker push
:将一个本地镜像上传到仓库。docker rmi
:删除一个或多个本地镜像。
管理容器资源:
docker exec
:在运行中的容器中执行命令。docker cp
:在容器与本地文件系统之间复制文件。docker logs
:查看容器的日志输出。docker stats
:显示容器资源的实时统计信息。
管理容器网络(Networking):
docker network ls
:列出所有网络。docker network create
:创建一个网络。docker network connect
:将容器连接到一个网络。docker network disconnect
:将容器从一个网络断开。
其他常用命令:
docker version
:显示Docker客户端和服务器的版本信息。docker info
:显示Docker系统信息,包括容器、镜像和存储的详细信息。docker inspect
:检查容器或镜像的详细配置信息。
Podman常用命令
-
attach
: 连接到正在运行的容器以查看其输出和日志。 -
build
: 使用 Containerfiles 中的指令构建一个镜像。 -
commit
: 基于已更改的容器创建新的镜像。 -
compose
: 通过外部提供者(如 docker-compose 或 podman-compose)运行 compose 工作负载。 -
diff
: 显示对象文件系统的更改。 -
events
: 显示 Podman 系统事件。 -
generate
: 基于容器、Pods 或卷生成结构化数据。 -
healthcheck
: 管理容器的健康检查。 -
history
: 显示指定镜像的历史记录。 -
init
: 创建一个或多个容器,但不启动它们。 -
kube
: 从结构化文件中运行容器、Pods 或卷。 -
machine
: 管理虚拟机。 -
manifest
: 操作清单列表和镜像索引。 -
mount
: 挂载工作容器的根文件系统。 -
network
: 管理网络。 -
port
: 列出容器的端口映射或特定映射。 -
push
: 将镜像推送到指定的目标。 -
rename
: 重命名一个现有容器。 -
rmi
: 从本地存储中删除一个或多个镜像。 -
save
: 将镜像保存到存档文件中。 -
search
: 在镜像仓库中搜索镜像。 -
secret
: 管理密钥。 -
tag
: 为本地镜像添加额外的名称。 -
unshare
: 在修改过的用户命名空间中运行命令。 -
version
: 显示 Podman 的版本信息。 -
volume
: 管理卷。