
# 设置非集群节点容器应用为只读
#### 操作场景
针对在非集群节点部署的容器（单机容器），企业主机安全不会将其设置为只读模式。为了进一步提升容器网页防篡改防护效果，您可以参考本章节手动将容器设置为只读模式。
#### 约束与限制
当前仅提供Docker和Containerd容器的只读配置指导，其他运行时容器请参考对应官方文档。
#### 配置Docker只读文件系统
在Docker中，主要通过以下两种方式配置只读文件系统。
- 单容器场景：通过"docker run"命令的"--read-only"参数配置只读根文件系统。
- 多容器场景：通过Docker Compose配置只读文件系统。
**注意事项**
- 检查应用是否需要临时写入：请检查您的应用是否需要在只读模式下写入数据。如果写入临时文件、日志或数据，可通过"--tmpfs"或"-v"将这些操作定向挂载到可写路径。
- 只读模式禁止修改：设置为只读文件系统后，如果应用尝试在只读文件系统上创建文件或目录，会遇到"Read-only file system"报错。
- 特殊路径处理：由Linux内核直接管理的目录，例如"/proc"、"/sys"、"/dev"等，不受"--read-only"参数配置影响，因此您需要单独配置只读模式。您可以根据需要额外挂载，例如以只读方式重新挂载"/proc/sys"或"/dev/shm"。
**操作步骤**
- **通过"docker run"命令的"--read-only"参数配置只读根文件系统**
  1. 设置基本只读模式**。**
     使用"--read-only"参数启动容器，使其根文件系统为只读。命令如下：
     ```
     docker run --read-only -d --name my-readonly-container nginx:alpine
     ```
     
  
  
  
  2. 使用 "--tmpfs"，允许临时写入。 许多应用需要在"/tmp"、"/run等"目录创建临时文件。您可以通过"--tmpfs"参数挂载可写的目录。命令如下：
     ```
     docker run --read-only \
     --tmpfs /tmp \
     --tmpfs /run \
     -d --name nginx-tmpfs nginx:alpine
     ```
     
  
  
  
  3. 使用 "-v"挂载可写卷，允许特定路径写入。 如果应用需要向特定目录（如日志、数据目录）写入，可将这些目录以卷（volume）或绑定挂载（bind mount）方式挂载为可写。命令如下：
     - 使用命名卷挂载日志目录
     
     
     ```
     docker volume create nginx-logs
     docker run --read-only \
     --tmpfs /tmp \
     --tmpfs /var/lib/nginx/tmp \
     -v nginx-logs:/var/log/nginx \
     -d --name nginx-with-logs nginx:alpine
     ```
     - 使用绑定挂载到宿主机目录
     
     
     ```
     mkdir -p /host/path/nginx/logs
     docker run --read-only \
     --tmpfs /tmp \
     -v /host/path/nginx/logs:/var/log/nginx \
     -d --name nginx-bind-logs nginx:alpine
     ```
     
  
  
  配置示例可参见[Docker配置示例：运行一个只读的Nginx容器]。
  

- **通过Docker Compose配置只读文件系统**
  在"docker-compose.yml"文件中，可参考如下配置只读文件系统和tmpfs。
  ```
  ```yaml
      version: '3.8'
      services:
        my-app:
          image: nginx:alpine
          read_only: true
          tmpfs:
            - /tmp
            - /run
          volumes:
            - nginx-logs:/var/log/nginx
      volumes:
        nginx-logs:
      ```
  ```
  
 
#### 配置Containerd只读文件系统
在Containerd中，可以通过客户端工具，如ctr、nerdctl，配置只读根文件系统。
**约束限制**
不同版本的Containerd和ctr，设置只读文件系统的参数可能略有不同，请以实际环境为准。
**操作步骤**
- **使用ctr设置只读文件系统**
  通过ctr运行容器时，可以使用"--rootfs-readonly"参数来设置根文件系统为只读。命令如下：
  ```
  # 首先将镜像拉取到本地
  ctr images pull docker.io/library/nginx:alpine
  # 使用--rootfs-readonly参数运行容器
  ctr run --rm \
  --read-only \  # 这个参数通常用于设置根文件系统只读
  --mount type=tmpfs,destination=/tmp,tmpfs-size=16777216 \
    docker.io/library/nginx:alpine \
    nginx-readonly
  ```
  ![](https://support.huaweicloud.com/usermanual-hss2.0/public_sys-resources/caution_3.0-zh-cn.png)
  ctr命令的参数和功能可能随版本更新，上述"--read-only"或"--rootfs-readonly"参数需根据您的Containerd版本确认，如有需要请查阅官方文档。
  
- **使用 nerdctl设置只读文件系统**
  nerdctl是一个与Docker CLI兼容的Containerd客户端。您可以使用nerdctl启动只读容器，语法类似Docker。命令如下：
  ```
  nerdctl run --read-only \
  --tmpfs /tmp \
  -d --name nginx-nerdctl nginx:alpine
  ```
  配置示例可参见[Containerd配置示例：使用nerdctl运行只读容器]。
  
 
 #### Docker配置示例：运行一个只读的Nginx容器
如下是一个使用"--read-only"运行只读的Nginx容器的示例，处理了Nginx需要写入的目录：
```
# 创建存储Nginx日志和临时文件的卷
docker volume create nginx-logs
docker volume create nginx-cache
# 启动一个只读的Nginx容器
docker run -d \
  --name nginx-readonly \
  --read-only \
  --tmpfs /tmp \
  --tmpfs /var/cache/nginx:mode=755,uid=101,gid=101 \  # nginx用户通常uid=101
  -v nginx-logs:/var/log/nginx \
  -v nginx-cache:/var/cache/nginx \
  -p 80:80 \
  nginx:alpine
# 检查容器日志，确认Nginx启动正常
docker logs nginx-readonly
```
 #### Containerd配置示例：使用nerdctl运行只读容器
如下是使用nerdctl运行一个只读Nginx容器的示例：
```
# 拉取镜像
nerdctl pull nginx:alpine
# 运行只读容器，挂载tmpfs和卷
nerdctl run -d \
  --name nginx-readonly-nerdctl \
  --read-only \
  --tmpfs /tmp \
  --tmpfs /run \
  --mount type=volume,source=nginx-logs,destination=/var/log/nginx \
  -p 8080:80 \
  nginx:alpine
# 查看容器状态
nerdctl ps
```
