关于java:Docker-大势已去Podman-即将崛起……

起源:https://blog.csdn.net/qq_4828…

Podman 简介

什么是Podman?

Podman 是一个开源的容器运行时我的项目,可在大多数 Linux 平台上应用。Podman 提供与 Docker 十分类似的性能。正如后面提到的那样,它不须要在你的零碎上运行任何守护过程,并且它也能够在没有 root 权限的状况下运行。

Podman 能够治理和运行任何合乎 OCI(Open Container Initiative)标准的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端来治理 Docker 镜像。

Podman 官网地址:https://podman.io/

Podman和Docker的次要区别是什么?
  • dockers在实现CRI的时候,它须要一个守护过程,其次须要以root运行,因而这也带来了安全隐患。
  • podman不须要守护程序,也不须要root用户运行,从逻辑架构上,比docker更加正当。
  • 在docker的运行体系中,须要多个daemon能力调用到OCI的实现RunC。
  • 在容器治理的链路中,Docker Engine的实现就是dockerd
  • daemon,它在linux中须要以root运行,dockerd调用containerd,containerd调用containerd-shim,而后能力调用runC。顾名思义shim起的作用也就是“垫片”,防止父过程退出影响容器的运训
  • podman间接调用OCI,runtime(runC),通过common作为容器过程的管理工具,但不须要dockerd这种以root身份运行的守护过程。
  • 在podman体系中,有个称之为common的守护过程,其运行门路通常是/usr/libexec/podman/conmon,它是各个容器过程的父过程,每个容器各有一个,common的父则通常是1号过程。podman中的common其实相当于docker体系中的containerd-shim。

图中所体现的事件是,podman不须要守护过程,而dorker须要守护过程。在这个图的示意中,dorcker的containerd-shim与podman的common被归在Container一层。

Podman的应用与docker有什么区别?

podman的定位也是与docker兼容,因而在应用下面尽量凑近docker。在应用方面,能够分成两个方面来说,一是零碎构建者的角度,二是使用者的角度。

在零碎构建者方面,用podman的默认软件,与docker的区别不大,只是在过程模型、过程关系方面有所区别。如果习惯了docker几个关联过程的调试办法,在podman中则须要适应。能够通过pstree命令查看过程的树状构造。总体来看,podman比docker要简略。因为podman比docker少了一层daemon,因而重启的机制也就不同了。

在使用者方面,podman与docker的命令根本兼容,都包含容器运行时(run/start/kill/ps/inspect),本地镜像(images/rmi/build)、镜像仓库(login/pull/push)等几个方面。因而podman的命令行工具与docker相似,比方构建镜像、启停容器等。甚至能够通过alias docker=podman能够进行替换。因而,即使应用了podman,依然能够应用docker.io作为镜像仓库,这也是兼容性最要害的局部。

Podman 常用命令

容器
podman run           创立并启动容器
podman start       #启动容器
podman ps          #查看容器
podman stop        #终止容器
podman restart     #重启容器
podman attach      #进入容器
podman exec        #进入容器
podman export      #导出容器
podman import      #导入容器快照
podman rm          #删除容器
podman logs        #查看日志
镜像
podman search             #检索镜像
docke pull                #获取镜像
podman images             #列出镜像
podman image Is           #列出镜像
podman rmi                #删除镜像
podman image rm           #删除镜像
podman save               #导出镜像
podman load               #导入镜像
podmanfile                #定制镜像(三个)
 podman build              #构建镜像
    podman run              #运行镜像
    podmanfile              #罕用指令(四个)
     COPY                    #复制文件
        ADD                     #高级复制
        CMD                     #容器启动命令
        ENV                     #环境变量
        EXPOSE                  #裸露端口

部署 Podman

//装置podman
[root@localhost ~]# yum -y install podman

//仓库配置
[root@localhost ~]# vim /etc/containers/registries.conf
[registries.search]
registries = ['registry.access.redhat.com', 'registry.redhat.io', 'docker.io'] //这个是查找,从这三个中央查找,如果只留一个,则只在一个源里查找
unqualified-search-registries = ["registry.fedoraproject.org", "registry.access.redhat.com", "registry.centos.org", "docker.io"] //这里也要改为一个

[registries.insecure]
registries = [10.0.0.1]   //这里写那些http的仓库,比方harbor

//配置加速器
[registries.search]
registries = ['https://l9h8fu9j.mirror.aliyuncs.com','docker.io']

应用 Podman

应用 Podman 十分的简略,Podman 的指令跟 Docker 大多数都是雷同的。上面咱们来看几个罕用的例子:

运行一个容器
[root@localhost ~]# podman run -d --name httpd docker.io/library/httpd
Trying to pull docker.io/library/httpd...
Getting image source signatures
Copying blob e5ae68f74026 done
Copying blob d3576f2b6317 done
Copying blob bc36ee1127ec done
Copying blob f1aa5f54b226 done
Copying blob aa379c0cedc2 done
Copying config ea28e1b82f done
Writing manifest to image destination
Storing signatures
0492e405b9ecb05e6e6be1fec0ac1a8b6ba3ff949df259b45146037b5f355035

//查看镜像
[root@localhost ~]# podman images
REPOSITORY                  TAG      IMAGE ID       CREATED       SIZE
docker.io/library/httpd     latest   ea28e1b82f31   11 days ago   148 MB
列出运行的容器
[root@localhost ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND           CREATED             STATUS                 PORTS  NAMES
0492e405b9ec  docker.io/library/httpd:latest    httpd-foreground  About a minute ago  Up About a minute ago         httpd

留神:如果在ps命令中增加-a,Podman 将显示所有容器。

查看正在运行的容器

您能够“查看”正在运行的容器的元数据和无关其本身的详细信息。咱们甚至能够应用 inspect 子命令查看调配给容器的 IP 地址。因为容器以无根模式运行,因而未调配 IP 地址,并且该值将在查看的输入中列为“无”。

[root@localhost ~]# podman inspect -l | grep IPAddress\":
            "SecondaryIPAddresses": null,
            "IPAddress": "10.88.0.5",

[root@localhost ~]# curl 10.88.0.5
<html><body><h1>It works!</h1></body></html>

留神:-l 是最新容器的便当参数。您还能够应用容器的 ID 代替 -l。

查看一个运行中容器的日志
选项
 --latest  #最近的

[root@localhost ~]# podman logs --latest
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.5. Set the 'ServerName' directive globally to suppress this message
[Mon Dec 13 15:17:53.690844 2021] [mpm_event:notice] [pid 1:tid 140665160166720] AH00489: Apache/2.4.51 (Unix) configured -- resuming normal operations
[Mon Dec 13 15:17:53.690946 2021] [core:notice] [pid 1:tid 140665160166720] AH00094: Command line: 'httpd -D FOREGROUND'
10.88.0.1 - - [13/Dec/2021:15:19:48 +0000] "GET / HTTP/1.1" 200 45
10.88.0.1 - - [13/Dec/2021:15:20:47 +0000] "GET / HTTP/1.1" 200 45
查看一个运行容器中的过程资源应用状况

能够应用top察看容器中的 nginx pid

语法:

 podman top <container_id>
[root@localhost ~]# podman top httpd
USER       PID   PPID   %CPU    ELAPSED            TTY   TIME   COMMAND
root       1     0      0.000   15m38.599711321s   ?     0s     httpd -DFOREGROUND
www-data   7     1      0.000   15m38.599783256s   ?     0s     httpd -DFOREGROUND
www-data   8     1      0.000   15m38.599845342s   ?     0s     httpd -DFOREGROUND
www-data   9     1      0.000   15m38.599880444s   ?     0s     httpd -DFOREGROUND
进行一个运行中的容器
[root@localhost ~]# podman stop --latest
2f3edf712621d3a41e03fa8c7f6a5cdba56fbbad43a7a59ede26cc88f31006c4
[root@localhost ~]# podman ps
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES
删除一个容器
[root@localhost ~]# podman rm --latest
2f3edf712621d3a41e03fa8c7f6a5cdba56fbbad43a7a59ede26cc88f31006c4
[root@localhost ~]# podman ps -a
CONTAINER ID  IMAGE  COMMAND  CREATED  STATUS  PORTS  NAMES

以上这些个性基本上都和 Docker 一样,Podman 除了兼容这些个性外,还反对了一些新的个性。

上传镜像

例如,如果咱们想在 docker.io 上分享咱们新建的 Nginx 容器镜像,这很容易。首先登录码头:

[root@localhost nginx]# tree
.
├── Dockerfile
└── files
    └── nginx-1.20.1.tar.gz

[root@localhost nginx]# cat Dockerfile
FROM docker.io/library/centos

ENV PATH /usr/local/nginx/sbin:$PATH
ADD files/nginx-1.20.1.tar.gz /usr/src
RUN useradd -r -M -s /sbin/nologin nginx && \
    yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ make && \
    mkdir -p /var/log/nginx && \
    cd /usr/src/nginx-1.20.1 && \
    ./configure \
    --prefix=/usr/local/nginx \
    --user=nginx \
    --group=nginx \
    --with-debug \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_image_filter_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_stub_status_module \
    --http-log-path=/var/log/nginx/access.log \
    --error-log-path=/var/log/nginx/error.log && \
  make && make install

CMD ["nginx","-g","daemon off"]
[root@localhost nginx]# podman build -t nginx .
// 批改镜像名
 [root@localhost ~]# podman tag docker.io/library/nginx:latest docker.io/1314444/test:latest

// 登录并上传镜像
[root@localhost ~]# podman login docker.io // 须要通知其要登录到docker仓库
[root@localhost ~]# podman login docker.io
Username: 1314444  #账户
Password: ********  #明码
Login Succeeded!

[root@localhost nginx]# podman push docker.io/1314444/test:latest  //上传镜像
Getting image source signatures
Copying blob 38c40d6c2c85 done
Copying blob fee76a531659 done
Copying blob c2adabaecedb done
Copying config 7f3589c0b8 done
Writing manifest to image destination
Copying config 7f3589c0b8 done
Writing manifest to image destination
Storing signatures

//请留神,咱们将四层推送到咱们的注册表,当初可供其他人共享。疾速浏览一下:
[root@localhost ~]# podman inspect 1314444/test:nginx
//输入:
[
    {
        "Id": "7f3589c0b8849a9e1ff52ceb0fcea2390e2731db9d1a7358c2f5fad216a48263",
        "Digest": "sha256:7822b5ba4c2eaabdd0ff3812277cfafa8a25527d1e234be028ed381a43ad5498",
        "RepoTags": [
            "docker.io/1314444/test:nginx",
  ......

总而言之,Podman 使查找、运行、构建和共享容器变得容易

配置别名

如果习惯了应用 Docker 命令,能够间接给 Podman 配置一个别名来实现无缝转移。你只须要在 .bashrc 下退出以下行内容即可:

[root@localhost ~]# echo "alias docker=podman" >> .bashrc
source .bashrc
[root@localhost ~]# alias
alias cp='cp -i'
alias docker='podman'
.......
用户操作

在容许没有root特权的用户运行Podman之前,管理员必须装置或构建Podman并实现以下配置。

cgroup V2Linux内核性能容许用户限度普通用户容器能够应用的资源,如果应用cgroupV2启用了运行Podman的Linux发行版,则可能须要更改默认的OCI运行时。某些较旧的版本runc不适用于cgroupV2,必须切换到备用OCI运行时crun。

[root@localhost ~]# yum -y install crun     //centos8零碎自带

[root@localhost ~]# vi /usr/share/containers/containers.conf
    446 # Default OCI runtime
    447 #
    448 runtime = "crun"      //勾销正文并将runc改为crun

[root@localhost ~]# podman run -d --name web -p 80:80 docker.io/library/nginx
c8664d2e43c872e1e5219f82d41f63048ed3a5ed4fb6259c225a14d6c243677f

[root@localhost ~]# podman inspect web | grep crun
        "OCIRuntime": "crun",
            "crun",
装置slirp4netns和fuse-overlayfs

在普通用户环境中应用Podman时,倡议应用fuse-overlayfs而不是VFS文件系统,至多须要版本0.7.6。当初新版本默认就是了。

[root@localhost ~]# yum -y install slirp4netns

[root@localhost ~]# yum -y install fuse-overlayfs
[root@localhost ~]# vi /etc/containers/storage.conf
77 mount_program = "/usr/bin/fuse-overlayfs"     //勾销正文
/etc/subuid和/etc/subgid配置

Podman要求运行它的用户在/etc/subuid/etc/subgid文件中列出一系列UID,shadow-utils或newuid包提供这些文件

[root@localhost ~]# yum -y install shadow-utils

能够在/etc/subuid和/etc/subgid查看,每个用户的值必须惟一且没有任何重叠。

[root@localhost ~]# useradd zz
[root@localhost ~]# cat /etc/subuid
zz:100000:65536
[root@localhost ~]# cat /etc/subgid
zz:100000:65536

// 启动非特权ping
[root@localhost ~]# sysctl -w "net.ipv4.ping_group_range=0 200000" //大于100000这个就示意tom能够操作podman
net.ipv4.ping_group_range = 0 200000

这个文件的格局是 USERNAME:UID:RANGE

  • 中/etc/passwd或输入中列出的用户名getpwent。
  • 为用户调配的初始 UID。
  • 为用户调配的 UID 范畴的大小。

该usermod程序可用于为用户调配 UID 和 GID,而不是间接更新文件。

[root@localhost ~]# usermod --add-subuids 200000-201000 --add-subgids 200000-201000 hh
grep hh /etc/subuid /etc/subgid
/etc/subuid:hh:200000:1001
/etc/subgid:hh:200000:1001
用户配置文件

三个次要的配置文件是container.conf、storage.confregistries.conf。用户能够依据须要批改这些文件。

  • container.conf
// 用户配置文件
[root@localhost ~]# cat /usr/share/containers/containers.conf
[root@localhost ~]# cat /etc/containers/containers.conf
[root@localhost ~]# cat ~/.config/containers/containers.conf  //优先级最高

如果它们以该程序存在。每个文件都能够笼罩特定字段的前一个文件。

  • 配置storage.conf文件
1./etc/containers/storage.conf
2.$HOME/.config/containers/storage.conf

在普通用户中/etc/containers/storage.conf的一些字段将被疏忽

[root@localhost ~]#  vi /etc/containers/storage.conf
[storage]

# Default Storage Driver, Must be set for proper operation.
driver = "overlay"  #此处改为overlay
.......
mount_program = "/usr/bin/fuse-overlayfs"  #勾销正文

[root@localhost ~]# sysctl user.max_user_namespaces=15000  #如果版本为8以下,则须要做以下操作:

在普通用户中这些字段默认

graphroot="$HOME/.local/share/containers/storage"
runroot="$XDG_RUNTIME_DIR/containers"
  • registries.conf

配置按此程序读入,这些文件不是默认创立的,能够从/usr/share/containers或复制文件/etc/containers并进行批改。

1./etc/containers/registries.conf
2./etc/containers/registries.d/*
3.HOME/.config/containers/registries.conf
受权文件

此文件外面写了docker账号的明码,以加密形式显示

[root@localhost ~]# podman login
Username: 1314444
Password:
Login Succeeded!
[root@localhost ~]# cat /run/user/0/containers/auth.json
{
        "auths": {
                "registry.fedoraproject.org": {
                        "auth": "MTMxNDQ0NDpIMjAxNy0xOA=="
                }
        }
}

普通用户是无奈看见root用户的镜像的

//root用户
[root@localhost ~]# podman images
REPOSITORY                  TAG      IMAGE ID       CREATED       SIZE
docker.io/library/httpd     latest   ea28e1b82f31   11 days ago   146 MB

//普通用户
[root@localhost ~]# su - zz
[zz@localhost ~]$ podman images
REPOSITORY  TAG         IMAGE ID    CREATED     SIZE

  • 容器与root用户一起运行,则root容器中的用户实际上就是主机上的用户。
  • UID GID是在/etc/subuid和/etc/subgid等中用户映射中指定的第一个UID GID。
  • 如果普通用户的身份从主机目录挂载到容器中,并在该目录中以根用户身份创立文件,则会看到它实际上是你的用户在主机上领有的。
应用卷
[root@localhost ~]# su - zz
[zz@localhost ~]$ pwd
/home/zz
[zz@localhost ~]$ mkdir /home/zz/data

[zz@localhost ~]$ podman run -it -v "$(pwd)"/data:/data docker.io/library/busybox /bin/sh
Trying to pull docker.io/library/busybox:latest...
Getting image source signatures
Copying blob 3cb635b06aa2 done
Copying config ffe9d497c3 done
Writing manifest to image destination
Storing signatures
/ # ls
bin   data  dev   etc   home  proc  root  run   sys   tmp   usr   var
/ # cd data/
/data # ls
/data # touch 123
/data # ls -l
total 0
-rw-r--r--    1 root     root             0 Dec 13 00:17 123
在主机上查看
[zz@localhost ~]$ ll data/
总用量 0
-rw-r--r-- 1 zz zz 0 12月 13 00:17 123

//写入文件
[zz@localhost ~]$ echo "hell world" >> 123
[zz@localhost ~]$ cat 123
hell world
容器里查看
/data # cat 123
hell world

//咱们能够发现在容器外面的文件的属主和属组都属于root,那么如何能力让其属于tom用户呢?上面通知你答案
/data # ls -l
total 4
-rw-rw-r--    1 root     root            12 Dec 13 00:20 123

//只有在运行容器的时候加上一个--userns=keep-id即可。
[zz@localhost ~]$ podman run -it --name test -v "$(pwd)"/data:/data --userns=keep-id docker.io/library/busybox /bin/sh
~ $ cd data/
/data $ ls -l
total 4
-rw-r--r--    1 zz       zz              11 Dec 13 00:21 123

应用普通用户映射容器端口时会报“ permission denied”的谬误

[zz@localhost ~]$ podman run  -d -p 80:80 httpd
Error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied

普通用户能够映射>= 1024的端口

[zz@localhost ~]$ podman run  -d -p 1024:80 httpd
58613a6bdc70d4d4f9f624583f795a62a610596d166f0873bdff8fb26aa15092
[zz@localhost ~]$ ss -anlt
State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port      Process
LISTEN      0           128                    0.0.0.0:22                  0.0.0.0:*
LISTEN      0           128                          *:1024                      *:*
LISTEN      0           128                       [::]:22                     [::]:*

配置echo ‘net.ipv4.ip_unprivileged_port_start=80’ >> /etc/sysctl.conf后能够映射大于等于80的端口

[root@localhost ~]# echo  'net.ipv4.ip_unprivileged_port_start=80'  >> /etc/sysctl.conf
[root@localhost ~]# sysctl -p
net.ipv4.ip_unprivileged_port_start = 80

[zz@localhost ~]$ podman run -d -p 80:80 httpd
1215455a0c300d78e7bf6afaefc9873f818c6b0f26affeee4e2bc17954e72d8e
[zz@localhost ~]$ ss -anlt
State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port      Process
LISTEN      0           128                    0.0.0.0:22                  0.0.0.0:*
LISTEN      0           128                          *:1024                      *:*
LISTEN      0           128                          *:80                        *:*
LISTEN      0           128                       [::]:22                     [::]:*

近期热文举荐:

1.1,000+ 道 Java面试题及答案整顿(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!

5.《Java开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞+转发哦!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理