容器引擎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运行时,后续文章将对其进行剖析。


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
4月前
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
1月前
|
弹性计算 Java Maven
从代码到容器:Cloud Native Buildpacks技术解析
Cloud Native Buildpacks(CNB)是一种标准化、云原生的容器镜像构建系统,旨在消除手动编写Dockerfile,提供可重复、安全且高效的构建流程。它通过分层策略生成符合OCI标准的镜像,实现应用与基础镜像解耦,并自动化依赖管理和更新。阿里云应用管理支持通过CNB技术一键部署应用至ECS,简化构建和运行流程。
|
5月前
|
NoSQL Java Linux
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
381 76
|
4月前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
1425 11
|
5月前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
201 3
|
6月前
|
安全 持续交付 Docker
深入理解并实践容器化技术——Docker 深度解析
深入理解并实践容器化技术——Docker 深度解析
194 2
|
6月前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
19天前
|
关系型数据库 MySQL Docker
|
2月前
|
Ubuntu 关系型数据库 MySQL
容器技术实践:在Ubuntu上使用Docker安装MySQL的步骤。
通过以上的操作,你已经步入了Docker和MySQL的世界,享受了容器技术给你带来的便利。这个旅程中你可能会遇到各种挑战,但是只要你沿着我们划定的路线行进,你就一定可以达到目的地。这就是Ubuntu、Docker和MySQL的灵魂所在,它们为你开辟了一条通往新探索的道路,带你亲身感受到了技术的力量。欢迎在Ubuntu的广阔大海中探索,用Docker技术引领你的航行,随时准备感受新技术带来的震撼和乐趣。
128 16
|
2月前
|
监控 关系型数据库 MySQL
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
zabbix7.0.9安装-以宝塔安装形式-非docker容器安装方法-系统采用AlmaLinux9系统-最佳匹配操作系统提供稳定运行环境-安装教程完整版本-优雅草卓伊凡
159 30