容器引擎Docker与Podman解析

简介: 最近技术群里有朋友问我,不是说K8S要弃用Docker了吗?还要不要继续学习这块内容?是不是得改行卖白菜了?

      最近技术群里有朋友问我,不是说K8S要弃用Docker了吗?还要不要继续学习这块内容?是不是得改行卖白菜了?

      毫无疑问,传统虚拟机的造反,容器化的革命是从Docker开始的。发展至今,并成为最受欢迎和广泛使用的容器管理系统之一。它改变了我们构建云原生应用程序的方式。Docker为构建、部署和管理容器提供了非常好的端到端架构。

      作为一种开源的应用容器引擎,基于 Linux 容器的一种封装,Docker 提供简单易用的容器使用接口,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。容器是完全使用沙箱机制,相互之间不会有任何接口。Docker体系结构基于守护程序,该守护程序在后台作为服务运行。Docker守护程序负责运行命令,将镜像推入/拉出仓库或从中拉出镜像,管理计算机上的容器和镜像。

      下面我们看下Docker的体系架构,具体如下所示:

      基于上述架构图,我们可以看出,Docker体系主要围绕“Docker Daemon 和 Docker CLI”2大核心组件运行:

      Docker Daemon:一个常驻的系统后台进程,帮助管理和创建 Docker 镜像、容器、网络和存储卷等。

      Docker CLI:一个用来与 Docker 守护进程进行交互的 Docker 命令行客户端。

      除此之外,Docker Engine REST API,应用程序用来与 Docker 守护进程进行交互的 API,可以通过 HTTP 客户端来访问它。

      Podman 是一个开源的容器运行时项目,可在大多数 Linux 平台上使用。Podman 提供与 Docker 非常相似的功能。正如前面提到的那样,它不需要在你的系统上运行任何守护进程,并且它也可以在没有 root 权限的情况下运行。

      Podman 可以管理和运行任何符合 OCI(Open Container Initiative)规范的容器和容器镜像。Podman 提供了一个与 Docker 兼容的命令行前端来管理 Docker 镜像。

      下面我们看下Podman的体系架构,具体如下所示:

      相比Docker,Podman没有Daemon的概念,直接通过 OCI runtime(默认也是 runc)来启动容器,所以容器的进程是 Podman 的子进程。这比较像 Linux 的 fork/exec 模型,而 Docker 采用的是 C/S(客户端/服务器)模型。与 C/S 模型相比,fork/exec 模型有很多优势。

      那么,针对Podman 和Docker,它们到底有哪些本质不同之处呢?

      具体,Docker 需要在我们的系统上运行一个守护进程(Docker Daemon),而Podman 则不需要。

      两者启动容器方式不同:

      1、Docker Cli 命令通过API跟 Docker Engine(引擎)交互告诉它我想创建一个Container,然后Docker Engine才会调用OCI Container Runtime(runc)来启动一个Container。这代表Container的Process(进程)不会是Docker CLI的Child Process(子进程),而是Docker Engine的Child Process。

       2、Podman是直接给OCI Containner Runtime(runc)进行交互来创建Container的,所以Container Process直接是Podman的Child Process。

      3、因为Docke有Docker Daemon,所以Docker启动的容器支持--restart策略,但Podman不支持,如果在K8S中就不存在这个问题,我们可以设置Pod的重启策略,在系统中我们可以采用编写Systemd服务来完成自启动。

       4、Docker需要使用root用户来创建容器,而Podman则不需要。

      下面我们就针对Podman相关具体实践操作进行简要解析,以方便大家能够熟悉2者之间的差异,具体如下:


[administrator@JavaLangOutOfMemory ~ ]%podman version
Version:            1.6.4
RemoteAPI Version:  1
Go Version:         go1.12.12
OS/Arch:            linux/amd64
[administrator@JavaLangOutOfMemory ~ ]%podman info
host:
  BuildahVersion: 1.11.5
  CgroupVersion: v1
  Conmon:
    package: conmon-2.0.8-1.el7.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.0.8, commit: f85c8b1ce77b73bcd48b2d802396321217008762'
  Distribution:
    distribution: '"centos"'
    version: "7"
  MemFree: 339603456
  MemTotal: 3973734400
  OCIRuntime:
    name: runc
    package: containerd.io-1.2.13-3.2.el7.x86_64
    path: /usr/bin/runc
    version: |-
      runc version 1.0.0-rc10
      commit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
      spec: 1.0.1-dev
  SwapFree: 0
  SwapTotal: 0
  arch: amd64
  cpus: 2
  eventlogger: journald
  hostname: k8s-node01
  kernel: 3.10.0-1127.18.2.el7.x86_64
  os: linux
  rootless: false
  uptime: 3h 44m 8.68s (Approximately 0.12 days)
registries:
  blocked: null
  insecure: null
  search:
  - registry.access.redhat.com
  - registry.redhat.io
  - docker.io
store:
  ConfigFile: /etc/containers/storage.conf
  ContainerStore:
    number: 3
  GraphDriverName: overlay
  GraphOptions: {}
  GraphRoot: /var/lib/containers/storage
  GraphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Using metacopy: "false"
  ImageStore:
    number: 4
  RunRoot: /var/run/containers/storage
  VolumePath: /var/lib/containers/storage/volumes

      现在,我们运行一个简单的示例容器,以Tomcat Web容器为例,具体如下所示:


[administrator@JavaLangOutOfMemory ~ ]% podman run -d -t -p 9988:9988 tomcat
Trying to pull registry.access.redhat.com/tomcat...
  name unknown: Repo not found
Trying to pull registry.redhat.io/tomcat...
  unable to retrieve auth token: invalid username/password: unauthorized: Please login to the Red Hat Registry using your Customer Portal credentials. Further instructions can be found here: https://access.redhat.com/RegistryAuthentication
Trying to pull docker.io/library/tomcat...
Getting image source signatures
Copying blob d557ee20540b skipped: already exists  
Copying blob b9a857cbf04d skipped: already exists  
Copying blob 667fd949ed93 skipped: already exists  
Copying blob 3b9ca4f00c2e skipped: already exists  
Copying blob 661d3b55f657 skipped: already exists  
Copying blob 0115df4a56b1 done  
Copying blob 292eeca13ab1 done  
Copying blob 6f89638f9b1f done  
Copying blob a2353fa2a135 done  
Copying blob 511ef4338a0b done  
Copying config 345867df08 done  
Writing manifest to image destination
Storing signatures
3887123f2a92beda0a949e5f462ce7fde8c4b7fb7a3ebf6f0738064bae17c917

      此时,列出所有创建的容器,具体如下:


[administrator@JavaLangOutOfMemory ~ ]% podman ps
CONTAINER ID  IMAGE                                   COMMAND               CREATED         STATUS             PORTS                   NAMES
3887123f2a92  docker.io/library/tomcat:latest         catalina.sh run       2 minutes ago   Up 2 minutes ago   0.0.0.0:9988->9988/tcp  luga-tomcat-2
66c05be56143  docker.io/unidata/tomcat-docker:latest  start-tomcat.sh       8 minutes ago   Up 8 minutes ago   0.0.0.0:8088->8088/tcp  luga-tomcat-1
6accf83c23c9  docker.io/library/nginx:alpine          nginx -g daemon o...  30 minutes ago  Up 30 minutes ago                          luga-nginx

      我们再看下容器是否运行成功,可借助Log参考,具体如下所示:


[administrator@JavaLangOutOfMemory ~ ]% podman logs 3887123f2a92
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/openjdk-11
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
01-Feb-2021 17:35:57.858 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.41
01-Feb-2021 17:35:57.957 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Dec 3 2020 11:43:00 UTC
01-Feb-2021 17:35:57.959 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.41.0
01-Feb-2021 17:35:57.959 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
01-Feb-2021 17:35:57.969 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            3.10.0-1127.18.2.el7.x86_64
01-Feb-2021 17:35:57.969 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
01-Feb-2021 17:35:57.980 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/openjdk-11
01-Feb-2021 17:35:57.980 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.10+9
01-Feb-2021 17:35:57.980 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
01-Feb-2021 17:35:57.981 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
01-Feb-2021 17:35:57.981 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
01-Feb-2021 17:35:58.141 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
01-Feb-2021 17:35:58.141 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
01-Feb-2021 17:35:58.144 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
01-Feb-2021 17:35:58.144 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
01-Feb-2021 17:35:58.145 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
01-Feb-2021 17:35:58.148 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
01-Feb-2021 17:35:58.149 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
01-Feb-2021 17:35:58.149 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
01-Feb-2021 17:35:58.149 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
01-Feb-2021 17:35:58.150 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
01-Feb-2021 17:35:58.150 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
01-Feb-2021 17:35:58.150 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
01-Feb-2021 17:35:58.229 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded Apache Tomcat Native library [1.2.25] using APR version [1.6.5].
01-Feb-2021 17:35:58.233 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
01-Feb-2021 17:35:58.237 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
01-Feb-2021 17:35:58.261 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1d  10 Sep 2019]
01-Feb-2021 17:36:03.709 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
01-Feb-2021 17:36:04.128 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [9607] milliseconds
01-Feb-2021 17:36:05.784 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
01-Feb-2021 17:36:05.785 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.41]
01-Feb-2021 17:36:06.135 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
01-Feb-2021 17:36:06.778 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [2648] milliseconds

      同时,我们查看其进程资源,具体如下所示:


[administrator@JavaLangOutOfMemory ~ ]% podman top 3887123f2a92
USER   PID   PPID   %CPU    ELAPSED            TTY     TIME    COMMAND
root   1     0      5.313   21m57.402336601s   pts/0   1m10s   /usr/local/openjdk-11/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start

[administrator@JavaLangOutOfMemory ~ ]% podman stats 3887123f2a92       
ID             NAME                    CPU %   MEM USAGE / LIMIT   MEM %   NET IO           BLOCK IO   PIDS
3887123f2a92   festive_chandrasekhar   3.10%   83.09MB / 3.974GB   2.09%   1.028kB / 836B   -- / --    36
ID             NAME                    CPU %   MEM USAGE / LIMIT   MEM %   NET IO           BLOCK IO   PIDS
3887123f2a92   festive_chandrasekhar   3.02%   83.09MB / 3.974GB   2.09%   1.028kB / 836B   -- / --    36
ID             NAME                    CPU %   MEM USAGE / LIMIT   MEM %   NET IO           BLOCK IO   PIDS
3887123f2a92   festive_chandrasekhar   6.11%   83.09MB / 3.974GB   2.09%   1.028kB / 836B   -- / --    36
ID             NAME                    CPU %   MEM USAGE / LIMIT   MEM %   NET IO           BLOCK IO   PIDS
3887123f2a92   festive_chandrasekhar   1.08%   83.09MB / 3.974GB   2.09%   1.028kB / 836B   -- / --    36

       然后,我们通过CURL命令查看,具体如下所示:


[administrator@JavaLangOutOfMemory ~ ]% curl http://192.168.56.109:8888/
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.41</h3></body></html

      由于 Podman 不再使用守护进程管理服务,所以不能通过守护进程去实现自动重启容器的功能。那如果要实现开机自动重启容器,又该如何实现呢?很简单,现在大多数系统都已经采用 Systemd 作为守护进程管理工具。有兴趣的可以自行尝试。

      由上面的返回结果可知,服务已经正常启动,至此,Podman解析到此为止。

      回到前面的问题:K8S为什么要弃用Docker?因为,Docker 至始至终并不支持 CRI(容器运行时接口)这一Kubernetes运行时API,而 Kubernetes 用户一直以来所使用的其实是名为“dockershim”的桥接服务。Dockershim 能够转换 Docker API 与 CRI,但在后续版本当中,Kubernetes 将不再提供这项桥接服务。针对CRI运行时,后续文章将对其进行剖析。


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
4天前
|
监控 Kubernetes Docker
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
【5月更文挑战第9天】本文探讨了Docker容器中应用的健康检查与自动恢复,强调其对应用稳定性和系统性能的重要性。健康检查包括进程、端口和应用特定检查,而自动恢复则涉及重启容器和重新部署。Docker原生及第三方工具(如Kubernetes)提供了相关功能。配置检查需考虑检查频率、应用特性和监控告警。案例分析展示了实际操作,未来发展趋势将趋向更智能和高效的检查恢复机制。
【Docker 专栏】Docker 容器内应用的健康检查与自动恢复
|
1天前
|
Kubernetes 持续交付 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【5月更文挑战第17天】在当今云计算和微服务架构的大潮中,Docker容器化技术和Kubernetes容器编排系统成为了后端开发领域的热门技术栈。本文将探讨如何通过Docker和Kubernetes的结合使用来构建一个高效、可扩展且易于管理的微服务环境。我们将从基础概念出发,深入到实际操作层面,最后讨论这种组合对持续集成和持续部署(CI/CD)流程的影响,旨在为开发者和企业提供一种可靠的后端服务解决方案。
|
1天前
|
运维 网络协议 Linux
Docker网络_docker 网络,来看看这份超全面的《Linux运维面试题及解析》
Docker网络_docker 网络,来看看这份超全面的《Linux运维面试题及解析》
|
1天前
|
Java 虚拟化 Docker
Docker简介及用途,为什么要使用Docker?Docker容器和虚拟机的区别
Docker简介及用途,为什么要使用Docker?Docker容器和虚拟机的区别
|
1天前
|
存储 Linux Docker
CentOS7修改Docker容器和镜像默认存储位置
CentOS7修改Docker容器和镜像默认存储位置
|
1天前
|
Linux Docker 容器
更改docker容器中的时间而不影响宿主机
更改docker容器中的时间而不影响宿主机
|
1天前
|
Ubuntu Linux Go
docker容器启动报错
docker容器启动报错解决
|
2天前
|
Java 数据库连接 Spring
K8S+Docker理论与实践深度集成java面试jvm原理
K8S+Docker理论与实践深度集成java面试jvm原理
|
3天前
|
Ubuntu Docker 容器
docker容器保存和导入
docker容器保存和导入
20 0
|
3天前
|
Ubuntu Docker 容器
清理docker容器
清理docker容器
12 0