# 为安全容器配置资源

- [为安全容器配置资源](#为安全容器配置资源)
    - [资源共享](#资源共享)
    - [限制CPU资源](#限制CPU资源)
    - [限制内存资源](#限制内存资源)
    - [限制Blkio资源](#限制Blkio资源)
    - [限制文件描述符资源](#限制文件描述符资源)



安全容器运行于虚拟化隔离的轻量级虚拟机内，因此资源的配置应分为两部分：对轻量级虚拟机的资源配置，即Host资源配置；对虚拟机内容器的配置，即Guest容器资源配置。以下资源配置均分为这两部分。

## 资源共享-27

由于安全容器运行于虚拟化隔离的轻量虚拟机内，故无法访问Host上某些namespace下的资源，因此启动时不支持--net host，--ipc host，--pid host，--uts host。

当启动一个Pod时，同一个Pod中的所有容器默认共享同一个net namespace和ipc namespace。如果同一个Pod中的容器需要共享pid namespace，则可以通过Kubernetes进行配置，Kubernetes 1.11版本该值为默认关闭。

## 限制CPU资源

1.  配置轻量级虚拟机CPU运行资源

    对轻量级虚拟机的CPU资源配置即虚拟机运行的vcpu配置，安全容器使用--annotation com.github.containers.virtcontainers.sandbox\_cpu配置轻量级虚拟机运行CPU资源，该参数仅可配置在pause容器上：

    ```
    docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox --annotation com.github.containers.virtcontainers.sandbox_cpu=<cpu-nums> <pause-image> <command>
    ```

    举例：

    ```
    # 启动一个pause容器
    docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox --annotation com.github.containers.virtcontainers.sandbox_cpu=4 busybox sleep 999999
    be3255a3f66a35508efe419bc52eccd3b000032b9d8c9c62df611d5bdc115954
    
    # 进入容器查看CPU信息，查看CPU个数是否与com.github.containers.virtcontainers.sandbox_cpu配置的CPU个数相等
    docker exec be32 lscpu
    Architecture:        aarch64
    Byte Order:          Little Endian
    CPU(s):              4
    On-line CPU(s) list: 0-3
    Thread(s) per core:  1
    Core(s) per socket:  1
    Socket(s):           4
    ```

    >![](public_sys-resources/icon-note.gif) **说明：**   
    >CPU个数可以设置的最大值为当前OS上可供运行的CPU值（除去隔离核），最小值为0.5个CPU。  

2.  配置容器CPU运行资源

    配置容器CPU运行资源与开源docker容器配置CPU运行资源的方式相同，可以通过docker run命令中CPU资源限制相关的参数进行配置：

    <a name="zh-cn_topic_0183903699_table11321051171213"></a>
    <table><thead align="left"><tr id="zh-cn_topic_0183903699_row5321251121219"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="zh-cn_topic_0183903699_p1208737146"><a name="zh-cn_topic_0183903699_p1208737146"></a><a name="zh-cn_topic_0183903699_p1208737146"></a><strong id="zh-cn_topic_0183903699_b1243812519152"><a name="zh-cn_topic_0183903699_b1243812519152"></a><a name="zh-cn_topic_0183903699_b1243812519152"></a>参数</strong></p>
    </th>
    <th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="zh-cn_topic_0183903699_p1332145111210"><a name="zh-cn_topic_0183903699_p1332145111210"></a><a name="zh-cn_topic_0183903699_p1332145111210"></a><strong id="zh-cn_topic_0183903699_b12491112818158"><a name="zh-cn_topic_0183903699_b12491112818158"></a><a name="zh-cn_topic_0183903699_b12491112818158"></a>含义</strong></p>
    </th>
    </tr>
    </thead>
    <tbody><tr id="zh-cn_topic_0183903699_row1532175119122"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="zh-cn_topic_0183903699_p15321251191214"><a name="zh-cn_topic_0183903699_p15321251191214"></a><a name="zh-cn_topic_0183903699_p15321251191214"></a>--cpu-shares</p>
    </td>
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="zh-cn_topic_0183903699_p232951121217"><a name="zh-cn_topic_0183903699_p232951121217"></a><a name="zh-cn_topic_0183903699_p232951121217"></a>设置容器能使用的CPU时间比例。</p>
    </td>
    </tr>
    <tr id="zh-cn_topic_0183903699_row1232125121218"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="zh-cn_topic_0183903699_p43265191210"><a name="zh-cn_topic_0183903699_p43265191210"></a><a name="zh-cn_topic_0183903699_p43265191210"></a>--cpus</p>
    </td>
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="zh-cn_topic_0183903699_p193217517128"><a name="zh-cn_topic_0183903699_p193217517128"></a><a name="zh-cn_topic_0183903699_p193217517128"></a>设置容器可以使用的 CPU 个数。</p>
    </td>
    </tr>
    <tr id="zh-cn_topic_0183903699_row173275113128"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="zh-cn_topic_0183903699_p43295116127"><a name="zh-cn_topic_0183903699_p43295116127"></a><a name="zh-cn_topic_0183903699_p43295116127"></a>--cpu-period</p>
    </td>
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="zh-cn_topic_0183903699_p16321151161215"><a name="zh-cn_topic_0183903699_p16321151161215"></a><a name="zh-cn_topic_0183903699_p16321151161215"></a>设置容器进程的调度周期。</p>
    </td>
    </tr>
    <tr id="zh-cn_topic_0183903699_row188213501157"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="zh-cn_topic_0183903699_p158831150161512"><a name="zh-cn_topic_0183903699_p158831150161512"></a><a name="zh-cn_topic_0183903699_p158831150161512"></a>--cpu-quota</p>
    </td>
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="zh-cn_topic_0183903699_p12883750151511"><a name="zh-cn_topic_0183903699_p12883750151511"></a><a name="zh-cn_topic_0183903699_p12883750151511"></a>设置每个容器进程调度周期内能够使用的CPU时间。</p>
    </td>
    </tr>
    <tr id="zh-cn_topic_0183903699_row1475055510158"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="zh-cn_topic_0183903699_p5750145515159"><a name="zh-cn_topic_0183903699_p5750145515159"></a><a name="zh-cn_topic_0183903699_p5750145515159"></a>--cpuset-cpus</p>
    </td>
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="zh-cn_topic_0183903699_p1750125561520"><a name="zh-cn_topic_0183903699_p1750125561520"></a><a name="zh-cn_topic_0183903699_p1750125561520"></a>设置容器进程可以使用的CPU列表。</p>
    <div class="note" id="zh-cn_topic_0183903699_note1610940172310"><a name="zh-cn_topic_0183903699_note1610940172310"></a><a name="zh-cn_topic_0183903699_note1610940172310"></a><span class="notetitle"> 说明： </span><div class="notebody"><p id="zh-cn_topic_0183903699_p1410950132311"><a name="zh-cn_topic_0183903699_p1410950132311"></a><a name="zh-cn_topic_0183903699_p1410950132311"></a>安全容器使用 --cpuset-cpus 参数绑定CPU时，CPU的编号不能超过安全容器对应的轻量级虚机中CPU的个数减1（轻量级虚机中CPU的编号从0开始）。</p>
    </div></div>
    </td>
    </tr>
    <tr id="zh-cn_topic_0183903699_row830172021620"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="zh-cn_topic_0183903699_p173012012166"><a name="zh-cn_topic_0183903699_p173012012166"></a><a name="zh-cn_topic_0183903699_p173012012166"></a>--cpuset-mems</p>
    </td>
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="zh-cn_topic_0183903699_p129461755102515"><a name="zh-cn_topic_0183903699_p129461755102515"></a><a name="zh-cn_topic_0183903699_p129461755102515"></a><span>设定该容器进程可以访问的内存节点。</span></p>
    <div class="note" id="zh-cn_topic_0183903699_note17106188267"><a name="zh-cn_topic_0183903699_note17106188267"></a><a name="zh-cn_topic_0183903699_note17106188267"></a><span class="notetitle"> 说明： </span><div class="notebody"><p id="zh-cn_topic_0183903699_p21015188261"><a name="zh-cn_topic_0183903699_p21015188261"></a><a name="zh-cn_topic_0183903699_p21015188261"></a>安全容器不支持多NUMA架构和配置，使用NUMA memory的--cpuset-mems参数只能配置为0。</p>
    </div></div>
    </td>
    </tr>
    </tbody>
    </table>

3.  配置CPU热插拔功能

    >![](public_sys-resources/icon-note.gif) **说明：**   
    >安全容器CPU热插拔功能需要虚拟化组件qemu支持CPU热插拔。  

    kata-runtime配置文件config.toml中**enable\_cpu\_memory\_hotplug**选项负责开启和禁用CPU和内存热插拔。默认取值为false，表示禁用CPU和内存热插拔功能；取值为true，表示开启CPU和内存热插拔功能。

    kata-runtime中复用了**--cpus**选项实现了CPU热插拔的功能，通过统计Pod中所有容器的**--cpus**选项的和，然后确定需要热插多少个CPU到轻量级虚机中。

    举例：

    ```
    # 启动一个pause容器，轻量级虚机默认分配了1个vcpu
    docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox busybox sleep 999999
    77b40fb72f63b11dd3fcab2f6dabfc7768295fced042af8c7ad9c0286b17d24f
    
    # 查看启动完pause容器后轻量级虚机中CPU个数
    docker exec 77b40fb72f6 lscpu
    Architecture:          x86_64
    CPU op-mode(s):        32-bit, 64-bit
    Byte Order:            Little Endian
    CPU(s):                1
    On-line CPU(s) list:   0
    Thread(s) per core:    1
    Core(s) per socket:    1
    Socket(s):             1
    
    # 在同一个Pod中启动新的容器并通过--cpus设置容器需要的CPU数量为4
    docker run -tid --runtime kata-runtime --network none --cpus 4 --annotation io.kubernetes.docker.type=container --annotation io.kubernetes.sandbox.id=77b40fb72f63b11dd3fcab2f6dabfc7768295fced042af8c7ad9c0286b17d24f busybox sleep 999999
    7234d666851d43cbdc41da356bf62488b89cd826361bb71d585a049b6cedafd3
    
    # 查看当前轻量级虚机中CPU的个数
    docker exec 7234d6668 lscpu
    Architecture:          x86_64
    CPU op-mode(s):        32-bit, 64-bit
    Byte Order:            Little Endian
    CPU(s):                4
    On-line CPU(s) list:   0-3
    Thread(s) per core:    1
    Core(s) per socket:    1
    Socket(s):             4
    
    # 删除热插了CPU的容器后，查看轻量级虚机中CPU的个数
    docker rm -f 7234d666851d
    7234d666851d
    
    docker exec 77b40fb72f6  lscpu
    Architecture:          x86_64
    CPU op-mode(s):        32-bit, 64-bit
    Byte Order:            Little Endian
    CPU(s):                1
    On-line CPU(s) list:   0
    Thread(s) per core:    1
    Core(s) per socket:    1
    Socket(s):             1
    ```

      

      

    >![](public_sys-resources/icon-note.gif) **说明：**   
    >由于pause容器只是一个占位容器没有工作负载，所以轻量级虚机启动时默认分配的1个CPU可以被其它容器共享，因此上面例子中启动的新容器只需要再热插3个CPU到轻量级虚机中即可。  

    -   当停止热插了CPU的容器后，启动容器时热插进去的CPU也会被拔出。


## 限制内存资源

1.  配置轻量级虚拟机MEM运行资源

    对轻量级虚拟机的MEM资源配置即虚拟机运行的内存进行配置，安全容器使用--annotation com.github.containers.virtcontainers.sandbox\_mem配置轻量级虚拟机运行MEM资源，该参数仅可配置在pause容器上：

    ```
    docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox --annotation com.github.containers.virtcontainers.sandbox_mem=<memory-size> <pause-image> <command>
    ```

    举例：

    ```
    # 启动一个pause容器，通过--annotation com.github.containers.virtcontainers.sandbox_mem=4G为轻量级虚机分配4G内存
    docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox --annotation com.github.containers.virtcontainers.sandbox_mem=4G busybox sleep 999999
    1532c3e59e7a45cd6b419aa1db07dd0069b0cdd93097f8944177a25e457e4297
    
    # 查看轻量级虚机中内存信息，查看内存大小是否与com.github.containers.virtcontainers.sandbox_mem配置的内存大小相等
    docker exec 1532c3e free -m
                  total        used        free      shared  buff/cache   available
    Mem:           3950          20        3874          41          55        3858
    Swap:             0           0           0
    ```

    >![](public_sys-resources/icon-note.gif) **说明：**   
    >-   如果没有通过--annotation com.github.containers.virtcontainers.sandbox\_mem显示地设置轻量级虚机的内存大小，则轻量级虚机默认使用的内存大小为1GB。  
    >-   安全容器一个Pod的最小内存规格是1GB，支持的最大内存规格是256GB。如果用户分配的内存规格超过256GB，可能会出现未定义的错误，安全容器暂不支持超过256GB的大内存场景。  

2.  配置容器MEM运行资源

    配置容器MEM运行资源与开源docker容器配置MEM运行资源的方式相同，可以通过docker run命令中MEM资源限制相关的参数进行配置：

    <a name="zh-cn_topic_0182219834_table11321051171213"></a>
    <table><thead align="left"><tr id="zh-cn_topic_0182219834_row5321251121219"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="zh-cn_topic_0182219834_p1208737146"><a name="zh-cn_topic_0182219834_p1208737146"></a><a name="zh-cn_topic_0182219834_p1208737146"></a><strong id="zh-cn_topic_0182219834_b1243812519152"><a name="zh-cn_topic_0182219834_b1243812519152"></a><a name="zh-cn_topic_0182219834_b1243812519152"></a>参数</strong></p>
    </th>
    <th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="zh-cn_topic_0182219834_p1332145111210"><a name="zh-cn_topic_0182219834_p1332145111210"></a><a name="zh-cn_topic_0182219834_p1332145111210"></a><strong id="zh-cn_topic_0182219834_b12491112818158"><a name="zh-cn_topic_0182219834_b12491112818158"></a><a name="zh-cn_topic_0182219834_b12491112818158"></a>含义</strong></p>
    </th>
    </tr>
    </thead>
    <tbody><tr id="zh-cn_topic_0182219834_row1532175119122"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="zh-cn_topic_0182219834_p15321251191214"><a name="zh-cn_topic_0182219834_p15321251191214"></a><a name="zh-cn_topic_0182219834_p15321251191214"></a>-m/--memory</p>
    </td>
    <td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="zh-cn_topic_0182219834_p232951121217"><a name="zh-cn_topic_0182219834_p232951121217"></a><a name="zh-cn_topic_0182219834_p232951121217"></a>设置容器进程可以使用的内存大小。</p>
    <div class="note" id="zh-cn_topic_0182219834_note04024417164"><a name="zh-cn_topic_0182219834_note04024417164"></a><a name="zh-cn_topic_0182219834_note04024417164"></a><span class="notetitle"> 说明： </span><div class="notebody"><a name="zh-cn_topic_0182219834_ul16187123721710"></a><a name="zh-cn_topic_0182219834_ul16187123721710"></a><ul id="zh-cn_topic_0182219834_ul16187123721710"><li>当内存热插拔开关关闭时，-m的取值要小于等于轻量级虚机启动时分配的内存大小。</li></ul>
    </div></div>
    </td>
    </tr>
    </tbody>
    </table>

3.  配置MEM热插功能

    同配置CPU热插拔功能一样，MEM的热插功能也是由kata-runtime配置文件config.toml中**enable\_cpu\_memory\_hotplug**选项配置，用法参见[3](#限制CPU资源.md#zh-cn_topic_0183903699_li2167326144011)。

    >![](public_sys-resources/icon-note.gif) **说明：**   
    >内存资源当前只支持热插，不支持内存热拔。  

    kata-runtime中复用了**-m**选项实现了MEM热插的功能，通过统计Pod中所有容器的**-m**选项的和，然后确定需要热插多少内存到轻量级虚机中，例如，

    举例：

    ```
    # 启动一个pause容器，轻量级虚机默认分配了1GB内存
    docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox busybox sleep 999999
    99b78508ada3fa7dcbac457bb0f6e3784e64e7f7131809344c5496957931119f
    
    # 查看启动完pause容器后轻量级虚机中的内存大小
    docker exec 99b78508ada free -m
                  total        used        free      shared  buff/cache   available
    Mem:            983          18         914          36          50         908
    Swap:             0           0           0
    
    # 在同一个Pod中启动新的容器并通过-m设置容器需要的内存大小为4G
    docker run -tid --runtime kata-runtime --network none -m 4G --annotation io.kubernetes.docker.type=container --annotation io.kubernetes.sandbox.id=99b78508ada3fa7dcbac457bb0f6e3784e64e7f7131809344c5496957931119f busybox sleep 999999
    c49461745a712b2ef3127fdf43b2cbb034b7614e6060b13db12b7a5ff3c830c8
    
    # 查看当前轻量级虚机中内存的大小
    docker exec c49461745 free -m
                  total        used        free      shared  buff/cache   available
    Mem:           4055          69        3928          36          57        3891
    Swap:             0           0           0
    
    # 删除热插了CPU的容器后，查看轻量级虚机中内存的大小
    docker rm -f c49461745
    c49461745
    
    # 因为热插的内存暂不支持热拔功能，所以轻量级虚机中在删除热插内存容器之后还是拥有4GB的内存
    docker exec 99b78508ada free -m
                  total        used        free      shared  buff/cache   available
    Mem:           4055          69        3934          36          52        3894
    Swap:             0           0           0
    ```

    >![](public_sys-resources/icon-note.gif) **说明：**   
    >由于pause容器只是一个占位容器没有工作负载，所以轻量级虚机启动时分配的内存可以被其它容器共享使用，因此上面例子中启动的新容器只需要再热插3GB的内存到轻量级虚机中即可。  


## 限制Blkio资源

1.  配置轻量级虚拟机Blkio运行资源

    对轻量级虚拟机的BlkIio资源配置，安全容器使用--annotation com.github.containers.virtcontainers.blkio\_cgroup配置轻量级虚拟机使用的块设备的blkio资源，该参数仅可配置在pause容器上：

    ```
    docker run -tid --runtime --network none --annotation io.kubernetes.docker.type=podsandbox --annotation com.github.containers.virtcontainers.blkio_cgroup=<blkio json格式字符串> <pause-image> <command>
    ```

    其中--annotation com.github.containers.virtcontainers.blkio\_cgroup的取值要符合下面BlkioCgroup结构体的定义：

    ```
    // BlkioCgroup for Linux cgroup 'blkio' data exchange
    type BlkioCgroup struct {
    	// Items specifies per cgroup values
    	Items []BlockIOCgroupItem `json:"blkiocgroup,omitempty"`
    }
    
    type BlockIOCgroupItem struct {
    	// Path represent path of blkio device
    	Path string `json:"path,omitempty"`
    	// Limits specifies the blkio type and value
    	Limits []IOLimit `json:"limits,omitempty"`
    }
    
    type IOLimit struct {
    	// Type specifies IO type
    	Type string `json:"type,omitempty"`
    	// Value specifies rate or weight value
    	Value uint64 `json:"value,omitempty"`
    }
    ```

    IOLimit结构体中Type字段取值列表为：

    ```
    // BlkioThrottleReadBps is the key to fetch throttle_read_bps
    BlkioThrottleReadBps = "throttle_read_bps"
    
    // BlkioThrottleWriteBps is the key to fetch throttle_write_bps
    BlkioThrottleWriteBps = "throttle_write_bps"
    
    // BlkioThrottleReadIOPS is the key to fetch throttle_read_iops
    BlkioThrottleReadIOPS = "throttle_read_iops"
    
    // BlkioThrottleWriteIOPS is the key to fetch throttle_write_iops
    BlkioThrottleWriteIOPS = "throttle_write_iops"
    
    // BlkioWeight is the key to fetch blkio_weight
    BlkioWeight = "blkio_weight"
    
    // BlkioLeafWeight is the key to fetch blkio_leaf_weight
    BlkioLeafWeight = "blkio_leaf_weight"
    ```

    举例：

    ```
    docker run -tid --runtime kata-runtime --network none --annotation com.github.containers.virtcontainers.blkio_cgroup='{"blkiocgroup":[{"path":"/dev/sda","limits":[{"type":"throttle_read_bps","value":400},{"type":"throttle_write_bps","value":400},{"type":"throttle_read_iops","value":700},{"type":"throttle_write_iops","value":699}]},{"limits":[{"type":"blkio_weight","value":78}]}]}' busybox sleep 999999
    ```

    上面命令表示对启动的安全容器所使用的/dev/sda磁盘进行blkio限流，分别将throttle\_read\_bps限速为400bps，throttle\_write\_bps限速为400bps，throttle\_read\_iops限速为700次/秒，throttle\_write\_iops限速为699次/秒，以及所在blkio cgroup组的权重值设置为78。


## 限制文件描述符资源

为了避免在容器中打开大量9p共享目录中的文件导致主机上文件描述符资源耗尽，使得安全容器无法正常提供服务，安全容器支持自定义配置安全容器qemu进程最多可以打开的文件描述符数量限制。

安全容器通过复用docker run命令中的**--files-limit**选项来设置安全容器qemu进程最多可以打开文件描述符，该参数仅可配置在pause容器上，使用方法如下所示：

```
docker run -tid --runtime kata-runtime --network none --annotation io.kubernetes.docker.type=podsandbox --files-limit <max-open-files> <pause-image> bash
```

>![](public_sys-resources/icon-note.gif) **说明：**   
>-   如果**--files-limit**选项的取值小于安全容器默认设置的最小值1024且不为0时，安全容器qemu进程最多可以打开的文件描述符数量会被设置为最小值1024。  
>-   如果**--files-limit**选项的取值为0时，安全容器qemu进程最多可以打开的文件描述符数量为系统可以打开文件描述符的最大值/proc/sys/fs/file-max除以400后得到的默认值。  
>-   如果启动安全容器时没有显示指定**--files-limit**可以打开的文件描述符的上限，安全容器qemu进程可以打开的文件描述符数量的上限和系统默认值保持一致。  

