本文首發於:微信公眾號「運維之美」,公眾號 ID:Hi Linux。 「運維之美」是一個有情懷、有態度,專註於 Linux 運維相關技術文章分享的公眾號。公眾號致力於為廣大運維工作者分享各類技術文章和發佈最前沿的科技信息。公眾號的核心理念是:分享,我們認為只有分享才能使我們的團體更強大。如果你想第一 ...
本文首發於:微信公眾號「運維之美」,公眾號 ID:Hi-Linux。
「運維之美」是一個有情懷、有態度,專註於 Linux 運維相關技術文章分享的公眾號。公眾號致力於為廣大運維工作者分享各類技術文章和發佈最前沿的科技信息。公眾號的核心理念是:分享,我們認為只有分享才能使我們的團體更強大。如果你想第一時間獲取最新技術文章,歡迎關註我們!
公眾號作者 Mike,一個月薪 3000 的雜工。從事 IT 相關工作 15+ 年,熱衷於互聯網技術領域,認同開源文化,對運維相關技術有自己獨特的見解。很願意將自己積累的經驗、心得、技能與大家分享交流,篇篇乾貨不要錯過喲。如果你想聯繫到我,可關註公眾號獲取相關信息。
什麼是 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
安裝 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
規範容器鏡像。其它的組件還有 Buildah
、Skopeo
等。
Buildah
雖然 Podman
也可以支持用戶構建 Docker
鏡像,但是構建速度比較慢。並且預設情況下使用 VFS
存儲驅動程式會消耗大量磁碟空間。
Buildah
是一個專註於構建 OCI
容器鏡像的工具,Buildah
構建速度非常快並使用覆蓋存儲驅動程式,可以節約大量的空間。
Buildah
基於 fork-exec
模型,不以守護進程運行。Buildah
支持 Dockerfile
中的所有命令。你可以直接使用 Dockerfiles
來構建鏡像,並且不需要任何 root
許可權。 Buildah
也支持用自己的語法文件構建鏡像,可以允許將其他腳本語言集成到構建過程中。
下麵是一個使用 Buidah
自有語法構建的例子。
Buildah
和 Podman
之間的一個主要區別是:Podman
用於運行和管理容器, 允許我們使用熟悉的容器 CLI
命令在生產環境中管理和維護這些鏡像和容器,而 Buildah
主用於構建容器。
Skopeo
Skopeo
是一個鏡像管理工具,允許我們通過 Push
、Pull
和複製鏡像來處理 Docker
和符合 OCI
規範的鏡像。
延伸閱讀
什麼是 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
守護程式導致的啟動和安全問題,提高了容器的性能和安全。
參考文檔
- https://igene.tw/podman-intro
- https://zhuanlan.zhihu.com/p/77373246
- https://zhuanlan.zhihu.com/p/47706426
- https://xuanwo.io/2019/08/06/oci-intro/
- https://www.jianshu.com/p/62e71584d1cb
- https://kubernetes.feisky.xyz/cha-jian-kuo-zhan/cri
- https://blog.csdn.net/networken/article/details/98684527
- https://www.zcfy.cc/article/demystifying-the-open-container-initiative-oci-specifications