运行容器

描述

isula run命令命令用于创建一个新的容器。会使用指定的容器镜像创建容器读写层,并且为运行指定的命令做好准备。创建完成后,使用指定的命令启动该容器。run命令相当于create然后start容器。

用法

  1. isula run [OPTIONS] ROOTFS|IMAGE [COMMAND] [ARG...]

参数

run命令支持参数参考下表。

表 1 run命令参数列表

命令

参数

说明

run

—annotation

设置容器的annotations。例如支持native.umask选项:

  1. annotation native.umask=normal # 启动的容器umask值为0022
  2. annotation native.umask=secure # 启动的容器umask值为0027

注意如果没有配置该参数,则使用isulad中的umask配置。

—cap-add

添加Linux功能

—cap-drop

删除Linux功能

—cgroup-parent

指定容器cgroup父路径

—cpuset-cpus

允许执行的CPU(e.g. 0-3,0,1)

—cpu-shares

CPU份额(相对权重)

—cpu-quota

限制CPU CFS(完全公平调度器)的配额

-d, —detach

后台运行容器并打印容器ID

—device=[]

为容器添加一个主机设备

-e, —env

设置环境变量

—env-file

通过文件配置环境变量

—entrypoint

启动容器时要运行的入口点

—external-rootfs=PATH

指定一个不由iSulad管理的rootfs(可以为文件夹或块设备)给容器

—files-limit

调整容器内能够打开的文件句柄数(-1表示不限制)

—group-add=[]

指定额外的用户组添加到容器

—help

打印帮助信息

—hook-spec

钩子配置文件

-H, —host

指定要连接的iSulad socket文件路径

-h, —hostname

容器主机名称

—hugetlb-limit=[]

大页文件限制,例如:—hugetlb-limit 2MB:32MB

-i, —interactive

即使没有连接到容器的标准输入,也要保持容器的标准输入打开

—log-opt=[]

日志驱动程序选项,默认禁用记录容器串口日志功能,可以通过”—log-opt disable-log=false”来开启。

-m, —memory

内存限制

—memory-reservation

设置容器内存限制,默认与—memory一致。可认为—memory是硬限制,—memory-reservation是软限制;当使用内存超过预设值时,会动态调整(系统回收内存时尝试将使用内存降低到预设值以下),但不确保一定不超过预设值。一般可以和—memory一起使用,数值小于—memory的预设值,最小设置为4MB。

—memory-swap

正整数,内存 + 交换空间,-1 表示不限制

—mount

挂载主机目录到容器中

—name=NAME

容器名

—net=none

容器连接到网络

—pids-limit

调整容器内能够执行的进程数(-1表示不限制)

—privileged

给予容器扩展的特权

-R, —runtime

容器运行时,参数支持”lcr”,忽略大小写,因此”LCR”和”lcr”是等价的

—read-only

设置容器的根文件系统为只读

—restart

当容器退出时重启策略

系统容器支持—restart on-reboot

—rm

当容器退出时自动清理容器

—storage-opt

配置容器的存储驱动选项

-t, —tty

分配伪终端

—ulimit

为容器设置ulimit限制

-u, —user

用户名或UID,格式[<name|uid>][:<group|gid>]

-v, —volume=[]

挂载一个卷

约束限制

  • 容器父进程进程退出时,则对应的容器也自动退出。
  • 创建普通容器时父进程不能为init,因为普通容器的权限不够,导致容器可以创建成功,但是attach进去的时候会卡住。
  • 运行容器时,不指定—net,默认hostname为localhost
  • 使用—files-limit参数传入一个很小的值,如1时,启动容器时,iSulad创建cgroup子组后先设置files.limit值,再将容器进程的PID写入该子组的cgroup.procs文件,此时容器进程已经打开超过1个句柄,因而写入报错导致启动失败启动容器会失败。
  • —mount参数和—volume参数同时存在时,如果目的路径有冲突,则—mount会在—volume之后挂载(即将—volume中的挂载点覆盖掉)。

    备注:轻量级容器的参数中type支持bind或squashfs,当type=squashfs时,src是镜像的路径;原生docker的参数type支持bind、volume、tmpfs。

  • restart重启策略不支持unless-stopped。

  • 以下三种情况与docker 返回值不一致,docker返回127,轻量级容器返回125

    —device参数指定主机设备为不存在的设备

    —hook-spec参数指定不存在的hook json文件

    —entrypoint 参数指定不存在的入口参数

  • 使用—volume参数时,由于容器启动时会对/dev/ptmx设备进行删除重建,因此请勿将/dev目录挂载至容器/dev目录,应使用—device对/dev下的设备在容器中进行挂载

  • 禁止使用echo的方式向run命令的stdin输入数据,会导致客户端卡死。应该直接将echo的值作为命令行参数传给容器

    ``` [root@localhost ~]# echo ls | isula run -i busybox /bin/sh

  1. ^C
  2. [root@localhost ~]#
  3. ```
  4. 上述命令出现客户端卡死现象,这是由于上述命令相当于往stdin输入ls,随后EOF被读取,客户端不再发送数据,等待服务端退出,但是服务端无法区分客户端是否需要继续发送数据,因而服务端卡在read数据上,最终导致双方均卡死。
  5. 正确的执行方式为:
  6. ```
  7. [root@localhost ~]# isula run -i busybox ls
  8. bin
  9. dev
  10. etc
  11. home
  12. proc
  13. root
  14. sys
  15. tmp
  16. usr
  17. var
  18. [root@localhost ~]#
  19. ```
  • 使用host的根目录(/)作为容器的文件系统,那么在挂载路径时,如果有如下情况

    表 2 挂载情况

    Host 路径(source)

    容器路径(dest

    /home/test1

    /mnt/

    /home/test2

    /mnt/abc

    运行容器 - 图1 须知:
    第一种情况,先挂载/home/test1,然后挂载/home/test2,这种情况会导致/home/test1的内容覆盖掉原来/mnt下面的内容,这样可能导致/mnt下面不存在abc目录,这样会导致挂载/home/test2到/mnt/abc失败。
    第二种情况,先挂载/home/test2,然后挂载/home/test1。这种情况,第二次的挂载会把/mnt的内容替换为/home/test1的内容,这样第一次挂载的/home/test2到/mnt/abc的内容就看不到了。
    因此,不支持第一种使用方式;第二种使用用户需要了解这种数据无法访问的风险

    运行容器 - 图2 须知:

    • 高并发场景(并发启动200容器)下,glibc的内存管理机制会导致内存空洞以及虚拟内存较大(例如10GB)的问题。该问题是高并发场景下glibc内存管理机制的限制,而不是内存泄露,不会导致内存消耗无限增大。可以通过设置MALLOC_ARENA_MAX环境变量来减少虚拟内存的问题,而且可以增大减少物理内存的概率。但是这个环境变量会导致iSulad的并发性能下降,需要用户根据实际情况做配置。
      1. 参考实践情况,平衡性能和内存,可以设置MALLOC_ARENA_MAX4。(在arm64服务器上面对iSulad的性能影响在10%以内)
      2. 配置方法:
      3. 1. 手动启动iSulad的场景,可以直接export MALLOC_ARENA_MAX=4,然后再启动iSulad即可。
      4. 2. systemd管理iSulad的场景,可以修改/etc/sysconfig/iSulad,增加一条MALLOC_ARENA_MAX=4即可。

示例

运行一个新容器

  1. $ isula run -itd busybox
  2. 9c2c13b6c35f132f49fb7ffad24f9e673a07b7fe9918f97c0591f0d7014c713b