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,我们该怎么办?_第1张图片

应该停止将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
    end
end

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/fstab
swapoff -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<>/etc/sysctl.d/kubernetes.conf</dev/null 2>&1

echo "[TASK 5] Install containerd runtime"
apt update -qq >/dev/null 2>&1
apt install -qq -y containerd apt-transport-https >/dev/null 2>&1
mkdir /etc/containerd
containerd config default > /etc/containerd/config.toml
systemctl restart containerd
systemctl 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>&1
apt-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.sh
vagrant@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.sh
vagrant@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>&1
mkdir /home/vagrant/.kube
cp /etc/kubernetes/admin.conf /home/vagrant/.kube/config
chown -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.sh
vagrant@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 wide
NAME      STATUS   ROLES                  AGE     VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
master    Ready    control-plane,master   2m41s   v1.21.0   10.0.2.15             Ubuntu 20.04.2 LTS   5.4.0-72-generic   containerd://1.5.2
worker0   Ready                     98s     v1.21.0   10.0.2.15             Ubuntu 20.04.2 LTS   5.4.0-72-generic   containerd://1.5.2

结论

至此,我们已经解决了为什么Kubernetes不需要Docker来工作的问题,并且也看到了Docker在工作流程中的重要性,以及在没有Docker运行时的情况下安装Kubernetes是多么简单。

Kubernetes 正在成长,但改变不一定是痛苦的经历。

大多数用户不需要采取任何行动。对于那些需要的人来说,仍然有时间进行下一步的测试和计划。


聚焦云原生新技术、新实践,帮助开发者群体赢在开发范式转移的新时代。欢迎关注CSDN云原生微信公众号~  

扫这里↓↓↓加入CSDN云原生交流群

Kubernetes弃用Docker,我们该怎么办?_第2张图片

你可能感兴趣的:(docker,kubernetes,容器,云原生,微服务)