Kubernetes 棄用 Docker ,我們該怎麼辦?

整理 | 山河已無恙 校對 | 小雨青年

出品 | CSDN雲原生

聲明:本文出自CNCF網站,最初由Alessandro Lo Manto在Sighup部落格上發表。CSDN將文章翻譯成中文,分享給大家。

2020年底,Kubernetes團隊棄用了Docker,並宣佈將在2021年底完全移除對Docker的支持。這種棄用帶來了很多變化,因為使用Docker作為容器運行時接口(CRI)而不是開放容器倡議(OCI)造成了一點混亂。

那麼,為什麼要這麼大驚小怪呢?我們應該繼續寫Dockerfile嗎?

如今,人們仍然很難理解Docker是什麼。公司、容器、映象和開發者使用的工具之間似乎沒有什麼區別,對許多人來說,只有一個叫做「Docker」的詞來指代這一切。

Docker內部的奧秘

Docker是一個開發、發佈和運行應用程序的開放平臺。Docker能夠將應用程序與基礎設施分離,從而快速交付軟體。Docker利用了Linux核心及其功能,因為獨立運行進程,所以隔離方法十分重要。

Docker之所以使用Linux Container(LXC),是因為其使用Runtime 作為後端。隨著任務的發展,LXC被改變為Containerd。

當前的Docker設置分為:Containerd(用於管理容器)和Dockerd(用於提供來自Docker主機的資訊的持久進程守護進程)。被定義為「容器」的Docker,只不過是一個與使用者友好的容器互動工具。它的創建方式使每個人都可以安裝它、構建容器映象、從註冊表中提取映象,並創建、啟動和管理容器。這就是Docker被稱為「容器」的原因。

那麼Kubernetes是什麼?和這一切又有什麼關係?

要想理解為什麼Kubernetes和Docker會一起出名,我們需要先了解Docker是如何集成在Kubernetes中以及開放容器倡議(OCI)和容器運行時接口(CRI)的含義。

什麼是OCI

Kubernetes採用容器的概念,它並不是在一臺伺服器上運行容器化應用程序,而是將它們分佈在一個集群上。

容器的普及需要有一個開放的映象標準。Docker Inc和CoreOS創建了OCI(Open Container Initiative,開放容器倡議),其使命是產生標準格式。它推出了兩個具體的標準:

  • 對二進位制格式映象的要求

  • 一個描述如何互動和運行容器的規範。OCI維護著一個名為Runc的參考實現,Containerd在後臺使用Runc與容器進行互動

OCI增加了不同容器運行時解決方案之間的互操作性,因此,映象可以在任何其他遵守此標準的系統中運行。

什麼是CRI

為了工作,Kubernetes 需要一個支持CRI的容器運行時。CRI是一個Kubernetes API,它定義了Kubernetes與不同容器運行時互動的方式。因為它是標準化的規範,所以您可以選擇想要使用的CRI實現或自行編寫。

為什麼Kubernetes不需要Docker作為容器運行時?Docker比Kubernetes更老,並且沒有實現CRI,為什麼它能夠發揮作用?

Dockershim元件的創建是為了讓你與CRI互動。但如今Docker有替代品,Kubernetes便不再需要保持這種額外的複雜性了。

前面解釋過,Docker並不是一個容器運行時,它是一系列與容器互動的工具,只是一個中間人。

應該停止將Kubernetes與Docker一起使用嗎?

如果您的集群已經由GKE、EKS或AKS‌(默認為Containerd)等主要雲提供商配置,或者您只是一個Kubernetes使用者,這對您沒有影響。

Docker已經並將繼續在Kubernetes生態系統中發揮重要作用。後者將繼續運行Docker容器並從Docker註冊表中提取映象,因為Docker生成了符合OCI的映象。

但是,讓我們來談談自己吧!在本文中,我們將引導您使用Containerd而不是Docker創建一個Kubernetes集群。

Vagrant VM上的集群設置

下面我們編寫一個基本的Vagrantfile和腳本配置供大家理解,可以按照以下提供的步驟創建Kubernetes集群。

作為先決條件,您需要安裝和配置Virtualbox和Vagrant。

Step 1:在啟動集群之前,首先在您選擇的檔案夾中創建一個Vagrantfile檔案。

Vagrantfile

    # -*- mode: ruby -*-# vi: set ft=ruby :
    ENV['VAGRANT_NO_PARALLEL'] = 'yes'
    Vagrant.configure(2) do |config|
    # Kubernetes Master Server config.vm.define "master" do |node|
    node.vm.box = "generic/ubuntu2004" node.vm.box_check_update = false node.vm.box_version = "3.2.18" node.vm.hostname = "master"
    node.vm.network "private_network", ip: "172.0.0.100"
    node.vm.provider :virtualbox do |v| v.name = "master" v.memory = 2048 v.cpus = 2 end
    node.vm.provider :libvirt do |v| v.memory = 2048 v.nested = true v.cpus = 2 end

    end
    # Kubernetes Worker Node
    config.vm.define "worker0" do |node|
    node.vm.box = "generic/ubuntu2004" node.vm.box_check_update = false node.vm.box_version = "3.2.18" node.vm.hostname = "worker0"
    node.vm.network "private_network", ip: "172.0.1.101"
    node.vm.provider :virtualbox do |v| v.name = "worker0" v.memory = 1024 v.cpus = 1 end
    node.vm.provider :libvirt do |v| v.memory = 1024 v.nested = true v.cpus = 1      end    endend

    Step 2:執行vagrant命令。它將啟動兩個節點,一個主節點和一個工作節點。

      vagrant up

      Step 3 :登入主節點和工作節點安裝集群初始化配置腳本。

        vagrant ssh master

          vagrant ssh worker0

          main.sh

            #!/bin/bash
            echo "[TASK 1] Disable and turn off SWAP"sed -i '/swap/d' /etc/fstabswapoff -a
            echo "[TASK 2] Stop and Disable firewall"systemctl disable --now ufw >/dev/null 2>&1
            echo "[TASK 3] Enable and Load Kernel modules"cat >>/etc/modules-load.d/containerd.conf<<EOFoverlaybr_netfilterEOFmodprobe overlaymodprobe br_netfilter
            echo "[TASK 4] Add Kernel settings"cat >>/etc/sysctl.d/kubernetes.conf<<EOFnet.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1net.ipv4.ip_forward = 1EOFsysctl --system >/dev/null 2>&1
            echo "[TASK 5] Install containerd runtime"apt update -qq >/dev/null 2>&1apt install -qq -y containerd apt-transport-https >/dev/null 2>&1mkdir /etc/containerdcontainerd config default > /etc/containerd/config.tomlsystemctl restart containerdsystemctl enable containerd >/dev/null 2>&1
            echo "[TASK 6] Add apt repo for kubernetes"curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - >/dev/null 2>&1apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main" >/dev/null 2>&1
            echo "[TASK 7] Install Kubernetes components (kubeadm, kubelet and kubectl)"apt install -qq -y kubeadm=1.21.0-00 kubelet=1.21.0-00 kubectl=1.21.0-00 >/dev/null 2>&1

            Master node

              vagrant@master:~$ vim main.shvagrant@master:~$ sudo bash main.sh[TASK 1] Disable and turn off SWAP[TASK 2] Stop and Disable firewall[TASK 3] Enable and Load Kernel modules[TASK 4] Add Kernel settings[TASK 5] Install containerd runtime[TASK 6] Add apt repo for kubernetes[TASK 7] Install Kubernetes components (kubeadm, kubelet and kubectl)

              Worker node

                vagrant@worker0:~$ vim main.shvagrant@worker0:~$ sudo bash main.sh[TASK 1] Disable and turn off SWAP[TASK 2] Stop and Disable firewall[TASK 3] Enable and Load Kernel modules[TASK 4] Add Kernel settings[TASK 5] Install containerd runtime[TASK 6] Add apt repo for kubernetes[TASK 7] Install Kubernetes components (kubeadm, kubelet and kubectl)

                Step 4 :只在主節點上安裝下面的腳本,並在最後複製kubeadm join命令。

                master.sh

                  #!/bin/bash
                  echo "[TASK 1] Pull required containers"kubeadm config images pull >/dev/null 2>&1
                  echo "[TASK 2] Initialize Kubernetes Cluster"kubeadm init --apiserver-advertise-address=172.0.0.100 --pod-network-cidr=192.168.0.0/16 >> /root/kubeinit.log 2>/dev/null
                  echo "[TASK 3] Deploy Calico network"kubectl --kubeconfig=/etc/kubernetes/admin.conf create -f https://docs.projectcalico.org/v3.18/manifests/calico.yaml >/dev/null 2>&1mkdir /home/vagrant/.kubecp /etc/kubernetes/admin.conf /home/vagrant/.kube/configchown -R vagrant:vagrant /home/vagrant/.kube
                  echo "[TASK 4] Generate and save cluster join command"kubeadm token create --print-join-command

                    vagrant@master:~$ vim master.shvagrant@master:~$ sudo bash master.sh
                    [TASK 1] Pull required containers[TASK 2] Initialize Kubernetes Cluster[TASK 3] Deploy Calico network[TASK 4] Generate and save cluster join command
                    kubeadm join 172.0.0.100:6443 --token 5d6fgz.0lll5srvyxa9wfcm --discovery-token-ca-cert-hash sha256:0828fbc966896ac32550a7641d54593ef98738d2878ed80c1966431888cc1324

                    Step 5 :複製並以sudo使用者身份在工作節點中運行join命令。

                      vagrant@worker0:~$ sudo kubeadm join 172.0.0.100:6443 --token 5d6fgz.0lll5srvyxa9wfcm --discovery-token-ca-cert-hash sha256:0828fbc966896ac32550a7641d54593ef98738d2878ed80c1966431888cc1324[preflight] Running pre-flight checks[preflight] Reading configuration from the cluster...[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"[kubelet-start] Starting the kubelet[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
                      This node has joined the cluster:* Certificate signing request was sent to apiserver and a response was received.* The Kubelet was informed of the new secure connection details.
                      Run 'kubectl get nodes' on the control-plane to see this node join the cluster

                      Step 6 :在主節點上,列出所有集群節點,以確保工作節點連接到主節點並處於就緒狀態。

                        kubectl get nodes -o wide

                        您可以使用Containerd而不是Docker來查看運行時。

                          vagrant@master:~$ kubectl get nodes -o wideNAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIMEmaster Ready control-plane,master 2m41s v1.21.0 10.0.2.15 <none> Ubuntu 20.04.2 LTS 5.4.0-72-generic containerd://1.5.2worker0 Ready <none> 98s v1.21.0 10.0.2.15 <none> Ubuntu 20.04.2 LTS 5.4.0-72-generic containerd://1.5.2

                          結論

                          至此,我們已經解決了為什麼Kubernetes不需要Docker來工作的問題,並且也看到了Docker在工作流程中的重要性,以及在沒有Docker運行時的情況下安裝Kubernetes是多麼簡單。

                          Kubernetes 正在成長,但改變不一定是痛苦的經歷。

                          大多數使用者不需要採取任何行動。對於那些需要的人來說,仍然有時間進行下一步的測試和計劃。

                          相關文章

                          Docker 映象詳細講解

                          Docker 映象詳細講解

                          作者 | 微楓Micromaple 來源 | CSDN部落格 前言 大家好,本文是對 Docker 映象的詳細講解,講解了如何安裝 Dock...

                          在 MacOS 上運行 Docker 太慢!

                          在 MacOS 上運行 Docker 太慢!

                          你是否也覺得,MacOS 中的 Docker 非常慢?本文作者想出了解決辦法,不妨來試試看。 原文連結:https://www.paolom...

                          Docker 如何安全地進入到容器內部

                          Docker 如何安全地進入到容器內部

                          作者 | 飛向星的客機 來源 | CSDN部落格 🌟 前言 映象是構建容器的藍圖,Docker 以映象為模板,構建出容器。 容器在映象的基礎...

                          WebAssembly 真能取代 Kubernetes?

                          WebAssembly 真能取代 Kubernetes?

                          摘要:許多開發者總是習慣性地將 WebAssembly 與 Kubernetes 進行對比,也許將來可能會出現某種技術,在雲環境中部署和管理...

                          雲原生時代的DevOps平臺設計之道

                          雲原生時代的DevOps平臺設計之道

                          【CSDN 編者按】雲原生時代,開發和運維的分工愈加分明,運維人員通過建設並維護一套 IaaS 雲平臺,將計算資源進行池化。開發人員按需申請...

                          40 張圖 詳解 Docker 容器監控

                          40 張圖 詳解 Docker 容器監控

                          作者 | 飛向星的客機 來源 | CSDN部落格 前言 在企業中,通常業務是不允許隨意停止的,否則將給企業帶來巨大的經濟損失。 運維工程師要...