以沙箱的方式執行容器:安全容器Kata Containers

人生的哲理發表於2024-06-20

目錄
  • 一.系統環境
  • 二.前言
  • 三.Kata Containers 簡介
  • 四.Gvisor與Kata區別對比
  • 五.配置docker使用kata作為runtime
    • 5.1 安裝docker
    • 5.2 安裝kata
      • 5.2.1 線上安裝(不推薦,下載非常慢)
      • 5.2.2 使用rpm包離線安裝(推薦)
    • 5.3 配置docker支援kata作為runtime
    • 5.4 docker使用kata作為runtime建立容器
  • 六.配置containerd使用kata作為runtime
    • 6.1 安裝containerd
    • 6.2 安裝kata
    • 6.3 配置containerd支援kata作為runtime
    • 6.4 containerd使用kata作為runtime建立容器
  • 七.在k8s環境裡,配置containerd作為高階別runtime,containerd使用kata作為低階別runtime
    • 7.1 把ubuntuk8sclient節點加入k8s叢集
    • 7.2 配置kubelet使其支援Kata
    • 7.3 建立容器執行時類(Runtime Class)
    • 7.4 使用kata建立pod
  • 八.總結

一.系統環境

本文主要基於Kubernetes1.22.2和Linux作業系統Ubuntu 18.04。

伺服器版本 docker軟體版本 Kubernetes(k8s)叢集版本 Kata軟體版本 containerd軟體版本 CPU架構
Ubuntu 18.04.5 LTS Docker version 20.10.14 v1.22.2 1.11.5 1.6.4 x86_64

Kubernetes叢集架構:k8scludes1作為master節點,k8scludes2,k8scludes3作為worker節點。

伺服器 作業系統版本 CPU架構 程序 功能描述
k8scludes1/192.168.110.128 Ubuntu 18.04.5 LTS x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master節點
k8scludes2/192.168.110.129 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker節點
k8scludes3/192.168.110.130 Ubuntu 18.04.5 LTS x86_64 docker,kubelet,kube-proxy,calico k8s worker節點

二.前言

容器技術因其輕量級、可移植和易於管理的特點而受到廣泛歡迎。然而,傳統容器技術在安全方面存在一定的缺陷。為了解決這些問題,安全容器技術應運而生。本文將重點介紹一種名為 Kata Containers 的安全容器解決方案。另外一種安全容器為gVisor,相關詳細操作請檢視部落格《以沙箱的方式執行容器:安全容器gvisor》。

安全容器是一種執行時技術,為容器應用提供一個完整的作業系統執行環境,但將應用的執行與宿主機作業系統隔離開,避免應用直接訪問主機資源,從而可以在容器主機之間或容器之間提供額外的保護。

以沙箱的方式執行容器的前提是已經有一套可以正常執行的Kubernetes叢集,關於Kubernetes(k8s)叢集的安裝部署,可以檢視部落格《Ubuntu 安裝部署Kubernetes(k8s)叢集》https://www.cnblogs.com/renshengdezheli/p/17632858.html。

三.Kata Containers 簡介

Kata源自希臘文Καταπστευμα(ka-ta-PI-stev-ma),原意是值得信任的人,kata container正是解容器安全的問題而誕生的。傳統的容器是基於namespace和cgroup進行隔離,在帶來輕量簡潔的同時,也帶來了安全的隱患。事實上容器雖然提供一個與系統中的其它程序資源相隔離的執行環境,但是與宿主機系統是共享核心的,一旦容器裡的應用逃逸到核心,後果不堪設想,尤其是在多租戶的場景下。Kata就是在這樣的背景下應運而生,kata很好的權衡了傳統虛擬機器的隔離性、安全性與容器的簡潔、輕量。這一點和firecracker很相似,都是輕量的虛擬機器。但是他們的本質的區別在於:kata雖然是基於虛機,但是其表現的卻跟容器是一樣的,可以像使用容器一樣使用kata;而firecracker雖然具備容器的輕量、極簡性,但是其依然是虛機,一種比QEMU更輕量的VMM,暫時不能相容容器生態。

Kata的基本原理是,為每一個容器單獨開一個虛機(如果是k8s下作為runtime,則是一個pod對應一個虛機而不是容器),具有獨立的核心,這樣交付的容器就具備了虛機級別的隔離和安全性。kata的原理圖如下所示:

image-20230809145009704

Kata Containers結合了虛擬機器和容器的優勢,提供了一種更加安全和隔離的容器執行時環境。Kata Containers使用輕量級的虛擬機器(如QEMU)來執行容器,每個容器都有一個獨立的虛擬機器例項,這樣可以實現容器之間的完全隔離。

由於Kata Containers使用了虛擬機器來執行容器,所以相對於gVisor來說,它的效能開銷更大。根據測試資料,Kata Containers的效能損失在20%左右。這主要是因為每個容器都執行在一個獨立的虛擬機器例項中,需要額外的資源和開銷。Kata Containers支援多核併發,可以在多核系統上實現更好的效能。

image-20240607111345903

Kata Containers 的本質,就是一個輕量化虛擬機器。所以當你啟動一個 Kata Containers 之後,你其實就會看到一個正常的虛擬機器在執行。這也就意味著,一個標準的虛擬機器管理程式(Virtual Machine Manager, VMM)是執行 Kata Containers 必備的一個元件。在我們上面圖中,使用的 VMM 就是 Qemu。

而使用了虛擬機器作為程序的隔離環境之後,Kata Containers 原生就帶有了 Pod 的概念。即:這個 Kata Containers 啟動的虛擬機器,就是一個 Pod;而使用者定義的容器,就是執行在這個輕量級虛擬機器裡的程序。在具體實現上,Kata Containers 的虛擬機器裡會有一個特殊的 Init 程序負責管理虛擬機器裡面的使用者容器,並且只為這些容器開啟 Mount Namespace。所以,這些使用者容器之間,原生就是共享 Network 以及其他 Namespace 的。

此外,為了跟上層編排框架比如 Kubernetes 進行對接,Kata Containers 專案會啟動一系列跟使用者容器對應的 shim 程序,來負責操作這些使用者容器的生命週期。當然,這些操作,實際上還是要靠虛擬機器裡的 Init 程序來幫你做到。

四.Gvisor與Kata區別對比

無論是 Kata Containers,還是 gVisor,它們實現安全容器的方法其實是殊途同歸的。這兩種容器實現的本質,都是給程序分配了一個獨立的作業系統核心,從而避免了讓容器共享宿主機的核心。這樣,容器程序能夠看到的攻擊面,就從整個宿主機核心變成了一個極小的、獨立的、以容器為單位的核心,從而有效解決了容器程序發生“逃逸”或者奪取整個宿主機的控制權的問題。

它們的區別在於,Kata Containers 使用的是傳統的虛擬化技術,透過虛擬硬體模擬出了一臺“小虛擬機器”,然後在這個小虛擬機器裡安裝了一個裁剪後的 Linux 核心來實現強隔離。

而 gVisor 的做法則更加激進,Google 的工程師直接用 Go 語言“模擬”出了一個執行在使用者態的作業系統核心,然後透過這個模擬的核心來代替容器程序向宿主機發起有限的、可控的系統呼叫。

五.配置docker使用kata作為runtime

注意:kata本質上是以虛擬機器的方式執行的,需要開啟虛擬化引擎功能,VMware Workstation需要如下設定:

image-20230809145048422

安裝kata網址:https://github.com/kata-containers/kata-containers/tree/main/docs/install

image-20240613172710898

5.1 安裝docker

我們在客戶端機器etcd2(centos系統)上安裝docker。

[root@etcd2 ~]# yum -y install docker-ce

設定docker開機自啟動並現在啟動docker。

[root@etcd2 ~]# systemctl enable docker --now
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

[root@etcd2 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 二 2022-06-07 11:07:18 CST; 7s ago
     Docs: https://docs.docker.com
 Main PID: 1231 (dockerd)
   Memory: 36.9M
   CGroup: /system.slice/docker.service
           └─1231 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

檢視docker版本。

[root@etcd2 ~]# docker --version
Docker version 20.10.12, build e91ed57

配置docker映象加速器。

[root@etcd2 ~]# vim /etc/docker/daemon.json

[root@etcd2 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://frz7i079.mirror.aliyuncs.com"] 
}

重啟docker。

[root@etcd2 ~]# systemctl restart docker

設定iptables不對bridge的資料進行處理,啟用IP路由轉發功能。

[root@etcd2 ~]# vim /etc/sysctl.d/k8s.conf 

[root@etcd2 ~]# cat /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

使配置生效。

[root@etcd2 ~]# sysctl -p /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

現在docker預設的runtime為runc。

[root@etcd2 ~]# docker info | grep -i runtime
 Runtimes: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux
 Default Runtime: runc

接下來配置docker使用kata作為runtime,思路還是首先安裝所需的runtime,接著配置docker支援多個runtime。

5.2 安裝kata

5.2.1 線上安裝(不推薦,下載非常慢)

編輯下載源。

[root@etcd2 ~]# vim /etc/yum.repos.d/home\:katacontainers\:releases\:x86_64\:head.repo 

[root@etcd2 ~]# cat /etc/yum.repos.d/home\:katacontainers\:releases\:x86_64\:head.repo 
[home_katacontainers_releases_x86_64_head]
name=Branch project for Kata Containers branch head (CentOS_7)
type=rpm-md
baseurl=https://download.opensuse.org/repositories/home:/katacontainers:/releases:/x86_64:/head/CentOS_7/
gpgcheck=1
gpgkey=https://download.opensuse.org/repositories/home:/katacontainers:/releases:/x86_64:/head/CentOS_7/repodata/repomd.xml.key
enabled=1

安裝kata。

[root@etcd2 ~]# yum -y install kata-runtime kata-proxy kata-shim

5.2.2 使用rpm包離線安裝(推薦)

建立存放檔案的目錄,先下載centos7的kata 1.11.5 RPM包。

[root@etcd2 ~]# mkdir kata-rpm

[root@etcd2 ~]# cd kata-rpm/

[root@etcd2 kata-rpm]# ll -h
總用量 103M
-rw-r--r-- 1 root root  42M 12月 27 03:14 kata-containers-image-1.11.5-10.1.x86_64.rpm
-rw-r--r-- 1 root root 6.1M 12月 27 03:14 kata-ksm-throttler-1.11.5-10.1.x86_64.rpm
-rw-r--r-- 1 root root 9.1M 12月 27 03:14 kata-linux-container-5.4.32.76-11.1.x86_64.rpm
-rw-r--r-- 1 root root 2.4K 12月 27 03:14 kata-proxy-1.11.5-10.1.x86_64.rpm
-rw-r--r-- 1 root root 1.9M 12月 27 03:14 kata-proxy-bin-1.11.5-10.1.x86_64.rpm
-rw-r--r-- 1 root root  22M 12月 27 03:13 kata-runtime-1.11.5-10.1.x86_64.rpm
-rw-r--r-- 1 root root 2.4K 12月 27 03:13 kata-shim-1.11.5-10.1.x86_64.rpm
-rw-r--r-- 1 root root 7.4M 12月 27 03:13 kata-shim-bin-1.11.5-10.1.x86_64.rpm
-rw-r--r-- 1 root root 2.6K 12月 27 03:13 qemu-vanilla-4.1.1+git.99c5874a9b-10.1.x86_64.rpm
-rw-r--r-- 1 root root 2.6M 12月 27 03:13 qemu-vanilla-bin-4.1.1+git.99c5874a9b-10.1.x86_64.rpm
-rw-r--r-- 1 root root  13M 12月 27 03:14 qemu-vanilla-data-4.1.1+git.99c5874a9b-10.1.x86_64.rpm

安裝kata。

[root@etcd2 kata-rpm]# yum -y install ./*

此時kata就安裝好了。

[root@etcd2 kata-rpm]# which kata-runtime
/usr/bin/kata-runtime

5.3 配置docker支援kata作為runtime

kata安裝好之後,要配置docker支援kata作為runtime。

檢視docker狀態。

[root@etcd2 kata-rpm]# systemctl status docker 
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 日 2022-06-12 15:48:15 CST; 58min ago
     Docs: https://docs.docker.com
 Main PID: 1114 (dockerd)
   Memory: 93.1M
   CGroup: /system.slice/docker.service
           └─1114 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

需要修改docker的啟動引數:ExecStart=/usr/bin/dockerd -D --add-runtime kata-runtime=/usr/bin/kata-runtime --default-runtime=kata- runtime -H fd:// --containerd=/run/containerd/containerd.sock

-D --add-runtime kata-runtime=/usr/bin/kata-runtime 表示讓docker支援kata作為runtime。

--default-runtime=kata-runtime表示讓docker預設以kata作為runtime。

[root@etcd2 kata-rpm]# vim /usr/lib/systemd/system/docker.service

[root@etcd2 kata-rpm]# cat /usr/lib/systemd/system/docker.service | grep ExecStart
#ExecStart=/usr/bin/dockerd --default-runtime runsc -H fd:// --containerd=/run/containerd/containerd.sock
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -D --add-runtime kata-runtime=/usr/bin/kata-runtime -H fd:// --containerd=/run/containerd/containerd.sock

重新載入配置檔案,重啟docker。

[root@etcd2 kata-rpm]# systemctl daemon-reload ; systemctl restart docker 

檢視docker runtime,可以發現,現在docker支援kata-runtime了。

[root@etcd2 kata-rpm]# docker info | grep -i runtime
 Runtimes: kata-runtime runc runsc io.containerd.runc.v2 io.containerd.runtime.v1.linux
 Default Runtime: runc

5.4 docker使用kata作為runtime建立容器

現在有nginx映象。

[root@etcd2 kata-rpm]# docker images
REPOSITORY                    TAG       IMAGE ID       CREATED        SIZE
hub.c.163.com/library/nginx   latest    46102226f2fd   5 years ago    109MB

--runtime=kata-runtime 表示使用kata作為runtime建立容器,不過報錯了,由報錯可知記憶體不夠了,因為kata本質上是kvm虛擬機器,所以記憶體要求比容器大。

[root@etcd2 ~]# docker run -dit --name=nginxweb --restart=always --runtime=kata-runtime hub.c.163.com/library/nginx:latest
2ed23f2ff16723aaa81bdfa01c3cb6ab787925c35362b4b45f3651aef9e74f96
docker: Error response from daemon: OCI runtime create failed: failed to launch qemu: exit status 1, error messages from qemu log: qemu-vanilla-system-x86_64: -device nvdimm,id=nv0,memdev=mem0: not enough space, currently 0x0 in use of total space for memory devices 0x5c00000: unknown.

記憶體空間不足,需要擴容,我把機器記憶體從1.2G擴容到2G。

再次建立容器。

[root@etcd2 ~]# docker run -dit --name=nginxweb --restart=always --runtime=kata-runtime hub.c.163.com/library/nginx:latest
04adab727ed79d78b145ad81ea8b395a992df2af7ff50da86993667a1eea929c

容器建立成功。

[root@etcd2 ~]# docker ps 
CONTAINER ID   IMAGE                                COMMAND                  CREATED              STATUS              PORTS     NAMES
04adab727ed7   hub.c.163.com/library/nginx:latest   "nginx -g 'daemon of…"   About a minute ago   Up About a minute   80/tcp    nginxweb
bc99f286802f   quay.io/calico/node:v2.6.12          "start_runit"            3 months ago         Up 13 seconds                 calico-node

docker使用kata作為runtime,以沙箱的方式執行容器,在宿主機裡就看不到容器裡執行的程序了。

[root@etcd2 ~]# ps -ef | grep nginx
root       2152   1369  0 17:09 pts/0    00:00:00 grep --color=auto nginx

檢視容器屬性,可以發現,現在容器的Runtime為kata-runtime。

[root@etcd2 ~]# docker inspect nginxweb | grep -i runtime
            "Runtime": "kata-runtime",
            "CpuRealtimeRuntime": 0,

刪除容器。

[root@etcd2 ~]# docker rm -f nginxweb
nginxweb

六.配置containerd使用kata作為runtime

6.1 安裝containerd

如果你熟悉docker,但是不瞭解containerd,請檢視部落格《在centos下使用containerd管理容器:5分鐘從docker轉型到containerd》,裡面有詳細講解。

我們在客戶端機器ubuntuk8sclient(ubuntu系統)上安裝containerd。

更新軟體源。

root@ubuntuk8sclient:~#  apt-get update

安裝containerd。

root@ubuntuk8sclient:~# apt-get -y install containerd.io cri-tools 

設定containerd開機自啟動並現在啟動containerd。

root@ubuntuk8sclient:~# systemctl enable containerd --now

檢視containerd狀態。

root@ubuntuk8sclient:~# systemctl is-active containerd
active

root@ubuntuk8sclient:~# systemctl status containerd
● containerd.service - containerd container runtime
   Loaded: loaded (/lib/systemd/system/containerd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2022-06-04 15:54:08 CST; 58min ago
     Docs: https://containerd.io
 Main PID: 722 (containerd)
    Tasks: 8
   CGroup: /system.slice/containerd.service
           └─722 /usr/bin/containerd

containerd的配置檔案為/etc/containerd/config.toml 。

root@ubuntuk8sclient:~# ll -h /etc/containerd/config.toml
-rw-r--r-- 1 root root 886 May  4 17:04 /etc/containerd/config.toml

containerd的配置檔案為/etc/containerd/config.toml ,可以使用containerd config default > /etc/containerd/config.toml生成預設的配置檔案,containerd config default生成的配置檔案內容還是挺多的。

root@ubuntuk8sclient:~# containerd config default > /etc/containerd/config.toml

root@ubuntuk8sclient:~# vim /etc/containerd/config.toml 

containerd config dump顯示當前的配置。

root@ubuntuk8sclient:~# containerd config dump
disabled_plugins = []
imports = ["/etc/containerd/config.toml"]
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
......
......
  address = ""
  gid = 0
  uid = 0

檢視containerd版本。

root@ubuntuk8sclient:~# containerd --version
containerd containerd.io 1.6.4 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16

root@ubuntuk8sclient:~# containerd -v
containerd containerd.io 1.6.4 212e8b6fa2f44b9c21b2798135fc6fb7c53efc16

修改配置檔案,新增阿里雲映象加速器。

root@ubuntuk8sclient:~# vim /etc/containerd/config.toml 

root@ubuntuk8sclient:~# grep endpoint /etc/containerd/config.toml
    endpoint = "https://frz7i079.mirror.aliyuncs.com"

SystemdCgroup = false修改為SystemdCgroup = true。

root@ubuntuk8sclient:~# vim /etc/containerd/config.toml 

root@ubuntuk8sclient:~# grep SystemdCgroup -B 11 /etc/containerd/config.toml 
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            BinaryName = ""
            CriuImagePath = ""
            CriuPath = ""
            CriuWorkPath = ""
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = ""
            ShimCgroup = ""
            SystemdCgroup = true

有個sandbox的映象,k8s.gcr.io/pause:3.6訪問不了。

root@ubuntuk8sclient:~# grep sandbox_image /etc/containerd/config.toml
    sandbox_image = "k8s.gcr.io/pause:3.6"

修改sandbox映象為可以訪問的阿里雲映象。

root@ubuntuk8sclient:~# vim /etc/containerd/config.toml 

root@ubuntuk8sclient:~# grep sandbox_image /etc/containerd/config.toml
    sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6"

重新載入配置檔案並重啟containerd服務。

root@ubuntuk8sclient:~# systemctl daemon-reload ; systemctl restart containerd

containerd 客戶端工具有 ctr 和 crictl ,如果使用 crictl 命令的話,需要執行 crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock ,不然會有告警。ctr和crictl更多命令細節,請檢視部落格《在centos下使用containerd管理容器:5分鐘從docker轉型到containerd》。

root@ubuntuk8sclient:~# crictl config runtime-endpoint unix:///var/run/containerd/containerd.sock

檢視containerd資訊。

root@ubuntuk8sclient:~# crictl info 
{
  "status": {
    "conditions": [
      {
        "type": "RuntimeReady",
        "status": true,
        "reason": "",
        "message": ""
      },
......
    "enableUnprivilegedPorts": false,
    "enableUnprivilegedICMP": false,
    "containerdRootDir": "/var/lib/containerd",
    "containerdEndpoint": "/run/containerd/containerd.sock",
    "rootDir": "/var/lib/containerd/io.containerd.grpc.v1.cri",
    "stateDir": "/run/containerd/io.containerd.grpc.v1.cri"
  },
  "golang": "go1.17.9",
  "lastCNILoadStatus": "cni config load failed: no network config found in /etc/cni/net.d: cni plugin not initialized: failed to load cni config",
  "lastCNILoadStatus.default": "cni config load failed: no network config found in /etc/cni/net.d: cni plugin not initialized: failed to load cni config"
}

containerd 客戶端工具 ctr 和 crictl 不好用,推薦使用nerdctl,nerdctl是containerd的cli客戶端工具,與docker cli大部分相容,用法類似docker命令。

使用nerdctl命令需要兩個安裝包nerdctl-0.20.0-linux-amd64.tar.gz和cni-plugins-linux-amd64-v1.1.1.tgz。

nerdctl-0.20.0-linux-amd64.tar.gz下載地址:https://github.com/containerd/nerdctl/releases

網路外掛cni-plugins-linux-amd64-v1.1.1.tgz下載地址:https://github.com/containernetworking/plugins/releases

root@ubuntuk8sclient:~# ll -h cni-plugins-linux-amd64-v1.1.1.tgz nerdctl-0.20.0-linux-amd64.tar.gz 
-rw-r--r-- 1 root root  35M Jun  5 12:19 cni-plugins-linux-amd64-v1.1.1.tgz
-rw-r--r-- 1 root root 9.8M Jun  5 12:15 nerdctl-0.20.0-linux-amd64.tar.gz

分別進行解壓。

root@ubuntuk8sclient:~# tar xf nerdctl-0.20.0-linux-amd64.tar.gz -C /usr/local/bin/

root@ubuntuk8sclient:~# ls /usr/local/bin/
containerd-rootless-setuptool.sh  containerd-rootless.sh  nerdctl

root@ubuntuk8sclient:~# mkdir -p /opt/cni/bin

root@ubuntuk8sclient:~# tar xf cni-plugins-linux-amd64-v1.1.1.tgz -C /opt/cni/bin/

root@ubuntuk8sclient:~# ls /opt/cni/bin/
bandwidth  bridge  dhcp  firewall  host-device  host-local  ipvlan  loopback  macvlan  portmap  ptp  sbr  static  tuning  vlan  vrf

配置nerdctl命令tab自動補全,新增source <(nerdctl completion bash)。

root@ubuntuk8sclient:~# vim /etc/profile

root@ubuntuk8sclient:~# cat /etc/profile | head -3
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
source <(nerdctl completion bash)

root@ubuntuk8sclient:~# nerdctl completion bash

使配置檔案/etc/profile生效。

root@ubuntuk8sclient:~# source /etc/profile

檢視映象。

root@ubuntuk8sclient:~# nerdctl images 
REPOSITORY    TAG    IMAGE ID    CREATED    PLATFORM    SIZE    BLOB SIZE

檢視名稱空間。

root@ubuntuk8sclient:~# nerdctl ns list
NAME            CONTAINERS    IMAGES    VOLUMES    LABELS
default         0             0         0              
k8s.io          0             4         0              
moby            0             0         0              
plugins.moby    0             0         0    

nerdctl的命令和docker命令很相似,只要把docker命令裡的docker換成nerdctl,基本都能執行成功。

拉取映象。

root@ubuntuk8sclient:~# nerdctl pull hub.c.163.com/library/nginx:latest
                
root@ubuntuk8sclient:~# nerdctl images
REPOSITORY                     TAG       IMAGE ID        CREATED           PLATFORM       SIZE         BLOB SIZE
hub.c.163.com/library/nginx    latest    8eeb06742b41    22 seconds ago    linux/amd64    115.5 MiB    41.2 MiB

檢視containerd資訊。

root@ubuntuk8sclient:~# nerdctl info 

6.2 安裝kata

Ubuntu系統的kata 1.11.5 軟體包下載網址:
https://download.opensuse.org/repositories/home:/katacontainers:/releases:/x86_64:/stable-1.11/xUbuntu_18.04/amd64/

提前下載好軟體包。

root@ubuntuk8sclient:~/kata-rpm# cd kata-ubuntu/

root@ubuntuk8sclient:~/kata-rpm/kata-ubuntu# ls
ibverbs-providers_17.1-1ubuntu0.2_amd64.deb    kata-proxy_1.12.0~rc0-49_amd64.deb     libnl-route-3-200_3.2.29-0ubuntu3_amd64.deb  librados2_12.2.13-0ubuntu0.18.04.6_amd64.deb
kata-containers-image_1.12.0~rc0-48_amd64.deb  kata-runtime_1.12.0~rc0-56_amd64.deb   libnspr4_2%3a4.18-1ubuntu1_amd64.deb         librbd1_12.2.13-0ubuntu0.18.04.6_amd64.deb
kata-ksm-throttler_1.12.0~rc0-51_amd64.deb     kata-shim_1.12.0~rc0-47_amd64.deb      libnss3_2%3a3.35-2ubuntu2.12_amd64.deb       qemu-vanilla_5.0.0+git.fdd76fecdd-52_amd64.deb
kata-linux-container_5.4.60.89-51_amd64.deb    libibverbs1_17.1-1ubuntu0.2_amd64.deb  libpixman-1-0_0.34.0-2_amd64.deb

更新軟體源。

root@ubuntuk8sclient:~/kata-rpm/kata-ubuntu# apt-get update

安裝kata。

root@ubuntuk8sclient:~/kata-rpm/kata-ubuntu# apt-get -y install ./*

#如果 apt-get -y install ./* 報錯就執行如下:
root@ubuntuk8sclient:~/kata-rpm/kata-ubuntu# sudo apt -y install ./*

現在kata就安裝好了。

root@ubuntuk8sclient:~/kata-rpm/kata-ubuntu# which kata-runtime
/usr/bin/kata-runtime

6.3 配置containerd支援kata作為runtime

kata安裝好之後,現在要配置containerd支援kata作為runtime。

修改containerd配置檔案,runtime_type = "io.containerd.kata.v2" 。

root@ubuntuk8sclient:~# vim /etc/containerd/config.toml 

#[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata-runtime]下面是新增的內容
root@ubuntuk8sclient:~# cat /etc/containerd/config.toml | grep -A27 "containerd.runtimes.runc"
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          base_runtime_spec = ""
          cni_conf_dir = ""
          cni_max_conf_num = 0
          container_annotations = []
          pod_annotations = []
          privileged_without_host_devices = false
          runtime_engine = ""
          runtime_path = ""
          runtime_root = ""
          runtime_type = "io.containerd.runc.v2"

          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            BinaryName = ""
            CriuImagePath = ""
            CriuPath = ""
            CriuWorkPath = ""
            IoGid = 0
            IoUid = 0
            NoNewKeyring = false
            NoPivotRoot = false
            Root = ""
            ShimCgroup = ""
            SystemdCgroup = true
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata-runtime]
          base_runtime_spec = ""
          cni_conf_dir = ""
          cni_max_conf_num = 0
          container_annotations = []
          pod_annotations = []
          privileged_without_host_devices = false
          runtime_engine = ""
          runtime_path = ""
          runtime_root = ""
          runtime_type = "io.containerd.kata.v2"       

重新載入配置檔案,重啟containerd。

root@ubuntuk8sclient:~# systemctl daemon-reload ; systemctl restart containerd

檢視runtime,現在就可以看到containerd支援三種runtime了:runc,runsc(這個看不到正常),kata-runtime。

root@ubuntuk8sclient:~# crictl info | grep -A44 runtimes
      "runtimes": {
        "kata": {
          "runtimeType": "io.containerd.kata.v2",
          "runtimePath": "",
          "runtimeEngine": "",
          "PodAnnotations": [],
          "ContainerAnnotations": [],
          "runtimeRoot": "",
          "options": null,
          "privileged_without_host_devices": false,
          "baseRuntimeSpec": "",
          "cniConfDir": "",
          "cniMaxConfNum": 0
        },
        "runc": {
          "runtimeType": "io.containerd.runc.v2",
          "runtimePath": "",
          "runtimeEngine": "",
          "PodAnnotations": [],
          "ContainerAnnotations": [],
          "runtimeRoot": "",
          "options": {
            "BinaryName": "",
            "CriuImagePath": "",
            "CriuPath": "",
            "CriuWorkPath": "",
            "IoGid": 0,
            "IoUid": 0,
            "NoNewKeyring": false,
            "NoPivotRoot": false,
            "Root": "",
            "ShimCgroup": "",
            "SystemdCgroup": true
          },
          "privileged_without_host_devices": false,
          "baseRuntimeSpec": "",
          "cniConfDir": "",
          "cniMaxConfNum": 0
        },
        "runsc": {
          "runtimeType": "io.containerd.runsc.v1",
          "runtimePath": "",
          "runtimeEngine": "",
          "PodAnnotations": [],
          "ContainerAnnotations": [],

6.4 containerd使用kata作為runtime建立容器

檢視映象。

root@ubuntuk8sclient:~# nerdctl images | grep nginx
nginx                                                 <none>                                                              2bcabc23b454    7 days ago      linux/amd64    149.1 MiB    54.1 MiB
hub.c.163.com/library/nginx                           latest                                                              8eeb06742b41    7 days ago      linux/amd64    115.5 MiB    41.2 MiB

建立容器,--runtime=kata-runtime 表示containerd使用kata-runtime建立容器。

root@ubuntuk8sclient:~# nerdctl run -d --name=nginxweb --restart=always --runtime=kata-runtime hub.c.163.com/library/nginx:latest
8e1518fe432771417fae9c0a23a9e9a37e71d5e8a87495f60a439f5b172adef4

containerd使用kata作為runtime,以沙箱的方式執行容器,在宿主機裡就看不到容器裡執行的程序了。

root@ubuntuk8sclient:~# ps -ef | grep nginx
root       1878   1693  0 17:39 pts/1    00:00:00 grep --color=auto nginx

停止容器。

root@ubuntuk8sclient:~# nerdctl ps
CONTAINER ID    IMAGE                                 COMMAND                   CREATED          STATUS    PORTS    NAMES
8e1518fe4327    hub.c.163.com/library/nginx:latest    "nginx -g daemon off;"    3 minutes ago    Up                 nginxweb    

root@ubuntuk8sclient:~# nerdctl stop nginxweb
nginxweb

刪除容器。

root@ubuntuk8sclient:~# nerdctl rm nginxweb

七.在k8s環境裡,配置containerd作為高階別runtime,containerd使用kata作為低階別runtime

7.1 把ubuntuk8sclient節點加入k8s叢集

注意docker作為k8s的高階別runtime的時候,不支援kata作為docker的低階別runtime,只有單機版的時候,kata才能作為docker的低階別runtime。

描述一下當前的系統環境:現在有一個k8s叢集,1個master,2個worker,三臺機器都是使用docker作為高階別runtime,現在新增一個新的worker節點,新的worker節點使用containerd作為高階別runtime,kata作為containerd的低階別runtime

現在把ubuntuk8sclient機器加入k8s叢集,ubuntuk8sclient的CONTAINER-RUNTIME為containerd。

檢視叢集節點。

root@k8scludes1:~# kubectl get nodes -o wide
NAME         STATUS   ROLES                  AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
k8scludes1   Ready    control-plane,master   55d   v1.22.2   192.168.110.128   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
k8scludes2   Ready    <none>                 55d   v1.22.2   192.168.110.129   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
k8scludes3   Ready    <none>                 55d   v1.22.2   192.168.110.130   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14

先在所有的機器配置IP主機名對映(以ubuntuk8sclient為例)。

root@ubuntuk8sclient:~# vim /etc/hosts

root@ubuntuk8sclient:~# cat /etc/hosts
127.0.0.1	localhost
127.0.1.1	tom
192.168.110.139 ubuntuk8sclient
192.168.110.128 k8scludes1
192.168.110.129 k8scludes2
192.168.110.130 k8scludes3

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

配置軟體源,軟體源如下,最後三行是k8s源。

root@ubuntuk8sclient:~# cat /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable
# deb-src [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu bionic stable

apt-key.gpg是k8s的deb源公鑰,載入k8s的deb源公鑰 apt-key add apt-key.gpg。

下載並載入k8s的deb源公鑰:curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - ; apt-get update。但是谷歌的網址訪問不了,我們直接去網上下載apt-key.gpg檔案,載入k8s的deb源公鑰。

root@ubuntuk8sclient:~# cat apt-key.gpg | apt-key add -
OK

更新軟體源。

root@ubuntuk8sclient:~# apt-get update

Linux swapoff命令用於關閉系統交換分割槽(swap area)。如果不關閉swap,就會在kubeadm初始化Kubernetes的時候報錯:“[ERROR Swap]: running with swap on is not supported. Please disable swap”。

root@ubuntuk8sclient:~# swapoff -a ;sed -i '/swap/d' /etc/fstab

root@ubuntuk8sclient:~# cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/dev/mapper/tom--vg-root /               ext4    errors=remount-ro 0       1

設定containerd當前名稱空間為k8s.io。

root@ubuntuk8sclient:~# cat /etc/nerdctl/nerdctl.toml | head -3
namespace = "k8s.io"

載入overlay和br_netfilter模組。

root@ubuntuk8sclient:~# cat > /etc/modules-load.d/containerd.conf <<EOF 
> overlay 
> br_netfilter 
> EOF

root@ubuntuk8sclient:~# cat /etc/modules-load.d/containerd.conf
overlay 
br_netfilter 

root@ubuntuk8sclient:~# modprobe overlay

root@ubuntuk8sclient:~# modprobe br_netfilter

設定iptables不對bridge的資料進行處理,啟用IP路由轉發功能。

root@ubuntuk8sclient:~# cat <<EOF> /etc/sysctl.d/k8s.conf 
> net.bridge.bridge-nf-call-ip6tables = 1 
> net.bridge.bridge-nf-call-iptables = 1 
> net.ipv4.ip_forward = 1 
> EOF

使配置生效。

root@ubuntuk8sclient:~# sysctl -p /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

為了k8s節點間的通訊,需要安裝cni網路外掛,提前下載好calico映象,calico映象版本要和k8s的那三個節點的calico版本一致。

root@ubuntuk8sclient:~# nerdctl pull docker.io/calico/cni:v3.22.2

root@ubuntuk8sclient:~# nerdctl pull docker.io/calico/pod2daemon-flexvol:v3.22.2
                               
root@ubuntuk8sclient:~# nerdctl pull docker.io/calico/node:v3.22.2
                        
root@ubuntuk8sclient:~# nerdctl pull docker.io/calico/kube-controllers:v3.22.2
                               
root@ubuntuk8sclient:~# nerdctl images | grep calico
calico/cni                                       v3.22.2                                                             757d06fe361c    4 minutes ago     linux/amd64    227.1 MiB    76.8 MiB
calico/kube-controllers                          v3.22.2                                                             751f1a8ba0af    20 seconds ago    linux/amd64    128.1 MiB    52.4 MiB
calico/node                                      v3.22.2                                                             41aac6d0a440    2 minutes ago     linux/amd64    194.2 MiB    66.5 MiB
calico/pod2daemon-flexvol                        v3.22.2                                                             413c5ebad6a5    3 minutes ago     linux/amd64    19.0 MiB     8.0 MiB

安裝kubelet,kubeadm,kubectl。

  • Kubelet 是 kubernetes 工作節點上的一個代理元件,執行在每個節點上;
  • Kubeadm 是一個快捷搭建kubernetes(k8s)的安裝工具,它提供了 kubeadm init 以及 kubeadm join 這兩個命令來快速建立 kubernetes 叢集;kubeadm 透過執行必要的操作來啟動和執行一個最小可用的叢集;
  • kubectl是Kubernetes叢集的命令列工具,透過kubectl能夠對叢集本身進行管理,並能夠在叢集上進行容器化應用的安裝部署。
root@ubuntuk8sclient:~# apt-get -y install kubelet=1.22.2-00 kubeadm=1.22.2-00 kubectl=1.22.2-00

設定kubelet開機自啟動並現在啟動。

root@ubuntuk8sclient:~# systemctl enable kubelet --now

在k8s的master節點,檢視k8s worker節點加入k8s叢集的token。

root@k8scludes1:~# kubeadm token create --print-join-command
kubeadm join 192.168.110.128:6443 --token rwau00.plx8xdksa8zdnfrn --discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e 

把ubuntuk8sclient節點加入k8s叢集。

root@ubuntuk8sclient:~# kubeadm join 192.168.110.128:6443 --token rwau00.plx8xdksa8zdnfrn --discovery-token-ca-cert-hash sha256:3f401b6187ed44ff8f4b50aa6453cf3eacc3b86d6a72e3bf2caba02556cb918e
[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.

去k8s master節點檢視是否加入k8s叢集,可以看到ubuntuk8sclient成功加入k8s叢集,並且CONTAINER-RUNTIME為containerd://1.6.4。

root@k8scludes1:~# kubectl get node -o wide
NAME              STATUS   ROLES                  AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
k8scludes1        Ready    control-plane,master   55d   v1.22.2   192.168.110.128   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
k8scludes2        Ready    <none>                 55d   v1.22.2   192.168.110.129   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
k8scludes3        Ready    <none>                 55d   v1.22.2   192.168.110.130   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
ubuntuk8sclient   Ready    <none>                 87s   v1.22.2   192.168.110.139   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   containerd://1.6.4

7.2 配置kubelet使其支援Kata

配置kubelet,使其可以支援Kata作為containerd的低階別runtime,修改kubelet引數,讓其支援Kata作為runtime。

root@ubuntuk8sclient:~# cat > /etc/systemd/system/kubelet.service.d/0-cri-containerd.conf <<EOF 
> [Service] 
> Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m 
> --container-runtime-endpoint=unix:///run/containerd/containerd.sock" 
> EOF

root@ubuntuk8sclient:~# cat /etc/systemd/system/kubelet.service.d/0-cri-containerd.conf
[Service] 
Environment="KUBELET_EXTRA_ARGS=--container-runtime=remote --runtime-request-timeout=15m  --container-runtime-endpoint=unix:///run/containerd/containerd.sock" 

重新載入配置檔案並重啟kubelet。

root@ubuntuk8sclient:~# systemctl daemon-reload ; systemctl restart kubelet

root@ubuntuk8sclient:~# systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/kubelet.service.d
           └─0-cri-containerd.conf, 10-kubeadm.conf
   Active: active (running) since Sat 2022-06-11 18:00:31 CST; 14s ago
     Docs: https://kubernetes.io/docs/home/
 Main PID: 31685 (kubelet)
    Tasks: 13 (limit: 1404)
   CGroup: /system.slice/kubelet.service
           └─31685 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --container-runtime=remote --con

7.3 建立容器執行時類(Runtime Class)

在k8s裡使用kata建立pod,需要使用到容器執行時類(Runtime Class)。

RuntimeClass 是一個用於選擇容器執行時配置的特性,容器執行時配置用於執行 Pod 中的容器。你可以在不同的 Pod 設定不同的 RuntimeClass,以提供效能與安全性之間的平衡。 例如,如果你的部分工作負載需要高階別的資訊保安保證,你可以決定在排程這些 Pod 時,儘量使它們在使用硬體虛擬化的容器執行時中執行。 這樣,你將從這些不同執行時所提供的額外隔離中獲益,代價是一些額外的開銷。

你還可以使用 RuntimeClass 執行具有相同容器執行時,但具有不同設定的 Pod。

注意RuntimeClass是全域性生效的,不受名稱空間限制。

編輯RuntimeClass配置檔案,handler後面寫runtime的名字,我們要使用kata就寫kata-runtime,handler: kata-runtime表示指定使用kata-runtime作為runtime。

root@k8scludes1:~# cd containerd-kata/

root@k8scludes1:~/containerd-kata# vim mykataruntimeclass.yaml 

root@k8scludes1:~/containerd-kata# cat mykataruntimeclass.yaml 
# RuntimeClass 定義於 node.k8s.io API 組
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  # 用來引用 RuntimeClass 的名字
  # RuntimeClass 是一個叢集層面的資源
  name: mykataruntimeclass  
# 對應的 CRI 配置的名稱
#handler: myconfiguration
#注意:handler後面寫runtime的名字,我們要使用kata就寫kata-runtime
handler: kata-runtime

建立RuntimeClass。

root@k8scludes1:~/containerd-kata# kubectl apply -f mykataruntimeclass.yaml 
runtimeclass.node.k8s.io/mykataruntimeclass created

root@k8scludes1:~/containerd-kata# kubectl get runtimeclass -o wide
NAME                 HANDLER        AGE
mykataruntimeclass   kata-runtime   13s
myruntimeclass       runsc          16h

給ubuntuk8sclient節點建立一個標籤con=kata。

root@k8scludes1:~/containerd-kata# kubectl label node ubuntuk8sclient con=kata --overwrite
node/ubuntuk8sclient labeled

root@k8scludes1:~/containerd-kata# kubectl get node -l con=kata -o wide --show-labels
NAME              STATUS   ROLES    AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME    LABELS
ubuntuk8sclient   Ready    <none>   25h   v1.22.2   192.168.110.139   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   containerd://1.6.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,con=kata,kubernetes.io/arch=amd64,kubernetes.io/hostname=ubuntuk8sclient,kubernetes.io/os=linux

7.4 使用kata建立pod

編輯pod配置檔案,在ubuntuk8sclient節點建立pod。

runtimeClassName: mykataruntimeclass 表示使用mykataruntimeclass裡的kata作為runtime。

nodeSelector:con: kata指定pod執行在標籤為con=kata的ubuntuk8sclient節點。

root@k8scludes1:~/containerd-kata# vim pod.yaml 

root@k8scludes1:~/containerd-kata# cat pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podtest
  name: podtest
spec:
  #當需要關閉容器時,立即殺死容器而不等待預設的30秒優雅停機時長。
  terminationGracePeriodSeconds: 0
  #指定容器執行時類
  runtimeClassName: mykataruntimeclass
  nodeSelector:
    con: kata
  containers:
  - image: hub.c.163.com/library/nginx:latest
    #imagePullPolicy: IfNotPresent:表示如果本地已經存在該映象,則不重新下載;否則從遠端 Docker Hub 下載該映象
    imagePullPolicy: IfNotPresent
    name: podtest
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

建立pod,pod執行在ubuntuk8sclient節點。

root@k8scludes1:~/containerd-kata# kubectl apply -f pod.yaml 
pod/podtest created

root@k8scludes1:~/containerd-kata# kubectl get pod -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP              NODE              NOMINATED NODE   READINESS GATES
podtest   1/1     Running   0          10s   10.244.228.30   ubuntuk8sclient   <none>           <none>

建立好pod之後,去ubuntuk8sclient節點檢視nginx程序,kata以沙箱的方式執行容器,在宿主機裡就看不到容器裡執行的程序了。

root@ubuntuk8sclient:~# nerdctl ps | grep nginx
6dd99b54705f    hub.c.163.com/library/nginx:latest                            "nginx -g daemon off;"    2 minutes ago     Up                 k8s://minsvcbug/podtest/podtest         
           
root@ubuntuk8sclient:~# ps -ef | grep nginx
root      33736  32877  0 18:52 pts/2    00:00:00 grep --color=auto nginx

kata本質上是kvm虛擬機器,需要開啟CPU虛擬化功能,顯示vmx或者svm,表示已經開啟CPU虛擬化功能了。

root@ubuntuk8sclient:~# egrep 'vmx|svm' /proc/cpuinfo 
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xsaves arat md_clear flush_l1d arch_capabilities
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid mpx rdseed adx smap clflushopt xsaveopt xsavec xsaves arat md_clear flush_l1d arch_capabilities

刪除pod。

root@k8scludes1:~/containerd-kata# kubectl delete pod podtest 
pod "podtest" deleted

可以把ubuntuk8sclient節點從k8s叢集刪掉。

root@k8scludes1:~/containerd-kata# kubectl get node -o wide
NAME              STATUS   ROLES                  AGE   VERSION   INTERNAL-IP       EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
k8scludes1        Ready    control-plane,master   56d   v1.22.2   192.168.110.128   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
k8scludes2        Ready    <none>                 56d   v1.22.2   192.168.110.129   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
k8scludes3        Ready    <none>                 56d   v1.22.2   192.168.110.130   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   docker://20.10.14
ubuntuk8sclient   Ready    <none>                 25h   v1.22.2   192.168.110.139   <none>        Ubuntu 18.04.5 LTS   4.15.0-112-generic   containerd://1.6.4

root@k8scludes1:~/containerd-kata# kubectl drain ubuntuk8sclient --ignore-daemonsets 

root@k8scludes1:~/containerd-kata# kubectl delete nodes ubuntuk8sclient

八.總結

Kata Containers 作為一種安全容器技術,透過硬體虛擬化和沙箱隔離為容器提供了更高的安全性。與傳統容器技術相比,Kata Containers 在安全效能方面具有明顯優勢。在本文中,我們以 Kubernetes 1.22.2 和 Ubuntu 18.04 為例,介紹瞭如何在 Linux 作業系統上使用 Kata Containers 以沙箱的方式執行容器。希望本文能為您的容器安全部署提供參考。

相關文章