容器引擎Docker与Podman解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 最近技术群里有朋友问我,不是说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搭建和管理企业级网站应用
相关文章
|
7天前
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
|
5天前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
150 93
|
23天前
|
NoSQL Java Linux
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
210 75
|
1月前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
248 77
|
7天前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
65 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
18天前
|
搜索推荐 安全 数据安全/隐私保护
7 个最能提高生产力的 Docker 容器
7 个最能提高生产力的 Docker 容器
98 35
|
6天前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
33 17
|
17天前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
6天前
|
运维 Java 虚拟化
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
61 12
|
7天前
|
Kubernetes Linux 虚拟化
入门级容器技术解析:Docker和K8s的区别与关系
本文介绍了容器技术的发展历程及其重要组成部分Docker和Kubernetes。从传统物理机到虚拟机,再到容器化,每一步都旨在更高效地利用服务器资源并简化应用部署。容器技术通过隔离环境、减少依赖冲突和提高可移植性,解决了传统部署方式中的诸多问题。Docker作为容器化平台,专注于创建和管理容器;而Kubernetes则是一个强大的容器编排系统,用于自动化部署、扩展和管理容器化应用。两者相辅相成,共同推动了现代云原生应用的快速发展。
56 11

热门文章

最新文章