<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>

          容器與Pod到底有什么區(qū)別和聯(lián)系?

          共 895字,需瀏覽 2分鐘

           ·

          2022-04-11 16:43

          點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)??


          容器本可以成為輕量級(jí)虛擬機(jī)的替代品。但是,由于 Docker/OCI 的標(biāo)準(zhǔn)化,最廣泛使用的容器形式是每個(gè)容器只有一個(gè)進(jìn)程服務(wù)。這種方法有很多優(yōu)點(diǎn)——增加隔離性、簡(jiǎn)化水平擴(kuò)展、更高的可重用性等。但是,它也有一個(gè)很大的缺點(diǎn)——正常情況下,虛擬(或物理)機(jī)器很少只運(yùn)行一個(gè)服務(wù)。

          雖然 Docker 試圖提供一些變通方法來(lái)創(chuàng)建多服務(wù)容器,但 Kubernetes 邁出了更大膽的一步,并選擇了一組稱為 Pod 的內(nèi)聚容器作為最小的可部署單元。

          幾年前,當(dāng)我偶然發(fā)現(xiàn) Kubernetes 時(shí),我之前的虛擬機(jī)和裸機(jī)經(jīng)驗(yàn)讓我很快就了解了 Pod。

          剛開(kāi)始接觸 Kubernetes 時(shí),你學(xué)到的第一件事就是每個(gè) Pod 都有一個(gè)唯一的 IP 和主機(jī)名,并且在同一個(gè) Pod 中,容器可以通過(guò) localhost 相互通信。所以,顯而易見(jiàn),一個(gè) Pod 就像一個(gè)微型的服務(wù)器。

          但是,過(guò)段時(shí)間,你會(huì)發(fā)現(xiàn) Pod 中的每個(gè)容器都有一個(gè)隔離的文件系統(tǒng),并且從一個(gè)容器內(nèi)部,你看不到在同一 Pod 的其他容器中運(yùn)行的進(jìn)程。好吧!也許 Pod 不是一個(gè)微型的服務(wù)器,而只是一組具有共享網(wǎng)絡(luò)堆棧的容器。

          但隨后你會(huì)了解到,Pod 中的容器可以通過(guò)共享內(nèi)存進(jìn)行通信!所以,在容器之間,網(wǎng)絡(luò)命名空間不是唯一可以共享的東西……

          基于最后的發(fā)現(xiàn),所以,我決定深入了解:

          • Pod 是如何在底層實(shí)現(xiàn)的

          • Pod 和 Container 之間的實(shí)際區(qū)別是什么

          • 如何使用 Docker 創(chuàng)建 Pod

          在此過(guò)程中,我希望它能幫助我鞏固我的 Linux、Docker 和 Kubernetes 技能。


          ?
          1?
          探索 Container


          OCI 運(yùn)行時(shí)規(guī)范并不將容器實(shí)現(xiàn)僅限于 Linux 容器,即使用 namespace 和 cgroup 實(shí)現(xiàn)的容器。但是,除非另有明確說(shuō)明,否則本文中的容器一詞指的是這種相當(dāng)傳統(tǒng)的形式。

          設(shè)置實(shí)驗(yàn)環(huán)境(playground)

          在了解構(gòu)成容器的 namespace 和 cgroups 之前,讓我們快速設(shè)置一個(gè)實(shí)驗(yàn)環(huán)境:

          $?cat?>?Vagrantfile?<#?-*-?mode:?ruby?-*-
          #?vi:?set?ft=ruby?:

          Vagrant.configure("2")?do?|config|
          ??config.vm.box?=?"debian/buster64"
          ??config.vm.hostname?=?"docker-host"
          ??config.vm.define?"docker-host"
          ??config.vagrant.plugins?=?['vagrant-vbguest']

          ??config.vm.provider?"virtualbox"?do?|vb|
          ????vb.cpus?=?2
          ????vb.memory?=?"2048"
          ??end

          ??config.vm.provision?"shell",?inline:?<<-SHELL
          ????apt-get?update
          ????apt-get?install?-y?curl?vim
          ??SHELL

          ??config.vm.provision?"docker"
          end
          EOF

          $?vagrant?up
          $?vagrant?ssh

          最后讓我們啟動(dòng)一個(gè)容器:

          $?docker?run?--name?foo?--rm?-d?--memory='512MB'?--cpus='0.5'?nginx

          探索容器的 namespace

          首先我們來(lái)看一下,當(dāng)容器啟動(dòng)后,哪些隔離原語(yǔ)(primitives)被創(chuàng)建了:

          #?Look?up?the?container?in?the?process?tree.
          $?ps?auxf
          USER???????PID??...??COMMAND
          ...
          root??????4707???????/usr/bin/containerd-shim-runc-v2?-namespace?moby?-id?cc9466b3e...
          root??????4727????????\_?nginx:?master?process?nginx?-g?daemon?off;
          systemd+??4781????????????\_?nginx:?worker?process
          systemd+??4782????????????\_?nginx:?worker?process

          #?Find?the?namespaces?used?by?4727?process.
          $?sudo?lsns
          ????????NS?TYPE???NPROCS???PID?USER????COMMAND
          ...
          4026532157?mnt?????????3??4727?root????nginx:?master?process?nginx?-g?daemon?off;
          4026532158?uts?????????3??4727?root????nginx:?master?process?nginx?-g?daemon?off;
          4026532159?ipc?????????3??4727?root????nginx:?master?process?nginx?-g?daemon?off;
          4026532160?pid?????????3??4727?root????nginx:?master?process?nginx?-g?daemon?off;
          4026532162?net?????????3??4727?root????nginx:?master?process?nginx?-g?daemon?off;

          我們可以看到用于隔離以上容器的命名空間是以下這些:

          • mnt(掛載):容器有一個(gè)隔離的掛載表。

          • uts(Unix 時(shí)間共享):容器擁有自己的 hostname 和 domain。

          • ipc(進(jìn)程間通信):容器內(nèi)的進(jìn)程可以通過(guò)系統(tǒng)級(jí) IPC 和同一容器內(nèi)的其他進(jìn)程進(jìn)行通信。

          • pid(進(jìn)程 ID):容器內(nèi)的進(jìn)程只能看到在同一容器內(nèi)或擁有相同的 PID 命名空間的其他進(jìn)程。

          • net(網(wǎng)絡(luò)):容器擁有自己的網(wǎng)絡(luò)堆棧。

          注意,用戶(user)命名空間沒(méi)有被使用,OCI 運(yùn)行時(shí)規(guī)范提及了對(duì)用戶命名空間的支持。不過(guò),雖然 Docker 可以將此命名空間用于其容器,但由于固有的限制,它默認(rèn)情況下沒(méi)有使用。因此,容器中的 root 用戶很可能是主機(jī)系統(tǒng)中的 root 用戶。謹(jǐn)防!

          另一個(gè)沒(méi)有出現(xiàn)在這里的命名空間是 cgroup。我花了一段時(shí)間才理解 cgroup 命名空間與 cgroups 機(jī)制(mechanism)的不同。Cgroup 命名空間僅提供一個(gè)容器的 cgroup 層次結(jié)構(gòu)的孤立視圖。同樣,Docker 也支持將容器放入私有 cgroup 命名空間,但默認(rèn)情況下沒(méi)有這么做。

          探索容器的 cgroups

          Linux 命名空間可以讓容器中的進(jìn)程認(rèn)為自己是在一個(gè)專用的機(jī)器上運(yùn)行。但是,看不到別的進(jìn)程并不意味著不會(huì)受到其他進(jìn)程的影響。一些耗資源的進(jìn)程可能會(huì)意外的過(guò)多消耗宿主機(jī)上面共享的資源。

          這時(shí)候就需要 cgroups 的幫助!

          可以通過(guò)檢查 cgroup 虛擬文件系統(tǒng)中的相應(yīng)子樹(shù)來(lái)查看給定進(jìn)程的 cgroups 限制。Cgroupfs 通常被掛在?/sys/fs/cgroup 目錄,并且進(jìn)程特定相關(guān)的部分可以在?/proc//cgroup 中查看:

          PID=$(docker?inspect?--format?'{{.State.Pid}}'?foo)

          #?Check?cgroupfs?node?for?the?container?main?process?(4727).
          $?cat?/proc/${PID}/cgroup
          11:freezer:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          10:blkio:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          9:rdma:/
          8:pids:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          7:devices:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          6:cpuset:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          5:cpu,cpuacct:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          4:memory:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          3:net_cls,net_prio:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          2:perf_event:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          1:name=systemd:/docker/cc9466b3eb67ca374c925794776aad2fd45a34343ab66097a44594b35183dba0
          0::/system.slice/containerd.service

          似乎 Docker 使用?/docker/?模式。好吧,不管怎樣:

          ID=$(docker?inspect?--format?'{{.Id}}'?foo)

          #?Check?the?memory?limit.
          $?cat?/sys/fs/cgroup/memory/docker/${ID}/memory.limit_in_bytes
          536870912??#?Yay!?It's?the?512MB?we?requested!

          #?See?the?CPU?limits.
          ls?/sys/fs/cgroup/cpu/docker/${ID}

          有趣的是在不明確設(shè)置任何資源限制的情況下啟動(dòng)容器都會(huì)配置一個(gè) cgroup。實(shí)際中我沒(méi)有檢查過(guò),但我的猜測(cè)是默認(rèn)情況下,CPU 和 RAM 消耗不受限制,Cgroups 可能用來(lái)限制從容器內(nèi)部對(duì)某些設(shè)備的訪問(wèn)。

          這是我在調(diào)查后腦海中呈現(xiàn)的容器:


          ?
          2?
          探索 Pod


          現(xiàn)在,讓我們來(lái)看看 Kubernetes Pod。與容器一樣,Pod 的實(shí)現(xiàn)可以在不同的 CRI 運(yùn)行時(shí)(runtime)之間變化。例如,當(dāng) Kata 容器被用來(lái)作為一個(gè)支持的運(yùn)行時(shí)類時(shí),某些 Pod 可以就是真實(shí)的虛擬機(jī)了!并且正如預(yù)期的那樣,基于 VM 的 Pod 與傳統(tǒng) Linux 容器實(shí)現(xiàn)的 Pod 在實(shí)現(xiàn)和功能方面會(huì)有所不同。

          為了保持容器和 Pod 之間公平比較,我們會(huì)在使用 ContainerD/Runc 運(yùn)行時(shí)的 Kubernetes 集群上進(jìn)行探索。這也是 Docker 在底層運(yùn)行容器的機(jī)制。

          設(shè)置實(shí)驗(yàn)環(huán)境(playground)

          這次我們使用基于 VirtualBox driver 和 Containd 運(yùn)行時(shí)的 minikube 來(lái)設(shè)置實(shí)驗(yàn)環(huán)境。要快速安裝 minikube 和 kubectl,我們可以使用 Alex Ellis 編寫(xiě)的 arkade 工具:

          #?Install?arkade?()
          $?curl?-sLS?https://get.arkade.dev?|?sh

          $?arkade?get?kubectl?minikube

          $?minikube?start?--driver?virtualbox?--container-runtime?containerd

          實(shí)驗(yàn)的 Pod,可以按照下面的方式設(shè)置:

          $?kubectl?--context=minikube?apply?-f?-?<apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?foo
          spec:
          ??containers:
          ????-?name:?app
          ??????image:?docker.io/kennethreitz/httpbin
          ??????ports:
          ????????-?containerPort:?80
          ??????resources:
          ????????limits:
          ??????????memory:?"256Mi"
          ????-?name:?sidecar
          ??????image:?curlimages/curl
          ??????command:?["/bin/sleep",?"3650d"]
          ??????resources:
          ????????limits:
          ??????????memory:?"128Mi"
          EOF

          探索 Pod 的容器

          實(shí)際的 Pod 檢查應(yīng)在 Kubernetes 集群節(jié)點(diǎn)上進(jìn)行:

          $?minikube?ssh

          讓我們看看那里 Pod 的進(jìn)程:

          $?ps?auxf
          USER???????PID??...??COMMAND
          ...
          root??????4947?????????\_?containerd-shim?-namespace?k8s.io?-workdir?/mnt/sda1/var/lib/containerd/...
          root??????4966?????????????\_?/pause
          root??????4981?????????\_?containerd-shim?-namespace?k8s.io?-workdir?/mnt/sda1/var/lib/containerd/...
          root??????5001?????????????\_?/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          root??????5016?????????????????\_?/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          root??????5018?????????\_?containerd-shim?-namespace?k8s.io?-workdir?/mnt/sda1/var/lib/containerd/...
          100???????5035?????????????\_?/bin/sleep?3650d

          基于運(yùn)行的時(shí)間,上述三個(gè)進(jìn)程組很有可能是在 Pod 啟動(dòng)期間創(chuàng)建。這很有意思,因?yàn)樵谇鍐挝募?,只有兩個(gè)容器,httpbin 和 sleep。

          可以使用名為 ctr 的 ContainerD 命令行來(lái)交叉檢查上述的發(fā)現(xiàn):

          $?sudo?ctr?--namespace=k8s.io?containers?ls
          CONTAINER??????IMAGE???????????????????????????????????RUNTIME
          ...
          097d4fe8a7002??docker.io/curlimages/curl@sha256:1a220??io.containerd.runtime.v1.linux
          ...
          dfb1cd29ab750??docker.io/kennethreitz/httpbin:latest???io.containerd.runtime.v1.linux
          ...
          f0e87a9330466??k8s.gcr.io/pause:3.1????????????????????io.containerd.runtime.v1.linux

          的確是三個(gè)容器被創(chuàng)建了。同時(shí),使用另一個(gè)和 CRI 運(yùn)行時(shí)監(jiān)控的命令行 crictl 檢測(cè)發(fā)現(xiàn),僅僅只有兩個(gè)容器:

          $?sudo?crictl?ps
          CONTAINER??????IMAGE??????????CREATED????????????STATE????NAME?????ATTEMPT??POD?ID
          097d4fe8a7002??bcb0c26a91c90??About?an?hour?ago??Running??sidecar??0????????f0e87a9330466
          dfb1cd29ab750??b138b9264903f??About?an?hour?ago??Running??app??????0????????f0e87a9330466

          但是注意,上述的 POD ID 字段和 ctr 輸出的 pause:3.1 容器 id 一致。好吧,看上去這個(gè) Pod 是一個(gè)輔助容器。所以,它有什么用呢?

          我還沒(méi)有注意到在 OCI 運(yùn)行時(shí)規(guī)范中有和 Pod 相對(duì)應(yīng)的東西。因此,當(dāng)我對(duì) Kubernetes API 規(guī)范提供的信息不滿意時(shí),我通常直接進(jìn)入 Kubernetes Container Runtime 接口(CRI)Protobuf 文件中查找相應(yīng)的信息:

          //?kubelet?expects?any?compatible?container?runtime
          //?to?implement?the?following?gRPC?methods:

          service?RuntimeService?{
          ????...
          ????rpc?RunPodSandbox(RunPodSandboxRequest)?returns?(RunPodSandboxResponse)?{}????
          ????rpc?StopPodSandbox(StopPodSandboxRequest)?returns?(StopPodSandboxResponse)?{}????
          ????rpc?RemovePodSandbox(RemovePodSandboxRequest)?returns?(RemovePodSandboxResponse)?{}????
          ????rpc?PodSandboxStatus(PodSandboxStatusRequest)?returns?(PodSandboxStatusResponse)?{}
          ????rpc?ListPodSandbox(ListPodSandboxRequest)?returns?(ListPodSandboxResponse)?{}

          ????rpc?CreateContainer(CreateContainerRequest)?returns?(CreateContainerResponse)?{}
          ????rpc?StartContainer(StartContainerRequest)?returns?(StartContainerResponse)?{}????
          ????rpc?StopContainer(StopContainerRequest)?returns?(StopContainerResponse)?{}????
          ????rpc?RemoveContainer(RemoveContainerRequest)?returns?(RemoveContainerResponse)?{}
          ????rpc?ListContainers(ListContainersRequest)?returns?(ListContainersResponse)?{}????
          ????rpc?ContainerStatus(ContainerStatusRequest)?returns?(ContainerStatusResponse)?{}????
          ????rpc?UpdateContainerResources(UpdateContainerResourcesRequest)?returns?(UpdateContainerResourcesResponse)?{}????
          ????rpc?ReopenContainerLog(ReopenContainerLogRequest)?returns?(ReopenContainerLogResponse)?{}

          ????//?...????
          }

          message?CreateContainerRequest?{
          ????//?ID?of?the?PodSandbox?in?which?the?container?should?be?created.
          ????string?pod_sandbox_id?=?1;
          ????//?Config?of?the?container.
          ????ContainerConfig?config?=?2;
          ????//?Config?of?the?PodSandbox.?This?is?the?same?config?that?was?passed
          ????//?to?RunPodSandboxRequest?to?create?the?PodSandbox.?It?is?passed?again
          ????//?here?just?for?easy?reference.?The?PodSandboxConfig?is?immutable?and
          ????//?remains?the?same?throughout?the?lifetime?of?the?pod.
          ????PodSandboxConfig?sandbox_config?=?3;
          }

          所以,Pod 實(shí)際上就是由沙盒以及在沙盒中運(yùn)行的容器組成的。沙盒管理 Pod 中所有容器的常用資源,pause 容器會(huì)在 RunPodSandbox() 調(diào)用中被啟動(dòng)。簡(jiǎn)單的互聯(lián)網(wǎng)搜索就發(fā)現(xiàn)了該容器僅僅是一個(gè) idle 進(jìn)程。

          探索 Pod 的命名空間

          下面就是集群節(jié)點(diǎn)上的命名空間:

          $?sudo?lsns
          ????????NS?TYPE???NPROCS???PID?USER????????????COMMAND
          4026532614?net?????????4??4966?root????????????/pause
          4026532715?mnt?????????1??4966?root????????????/pause
          4026532716?uts?????????4??4966?root????????????/pause
          4026532717?ipc?????????4??4966?root????????????/pause
          4026532718?pid?????????1??4966?root????????????/pause
          4026532719?mnt?????????2??5001?root????????????/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          4026532720?pid?????????2??5001?root????????????/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          4026532721?mnt?????????1??5035?100?????????????/bin/sleep?3650d
          4026532722?pid?????????1??5035?100?????????????/bin/sleep?3650d

          前面第一部分很像 Docker 容器,pause 容器有五個(gè)命名空間:net、mnt、uts、ipc 以及 pid。但是很明顯,httpbin 和 sleep 容器僅僅有兩個(gè)命名空間:mnt 和 pid。這是怎么回事?

          事實(shí)證明,lsns 不是檢查進(jìn)程名稱空間的最佳工具。相反,要檢查某個(gè)進(jìn)程使用的命名空間,可以參考?/proc/${pid}/ns 位置:

          #?httpbin?container
          sudo?ls?-l?/proc/5001/ns
          ...
          lrwxrwxrwx?1?root?root?0?Oct?24?14:05?ipc?->?'ipc:[4026532717]'
          lrwxrwxrwx?1?root?root?0?Oct?24?14:05?mnt?->?'mnt:[4026532719]'
          lrwxrwxrwx?1?root?root?0?Oct?24?14:05?net?->?'net:[4026532614]'
          lrwxrwxrwx?1?root?root?0?Oct?24?14:05?pid?->?'pid:[4026532720]'
          lrwxrwxrwx?1?root?root?0?Oct?24?14:05?uts?->?'uts:[4026532716]'

          #?sleep?container
          sudo?ls?-l?/proc/5035/ns
          ...
          lrwxrwxrwx?1?100?101?0?Oct?24?14:05?ipc?->?'ipc:[4026532717]'
          lrwxrwxrwx?1?100?101?0?Oct?24?14:05?mnt?->?'mnt:[4026532721]'
          lrwxrwxrwx?1?100?101?0?Oct?24?14:05?net?->?'net:[4026532614]'
          lrwxrwxrwx?1?100?101?0?Oct?24?14:05?pid?->?'pid:[4026532722]'
          lrwxrwxrwx?1?100?101?0?Oct?24?14:05?uts?->?'uts:[4026532716]'

          雖然不太容易去注意到,但 httpbin 和 sleep 容器實(shí)際上重用了 pause 容器的 net、uts 和 ipc 命名空間!

          我們可以用 crictl 交叉檢測(cè)驗(yàn)證:

          #?Inspect?httpbin?container.
          $?sudo?crictl?inspect?dfb1cd29ab750
          {
          ??...
          ??"namespaces":?[
          ????{
          ??????"type":?"pid"
          ????},
          ????{
          ??????"type":?"ipc",
          ??????"path":?"/proc/4966/ns/ipc"
          ????},
          ????{
          ??????"type":?"uts",
          ??????"path":?"/proc/4966/ns/uts"
          ????},
          ????{
          ??????"type":?"mount"
          ????},
          ????{
          ??????"type":?"network",
          ??????"path":?"/proc/4966/ns/net"
          ????}
          ??],
          ??...
          }

          #?Inspect?sleep?container.
          $?sudo?crictl?inspect?097d4fe8a7002
          ...

          我認(rèn)為上述發(fā)現(xiàn)完美的解釋了同一個(gè) Pod 中容器具有的能力:

          • 能夠互相通信

          • 通過(guò) localhost 和/或

          • 使用 IPC(共享內(nèi)存,消息隊(duì)列等)

          • 共享 domain 和 hostname

          然而,在看過(guò)所有這些命名空間如何在容器之間自由重用之后,我開(kāi)始懷疑默認(rèn)邊界可以被打破。實(shí)際上,在對(duì) Pod API 規(guī)范的更深入閱讀后發(fā)現(xiàn),將 shareProcessNamespace 標(biāo)志設(shè)置為 true 時(shí),Pod 的容器將擁有四個(gè)通用命名空間,而不是默認(rèn)的三個(gè)。但是有一個(gè)更令人震驚的發(fā)現(xiàn)——hostIPC、hostNetwork 和 hostPID 標(biāo)志可以使容器使用相應(yīng)主機(jī)的命名空間。

          有趣的是,CRI API 規(guī)范似乎更加靈活。至少在語(yǔ)法上,它允許將 net、pid 和 ipc 命名空間限定為 CONTAINER、POD 或 NODE。因此,可以構(gòu)建一個(gè) Pod 使其容器無(wú)法通過(guò) localhost 相互通信 。

          探索 Pod 的 cgroups

          Pod 的 cgroups 是什么樣的?systemd-cgls 可以很好地可視化 cgroups 層次結(jié)構(gòu):

          $?sudo?systemd-cgls
          Control?group?/:
          -.slice
          ├─kubepods
          │?├─burstable
          │?│?├─pod4a8d5c3e-3821-4727-9d20-965febbccfbb
          │?│?│?├─f0e87a93304666766ab139d52f10ff2b8d4a1e6060fc18f74f28e2cb000da8b2
          │?│?│?│?└─4966?/pause
          │?│?│?├─dfb1cd29ab750064ae89613cb28963353c3360c2df913995af582aebcc4e85d8
          │?│?│?│?├─5001?/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          │?│?│?│?└─5016?/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          │?│?│?└─097d4fe8a7002d69d6c78899dcf6731d313ce8067ae3f736f252f387582e55ad
          │?│?│???└─5035?/bin/sleep?3650d
          ...

          所以,Pod 本身有一個(gè)父節(jié)點(diǎn)(Node),每個(gè)容器也可以單獨(dú)調(diào)整。這符合我的預(yù)期,因?yàn)樵?Pod 清單中,可以為 Pod 中的每個(gè)容器單獨(dú)設(shè)置資源限制。

          此刻,我腦海中的 Pod 看起來(lái)是這樣的:


          ?
          3?
          利用 Docker 實(shí)現(xiàn) Pod


          如果 Pod 的底層實(shí)現(xiàn)是一組具有共同 cgroup 父級(jí)的半融合(emi-fused)容器,是否可以使用 Docker 生產(chǎn)類似 Pod 的構(gòu)造?

          最近我嘗試做了一些類似的事情來(lái)讓多個(gè)容器監(jiān)聽(tīng)同一個(gè)套接字,我知道 Docker 可以通過(guò) docker run --network container:?語(yǔ)法來(lái)創(chuàng)建一個(gè)可以使用已存在的網(wǎng)絡(luò)命名空間容器。但我也知道?OCI 運(yùn)行時(shí)規(guī)范只定義了 create 和 start 命令

          因此,當(dāng)你使用 docker exec ?在現(xiàn)有容器中執(zhí)行命令時(shí),實(shí)際上是在運(yùn)行(即 create 然后 start)一個(gè)全新的容器,該容器恰好重用了目標(biāo)容器的所有命名空間(證明 1[1]?和 2[2])。這讓我非常有信心可以使用標(biāo)準(zhǔn) Docker 命令生成 Pod。

          我們可以使用僅僅安裝了 Docker 的機(jī)器作為實(shí)驗(yàn)環(huán)境。但是這里我會(huì)使用一個(gè)額外的包來(lái)簡(jiǎn)化使用 cgroups:

          $?sudo?apt-get?install?cgroup-tools

          首先,讓我們配置一個(gè)父 cgroup 條目。為了簡(jiǎn)潔起見(jiàn),我將僅使用 CPU 和內(nèi)存控制器:

          sudo?cgcreate?-g?cpu,memory:/pod-foo

          #?Check?if?the?corresponding?folders?were?created:
          ls?-l?/sys/fs/cgroup/cpu/pod-foo/
          ls?-l?/sys/fs/cgroup/memory/pod-foo/

          然后我們創(chuàng)建一個(gè)沙盒容器:

          $?docker?run?-d?--rm?\
          ??--name?foo_sandbox?\
          ??--cgroup-parent?/pod-foo?\
          ??--ipc?'shareable'?\
          ??alpine?sleep?infinity

          最后,讓我們啟動(dòng)重用沙盒容器命名空間的實(shí)際容器:

          #?app?(httpbin)
          $?docker?run?-d?--rm?\
          ??--name?app?\
          ??--cgroup-parent?/pod-foo?\
          ??--network?container:foo_sandbox?\
          ??--ipc?container:foo_sandbox?\
          ??kennethreitz/httpbin

          #?sidecar?(sleep)
          $?docker?run?-d?--rm?\
          ??--name?sidecar?\
          ??--cgroup-parent?/pod-foo?\
          ??--network?container:foo_sandbox?\
          ??--ipc?container:foo_sandbox?\
          ??curlimages/curl?sleep?365d

          你注意到我省略了哪個(gè)命名空間嗎?沒(méi)錯(cuò),我不能在容器之間共享 uts 命名空間。似乎目前在 docker run 命令中沒(méi)法實(shí)現(xiàn)。嗯,是有點(diǎn)遺憾。但是除開(kāi) uts 命名空間之外,它是成功的!

          cgroups 看上去很像 Kubernetes 創(chuàng)建的:

          $?sudo?systemd-cgls?memory
          Controller?memory;?Control?group?/:
          ├─pod-foo
          │?├─488d76cade5422b57ab59116f422d8483d435a8449ceda0c9a1888ea774acac7
          │?│?├─27865?/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          │?│?└─27880?/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          │?├─9166a87f9a96a954b10ec012104366da9f1f6680387ef423ee197c61d37f39d7
          │?│?└─27977?sleep?365d
          │?└─c7b0ec46b16b52c5e1c447b77d67d44d16d78f9a3f93eaeb3a86aa95e08e28b6
          │???└─27743?sleep?infinity

          全局命名空間列表看上去也很相似:

          $?sudo?lsns
          ????????NS?TYPE???NPROCS???PID?USER????COMMAND
          ...
          4026532157?mnt?????????1?27743?root????sleep?infinity
          4026532158?uts?????????1?27743?root????sleep?infinity
          4026532159?ipc?????????4?27743?root????sleep?infinity
          4026532160?pid?????????1?27743?root????sleep?infinity
          4026532162?net?????????4?27743?root????sleep?infinity
          4026532218?mnt?????????2?27865?root????/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          4026532219?uts?????????2?27865?root????/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          4026532220?pid?????????2?27865?root????/usr/bin/python3?/usr/local/bin/gunicorn?-b?0.0.0.0:80?httpbin:app?-k?gevent
          4026532221?mnt?????????1?27977?_apt????sleep?365d
          4026532222?uts?????????1?27977?_apt????sleep?365d
          4026532223?pid?????????1?27977?_apt????sleep?365d

          ?httpbin 和 sidecar 容器看上去共享了 ipc 和 net 命名空間:

          #?app?container
          $?sudo?ls?-l?/proc/27865/ns
          lrwxrwxrwx?1?root?root?0?Oct?28?07:56?ipc?->?'ipc:[4026532159]'
          lrwxrwxrwx?1?root?root?0?Oct?28?07:56?mnt?->?'mnt:[4026532218]'
          lrwxrwxrwx?1?root?root?0?Oct?28?07:56?net?->?'net:[4026532162]'
          lrwxrwxrwx?1?root?root?0?Oct?28?07:56?pid?->?'pid:[4026532220]'
          lrwxrwxrwx?1?root?root?0?Oct?28?07:56?uts?->?'uts:[4026532219]'

          #?sidecar?container
          $?sudo?ls?-l?/proc/27977/ns
          lrwxrwxrwx?1?_apt?systemd-journal?0?Oct?28?07:56?ipc?->?'ipc:[4026532159]'
          lrwxrwxrwx?1?_apt?systemd-journal?0?Oct?28?07:56?mnt?->?'mnt:[4026532221]'
          lrwxrwxrwx?1?_apt?systemd-journal?0?Oct?28?07:56?net?->?'net:[4026532162]'
          lrwxrwxrwx?1?_apt?systemd-journal?0?Oct?28?07:56?pid?->?'pid:[4026532223]'
          lrwxrwxrwx?1?_apt?systemd-journal?0?Oct?28?07:56?uts?->?'uts:[4026532222]'


          ?
          4?
          總結(jié)


          Container 和 Pod 是相似的。在底層,它們主要依賴 Linux 命名空間和 cgroup。但是,Pod 不僅僅是一組容器。Pod 是一個(gè)自給自足的高級(jí)構(gòu)造。所有 Pod 的容器都運(yùn)行在同一臺(tái)機(jī)器(集群節(jié)點(diǎn))上,它們的生命周期是同步的,并且通過(guò)削弱隔離性來(lái)簡(jiǎn)化容器間的通信。這使得 Pod 更接近于傳統(tǒng)的 VM,帶回了熟悉的部署模式,如 sidecar 或反向代理。

          相關(guān)鏈接:

          1. https://github.com/opencontainers/runtime-spec/issues/345
          2. https://github.com/opencontainers/runtime-spec/pull/388

          文章轉(zhuǎn)載:分布式實(shí)驗(yàn)室

          1.?Oracle官宣:騰訊 JDK 18 國(guó)內(nèi)第一,貢獻(xiàn)度!

          2.?ES+Redis+MySQL,這個(gè)高可用架構(gòu)設(shè)計(jì)太頂了!

          3.?為什么數(shù)據(jù)庫(kù)連接很消耗資源?

          4.?微服務(wù)架構(gòu)統(tǒng)一安全認(rèn)證設(shè)計(jì)與實(shí)踐

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊(cè),覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          PS:因公眾號(hào)平臺(tái)更改了推送規(guī)則,如果不想錯(cuò)過(guò)內(nèi)容,記得讀完點(diǎn)一下在看,加個(gè)星標(biāo),這樣每次新文章推送才會(huì)第一時(shí)間出現(xiàn)在你的訂閱列表里。

          點(diǎn)“在看”支持小哈呀,謝謝啦??

          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  污污污污污污污污污网站 | 插40岁女人视频 | 天天艹夜夜艹蜜桃 | 国产欧美在线 | 国产成人久久777777 |