Update 20210902 4 Linux technologies fundamental to containers.md

This commit is contained in:
SamMa 2021-09-16 19:33:22 +08:00 committed by GitHub
parent 371e3eff2f
commit 8af4b2c107
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,18 +3,18 @@
[#]: author: "Nived V https://opensource.com/users/nivedv"
[#]: collector: "lujun9972"
[#]: translator: "wxy"
[#]: reviewer: " "
[#]: reviewer: "turbokernel"
[#]: publisher: " "
[#]: url: " "
容器的四大基础技术
======
> 命名空间、控制组、seccomp 和 SELinux 构成了在你的系统上构建和运行一个容器进程的 Linux 技术基础。
> 命名空间、控制组、seccomp 和 SELinux 构成了在系统上构建和运行一个容器进程的 Linux 技术基础。
![企鹅驾驶一辆黄色背景的汽车][1]
在以前的文章中,我介绍过 [容器镜像][2] 及其 [运行时][3]。在这篇文章中,我研究了容器是如何在一些特殊的 Linux 技术基础上实现的,这些技术包括命名空间和控制组。
在以前的文章中,我介绍过 [容器镜像][2] 及其 [运行时][3]。在本文中,我研究了容器是如何在一些特殊的 Linux 技术基础上实现的,这其中包括命名空间和控制组。
![容器技术的层次][4]
@ -29,7 +29,7 @@
### 命名空间
<ruby>命名空间<rt>namespace</rt></ruby> 为容器提供了一个隔离层,给容器提供了一个看起来是它自己的 Linux 文件系统的视图。这就限制了进程所能看到的东西,从而限制了它所能获得的资源。
<ruby>命名空间<rt>namespace</rt></ruby> 为容器提供了一个隔离层,给容器提供了一个看起来是独占的 Linux 文件系统的视图。这就限制了进程能访问的内容,从而限制了它所能获得的资源。
在创建容器时Docker 或 Podman 和其他容器技术使用了 Linux 内核中的几个命名空间:
@ -48,15 +48,15 @@
```
#### 用户
用户(`user`)命名空间将用户和组隔离在一个容器内。这是通过允许容器与宿主系统有不同的 UID 和 GID 范围来实现的。用户命名空间使软件能够以 root 用户的身份在容器内运行。如果入侵者攻击容器,然后逃逸到宿主机上,他们就受限于只能以非 root身份出现了。
用户(`user`)命名空间将用户和组隔离在一个容器内。这是通过分配给容器与宿主系统有不同的 UID 和 GID 范围来实现的。用户命名空间使软件能够以 root 用户的身份在容器内运行。如果入侵者攻击容器,然后逃逸到宿主机上,他们就只能以受限的非 root身份运行了。
#### 挂载
挂载(`mnt`)命名空间允许容器对系统的文件系统层次结构有自己的视图。你可以在 Linux 系统中的 `/proc/<PID>/mounts` 位置找到每个容器进程的挂载点。
挂载(`mnt`)命名空间允许容器有自己的文件系统层次结构视图。你可以在 Linux 系统中的 `/proc/<PID>/mounts` 位置找到每个容器进程的挂载点。
#### UTS
<ruby>Unix 分时系统<rt>Unix Timeharing System</rt></ruby>UTS命名空间允许容器有一个唯一主机名和域名。当你运行一个容器时,即使使用 `- name` 标签,也会使用一个随机的 ID 作为主机名。你可以使用 [unshare 命令][6] 来了解一下这个工作原理。
<ruby>Unix 分时系统<rt>Unix Timeharing System</rt></ruby>UTS命名空间允许容器有一个唯一主机名和域名。当你运行一个容器时,即使使用 `- name` 标签,也会使用一个随机的 ID 作为主机名。你可以使用 [unshare 命令][6] 来了解一下这个工作原理。
```
nivedv@homelab ~]$ docker container run -it --name nived alpine sh
@ -76,7 +76,7 @@ homelab.redhat.com
#### IPC
<ruby>进程间通信<rt>Inter-Process Communication</rt></ruby>IPC命名空间允许不同的容器进程通过访问共享内存或使用共享消息队列来进行通信。
<ruby>进程间通信<rt>Inter-Process Communication</rt></ruby>IPC命名空间允许不同的容器进程之间,通过访问共享内存或使用共享消息队列来进行通信。
```
[root@demo /]# ipcmk -M 10M
@ -97,11 +97,11 @@ key semid owner perms nsems
#### PID
<ruby>进程 ID<rt>Process ID</rt></ruby>PID命名空间确保在容器内运行的进程与外部世界隔离。当你在容器内运行 `ps` 命令时,由于这个命名空间的存在,你只能看到在容器内运行的进程,而不是在宿主机上。
<ruby>进程 ID<rt>Process ID</rt></ruby>PID命名空间确保运行在容器内的进程与外部隔离。当你在容器内运行 `ps` 命令时,由于这个命名空间隔离的存在,你只能看到在容器内运行的进程,而不是在宿主机上。
#### 网络
网络(`net`)命名空间允许容器网络接口、IP 地址、路由表、端口号等有自己的视图。容器如何能够与外部世界沟通?你创建的所有容器都会被附加到一个特殊的虚拟网络接口上进行通信。
网络(`net`)命名空间允许容器有自己网络接口、IP 地址、路由表、端口号等视图。容器如何能够与外部通?你创建的所有容器都会被附加到一个特殊的虚拟网络接口上进行通信。
```
[nivedv@homelab ~]$ docker container run --rm -it alpine sh
@ -117,7 +117,7 @@ master docker0 state UP mode DEFAULT group default
### 控制组
控制组(`cgroup`)是制作一个容器的基本模块。控制组会分配和限制资源,如 CPU、内存、网络 I/O 等,这些资源被容器所使用。容器引擎会自动创建每种类型的控制组文件系统,并在容器运行时为每个容器设置
控制组(`cgroup`)是组成一个容器的基本模块。控制组会分配和限制容器所使用的资源,如 CPU、内存、网络 I/O 等。容器引擎会自动创建每种类型的控制组文件系统,并在容器运行时为每个容器设置配额
```
[root@homelab ~]# lscgroup | grep docker
@ -133,7 +133,7 @@ blkio:/docker
pids:/docker
```
容器运行时为每个容器设置了控制组值,所有信息都存储在 `/sys/fs/cgroup/*/docker`。下面的命令将确保容器可以使用 50000 微秒的 CPU 时间,并将内存的软、硬限制分别设置为 500M 和 1G。
容器运行时为每个容器设置了控制组值,所有信息都存储在 `/sys/fs/cgroup/*/docker`。下面的命令将确保容器可以使用 50000 微秒的 CPU 时间,并将内存的软、硬限制分别设置为 500M 和 1G。
```
[root@homelab ~]# docker container run -d --name test-cgroups --cpus 0.5 --memory 1G --memory-reservation 500M httpd
@ -154,13 +154,13 @@ memory:/docker/c3503ac704dafea3522d3bb82c77faff840018e857a2a7f669065f05c8b2cc84
### SECCOMP
Seccomp 意思是“<ruby>安全计算<rt>secure computing</rt></ruby>”。它是一项 Linux 功能,用于限制应用程序允许进行的系统调用的集合。例如Docker 的默认 seccomp 配置文件禁用了大约 44 个系统调用(总计超过 300 个)。
Seccomp 意思是“<ruby>安全计算<rt>secure computing</rt></ruby>”。它是一项 Linux 功能用于限制应用程序进行的系统调用的集合。例如Docker 的默认 seccomp 配置文件禁用了大约 44 个系统调用(总计超过 300 个)。
这里的思路是让容器只访问容器可能需要的那些资源。例如,如果你不需要容器改变主机上的时钟时间,你可能不会使用 `clock_adjtime``clock_settime` 系统调用,屏蔽它们是合理的。同样地,你不希望容器改变内核模块,所以没有必要让它们进行 `create_module``delete_module` 系统调用。
这里的思路是让容器只访问所必须的资源。例如,如果你不需要容器改变主机上的时钟时间,你可能不会使用 `clock_adjtime``clock_settime` 系统调用,屏蔽它们是合理的。同样地,你不希望容器改变内核模块,所以没有必要让它们使用 `create_module``delete_module` 系统调用。
### SELinux
SELinux 是“<ruby>安全增强的 Linux<rt>security-enhanced Linux</rt></ruby>”的缩写。如果你在你的宿主机上运行的是 Red Hat 发行版,那么 SELinux 是默认启用的。SELinux 可以让你限制一个应用程序只能访问它自己的文件,并阻止任何其他进程访问它们。因此,如果一个应用程序被破坏了,它将限制该应用程序可以影响或控制的文件数量。通过为文件和进程设置上下文环境以及定义策略来实现这一目的,这些策略将强制执行一个进程可以看到和改变的内容。
SELinux 是“<ruby>安全增强的 Linux<rt>security-enhanced Linux</rt></ruby>”的缩写。如果你在你的宿主机上运行的是 Red Hat 发行版,那么 SELinux 是默认启用的。SELinux 可以让你限制一个应用程序只能访问它自己的文件,并阻止任何其他进程访问。因此,如果一个应用程序被破坏了,它将限制该应用程序可以影响或控制的文件数量。通过为文件和进程设置上下文环境以及定义策略来实现,这些策略将限制一个进程可以访问和更改的内容。
容器的 SELinux 策略是由 `container-selinux` 包定义的。默认情况下,容器以 `container_t` 标签运行,允许在 `/usr` 目录下读取(`r`)和执行(`x`),并从 `/etc` 目录下读取大部分内容。标签`container_var_lib_t` 是与容器有关的文件的通用标签。
@ -177,7 +177,7 @@ via: https://opensource.com/article/21/8/container-linux-technology
作者:[Nived V][a]
选题:[lujun9972][b]
译者:[wxy](https://github.com/wxy)
校对:[校对者ID](https://github.com/校对者ID)
校对:[turbokernel](https://github.com/turbokernel)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出