再見Docker,是時候擁抱下一代容器工具了
什么是 Linux 容器?
Linux 容器是由 Linux 內核所提供的具有特定隔離功能的進程,Linux 容器技術能夠讓你對應用及其整個運行時環境(包括全部所需文件)一起進行打包或隔離。從而讓你在不同環境(如開發、測試和生產等環境)之間輕松遷移應用的同時,還可保留應用的全部功能。
Linux 容器還有利于明確劃分職責范圍,減少開發和運維團隊間的沖突。這樣,開發人員可以全心投入應用開發,而運維團隊則可專注于基礎架構維護。由于 Linux 容器基于開源技術構建,還將便于你在未來輕松采用各類更新、更強的技術產品。包括 CRI-O、Kubernetes 和 Docker 在內的容器技術,可幫助你的團隊有效簡化、加速和編排應用的開發與部署。
什么是 Docker?
Docker 是一個開源的應用容器引擎,屬于 Linux 容器的一種封裝,Docker 提供簡單易用的容器使用接口,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然后發布到任何流行的 Linux 機器上。容器是完全使用沙箱機制,相互之間不會有任何接口。
Docker 是目前很流行的 Linux 容器解決方案,即使 Docker 是目前管理 Linux 容器的一個非常方便的工具,但它也有兩個缺點:
- Docker 需要在你的系統上運行一個守護進程。
- Docker 是以 root 身份在你的系統上運行該守護程序。
這些缺點的存在可能有一定的安全隱患,為了解決這些問題,下一代容器化工具 Podman 出現了 。
什么是 Podman ?
Podman 是一個開源的容器運行時項目,可在大多數 Linux 平臺上使用。Podman 提供與 Docker 非常相似的功能。正如前面提到的那樣,它不需要在你的系統上運行任何守護進程,并且它也可以在沒有 root 權限的情況下運行。
Podman 可以管理和運行任何符合 OCI(Open Container Initiative)規范的容器和容器鏡像。Podman 提供了一個與 Docker 兼容的命令行前端來管理 Docker 鏡像。
- Podman 官網地址:https://podman.io/
- Podman 項目地址:https://github.com/containers/libpod
安裝 PodmanPodman
目前已支持大多數發行版本通過軟件包來進行安裝,下面我們來舉幾個常用發行版本的例子。
- 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 規范的容器鏡像。其它的組件還有 Buildah、Skopeo 等。
Buildah
雖然 Podman 也可以支持用戶構建 Docker 鏡像,但是構建速度比較慢。并且默認情況下使用 VFS 存儲驅動程序會消耗大量磁盤空間。
Buildah 是一個專注于構建 OCI 容器鏡像的工具,Buildah 構建速度非??觳⑹褂酶采w存儲驅動程序,可以節約大量的空間。
Buildah 基于 fork-exec 模型,不以守護進程運行。Buildah 支持 Dockerfile 中的所有命令。你可以直接使用 Dockerfiles 來構建鏡像,并且不需要任何 root 權限。Buildah 也支持用自己的語法文件構建鏡像,可以允許將其他腳本語言集成到構建過程中。
下面是一個使用 Buidah 自有語法構建的例子。
Buildah 和 Podman 之間的一個主要區別是:Podman 用于運行和管理容器, 允許我們使用熟悉的容器 CLI 命令在生產環境中管理和維護這些鏡像和容器,而 Buildah 主用于構建容器。
項目地址:https://github.com/containers/buildah
Skopeo
Skopeo 是一個鏡像管理工具,允許我們通過 Push、Pull和復制鏡像來處理 Docker和符合 OCI 規范的鏡像。
項目地址:https://github.com/containers/skopeo
延伸閱讀
什么是 OCI?
OCI (Open Container Initiative),是一個輕量級,開放的治理結構(項目)。在 Linux 基金會的支持下成立,致力于圍繞容器格式和運行時創建開放的行業標準。
OCI 項目由 Docker、CoreOS 和容器行業中的其它領導者在 2015 年 6 月的時候啟動,OCI 的技術委員會成員包括 Red Hat、Microsoft、Docker、Cruise、IBM、Google、Red Hat 和 SUSE 等。
什么是 CRI?
CRI(Container Runtime Interface)是 Kubernetes v1.5 引入的容器運行時接口,它將 Kubelet 與容器運行時解耦,將原來完全面向 Pod 級別的內部接口拆分成面向 Sandbox 和 Container 的 gRPC 接口,并將鏡像管理和容器管理分離到不同的服務。
什么是 CNI?
CNI(Container Network Interface)是 CNCF 旗下的一個項目,是 Google 和 CoreOS 主導制定的容器網絡標準。CNI 包含方法規范、參數規范等,是 Linux 容器網絡配置的一組標準和庫,用戶可以根據這些標準和庫來開發自己的容器網絡插件。CNI 已經被 Kubernetes、Mesos、Cloud Foundry、RKT 等使用,同時 Calico、Weave等項目都在為 CNI 提供插件。

總結

本文介紹三個了符合 CRI 標準的容器工具 Podman、 Buildah 和 Skopeo。這三個工具都是基于 *nix 傳統的 fork-exec 模型,解決了由于 Docker 守護程序導致的啟動和安全問題,提高了容器的性能和安全。