<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Podman 保姆級使用教程,太頂了!

          共 25464字,需瀏覽 51分鐘

           ·

          2022-03-03 20:06


          作者:華龍飛。主要負責 Red Hat 產品與技術棧的培訓交付,客戶主要涉及金融、通信、汽車、醫(yī)療等行業(yè)。熱愛并研究開源技術,熟悉 RHEL 各版本,SuSE Linux 各版本,熱衷研究云原生與 DevOps 相關技術。曾負責多家銀行數據中心 OpenStack 平臺與 VMware 平臺集成項目,某銀行數據中心主機雙核異構集成項目,某軟件開發(fā)中心 Linux 開放系統(tǒng)集成等。

          文檔說明:

          • 實驗用 OS 版本:
            • CentOS 7.9、RHEL 8.0、RHEL 8.2、Ubuntu 20.04.3 LTS
          • 實驗用 kernel 版本:
            • 3.10.0-1160.41.1.el7.x86_64
            • 4.18.0-193.el8.x86_64
            • 5.14.0-1.el7.elrepo.x86_64
          • 實驗用 Podman 版本:1.6.4、3.2.3、3.3.1
          • 實驗用 podman-compose 版本:0.1.8
          • 若未做特殊說明,以下示例均于 RHEL 8.24.18.0-193.el8.x86_64)上執(zhí)行,Podman 版本為 3.2.3
          • 該文檔中未涉及 podman 命令的基礎使用方法,可參閱 ??該文檔 加以熟悉。

          文檔目錄:

          • Podman 的特性概述
          • Podman 版本兼容性比較
          • Podman 的擴展功能
          • Podman 在不同 OS 版本中的安裝
          • Podman 的網絡實現原理(rootfull 與 rootless)
          • Podman rootless 容器用戶映射實現方式
          • Podman 的 macvlan 網絡實現
          • podman 與 podman-compose 使用示例
          • Podman 使用報錯示例
          • Podman 有待測試功能
          • 參考鏈接

          Podman 的特性概述:

          • LXC、LXD(Go 語言開發(fā))、systemd-nspawn 均可作為 Linux 容器,但缺少容器跨主機運行與應用打包的能力。
          • Docker 與 Podman 可使用容器鏡像實現應用打包發(fā)布,快速且輕量。
          • Docker 與 Podman 都使用 runC(Go 語言開發(fā))作為底層 oci-runtime
          • Docker 與 Podman 都支持 OCI Image Format(Go 語言開發(fā)),都能使用 DockerHub 上的容器鏡像,而 systemd-nspawn 無法使用它們的鏡像。
          • ?? Podman 使用 CNI(Go 語言開發(fā))作為 rootfull 容器網絡底層,實現比 Docker 網絡層略微簡單但原理相同。
          • 相對于 LXD 與 systemd-nspawn,CNI 可以避免編寫大量的網絡規(guī)則。
          • ?? 為了實現普通用戶 rootless 容器網絡,Podman 可以使用 slirp4netns 程序,避免 kernel space 中的大量 veth pair 虛擬接口的出現, 并且性能更好。
          • Docker 運行容器必須使用守護進程且使用 root 權限,存在系統(tǒng)安全問題,而 Podman 針對此問題使用以下兩個特性加以解決,如下所示:
            • Podman 支持無守護進程(no-daemon)運行容器。
            • Podman 支持普通用戶運行 rootless 容器,即,普通用戶直接運行容器無需提權具有 root 權限。
          • 雖然 Docker 與 Podman 的實現原理不同,但對于使用者而言其 CLI 十分相似,可平滑地從 Docker 過渡至 Podman。
          • Podman 的目標不是容器的編排,編排可以使用更加專業(yè)的 Kubernetes、OpenShift、Rancher 等,使用 Podman 可以更輕量的運行容器且不受 root 權限的安全問題,即便是 root 用戶也無法查看其它普通用戶空間下的容器,Podman 通過 user namespace 進行隔離。
          • ?? Podman 可使用 systemd service 單元文件直接管理容器,實現容器服務隨系統(tǒng)啟動而啟動。
          • ?? Podman 里集成了 CRIU,因此 Podman 中的容器可以在單機上熱遷移。
          • 由于 Kubernetes 將從 v1.24.x 版本后放棄使用 dockershim 接口層,容器運行時可選擇使用 Containerd 或者 CRI-O,兩者雖然均支持 OCI image 規(guī)范,但它們不是面向使用者或開發(fā)者直接管理容器或鏡像的工具,而 Podman 可直接面向使用者或開發(fā)者操作容器或鏡像。

          Podman 版本兼容性比較:

          • Podman 版本、kernel 版本與 OS 版本的兼容性將直接影響普通用戶使用 rootless 容器。

          • 如下所示,kernel 不支持 rootless 容器:

          • 普通用戶 rootless 容器兼容性比較:

            Podman 版本OS 版本kernel 版本是否支持 rootless
            1.6.4CentOS 7.93.10.0-1160.41.1.el7.x86_64no
            1.6.4CentOS 7.95.14.0-1.el7.elrepo.x86_64yes
            3.2.3RHEL 8.0/8.24.18.0-193.el8.x86_64yes

            ?? 注意:rootless 容器特性的支持取決于 kernel 的版本,不取決于 OS 與 Podman 的版本。

            • 由于 user namespace 特性在 kernel 4.9.0 之后出現,因此升級 kernel 即可解決 rootless 問題。

            • 關于 rootless 特性在 RHEL 8 中的設置,可 點擊此處[1] 參考 Red Hat 的官方配置說明。

          Podman 的擴展功能:

          • cockpit-podman 軟件包作為 cockpit 插件可集成于 Web UI 中,實現 Web UI 管理容器。

            • cockpit-podman 服務安裝與啟用:

              $?sudo?yum?install?-y?cockpit-podman
              $?sudo?systemctl?enable?--now?cockpit.socket
              $?sudo?systemctl?status?cockpit.service
              #?安裝 cockpit-podman 軟件包,并啟用 cockpit 服務。
              $?sudo?netstat?-tunlp?|?grep?9090
              #?查看?systemd?監(jiān)聽的?9090?端口是否啟用
            • 在 Web UI 中可查看并管理 podman 容器與鏡像:

          • podman-compose 旨在使用更輕量的方式實現單機容器編排,以用于替換 docker-compose,這種方式將不再依賴守護進程與 root 權限,同時可使用 rootless 容器,詳細示例見下文。

          • podman-compose 使用 Python 開發(fā),因此可直接使用 pip3 安裝該組件,或使用 rpm 軟件包方式安裝。

          • 由于 podman-compose 依然處于 dev 階段,僅作為功能測試使用,暫未受到 GA 環(huán)境支持。

          Podman 在不同 OS 版本中的安裝:

          • CentOS 7.x/8.x 或 RHEL 7.x/8.x 中:yum 命令使用 podman rpm 軟件包安裝

            $?sudo?yum?install?-y?podman-3.2.3-0.11.module_el8.4.0+942+d25aada8.x86_64
            #?安裝 podman 最新版本,低版本 podman 存在較多 bug。
            #?注意:
            #???1.?需配置?CentOS?8?的?yum?軟件源以安裝最新版的?podman?及其依賴軟件包
            #???2.?yum?安裝?podman?時也將安裝?containernetworking-plugins?軟件包
          • ?? Ubuntu 20.04.2 LTS 中:apt-get 命令使用 podman deb 軟件包安裝

            $?.?/etc/os-release
            #?查看當前的系統(tǒng)發(fā)行版
            $?echo?"deb?https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/?/"?|?sudo?tee?/etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
            $?curl?-L?"https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key"?|?sudo?apt-key?add?-
            #?添加?podman?軟件源與?apt?公鑰
            $?sudo?apt-get?update?-y
            $?sudo?apt-get?upgrade?-y
            #?更新系統(tǒng)軟件源并升級系統(tǒng)軟件包
            $?sudo?apt-get?install?-y?podman
            ??Reading?package?lists...?Done
            ??Building?dependency?tree
            ??Reading?state?information...?Done
            ??...
            ??The?following?NEW?packages?will?be?installed:
            ????catatonit?conmon?containernetworking-plugins?containers-common?criu?crun?fuse-overlayfs?fuse3?libfuse3-3?libnet1?libprotobuf-c1
            ????podman?podman-machine-cni?podman-plugins
            ??...
            #?安裝 podman 與相關的軟件包,包括 conmon、containernetworking-plugins、crun 等。

            安裝參考鏈接:

            • Podman Doc - installation[2]
            • Easy to Install Podman on Ubuntu 20.04[3]
            • podman from devel:kubic:libcontainers:stable project[4]

          Podman 的網絡實現原理(rootfull 與 rootless):

          • Podman 支持的容器網絡模式如下所示:

          • root 用戶運行 rootfull 容器網絡分析:

            • 默認情況下,rootfull 容器使用 bridge 網絡模式,并且在未創(chuàng)建任何容器前系統(tǒng)上不會自動創(chuàng)建 cni-podman0網橋,只有創(chuàng)建容器后自動生成。

            • root 用戶使用全局范圍內的 CNI 插件,podman 默認使用 bridgeportmap 插件,其配置文件如下:

              $?cat?/etc/cni/net.d/87-podman-bridge.conflist
              {
              ??"cniVersion":?"0.4.0",
              ??"name":?"podman",
              ??"plugins":?[
              ????{
              ??????"type":?"bridge",
              ??????"bridge":?"cni-podman0",
              ??????"isGateway":?true,
              ??????"ipMasq":?true,
              ??????"hairpinMode":?true,
              ??????"ipam":?{
              ????????"type":?"host-local",
              ????????"routes":?[{?"dst":?"0.0.0.0/0"?}],
              ????????"ranges":?[
              ??????????[
              ????????????{
              ??????????????"subnet":?"10.88.0.0/16",
              ??????????????"gateway":?"10.88.0.1"
              ????????????}
              ??????????]
              ????????]
              ??????}
              ????},
              ????{
              ??????"type":?"portmap",
              ??????"capabilities":?{
              ????????"portMappings":?true
              ??????}
              ????},
              ????{
              ??????"type":?"firewall"
              ????},
              ????{
              ??????"type":?"tuning"
              ????}
              ??]
              #?該配置文件位于?Podman?源碼?cni/87-podman-bridge.conflist
              #?Podman?可調用?bridge、portmap?等?CNI?插件

              $?sudo?podman?inspect??|?jq?.[0].HostConfig.NetworkMode
              ??"bridge"
              #?root?用戶創(chuàng)建的容器網絡模式
            • root 用戶創(chuàng)建具有端口映射的容器時,iptables filter 表與 nat 表規(guī)則將相應增加:

              #?-----?filter?表中創(chuàng)建新容器后的新增規(guī)則?-----
              *filter
              -A?FORWARD?-m?comment?--comment?"CNI?firewall?plugin?rules"?-j?CNI-FORWARD
              -A?CNI-FORWARD?-m?comment?--comment?"CNI?firewall?plugin?admin?overrides"?-j?CNI-ADMIN
              -A?CNI-FORWARD?-d?10.88.0.3/32?-m?conntrack?--ctstate?RELATED,ESTABLISHED?-j?ACCEPT
              #?新增規(guī)則:允許 3 層轉發(fā)目標地址為 10.88.0.3 的流量(進入容器的流量),conntrack 模塊進行連接狀態(tài)追蹤。
              #?當容器通過?MASQUERADE?對外訪問,回包再次進入容器宿主機時不再通過?DNAT?轉發(fā),而通過?conntrack
              #?記錄的連接狀態(tài)直接轉發(fā)至該規(guī)則并通過 cni-podman0?網橋進入容器。
              -A?CNI-FORWARD?-s?10.88.0.3/32?-j?ACCEPT
              #?新增規(guī)則:允許 3 層轉發(fā)源地址為 10.88.0.3 的流量(出容器的流量)。

              #?-----?nat?表中創(chuàng)建新容器后的新增規(guī)則?-----
              *nat
              -A?PREROUTING?-m?addrtype?--dst-type?LOCAL?-j?CNI-HOSTPORT-DNAT
              -A?POSTROUTING?-m?comment?--comment?"CNI?portfwd?requiring?masquerade"?-j?CNI-HOSTPORT-MASQ
              -A?POSTROUTING?-s?10.88.0.3/32?-m?comment?--comment?"name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-j?CNI-b6c5fb6c593e895d843cb5bd
              #?新增規(guī)則:來自于 10.88.0.3 容器的流量轉發(fā)至 CNI-b6c5fb6c593e895d843cb5bd 鏈
              -A?OUTPUT?-m?addrtype?--dst-type?LOCAL?-j?CNI-HOSTPORT-DNAT
              #?啟用?CNI?后即創(chuàng)建的規(guī)則,該規(guī)則接收來自本地應用的流量并轉發(fā)至?CNI-HOSTPORT-DNAT?鏈
              -A?CNI-HOSTPORT-SETMARK?-m?comment?--comment?"CNI?portfwd?masquerade?mark"?-j?MARK?--set-xmark?0x2000/0x2000
              -A?CNI-HOSTPORT-MASQ?-m?mark?--mark?0x2000/0x2000?-j?MASQUERADE
              ###?以下?6?條在創(chuàng)建新容器時同時創(chuàng)建
              -A?CNI-HOSTPORT-DNAT?-p?tcp?-m?comment?--comment?"dnat?name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-m?multiport?--dports?8843?-j?CNI-DN-b6c5fb6c593e895d843cb
              #?自定義 DNAT 鏈,發(fā)送至本地 8843 端口的流量轉發(fā)至 CNI-DN-b6c5fb6c593e895d843cb 鏈。
              -A?CNI-b6c5fb6c593e895d843cb5bd?-d?10.88.0.0/16?-m?comment?--comment?"name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-j?ACCEPT
              #?允許轉發(fā)目標網段為 10.88.0.0/16 的流量(進入容器的流量),該網段為容器所在的網絡。
              -A?CNI-b6c5fb6c593e895d843cb5bd?!?-d?224.0.0.0/4?-m?comment?--comment?"name:?\"podman\"?id:?\"2d2b3521457cb1d9b7ae6657304d05789a854e7a48916276a40da543df9aa217\""?-j?MASQUERADE
              #?MASQUERADE?出容器流量
              -A?CNI-DN-b6c5fb6c593e895d843cb?-s?10.88.0.0/16?-p?tcp?-m?tcp?--dport?8843?-j?CNI-HOSTPORT-SETMARK
              -A?CNI-DN-b6c5fb6c593e895d843cb?-s?127.0.0.1/32?-p?tcp?-m?tcp?--dport?8843?-j?CNI-HOSTPORT-SETMARK
              -A?CNI-DN-b6c5fb6c593e895d843cb?-p?tcp?-m?tcp?--dport?8843?-j?DNAT?--to-destination?10.88.0.3:443
              #?自定義?DNAT?鏈實現容器宿主機至容器的端口映射
            • ?? 示例:外部訪問容器內 Web 服務時,涉及的宿主機 iptables:

              從外部訪問容器內 Web 服務時,流量將通過 PREROUTING 鏈及自定義鏈(CNI-HOSTPORT-DNATCNI-DN-xxxxDNAT),經由 FORWARD 鏈及自定義鏈(CNI-FORWARD)的三層轉發(fā)與 cni-podman0 網橋的二層轉發(fā)進入容器,容器對外響應的流量將經過 cni-podman0 網橋轉發(fā),并經過 CNI-FORWARD 鏈與 POSTROUTING 鏈及自定義鏈(CNI-HOSTPORT-MASQ)出容器宿主機。

            • ?? 示例:直接從容器內訪問外部時,返回容器的回包將直接使用 conntrack 模塊追蹤的連接狀態(tài),流量通過 CNI-FORWARD 鏈的三層轉發(fā)與 cni-podman0 的二層轉發(fā)至容器中,即,回包進入容器宿主機不再通過CNI-HOSTPORT-DNAT鏈。

              如下所示,相關的 DNAT 鏈無流量通過(藍框),CNI-FORWARD 鏈均有流量通過(藍框)。

              ?? Kubernetes 相關問題提示:

            • 使用 iperf3 工具的容器測試不同 rootfull 容器之間的網絡性能,如下所示:

            1. 容器或 pod 通過 cni 網橋橋接的方式在 Kubernetes 或 OpenShift3 中需在計算節(jié)點(worker node)上配置 net.bridge.bridge-nf-call-iptablesnet.bridge.bridge-nf-call-iptables6 內核參數,使 cni 二層網橋可調用 iptables 的 conntrack 模塊,以解決前后端 pod 在同一節(jié)點上時,由于 pod 直連 cni 二層網橋,而二層網橋只實現二層轉發(fā),無法追蹤前后端的連接狀態(tài),造成后端 pod 向前端 pod 回包時無法處于同一連接鏈路的問題,可 點擊此處[5] 獲得更多幫助。
            2. 使用以上內核參數時,需加載 br_netfilter 內核模塊方能生效。
          • 普通用戶運行 rootless 容器網絡分析:

            • slirp4netns 程序支持 user rootless network namespace,而非通過 iptables 與 CNI 實現。

            • 普通用戶創(chuàng)建的容器網絡模式為 slirp4netns(slirp4netns 軟件包實現)。

              $?podman?inspect??|?jq?.[0].HostConfig.NetworkMode
              ??"slirp4netns"
              #?普通用戶創(chuàng)建的?rootless?容器網絡模式
            • 每個普通用戶運行 rootless 容器都將生成 slirp4netns 進程用于隔離該用戶的 network namespace,以下分別使用 godev 與 hualf 用戶運行 rootless 容器:

            • slirp4netns 實現的網絡模式與帶寬比較:

            • 使用 iperf3 工具的容器測試不同 rootless 容器之間的網絡性能,如下所示:

              對比 rootfull 容器之間的網絡性能來看,slirp4netns 實現的 rootless 容器在不同的網絡命名空間內的通信性能損耗較大,而 rootfull 容器之間的網絡性能相比前者在此次測試中高出近 5 倍。

            • 關于 slirp4netns 更加詳細的內容,請參考 Github 項目[6]

          Podman rootless 容器用戶映射實現方式:

          • Podman rootless 容器的實現核心在于解決 network namespace(NetNS) 與 user namespace(UserNS) 的問題,前文已介紹 NetNS 的實現方式,后文將介紹 UserNS 的實現方式。

          • 若要使用 rootless 容器,需確認 OS 是否開啟 user namespace 功能:

          $?sudo?sysctl?-a?|?grep?user\.max_user_namespaces
          ??user.max_user_namespaces?=?47494
          • 系統(tǒng)上每創(chuàng)建一個用戶就會在 /etc/subuid/etc/subgid 中生成對應用戶在其用戶命名空間中的映射規(guī)則,以 /etc/subuid 為例,參數以冒號分隔,每個參數含義如下所示:

            • 第一個參數(uid):用戶名稱

            • 第二個參數(loweruid):用戶命名空間中起始的映射 uid

          • 第三個參數(count):用戶命名空間內部與外部可映射 uid 數量(可理解為所有容器普通用戶的 uid 數量和)

          • 以上兩個文件允許運行進程的 uid 映射范圍,在 /proc//uid_map 中定義。

          • 可過濾容器 conmon 進程的 pid 確認每個容器中的 uid 映射情況,參見以下示例。

          • 關于以上兩個文件的具體說明可參考 newuidmapnewgidmap 命令的 man 手冊。

          • 可參考 Podman 官方推薦的命令創(chuàng)建 uid 的映射,如下所示:

            $?sudo?usermod?--add-subuids?10000-75535?$(whoami)

            #?-----?示例?-----
            $?sudo?cat?/etc/subuid
            ??appuser:10000:500
            $?sudo?cat?/etc/subgid
            ??appuser:500:50
            #?該用戶創(chuàng)建的 user namespace 中可以使用從 10000?開始的 500?個 UID 和從 500?開始的 50?個 GID 的映射。
          • ?? 示例:

            普通用戶 hualf 在 /etc/subuid 中映射為 hualf:165536:65536,說明在該用戶的用戶命名空間中可嵌套一個或多個用戶命名空間(或容器),每個容器中的 root 用戶 uid 0 都映射為 hualf 用戶的 uid 1001(運行容器進程的用戶),而容器中普通用戶的 uid 映射至宿主機的 subuid 范圍中,對于此例 subuid 范圍為 165536~231071,容器中的 uid 1 用戶映射為宿主機 uid 165536,因此容器中 admin 用戶 uid 1000 映射為宿主機 uid 166535(165536+999)。

            通過容器宿主機上每個普通用戶的用戶命名空間的 subuid 映射范圍,可分配眾多 uid 在 rootless 容器中運行應用進程。

          Podman 的 macvlan 網絡實現:

          • macvlan 作為 CNI 在 Kubernetes 與 OpenShift v4 中作為 Multus CNI 支持的額外插件類型使用愈加廣泛,集群中除了常規(guī)使用的 Flannel、Calico 等作為 slow path 的插件外,要求高性能的業(yè)務流量可使用 macvlan 直連 pod 宿主機物理網口實現 fast path

          • 為后續(xù)熟悉以上場景的實現,因此在 Podman rootfull 容器中使用 macvlan 網絡模式。

          • 關于 macvlan 的基礎知識可參考 Linux 虛擬網卡技術:Macvlan[7]

          • macvlan 特性由 Linux kernel 支持,筆者的實驗環(huán)境滿足 macvlan 的要求,請使用如下命令確定:

            $?sudo?lsmod?|?grep?macvlan
            #?若無任何返回,說明還未加載 macvlan 內核模塊。
            $?sudo?modprobe?macvlan
            #?加載 macvlan 內核模塊,若執(zhí)行報錯,說明 kernel 不支持該特性。
          • podman 與 macvlan 類型網絡的集成,如下所示:

            $?sudo?podman?network?create?-d?macvlan?-o?parent=ens33?
            ??/etc/cni/net.d/.conflist
            #?創(chuàng)建?macvlan?類型網絡
            $?sudo?podman?network?ls
            $?sudo?/opt/cni/bin/dhcp?daemon
            #?在另一個窗口中啟動 dhcp 守護進程供 macvlan 插件調用,為容器網口分配 IP 地址。
            $?sudo?podman?run?-it?--rm?\
            ??--name??--network=?\
            ??:?/bin/sh
            #?創(chuàng)建支持?macvlan?類型網絡的?rootfull?容器
          • 從與 rootfull 容器在同一廣播域的其他節(jié)點上 ping 該容器,可正常通信:

          podman 與 podman-compose 使用示例:

          • 示例 1:

            ?? 使用 podman 命令登錄 Quay 公共容器鏡像倉庫并推送鏡像:

            ?? 搜索并拉取 Red Hat 容器鏡像倉庫中的鏡像列表:

          • 示例 2:

            ?? 從頭創(chuàng)建 pod 并附加額外的容器:

            $?podman?pod?create?--name??[-p?:]
            #?使用?pause?容器鏡像從頭創(chuàng)建?pod
            #?若之后需在?pod?中創(chuàng)建使用端口映射的容器,需要在創(chuàng)建?pod?之初指定端口映射關系,無法在創(chuàng)建容器時指定,由于?pod
            #?提供了其中所有容器的共享網絡命名空間。
            #?注意:若需指定多個端口,可同時使用多個?-p 選項。
            $?podman?run?-d?--name??--pod??:
            #?創(chuàng)建容器將其附加到?pod?中
            $?podman?pod?[ps|list|ls]
            #?查看已存在的?pod
            $?podman?pod?[stop|rm]?
            #?停止或刪除 pod,將一并刪除 pod 中的所有容器。

            ?? 注意:

            ?? 隨創(chuàng)建容器時同時創(chuàng)建 pod:

            $?podman?run?-d?\
            ??--name??--pod?new:?\
            ??[-p?:]?\
            ??:
            #?隨創(chuàng)建容器時同時創(chuàng)建?pod
            $?podman?run?-d?\
            ??--name??--pod??\
            ??:
            #?在?pod?中創(chuàng)建新的容器

            如下所示,創(chuàng)建名為 nginx-docs 的容器并同時創(chuàng)建名為 docker-docs 的 pod,也可創(chuàng)建其他容器添加至 pod 中,使用該容器即可訪問 nginx-docs 容器(兩者共享網絡命名空間):

            ?? 使用 Podman 在單個 pod 中集成多容器的方法,可參考 之前發(fā)布的文檔[8],該文檔中將 Quay、MySQL 與 Redis 的單容器集成在單個 pod 中,使用 pod 的 network namespace 方便 Quay 鏡像倉庫的管理。

            1. k8s.gcr.io/pause:3.5 鏡像拉取需要科學上網。
            2. 若無法拉取,可先拉取 registry.aliyuncs.com/google_containers/pause:3.5 鏡像,再更改其 tag 即可。
          • 示例 3:

            ?? 部署并使用云原生輕量級對象存儲 MinIO Server

            ?? 注意:以上示例已將 podman 與 systemd 集成實現普通用戶的 rootless 容器開機自啟動。

            關于 MinIO Server 分布式對象存儲的詳細內容,請 參考官網[9]

          • 示例 4:

            ?? root 用戶運行 rootfull 容器:多個容器間通過 cni-podman0 網橋互相通信。

            ?? 部署 loganalyzer 管理集中式日志[10]

          • 示例 5:

            ?? 普通用戶或 root 用戶運行容器:

            ?? 同一個 pod 中的多個容器使用共享網絡命名空間,并通過 link 鏈接至指定的容器建立通信。

            ?? 使用 podman-compose 部署輕量級 Git 代碼版本控制倉庫:Gogs + PostgreSQL

            ?? 注意:可考慮如何使用 podman-compose 部署輕量級 Gitea + Drone CI 平臺

            • Run User 值:默認 git
            • Domain 值:若要從其他主機連接至 Gogs 倉庫,Domian 必須配置為容器宿主機的 IP 地址或主機名。
            • SSH Port 值:podman-compose 定義文件中對外暴露的 SSH 端口號。
            • HTTP Port 值:默認 3000 端口。
            • 關于 Gogs 項目的詳細內容可參考 Gogs GitHub 項目[12]

            • Gogs 代碼版本控制倉庫使用 Golang 語言開發(fā),可與后端 MySQL、PostgreSQL、SQLite3、TiDB 等集成。

            • 此處使用容器化部署 Gogs,并與 PostgreSQL 集成。

            • 部署用主機上必須先安裝 podman 與 podman-compose,并拉取相應容器鏡像加速部署過程,如下所示:

              ?? 注意:

              podman-compose 使用創(chuàng)建 pod 將多個容器組建成 pod 的方式進行容器編排,因此必須具有 pause 容器鏡像提供 pod 的共享網絡命名空間與掛載命名空間。

            • 使用普通用戶部署,過程如下所示:

              $?mkdir?-p?gogs-app/gogs-data/{gogs,gogs-logs,postgresql}
              #?創(chuàng)建用于存儲?gogs?與?postgresql?數據映射的目錄
              $?sudo?chown?-R?100999:100999?gogs-app/gogs-data/{gogs,gogs-logs}
              #?更改映射目錄的屬組,否則容器啟動權限報錯。
              $?getenforce
              ??Enforcing
              #?確認系統(tǒng)處于 enforcing SELinux 狀態(tài),需設置目錄映射時的標簽。
              #?也可禁用 SELinux,若禁用 SELinux,以下兩步可不執(zhí)行并且去除 podman-compose 定義文件中的?"Z"。
              $?sudo?semanage?port?-a?-t?http_port_t?-p?tcp?10800
              $?sudo?semanage?port?-a?-t?ssh_port_t?-p?tcp?10022
              #?添加自定義端口至 SELinux 數據庫中,否則由于權限問題無法訪問并安裝 Gogs。
              $?vim?gogs-app/gogs-postgres-podman-compose.yaml
              #?如下所示?podman-compose?的?yaml?定義文件
              version:?"3"
              services:
              ??postgresql:
              ????image:?docker.io/library/postgres:14.1-bullseye
              ????container_name:?"gogs-postgresql"
              ????volumes:
              ??????-?"./gogs-data/postgresql:/var/lib/postgresql:Z"
              ????environment:
              ??????-?"POSTGRES_USER=gogs"
              ??????-?"POSTGRES_PASSWORD=redhat"
              ??????-?"POSTGRES_DB=gogs"
              ????ports:
              ??????-?"5432:5432"

              ??gogs:
              ????image:?docker.io/gogs/gogs:0.12
              ????container_name:?"gogs"
              ????volumes:
              ??????-?"./gogs-data/gogs:/data:Z"
              ??????-?"./gogs-data/gogs-logs:/app/gogs/log:Z"
              ????ports:
              ??????-?"10022:22"
              ??????-?"10800:3000"
              ????links:
              ??????-?postgresql
              $?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?up
              #?啟動 Gogs 與 PostgreSQL 容器,并指定項目名稱。
              #?若不指定項目名稱,項目默認為 yaml 文件所在的目錄名稱。
              #?首次啟動容器時,所有的啟動與運行日志將打印至終端屏幕上,該終端不可關閉,直至關閉所有服務容器后將自動退出。
              $?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?ps
              ??using?podman?version:?podman?version?3.2.3
              ??podman?ps?-a?--filter?label=io.podman.compose.project=gogs-app
              ??CONTAINER?ID??IMAGE?????????????????????????????????????COMMAND???????????????CREATED??????STATUS??????????PORTS???????????????????????????????????????????????????????????????????NAMES
              ??2bed211ffe60??docker.io/library/postgres:14.1-bullseye??postgres??????????????6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs-postgresql
              ??2c7d0de4b0a0??docker.io/gogs/gogs:0.12??????????????????/bin/s6-svscan?/a...??6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs
              ??0
              #?查看?podman-compose?管理的容器服務
              $?podman?ps
              ??CONTAINER?ID??IMAGE?????????????????????????????????????COMMAND???????????????CREATED??????STATUS??????????PORTS???????????????????????????????????????????????????????????????????NAMES
              ??b6df150a3a49??k8s.gcr.io/pause:3.5????????????????????????????????????????????6?hours?ago??Up?6?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??c3a10da46f18-infra
              ??2bed211ffe60??docker.io/library/postgres:14.1-bullseye??postgres??????????????6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs-postgresql
              ??2c7d0de4b0a0??docker.io/gogs/gogs:0.12??????????????????/bin/s6-svscan?/a...??6?hours?ago??Up?3?hours?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??gogs
              #?查看正在運行的容器,包含 infra 容器。
            • 所有容器正常運行后,使用 http://<容器宿主機 IP 地址>:10800 訪問 Gogs 安裝界面,需填入的值參考如下:

            • Web 頁面中最后需設置 Gogs 管理員賬號以完成安裝。

            • 安裝完成后,使用管理員賬號登錄或重新注冊新賬號登錄與使用。

            • 如下所示,使用 devops 用戶創(chuàng)建新代碼庫并完成 commit 提交:

            • 如需關閉 Gogs 代碼倉庫,請使用以下方法停止 gogs 與 postgresql 容器服務即可:

              $?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?stop?gogs?postgresql
              ??using?podman?version:?podman?version?3.2.3
              ??podman?stop?-t?10?gogs
              ??gogs
              ??0
              ??podman?stop?-t?10?gogs-postgresql
              ??gogs-postgresql
              ??0
              $?podman?ps
              ??CONTAINER?ID??IMAGE?????????????????COMMAND?????CREATED???????STATUS?????????????PORTS???????????????????????????????????????????????????????????????????NAMES
              ??b6df150a3a49??k8s.gcr.io/pause:3.5??????????????30?hours?ago??Up?39?minutes?ago??0.0.0.0:10022->22/tcp,?0.0.0.0:10800->3000/tcp,?0.0.0.0:5432->5432/tcp??c3a10da46f18-infra

              ?? 注意:

              切不可直接使用 podman-compose 命令的 down 子命令,該子命令將所有相關的容器與 pod 全部刪除,pod 刪除后無法將其中的各容器映射至宿主機對應的目錄中,即使原始數據依然保留于目錄中。

            • 重新啟動 Gogs 代碼倉庫的方式,如下所示:

              $?podman-compose?-f?gogs-app/gogs-postgres-podman-compose.yaml?--project?gogs-app?start?gogs?postgresql
              ??using?podman?version:?podman?version?3.2.3
              ??podman?start?gogs
              ??gogs
              ??0
              ??podman?start?gogs-postgresql
              ??gogs-postgresql
              ??0
            • 以上 gogs-postgres-podman-compose.yaml 文件可參考 此處[13]

            • 關于 podman-compose 的安裝可參考 GitHub 項目[11]

          Podman 報錯示例:

          • podman 容器鏡像倉庫的配置方式:

            • 全局配置:/etc/containers/registries.conf
            • 局部配置:$HOME/.config/containers/registroes.conf
          • 若 podman 安裝后在以上配置中未唯一指定的容器鏡像倉庫,那么在拉取容器鏡像時,將交互式提示用戶選擇容器鏡像倉庫。

          • 示例 1:

            ?? podman v3.2.3 登錄 Harbor v1.8.1 身份認證報錯:

            $?podman?login?harbor.domain12.example.com:8880
            ??Username:?admin
            ??Password:?redhat
            ??Error:?authenticating?creds?for?"harbor.domain12.example.com:8880":?error?pinging?docker?registry
            ??harbor.domain12.example.com:8880:?Get?"https://harbor.domain12.example.com:8880/v2/":
            ??http:?server?gave?HTTP?response?to?HTTPS?client
            # Podman 未做任何配置登錄 Harbor 報錯,該 Harbor 容器鏡像倉庫未配置 TLS 加密傳輸。
            #?報錯顯示 Harbor 響應 HTTP 請求,而 Podman 發(fā)送 HTTPS 請求登錄。
            #?因此,將 Podman 配置為發(fā)送 HTTP 請求的客戶端。

            ?? 解決方式一:

            $?podman?login?--tls-verify=false?harbor.domain12.example.com:8880
            ??Username:?admin
            ??Password:?redhat
            ??Login?Succeeded!
            # Podman 未進行任何配置,直接使用?--tls-verify=false 選項即可認證登錄。

            ?? 解決方式二:

            $?mkdir?-p?~/.config/containers/?&&?cd?~/.config/containers/
            #?創(chuàng)建普通用戶?rootless?容器的目錄
            $?vim?~/.config/containers/registries.conf
            ??unqualified-search-registries?=?['harbor.domain12.example.com:8880']

            ??[[registry]]
            ??location?=?"harbor.domain12.example.com:8880"
            ??insecure?=?true
            ??#?If?true,?unencrypted?HTTP?as?well?as?TLS?connections?with?untrusted
            ??#?certificates?are?allowed.
            ??block?=?false
            #?配置未加密傳輸的?Harbor?容器鏡像倉庫的主機名與端口

            $?podman?login?--log-level=debug?harbor.domain12.example.com:8880
            ??INFO[0000]?podman?filtering?at?log?level?debug
            ??DEBU[0000]?Called?login.PersistentPreRunE(podman?login?--log-level=debug?harbor.domain12.example.com:8880)
            ??DEBU[0000]?overlay?storage?already?configured?with?a?mount-program
            ??DEBU[0000]?Merged?system?config?"/usr/share/containers/containers.conf"
            ??DEBU[0000]?overlay?storage?already?configured?with?a?mount-program
            ??DEBU[0000]?Using?conmon:?"/usr/bin/conmon"
            ??...
            ??DEBU[0000]?Using?OCI?runtime?"/usr/bin/runc"
            ??DEBU[0000]?Default?CNI?network?name?podman?is?unchangeable
            ??INFO[0000]?Setting?parallel?job?count?to?13
            ??DEBU[0000]?Loading?registries?configuration?"/home/kiosk/.config/containers/registries.conf"
            ??DEBU[0000]?Loading?registries?configuration?"/etc/containers/registries.conf.d/000-shortnames.conf"
            ??DEBU[0000]?Loading?registries?configuration?"/etc/containers/registries.conf.d/001-rhel-shortnames.conf"
            ??DEBU[0000]?Loading?registries?configuration?"/etc/containers/registries.conf.d/002-rhel-shortnames-overrides.conf"
            ??DEBU[0000]?No?credentials?for?harbor.domain12.example.com:8880?found
            ??Username:?admin
            ??Password:?#?交互式輸入登錄密碼
            ??DEBU[0004]?Looking?for?TLS?certificates?and?private?keys?in?/etc/docker/certs.d/harbor.domain12.example.com:8880
            ??DEBU[0004]?GET?https://harbor.domain12.example.com:8880/v2/
            ??DEBU[0004]?Ping?https://harbor.domain12.example.com:8880/v2/?err?Get?"https://harbor.domain12.example.com:8880/v2/":?http:
            ??server?gave?HTTP?response?to?HTTPS?client?(&url.Error{Op:"Get",?URL:"https://harbor.domain12.example.com:8880/v2/",
            ??Err:(*errors.errorString)(0xc000590030)})
            ??...
            ??DEBU[0004]?GET?http://harbor.domain12.example.com:8880/service/token?account=admin&service=harbor-registry
            ??DEBU[0004]?GET?http://harbor.domain12.example.com:8880/v2/
            ??DEBU[0004]?Stored?credentials?for?harbor.domain12.example.com:8880?in?credential?helper?containers-auth.json
            ??Login?Succeeded!
            ??DEBU[0004]?Called?login.PersistentPostRunE(podman?login?--log-level=debug?harbor.domain12.example.com:8880)
            #?Podman?默認使用?TLS?加密傳輸
            #?以上配置文件將使 Podman 以 HTTP 方式認證登錄 Harbor。
          • 示例 2:

            ?? podman v3.2.3 推送容器鏡像至 Harbor v1.8.1 中顯示 "不完整":

            $?podman?push?harbor.domain12.example.com:8880/library/apache-rhce8.2-alpine:1.0
            ??Getting?image?source?signatures
            ??Copying?blob?551db21ded82?skipped:?already?exists
            ??Copying?blob?8213d0880f11?skipped:?already?exists
            ??Copying?blob?e2eb06d8af82?skipped:?already?exists
            ??...
            ??Copying?blob?05e56f8d5aae?skipped:?already?exists
            ??Copying?blob?631e8a8040bb?skipped:?already?exists
            ??Copying?blob?dedba5c062fc?skipped:?already?exists
            ??Copying?blob?0e609f35aa06?[--------------------------------------]?0.0b?/?0.0b
            ??Copying?config?34f32c2e7a?[======================================]?10.0KiB?/?10.0KiB
            ??Writing?manifest?to?image?destination
            ??Storing?signatures

            從推送的返回結果顯示,具有 2 層容器鏡像層似乎未推送成功,但將該鏡像從 Harbor 中拉取并重新運行容器后,容器能正常提供服務,因此最后 2 層鏡像層實際推送成功。

          • 示例 3:

            ?? 容器鏡像無任何運行或退出狀態(tài)容器占用,但依然無法刪除鏡像,可嘗試使用 --force 選項將其強制刪除。

          • 示例 4:

            ?? 由于從 dockerbub 上直接拉取的鏡像為 docker image format,無法使用 podman commit 命令提交為新的容器鏡像,該命令對于 -m 選項不能對 docker image format 鏡像生效,默認只支持 OCI image format,因此使用 -m 選項對容器執(zhí)行提交時需強制指定 -f docker 才能生效。

            ?? 注意:可使用 skopeo 工具轉換 docker image format 與 OCI image format。

          • 示例 5:

            ?? podman 運行 rootfull 或 rootless busybox 容器后,ping 外網報錯權限問題無法 ping 通外網,但使用其他工具可與外網通信,通過 該文檔[14] 中可知,ping 命令對capability敏感,容器可能缺少 CAP_NET_RAWcapability 無法通過宿主機 ping 通外網。

            ?? 當然,運行容器時指定 --privileged 選項可使容器獲得與宿主機 root 用戶同樣的與宿主機交互的權限能力,但賦予的權限過高,應當壓制該權限,更好的選擇是對運行容器添加適當的 Linux capabilities

          Podman 有待測試功能:

          • 前文所述,使用 podman pod 命令或使用 podman-compose 組件單機編排容器,而且 Podman 支持 podman play kube 命令基于 YAML 資源定義文件創(chuàng)建 pod,該方法類似 Kubernetes 或 OpenShift,有待測試。
          • Podman 日志驅動目前只支持 k8s-filejournaldnone,暫時不支持容器日志的 JSON格式輸出,因此不能與日志收集引擎 fluentd 集成,由其實現 ELK/EFK 集中式的存儲、索引等。
          • Podman 與 Linux capabilities 的關系與應用在最后一個示例中有所提及,但更全面的關系有待測試。

          參考鏈接:

          • Reintroduction of Podman[15]
          • Using pods with Podman on Fedora[16]
          • Configuring container networking with Podman[17]
          • RedHat docs - Building, running, and managing Linux containers on Red Hat Enterprise Linux 8[18]
          • 容器安全拾遺 - Rootless Container 初探[19]
          • Documentation for /proc/sys/user/[20]
          • docker docs - Overview of Docker Compose[21]
          • CNI docs - firewall plugin[22]
          • CNI docs - Port-mapping plugin[23]
          • https://fossies.org/linux/podman/docs/tutorials/basic_networking.md

          引用鏈接

          [1]

          點擊此處: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/assembly_starting-with-containers_building-running-and-managing-containers#proc_setting-up-rootless-containers_assembly_starting-with-containers

          [2]

          Podman Doc - installation: https://podman.io/getting-started/installation

          [3]

          Easy to Install Podman on Ubuntu 20.04: https://www.hostnextra.com/kb/easy-to-install-podman-on-ubuntu-20-04/

          [4]

          podman from devel:kubic:libcontainers:stable project: https://software.opensuse.org//download.html?project=devel%3Akubic%3Alibcontainers%3Astable&package=podman

          [5]

          點擊此處: https://imroc.cc/k8s/faq/why-enable-bridge-nf-call-iptables/

          [6]

          Github 項目: https://github.com/rootless-containers/slirp4netns

          [7]

          Linux 虛擬網卡技術:Macvlan: https://mp.weixin.qq.com/s?__biz=MzU1MzY4NzQ1OA==&mid=2247484064&idx=1&sn=ffd745069b6c4aeac0589de00467b2f2&chksm=fbee426dcc99cb7bdf26f5e6a21bbeaebba7ccd384a02f850d4461ea92331ed140edf98ffaec&mpshare=1&scene=1&srcid=03049MKwF55OVgEZ4OCH39wd&sharer_sharetime=1583337046541&sharer_shareid=8eaca72194dae7b3d51d5c708436eee4#rd

          [8]

          之前發(fā)布的文檔: https://jsdelivr.fuckcloudnative.io/gh/Alberthua-Perl/tech-docs@master/Red%20Hat%20Quay%20v3%20registry%E5%8E%9F%E7%90%86%E4%B8%8E%E5%AE%9E%E7%8E%B0.md

          [9]

          參考官網: https://min.io/

          [10]

          部署 loganalyzer 管理集中式日志: https://github.com/Alberthua-Perl/scripts-confs/tree/master/deploy-rsyslog-viewer

          [11]

          GitHub 項目: https://github.com/containers/podman-compose

          [12]

          Gogs GitHub 項目: https://github.com/gogs/gogs

          [13]

          此處: https://github.com/Alberthua-Perl/dockerfile-s2i-demo/blob/master/gogs-postgres-compose/gogs-postgres-podman-compose.yaml

          [14]

          該文檔: https://www.redhat.com/sysadmin/container-networking-podman

          [15]

          Reintroduction of Podman: https://projectatomic.io/blog/2018/02/reintroduction-podman/

          [16]

          Using pods with Podman on Fedora: https://fedoramagazine.org/podman-pods-fedora-containers/

          [17]

          Configuring container networking with Podman: https://www.redhat.com/sysadmin/container-networking-podman

          [18]

          RedHat docs - Building, running, and managing Linux containers on Red Hat Enterprise Linux 8: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/index

          [19]

          容器安全拾遺 - Rootless Container 初探: https://developer.aliyun.com/article/700923

          [20]

          Documentation for /proc/sys/user/: https://www.kernel.org/doc/html/latest/admin-guide/sysctl/user.html

          [21]

          docker docs - Overview of Docker Compose: https://docs.docker.com/compose/

          [22]

          CNI docs - firewall plugin: https://www.cni.dev/plugins/current/meta/firewall/

          [23]

          CNI docs - Port-mapping plugin: https://www.cni.dev/plugins/current/meta/firewall/

          原文鏈接:https://github.com/Alberthua-Perl/tech-docs/blob/master/Podman%20%E5%AE%B9%E5%99%A8%E4%BD%BF%E7%94%A8%E4%B8%8E%E5%8E%9F%E7%90%86.md


          你可能還喜歡

          點擊下方圖片即可閱讀

          jsDelivr 備案被吊銷后,網頁靜態(tài)資源何去何從

          云原生是一種信仰???

          關注公眾號

          后臺回復?k8s?獲取史上最方便快捷的 Kubernetes 高可用部署工具,只需一條命令,連 ssh 都不需要!



          點擊?"閱讀原文"?獲取更好的閱讀體驗!


          發(fā)現朋友圈變“安靜”了嗎?



          瀏覽 362
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  萝莉操逼视频 | 强伦人妻一区二区三区视频 | 久草青娱乐小说在线视频 | 亚洲性爱小视频 | 国产精品久久久久久中文字 |