再见 Docker,是时候拥抱下一代容器工具了

file

本文首发于:微信公众号「运维之美」,公众号 ID:Hi-Linux。前端

「运维之美」是一个有情怀、有态度,专一于 Linux 运维相关技术文章分享的公众号。公众号致力于为广大运维工做者分享各种技术文章和发布最前沿的科技信息。公众号的核心理念是:分享,咱们认为只有分享才能使咱们的团体更强大。若是你想第一时间获取最新技术文章,欢迎关注咱们!nginx

公众号做者 Mike,一个月薪 3000 的杂工。从事 IT 相关工做 15+ 年,热衷于互联网技术领域,认同开源文化,对运维相关技术有本身独特的看法。很愿意将本身积累的经验、心得、技能与你们分享交流,篇篇干货不要错过哟。若是你想联系到我,可关注公众号获取相关信息。git

什么是 Linux 容器?

Linux 容器是由 Linux 内核所提供的具备特定隔离功能的进程,Linux 容器技术可以让你对应用及其整个运行时环境(包括所有所需文件)一块儿进行打包或隔离。从而让你在不一样环境(如开发、测试和生产等环境)之间轻松迁移应用的同时,还可保留应用的所有功能。github

Linux 容器还有利于明确划分职责范围,减小开发和运维团队间的冲突。这样,开发人员能够全心投入应用开发,而运维团队则可专一于基础架构维护。因为 Linux 容器基于开源技术构建,还将便于你在将来轻松采用各种更新、更强的技术产品。包括 CRI-OKubernetesDocker 在内的容器技术,可帮助你的团队有效简化、加速和编排应用的开发与部署。docker

什么是 Docker?

Docker 是一个开源的应用容器引擎,属于 Linux 容器的一种封装,Docker 提供简单易用的容器使用接口,让开发者能够打包他们的应用以及依赖包到一个可移植的容器中,而后发布到任何流行的 Linux 机器上。容器是彻底使用沙箱机制,相互之间不会有任何接口。vim

Docker 是目前最流行的 Linux 容器解决方案,即便 Docker 是目前管理 Linux 容器的一个很是方便的工具,但它也有两个缺点:安全

  1. Docker 须要在你的系统上运行一个守护进程。
  2. Docker 是以 root 身份在你的系统上运行该守护程序。

这些缺点的存在可能有必定的安全隐患,为了解决这些问题,下一代容器化工具 Podman 出现了 。bash

什么是 Podman ?

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

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

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

2. Podman 项目地址:https://github.com/containers/libpod

安装 Podman

Podman 目前已支持大多数发行版本经过软件包来进行安装,下面咱们来举几个经常使用发行版本的例子。

  • Fedora / CentOS
$ sudo yum -y install podman复制代码

  • Ubuntu
$ sudo apt-get update -qq
$ sudo apt-get install -qq -y software-properties-common uidmap
$ sudo add-apt-repository -y ppa:projectatomic/ppa
$ sudo apt-get update -qq
$ sudo apt-get -qq -y install podman复制代码

  • MacOS
$ brew cask install podman复制代码

  • RHEL 7
$ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
$ sudo yum -y install podman复制代码

  • Arch Linux
$ sudo pacman -S podman复制代码

更多系统的安装方法,可参考官方文档:https://github.com/containers/libpod/blob/master/install.md

使用 Podman

使用 Podman 很是的简单,Podman 的指令跟 Docker 大多数都是相同的。下面咱们来看几个经常使用的例子:

运行一个容器

$ podman run -dt -p 8080:8080/tcp  \
-e HTTPD_VAR_RUN=/var/run/httpd  \
-e HTTPD_MAIN_CONF_D_PATH=/etc/httpd/conf.d \
-e HTTPD_MAIN_CONF_PATH=/etc/httpd/conf \
-e HTTPD_CONTAINER_SCRIPTS_PATH=/usr/share/container-scripts/httpd/ \
registry.fedoraproject.org/f27/httpd /usr/bin/run-httpd复制代码

列出运行的容器

$ podman ps -a复制代码

分析一个运行的容器

$ podman inspect -l | grep IPAddress\":
"SecondaryIPAddresses": null,
"IPAddress": "",复制代码

查看一个运行中容器的日志

$ sudo podman logs --latest
10.88.0.1 - - [07/Feb/2018:15:22:11 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.55.1" "-"
10.88.0.1 - - [07/Feb/2018:15:22:30 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.55.1" "-"
10.88.0.1 - - [07/Feb/2018:15:22:30 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.55.1" "-"
10.88.0.1 - - [07/Feb/2018:15:22:31 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.55.1" "-"
10.88.0.1 - - [07/Feb/2018:15:22:31 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.55.1" "-"复制代码

查看一个运行容器中的进程资源使用状况

$ sudo podman top <container_id>
  UID   PID  PPID  C STIME TTY          TIME CMD
    0 31873 31863  0 09:21 ?        00:00:00 nginx: master process nginx -g daemon off;
  101 31889 31873  0 09:21 ?        00:00:00 nginx: worker process复制代码

中止一个运行中的容器

$ sudo podman stop --latest复制代码

删除一个容器

$ sudo podman rm --latest复制代码

以上这些特性基本上都和 Docker 同样,Podman 除了兼容这些特性外,还支持了一些新的特性。

给容器设置一个检查点

$ sudo podman container checkpoint <container_id>复制代码

须要 CRIU 3.11 以上版本支持,CRIU 项目地址:https://criu.org/

根据检查点位置恢复容器

$ sudo podman container restore <container_id>复制代码

迁移容器

Podman 支持将容器从一台机器迁移到另外一台机器。

首先,在源机器上对容器设置检查点,并将容器打包到指定位置。

$ sudo podman container checkpoint <container_id> -e /tmp/checkpoint.tar.gz
$ scp /tmp/checkpoint.tar.gz <destination_system>:/tmp复制代码

其次,在目标机器上使用源机器上传输过来的打包文件对容器进行恢复。

$ sudo podman container restore -i /tmp/checkpoint.tar.gz复制代码

配置别名

若是习惯了使用 Docker 命令,能够直接给 Podman 配置一个别名来实现无缝转移。你只须要在 .bashrc 下加入如下行内容便可:

$ echo "alias docker=podman" >> .bashrc
$ source .bashrc复制代码

Podman 如何实现开机重启容器

因为 Podman 再也不使用守护进程管理服务,因此不能经过守护进程去实现自动重启容器的功能。那若是要实现开机自动重启容器,又该如何实现呢?

其实方法很简单,如今大多数系统都已经采用 Systemd 做为守护进程管理工具。这里咱们就可使用 Systemd 来实现 Podman 开机重启容器,这里咱们以启动一个 Nginx 容器为例子。

首先,咱们先运行一个 Nginx 容器。

$ sudo podman run -t -d -p 80:80 --name nginx nginx复制代码

而后,在创建一个 Systemd 服务配置文件。

$ vim /etc/systemd/system/nginx_container.service

[Unit]
Description=Podman Nginx Service
After=network.target
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/podman start -a nginx
ExecStop=/usr/bin/podman stop -t 10 nginx
Restart=always

[Install]
WantedBy=multi-user.target复制代码

接下来,启用这个 Systemd 服务。

$ sudo systemctl daemon-reload
$ sudo systemctl enable nginx_container.service
$ sudo systemctl start nginx_container.service复制代码

服务启用成功后,咱们能够经过 systemctl status 命令查看到这个服务的运行情况。

$ sudo systemctl status nginx_container.service
● nginx_container.service - Podman Nginx Service
   Loaded: loaded (/etc/systemd/system/nginx_container.service; enabled; vendor preset: disabled)
   Active: active (running) since Sat 2019-08-20 20:59:26 UTC; 1min 41s ago
 Main PID: 845 (podman)
    Tasks: 16 (limit: 4915)
   Memory: 37.6M
   CGroup: /system.slice/nginx_container.service
           └─845 /usr/bin/podman start -a nginx

Aug 20 20:59:26 Ubuntu-dev.novalocal systemd[1]: Started Podman Nginx Service.复制代码

以后每次系统重启后 Systemd 都会自动启动这个服务所对应的容器。

其它相关工具

Podman 只是 OCI 容器生态系统计划中的一部分,主要专一于帮助用户维护和修改符合 OCI 规范容器镜像。其它的组件还有 BuildahSkopeo 等。

Buildah

虽然 Podman 也能够支持用户构建 Docker 镜像,可是构建速度比较慢。而且默认状况下使用 VFS 存储驱动程序会消耗大量磁盘空间。

Buildah 是一个专一于构建 OCI 容器镜像的工具,Buildah 构建速度很是快并使用覆盖存储驱动程序,能够节约大量的空间。

Buildah 基于 fork-exec 模型,不以守护进程运行。Buildah 支持 Dockerfile 中的全部命令。你能够直接使用 Dockerfiles 来构建镜像,而且不须要任何 root 权限。 Buildah 也支持用本身的语法文件构建镜像,能够容许将其余脚本语言集成到构建过程当中。

下面是一个使用 Buidah 自有语法构建的例子。

BuildahPodman 之间的一个主要区别是:Podman 用于运行和管理容器, 容许咱们使用熟悉的容器 CLI 命令在生产环境中管理和维护这些镜像和容器,而 Buildah 主用于构建容器。

项目地址:https://github.com/containers/buildah

Skopeo

Skopeo 是一个镜像管理工具,容许咱们经过 PushPull和复制镜像来处理 Docker 和符合 OCI 规范的镜像。

项目地址:https://github.com/containers/skopeo

延伸阅读

什么是 OCI?

OCI (Open Container Initiative),是一个轻量级,开放的治理结构(项目)。在 Linux 基金会的支持下成立,致力于围绕容器格式和运行时建立开放的行业标准。

OCI 项目由 DockerCoreOS 和容器行业中的其它领导者在 2015 年 6 月的时候启动,OCI 的技术委员会成员包括 Red HatMicrosoftDockerCruiseIBMGoogleRed HatSUSE 等。

什么是 CRI?

CRI(Container Runtime Interface)是 Kubernetes v1.5 引入的容器运行时接口,它将 Kubelet 与容器运行时解耦,将原来彻底面向 Pod 级别的内部接口拆分红面向 SandboxContainergRPC 接口,并将镜像管理和容器管理分离到不一样的服务。

什么是 CNI?

CNI(Container Network Interface)是 CNCF 旗下的一个项目,是 GoogleCoreOS 主导制定的容器网络标准。CNI 包含方法规范、参数规范等,是 Linux 容器网络配置的一组标准和库,用户能够根据这些标准和库来开发本身的容器网络插件。CNI 已经被 KubernetesMesosCloud FoundryRKT 等使用,同时 CalicoWeave 等项目都在为 CNI 提供插件。

总结

本文介绍三个了符合 CRI 标准的容器工具 PodmanBuildahSkopeo。这三个工具都是基于 *nix 传统的 fork-exec 模型,解决了因为 Docker 守护程序致使的启动和安全问题,提升了容器的性能和安全。

参考文档

  1. https://igene.tw/podman-intro
  2. https://zhuanlan.zhihu.com/p/77373246
  3. https://zhuanlan.zhihu.com/p/47706426
  4. https://xuanwo.io/2019/08/06/oci-intro/
  5. https://www.jianshu.com/p/62e71584d1cb
  6. https://kubernetes.feisky.xyz/cha-jian-kuo-zhan/cri
  7. https://blog.csdn.net/networken/article/details/98684527
  8. https://www.zcfy.cc/article/demystifying-the-open-container-initiative-oci-specifications
相关文章
相关标签/搜索