开发者
资源
iSula轻量级容器技术入门(实践)
iSula轻量级容器技术入门(实践)
发表于2025/05/16
4380

iSula轻量级容器技术入门(实践)

实验环境介绍

我们以华为云ECS openEuler 22.03 64bit with ARM为实验演示环境,由于是在虚拟机上进行实验,安全要求不是很严格,为方便起见,我们以root用户登录进行演示。

以下是实验环境的一些展示:

uname -m # aarch64
uname -r # 5.10.0-60.139.0.166.oe2203.aarch64
cat /etc/os-release # openEuler 22.03 LTS

ip addr # eth0
fdisk -l | grep dev # /dev/vda

作为开发者,我们首先安装开发工具:

yum group install -y "Development Tools"
yum install -y jq

🔔注意

如果在安装的过程中出现“Error: GPG check FAILED”错误则可在yum install命令后增加--nogpgcheck选项,例如:

yum group install -y "Development Tools" --nogpgcheck

iSulad轻量级容器引擎实践

iSulad的安装、配置和启动

请参照iSulad代码仓的README文件进行安装,下文是从YUM(Yellow dog Updater, Modified)软件仓库安装该软件的一个示例。

yum install -y iSulad

安装成功后,需要先配置好容器镜像的注册地址,以“hub.oepkgs.net”为例:

cp /etc/isulad/daemon.json{,.before}
vi /etc/isulad/daemon.json # 在此处配置“registry-mirrors”
cat /etc/isulad/daemon.json

配置情况如下所示:

......
    "registry-mirrors": [
        "hub.oepkgs.net"
    ],
	......

💡Tips

hub.oepkgs.net为openEuler社区与中科院软件所共建的、开源免费的容器镜像仓库。在该网站可以搜索到可用于该实验的容器镜像。

下面检查配置文件格式是否正确:

cat /etc/isulad/daemon.json | jq

一般来说,如果配置文件的内容能正确显示出来,即表示其格式合法。

现在需要重新启动isulad:

systemctl restart isulad

查看isulad运行状况:

systemctl status isulad

如果显示输出有“active (running)”的字样则表示启动成功。
注意:有时需要按“q”或“Q”键从查看信息的状态中退出。

iSulad容器与镜像管理

iSulad提供了两个管理镜像和容器的操作接口:

  • CLI:命令行接口。本文主要以此讲解iSulad容器与镜像生命周期管理。
  • CRI:容器运行时接口。iSulad可以通过CRI接口与kubernetes集成,本文对此不做叙述,有兴趣者可以参考k8s_integration

运行容器busybox

我们通过运行容器busybox展示iSulad容器与镜像生命周期管理。

🎶步骤 1isula run等命令

我们首先用isula run命令直接运行容器busybox:

isula run busybox echo "hello world"

输出如下所示:

Unable to find image 'busybox' locally
Image "busybox" pulling
Image "27725c36cdc8dd631fec82926947bf4be6799f049a329c7cca9800fddf7ff9d2" pulled
hello world

由于这是第一次运行,所以会拉取busybox的镜像,然后运行它的一个实例,并且调用echo命令打印hello world字符串。

查看镜像:

isula images

输出如下所示:

REPOSITORY                     TAG        IMAGE ID             CREATED              SIZE
busybox                        latest     27725c36cdc8         2017-05-13 05:36:57  3.159MB

现在,我们使用isula run -it命令再次运行容器busybox:

isula run -it busybox

参数解释:

  • -i:即使没有连接到容器的标准输入,也要保持容器的标准输入打开。
  • -t:等同于“--tty”,为容器分配伪终端。

这时,我们会进入容器里的命令行交互界面:

whoami # root
pwd # /
uname -a # Linux 432b4ded44ff 5.10.0-60.139.0.166.oe2203.aarch64 #1 SMP Thu May 30 05:18:35 UTC 2024 aarch64 GNU/Linux
exit

如上所示,我们可以在里面执行命令、并通过exit命令退出容器。

使用isula run -itd命令运行容器busybox:

isula run -itd busybox

参数解释:

  • -d:后台运行容器并打印容器ID

输出如下:

2f53dfb21e67750c61ef5ece06c32c87ce7034c09d7b7d6aeee3a16b36aea0b7

该容器在后台运行。

进入容器内部的命令行界面:

isula exec -it 2f53dfb21e67 # 注意我们在这里取用了容器ID的前12位数字以标识该容器

在容器内部的命令行,可以通过exit命令退出容器。虽然已经退出了该容器的命令行交互界面,但该容器实例仍然在运行:

isula ps

输出如下:

CONTAINER ID    IMAGE   COMMAND CREATED         STATUS          PORTS   NAMES
2f53dfb21e67    busybox "sh"    4 minutes ago   Up 4 minutes            2f53dfb21e67750c61ef5ece06c32c87ce7034c09d7b7d6aeee3a16b36aea0b7

现在我们通过isula attach命令接入容器:

isula attach 2f53dfb21e67 # 需要敲两次回车

同样也可以通过exit命令退出,但是这一次该容器实例也会终止运行。

🎶步骤 2isula create等命令

isula create命令创建容器并指定容器的名字:

isula create -it --name my-busybox1 busybox
isula create -it --name my-busybox2 busybox

启动容器:

isula start my-busybox1 my-busybox2

执行容器中的命令:

isula exec my-busybox1 echo "my busybox1"
isula exec my-busybox2 echo "my busybox2"

当容器业务结束需要释放资源时,可删除该容器。删除容器时,需要先停止容器。

停止容器:

isula stop my-busybox1 my-busybox2

由于容器实例已经停止运行,所以利用isula ps命令无法查找到它,这时我们可以用isula ps -a命令查看所有已创建的容器(包括处于“running”状态的容器):

isula ps -a

输出如下:

CONTAINER ID    IMAGE   COMMAND                 CREATED         STATUS                          PORTS   NAMES
244e6e9f8adc    busybox "sh"                    3 minutes ago   Exited (137) 2 minutes ago              my-busybox2
58f3745ca9a3    busybox "sh"                    3 minutes ago   Exited (137) 2 minutes ago              my-busybox1
2f53dfb21e67    busybox "sh"                    13 minutes ago  Exited (0) 7 minutes ago                2f53dfb21e67750c61ef5ece06c32c87ce7034c09d7b7d6aeee3a16b36aea0b7
432b4ded44ff    busybox "sh"                    17 minutes ago  Exited (0) 13 minutes ago               432b4ded44fff612fef87a57c9c1ec495eeff506b80a1bd62329997b260abfe1
ca85bd7bd1d9    busybox "echo 'hello world'"    19 minutes ago  Exited (0) 19 minutes ago               ca85bd7bd1d9b9f8f7c88b58811ff07bceb01ad6cb5e031d010c1b9faed36d0f

删除所有容器:

isula rm my-busybox2 my-busybox1 2f53dfb21e67 432b4ded44ff ca85bd7bd1d9

这时用isula psisula ps -a都看不到任何容器,这两个命令的输出都如下所示:

CONTAINER ID    IMAGE   COMMAND CREATED STATUS  PORTS   NAMES

这时可以删除busybox镜像(删除容器镜像前要先删除它的所有实例):

isula rmi busybox # Image "busybox" removed

当然可以再次拉取镜像:

isula pull busybox

输出如下:

Image "busybox" pulling
Image "27725c36cdc8dd631fec82926947bf4be6799f049a329c7cca9800fddf7ff9d2" pulled

🎶步骤 3:更多命令

显示系统范围的信息:

isula info

更多信息,请查看帮助:

isula --help

运行容器openeuler:24.03

我们通过运行容器openeuler:24.03展现如何将容器中的数据在主机上永续留存。

我们创建一个“iSula”目录作为我们的工作目录:

cd ~
mkdir iSula && cd $_

🎼主题 1:宿主机与容器间互相拷贝文件

isula create -it --name my-container-0 openeuler/openeuler:24.03

输出如下所示:

Unable to find image 'openeuler/openeuler:24.03' locally
Image "openeuler/openeuler:24.03" pulling
Image "7a0facc10e29fd4f3b5441bac3a8bb9af9c0d6a967f338941b2abe6f74cf78e7" pulled
3d9f6f7ac0b2f008320392867a35c505f82a82339132be0d71bc332b8a491b79

我们可以从宿主机(host)上拷贝文件到还未启动的容器:

mkdir host
echo "I'm Host." > ./host/host_file
isula cp host my-container-0:/

启动刚刚创建的容器:

isula start my-container-0

查看拷贝到容器中的文件:

isula exec my-container-0 whoami # root
isula exec my-container-0 cat /host/host_file # I'm Host.

查看容器中操作系统的版本信息:

isula exec my-container-0 cat /etc/os-release

输出如下:

NAME="openEuler"
VERSION="24.03 (LTS-SP1)"
ID="openEuler"
VERSION_ID="24.03"
PRETTY_NAME="openEuler 24.03 (LTS-SP1)"
ANSI_COLOR="0;31"

现在我们进入容器内部:

isula exec -it my-container-0

在容器内部创建文件后退出容器:

whoami # root
mkdir /container
echo "I'm container." > /container/container_file
exit

在宿主机环境中将容器中的文件拷贝到主机:

isula cp my-container-0:/container ./

查看文件内容:

cat container/container_file # I'm container.

停止容器:

isula stop my-container-0

删除容器:

isula rm my-container-0

🎼主题2:挂载本地卷到容器

iSula管理的容器销毁后,容器内自身所有的数据都会被销毁。如果用户希望容器销毁后依然保留数据,则需要有一种持久化数据的机制。iSula允许将主机上的文件、目录或卷在容器运行时挂载到容器内。

使用create和run创建并运行容器时,可以使用-v或者--volume参数将主机上的文件、目录或者卷挂载到容器内用于数据持久化。

我们先在宿主机上创建目录和文件:

pwd # /root/iSula
mkdir -p ./data/my-volume1
echo "Hello container!" > ./data/my-volume1/host_file

然后启动一个容器:

isula run -it --name my-container-1 -v /root/iSula/data/my-volume1:/volume1:rw openeuler/openeuler:24.03

这时会进入容器内部的命令行/ # 我们在容器中执行命令:

whoami # root
pwd # /
ls # ... volume1
cat ./volume1/host_file # Hello container!
echo "Hello host!" >> ./volume1/host_file
exit

上面最后一行退出容器后,我们将此容器删除:

isula rm my-container-1

再(在主机)查看文件内容:

cat ./data/my-volume1/host_file

输出如下:

Hello container!
Hello host!

可见将此容器删除后,宿主机上的文件依然存在,说明容器数据持久化成功。因此,我们可以通过将此目录挂载给新的容器,实现数据业务的恢复。而除了-v参数可以为容器挂载本地持久化存储卷以外,还可以使用--mount参数挂载。

比如将上述宿主机的“my-volume1”文件夹挂载给一个新容器:

isula create -it --mount type=bind,src=/root/iSula/data/my-volume1,dst=/volume2 --name my-container-2 openeuler/openeuler:24.03

启动容器:

isula start my-container-2

进入容器内部以交互式命令行方式执行命令:

isula exec -it my-container-2

该命令执行成功后会进入容器内部,我们在其命令行界面上执行命令:

whoami # root
pwd # /
ls # ... volume2
cat ./volume2/host_file

最后一行命令输出如下:

Hello container!
Hello host!

可见数据业务恢复成功。

在容器中命令行中输入命令退出容器:

exit

退出该容器实例后在主机环境停止该容器并将其删除:

isula stop my-container-2
isula rm my-container-2

最后删除镜像:

isula rmi openeuler/openeuler:24.03

使用isula-build构建容器镜像

到目前为止,我们使用的容器镜像都是从hub.oepkgs.net下载的已经构建好的容器镜像,下面我们尝试使用iSula提供的容器镜像构建工具isula-build,构建自己的容器镜像并运行。

安装isula-build

🎶步骤 1:检查yum源

yum repolist | grep update

如果输出:

update                                  update

也就是“update”赫然纸上,这表明[update]节的enable=1,这正是我们需要的。

🎶步骤 2:用yum命令安装isula-build

yum install -y isula-build

🎶步骤 3:安装docker-runc

isula-build构建Dockerfile内的RUN指令时依赖可执行文件runc,我们可以通过安装docker-runc来获取runc二进制:

yum install -y docker-runc

🎶步骤 4:用systemctl start命令启动

systemctl start isula-build

🎶步骤 5:查看版本

isula-build version

本例输出如下:

Client:
  Version:       0.9.6-13
  Go Version:    go1.17.3
  Git Commit:    de59790
  Built:         Tue Nov  1 08:00:00 2022
  OS/Arch:       linux/arm64

Server:
  Version:       0.9.6-13
  Go Version:    go1.17.3
  Git Commit:    de59790
  Built:         Tue Nov  1 08:00:00 2022
  OS/Arch:       linux/arm64

🎶步骤 6:修改配置

修改/etc/isula-build/registries.toml,将hub.oepkgs.net加入到isula-build可搜索的镜像仓库列表里:

cp /etc/isula-build/registries.toml{,.before}
vi /etc/isula-build/registries.toml # 在此修改文件内容
cat /etc/isula-build/registries.toml

修改后的内容如下:

……
[registries.search]
registries = ["hub.oepkgs.net"]
……

当然,如果有不同的镜像仓库也可以配置不同的镜像仓库。

然后需要重启isula-build服务:

systemctl restart isula-build

查看配置:

isula-build info -H

本例输出如下:

General:
  MemTotal:     2.57 GB
  MemFree:      1.91 GB
  SwapTotal:    0 B
  SwapFree:     0 B
  OCI Runtime:  runc
  DataRoot:     /var/lib/isula-build/
  RunRoot:      /var/run/isula-build/
  Builders:     0
  Goroutines:   11
  Experimental: false
Store:
  Storage Driver:     overlay
  Backing Filesystem: extfs
Registry:
  Search Registries:
    hub.oepkgs.net
  Insecure Registries:

在Search Registries 配置项里看到”hub.oepkgs.net”赫然纸上。
至此,isula-build安装完成。

构建容器镜像并导出到isulad

我们构建容器镜像并将其导出到本地isulad容器引擎的存储中。

🎶步骤 1:创建Dockerfile

whoami # root
mkdir -p ~/iSula/build && cd $_
vi Dockerfile    # 在此编辑文件内容
cat Dockerfile

编辑的内容如下所示:

FROM openeuler/openeuler:24.03
COPY hello.sh /usr/bin/
CMD ["sh", "-c", "/usr/bin/hello.sh"]

现在编辑Dockerfile中出现的hello.sh脚本,它将被加到原有的镜像中以构建出我们自己的镜像:

vi hello.sh    #在此编辑文件
cat hello.sh

编辑的内容如下所示:

#!/bin/sh
echo "Hello, iSula!"

还需要修改文件属性:

chmod +x hello.sh

🎶步骤 2:构建容器镜像

用isula-build构建我们自己的容器镜像并导出到isulad,镜像命名为hello-isula-build:v0.1:

isula-build ctr-img build -f ./Dockerfile -o isulad:hello-isula-build:v0.1

执行过程如下所示:

STEP  1: FROM openeuler/openeuler:24.03
Getting image source signatures
Copying blob sha256:9ab49502b701a1e0e74f56eef74b51ac7574a9a1aa75127c8099c33970c94532
Copying blob sha256:16146238a7e868a3df0624b6fbce0ffbe79785ed5e1492c0c13039f6e83dddab
Copying blob sha256:16146238a7e868a3df0624b6fbce0ffbe79785ed5e1492c0c13039f6e83dddab
Copying blob sha256:9ab49502b701a1e0e74f56eef74b51ac7574a9a1aa75127c8099c33970c94532
Copying config sha256:7a0facc10e29fd4f3b5441bac3a8bb9af9c0d6a967f338941b2abe6f74cf78e7
Writing manifest to image destination
Storing signatures
STEP  2: COPY hello.sh /usr/bin/
STEP  3: CMD ["sh", "-c", "/usr/bin/hello.sh"]
Getting image source signatures
Copying blob sha256:b702a8c7fe0fd134a86f349595e8d2ee8bf3565d899494f13c4a37e372ddf0be
Copying blob sha256:d7ae7c9fb8396fa672a2b0b8432da8dfcc7217272ec2fd3dc788c9f46f2bed50
Copying blob sha256:1d7a27b9e743f53c3a10ec3d3fd4e42268cb322248df1975584f0613d6916b0b
Copying config sha256:ea5dc198821f7c8e1b89853ce80b73f472a6ad9bc0af974846046138c1fdd29a
Writing manifest to image destination
Storing signatures
Committed stage 0 with ID: ea5dc198821f7c8e1b89853ce80b73f472a6ad9bc0af974846046138c1fdd29a
Getting image source signatures
Copying blob sha256:b702a8c7fe0fd134a86f349595e8d2ee8bf3565d899494f13c4a37e372ddf0be
Copying blob sha256:d7ae7c9fb8396fa672a2b0b8432da8dfcc7217272ec2fd3dc788c9f46f2bed50
Copying blob sha256:1d7a27b9e743f53c3a10ec3d3fd4e42268cb322248df1975584f0613d6916b0b
Copying config sha256:ea5dc198821f7c8e1b89853ce80b73f472a6ad9bc0af974846046138c1fdd29a
Writing manifest to image destination
Storing signatures
Build success with image id: ea5dc198821f7c8e1b89853ce80b73f472a6ad9bc0af974846046138c1fdd29a

🎶步骤 3:查询构建出来的镜像并运行容器

isula-build ctr-img images

输出如下所示:

---------------------------------------  ----------  -----------------  ------------------------  -----------
 REPOSITORY                               TAG         IMAGE ID           CREATED                   SIZE
---------------------------------------  ----------  -----------------  ------------------------  -----------
 hello-isula-build                        v0.1        ea5dc198821f       2025-05-20 13:07:23       211 MB
 hub.oepkgs.net/openeuler/openeuler       24.03       7a0facc10e29       2025-04-26 00:16:18       211 MB
---------------------------------------  ----------  -----------------  ------------------------  -----------

因为构建过程使用了-o参数导出构建的镜像到本地isulad容器引擎的存储中,所以用isula命令也可直接查看镜像并使用镜像创建容器:

isula images

输出如下所示:

REPOSITORY                     TAG        IMAGE ID             CREATED              SIZE
hello-isula-build              v0.1       ea5dc198821f         2025-05-20 21:07:23  195.150MB

运行容器:

我们使用自己构建出来的容器镜像来运行容器,按照预期,容器进程会打印出“hello, isula-build!”:

isula run hello-isula-build:v0.1

输出:

Hello, iSula!

🎶步骤 4:导出镜像为压缩包

可以将本地构建的镜像导出为tar格式压缩包:

isula-build ctr-img save hello-isula-build:v0.1 -o hello-isula-build.tar

执行过程如下:

Getting image source signatures
Copying blob sha256:b702a8c7fe0fd134a86f349595e8d2ee8bf3565d899494f13c4a37e372ddf0be
Copying blob sha256:d7ae7c9fb8396fa672a2b0b8432da8dfcc7217272ec2fd3dc788c9f46f2bed50
Copying blob sha256:1d7a27b9e743f53c3a10ec3d3fd4e42268cb322248df1975584f0613d6916b0b
Copying config sha256:ea5dc198821f7c8e1b89853ce80b73f472a6ad9bc0af974846046138c1fdd29a
Writing manifest to image destination
Storing signatures
Save success with image: [hello-isula-build:v0.1]

查看导出的文件:

ls # hello-isula-build.tar

🎶步骤 5:从压缩包导入镜像

为了验证导入镜像功能,我们删除先通过Dockerfile创建的镜像。

查看容器ID:

isula ps -a

输出如下:

CONTAINER ID    IMAGE   COMMAND CREATED STATUS  PORTS   NAMES
[root@oexp home]# isula ps -a
CONTAINER ID    IMAGE                   COMMAND                 CREATED         STATUS                          PORTS   NAMES                                           
ebb8433b95fa    hello-isula-build:v0.1  "sh -c /usr/bin/he..."  19 minutes ago  Exited (0) 19 minutes ago               ebb8433b95fa54a5263d0c80c40bbb91c9644a5e53bb28a0af9f2bd9cd0a32f8

删除容器:

isula rm ebb8433b95fa

删除镜像:

isula rmi hello-isula-build:v0.1 # Image "hello-isula-build:v0.1" removed

导入镜像:

isula load -i hello-isula-build.tar

输出如下:

Load image from "/home/hello-isula-build.tar" success

查看导入的镜像:

isula images

输出如下:

REPOSITORY                     TAG        IMAGE ID             CREATED              SIZE
hello-isula-build              v0.1       ea5dc198821f         2025-05-20 21:07:23  195.150MB

运行该镜像的容器实例:

isula run hello-isula-build:v0.1

输出:

Hello, iSula!

删除镜像:

isula ps -a # i.e. CONTAINER-ID is 735c676e84f8
isula rm 735c676e84f8 # 这里需要替换为您自己的CONTAINER-ID
isula rmi hello-isula-build:v0.1 # Image "hello-isula-build:v0.1" removed

🗒️Tips

在这里我们没有使用isula-build ctr-img load -i hello-isula-build.tar命令导入镜像,读者有兴趣的话可以自己通过实践体会它与isula load -i hello-isula-build.tar命令的区别。

🎶步骤 6:更多信息

可以通过帮助获取更多信息:

isula-build --help

isula-build的镜像导出方式

在openEuler操作系统中,isula-build ctr-img build是iSula容器镜像构建工具的核心命令,用于根据Dockerfile构建容器镜像并支持多种导出方式。一般来书,其导出方式有:

  • 导出到isula-build的本地持久化目录中
  • 导出到本地压缩包(前文已有示例)
  • 导出到Docker Daemon
  • 导出到远端仓库
  • 导出到本地iSulad容器引擎的存储中(前文已有示例)

通过isula-build的帮助命令可以查看这些导出方式:

isula-build ctr-img build --help

输出如下所示:

Build container images

Usage:
  isula-build ctr-img build [FLAGS] PATH

Examples:
isula-build ctr-img build -f Dockerfile .
isula-build ctr-img build -f Dockerfile -o docker-archive:name.tar:image:tag .
isula-build ctr-img build -f Dockerfile -o docker-daemon:image:tag .
isula-build ctr-img build -f Dockerfile -o docker://registry.example.com/repository:tag .
isula-build ctr-img build -f Dockerfile -o isulad:image:tag .
isula-build ctr-img build -f Dockerfile --build-static='build-time=2020-06-30 15:05:05' .

Flags:
      --build-arg stringArray   Arguments used during build time
      --build-static listopts   Static build with the given option
      --cap-add stringArray     Add Linux capabilities for RUN command
  -f, --filename string         Path for Dockerfile
      --iidfile string          Write image ID to the file
  -o, --output string           Destination of output images
      --proxy                   Inherit proxy environment variables from host (default true)
  -t, --tag string              Add tag to the built image

Global Flags:
  -D, --debug              Open debug mode
  -h, --help               Print usage
      --log-level string   Log level to be used. Either "debug", "info", "warn" or "error" (default "error")
      --timeout string     Timeout for connecting to daemon
  -v, --version            Version for isula-build client

可以参照以上信息作进一步研究。

FAQ

❔📃 FAQ

Q:在运行isula-build命令时(比如说isula-build ctr-img images)出现以下错误:

invalid socket path: unix:///var/run/isula_build.sock

A:这通常是isula-build服务没有启动导致的,启动该服务即可:

systemctl start isula-build

附录A iSulad架构简介

iSulad-Architecture.jpg

如上图“iSulad Architecture”所示,iSulad容器引擎主要包括以下几个模块:

  • 通信模块:支持gRPC/RESTFUL两种通信方式,提供对外通信的能力;
  • 镜像模块:支持OCI标准镜像,提供content/metadata、rootfs及snapshot管理能力;
  • 运行时模块:支持轻量级Runtime(lcr)和OCI标准的Runtime(runc,kata等);

从接口划分:

  • 北向接口:提供CLI(Command Line Interface)接口和CRI接口;
  • 南向接口:提供统一的Runtime管理接口Plugin,支持lcr和OCI两种类型的Runtime;

附录B iSulad代码仓

🔗iSulad代码仓

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞