• 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

    1. # -*- mode: ruby -*-
    2. # vi: set ft=ruby :
    3. ENV['VAGRANT_NO_PARALLEL'] = 'yes'
    4. Vagrant.configure(2) do |config|
    5. # Kubernetes Master Server
    6. config.vm.define "master" do |node|
    7. node.vm.box = "generic/ubuntu2004"
    8. node.vm.box_check_update = false
    9. node.vm.box_version = "3.2.18"
    10. node.vm.hostname = "master"
    11. node.vm.network "private_network", ip: "172.0.0.100"
    12. node.vm.provider :virtualbox do |v|
    13. v.name = "master"
    14. v.memory = 2048
    15. v.cpus = 2
    16. end
    17. node.vm.provider :libvirt do |v|
    18. v.memory = 2048
    19. v.nested = true
    20. v.cpus = 2
    21. end
    22. end
    23. # Kubernetes Worker Node
    24. config.vm.define "worker0" do |node|
    25. node.vm.box = "generic/ubuntu2004"
    26. node.vm.box_check_update = false
    27. node.vm.box_version = "3.2.18"
    28. node.vm.hostname = "worker0"
    29. node.vm.network "private_network", ip: "172.0.1.101"
    30. node.vm.provider :virtualbox do |v|
    31. v.name = "worker0"
    32. v.memory = 1024
    33. v.cpus = 1
    34. end
    35. node.vm.provider :libvirt do |v|
    36. v.memory = 1024
    37. v.nested = true
    38. v.cpus = 1
    39. end
    40. end
    41. end

    Step 2:执行vagrant命令。它将启动两个节点,一个主节点和一个工作节点。

    1. vagrant up

    Step 3 :登录主节点和工作节点安装集群初始化配置脚本。

    1. vagrant ssh master
    1. vagrant ssh worker0

    main.sh

    1. #!/bin/bash
    2. echo "[TASK 1] Disable and turn off SWAP"
    3. sed -i '/swap/d' /etc/fstab
    4. swapoff -a
    5. echo "[TASK 2] Stop and Disable firewall"
    6. systemctl disable --now ufw >/dev/null 2>&1
    7. echo "[TASK 3] Enable and Load Kernel modules"
    8. cat >>/etc/modules-load.d/containerd.conf<<EOF
    9. overlay
    10. br_netfilter
    11. EOF
    12. modprobe overlay
    13. modprobe br_netfilter
    14. echo "[TASK 4] Add Kernel settings"
    15. cat >>/etc/sysctl.d/kubernetes.conf<<EOF
    16. net.bridge.bridge-nf-call-ip6tables = 1
    17. net.bridge.bridge-nf-call-iptables = 1
    18. net.ipv4.ip_forward = 1
    19. EOF
    20. sysctl --system >/dev/null 2>&1
    21. echo "[TASK 5] Install containerd runtime"
    22. apt update -qq >/dev/null 2>&1
    23. apt install -qq -y containerd apt-transport-https >/dev/null 2>&1
    24. mkdir /etc/containerd
    25. containerd config default > /etc/containerd/config.toml
    26. systemctl restart containerd
    27. systemctl enable containerd >/dev/null 2>&1
    28. echo "[TASK 6] Add apt repo for kubernetes"
    29. curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - >/dev/null 2>&1
    30. apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main" >/dev/null 2>&1
    31. echo "[TASK 7] Install Kubernetes components (kubeadm, kubelet and kubectl)"
    32. 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

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

    Worker node

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

    Step 4 :只在主节点上安装下面的脚本,并在最后复制kubeadm join命令。

    master.sh

    1. #!/bin/bash
    2. echo "[TASK 1] Pull required containers"
    3. kubeadm config images pull >/dev/null 2>&1
    4. echo "[TASK 2] Initialize Kubernetes Cluster"
    5. kubeadm init --apiserver-advertise-address=172.0.0.100 --pod-network-cidr=192.168.0.0/16 >> /root/kubeinit.log 2>/dev/null
    6. echo "[TASK 3] Deploy Calico network"
    7. kubectl --kubeconfig=/etc/kubernetes/admin.conf create -f https://docs.projectcalico.org/v3.18/manifests/calico.yaml >/dev/null 2>&1
    8. mkdir /home/vagrant/.kube
    9. cp /etc/kubernetes/admin.conf /home/vagrant/.kube/config
    10. chown -R vagrant:vagrant /home/vagrant/.kube
    11. echo "[TASK 4] Generate and save cluster join command"
    12. kubeadm token create --print-join-command
    1. vagrant@master:~$ vim master.sh
    2. vagrant@master:~$ sudo bash master.sh
    3. [TASK 1] Pull required containers
    4. [TASK 2] Initialize Kubernetes Cluster
    5. [TASK 3] Deploy Calico network
    6. [TASK 4] Generate and save cluster join command
    7. kubeadm join 172.0.0.100:6443 --token 5d6fgz.0lll5srvyxa9wfcm --discovery-token-ca-cert-hash sha256:0828fbc966896ac32550a7641d54593ef98738d2878ed80c1966431888cc1324

    Step 5 :复制并以sudo用户身份在工作节点中运行join命令。

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

    Step 6 :在主节点上,列出所有集群节点,以确保工作节点连接到主节点并处于就绪状态。

    1. kubectl get nodes -o wide

    您可以使用Containerd而不是Docker来查看运行时。

    1. vagrant@master:~$ kubectl get nodes -o wide
    2. NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
    3. master 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.2
    4. worker0 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 正在成长,但改变不一定是痛苦的经历。

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


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

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

  • 相关阅读:
    Excel 文件比较工具 xlCompare 11.01 Crack
    7 SpringBoot与Elasticsearch
    进程信号(linux)
    下一代 IDE 工具 JetBrains Fleet 正式公测
    剑指 Offer II 037. 小行星碰撞
    randint和randrange的区别
    RedisTemplate缓存List的操作
    【C++编程能力提升】
    python 常用文件读取和保存方式汇总
    键盘映射笔记
  • 原文地址:https://blog.csdn.net/m0_46700908/article/details/124888616