再見 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
相關文章
相關標籤/搜索