namespace.rs
文件在 Kata 容器代理程序中定义了与 Linux 命名空间相关的功能。这些功能允许代理程序管理和操作不同类型的命名空间,以确保容器的隔离和安全。以下是该文件的主要功能和组件:
主要功能
- 命名空间路径获取:
get_current_thread_ns_path
函数用于获取当前线程的命名空间路径。这对于操作和引用特定类型的命名空间非常有用。
#[instrument]
pub fn get_current_thread_ns_path(ns_type: &str) -> String {
format!("/proc/{}/task/{}/ns/{}", getpid(), gettid(), ns_type)
}
- 命名空间对象:
Namespace
结构体封装了与单个命名空间相关的信息,如路径、类型和特定于类型的数据(例如 UTS 命名空间的主机名)。
#[derive(Debug)]
pub struct Namespace {
logger: Logger,
pub path: String,
persistent_ns_dir: String,
ns_type: NamespaceType,
//only used for uts namespace
pub hostname: Option<String>,
}
- 命名空间类型管理:
- 提供了方法来设置和获取不同类型的命名空间(IPC, UTS, PID),这些方法返回修改后的
Namespace
实例。
- 提供了方法来设置和获取不同类型的命名空间(IPC, UTS, PID),这些方法返回修改后的
#[instrument]
pub fn get_ipc(mut self) -> Self {
self.ns_type = NamespaceType::Ipc;
self
}
#[instrument]
pub fn get_uts(mut self, hostname: &str) -> Self {
self.ns_type = NamespaceType::Uts;
if !hostname.is_empty() {
self.hostname = Some(String::from(hostname));
}
self
}
#[instrument]
pub fn get_pid(mut self) -> Self {
self.ns_type = NamespaceType::Pid;
self
}
- 持久化命名空间的创建:
setup
方法用于创建持久化命名空间。这对于在容器重启后保持命名空间状态非常重要。注意,PID 类型的命名空间不能持久化。
// setup creates persistent namespace without switching to it.
// Note, pid namespaces cannot be persisted.
#[instrument]
#[allow(clippy::question_mark)]
pub async fn setup(mut self) -> Result<Self> {
fs::create_dir_all(&self.persistent_ns_dir)?;
let ns_path = PathBuf::from(&self.persistent_ns_dir);
let ns_type = self.ns_type;
if ns_type == NamespaceType::Pid {
return Err(anyhow!("Cannot persist namespace of PID type"));
}
let logger = self.logger.clone();
- 测试:
- 包含多个测试函数,用于验证命名空间功能的正确性,如创建新的命名空间实例、获取特定类型的命名空间等。
fn test_new() {
// Create dummy logger and temp folder.
let logger = slog::Logger::root(slog::Discard, o!());
let ns_ipc = Namespace::new(&logger);
assert_eq!(NamespaceType::Ipc, ns_ipc.ns_type);
}
#[test]
fn test_get_ipc() {
// Create dummy logger and temp folder.
let logger = slog::Logger::root(slog::Discard, o!());
let ns_ipc = Namespace::new(&logger).get_ipc();
assert_eq!(NamespaceType::Ipc, ns_ipc.ns_type);
}
#[test]
fn test_get_uts_with_hostname() {
let hostname = String::from("a.test.com");
// Create dummy logger and temp folder.
let logger = slog::Logger::root(slog::Discard, o!());
let ns_uts = Namespace::new(&logger).get_uts(hostname.as_str());
assert_eq!(NamespaceType::Uts, ns_uts.ns_type);
assert!(ns_uts.hostname.is_some());
}
#[test]
fn test_get_uts() {
let hostname = String::from("");
// Create dummy logger and temp folder.
let logger = slog::Logger::root(slog::Discard, o!());
let ns_uts = Namespace::new(&logger).get_uts(hostname.as_str());
assert_eq!(NamespaceType::Uts, ns_uts.ns_type);
assert!(ns_uts.hostname.is_none());
}
#[test]
fn test_get_pid() {
// Create dummy logger and temp folder.
let logger = slog::Logger::root(slog::Discard, o!());
let ns_pid = Namespace::new(&logger).get_pid();
assert_eq!(NamespaceType::Pid, ns_pid.ns_type);
}
#[test]
fn test_set_root_dir() {
// Create dummy logger and temp folder.
let logger = slog::Logger::root(slog::Discard, o!());
let tmpdir = Builder::new().prefix("pid").tempdir().unwrap();
let ns_root = Namespace::new(&logger).set_root_dir(tmpdir.path().to_str().unwrap());
assert_eq!(NamespaceType::Ipc, ns_root.ns_type);
assert_eq!(ns_root.persistent_ns_dir, tmpdir.path().to_str().unwrap());
}
#[rstest]
#[case::namespace_type_get_ipc(NamespaceType::Ipc, "ipc")]
#[case::namespace_type_get_uts(NamespaceType::Uts, "uts")]
#[case::namespace_type_get_pid(NamespaceType::Pid, "pid")]
fn test_namespace_type_get(#[case] ns_type: NamespaceType, #[case] ns_name: &str) {
assert_eq!(ns_name, ns_type.get())
}
总结
namespace.rs
文件为 Kata 容器代理提供了强大的工具,用于管理和操作 Linux 命名空间,这是实现容器隔离和安全的关键技术。通过这些功能,代理能够有效地控制和隔离在同一宿主机上运行的不同容器的进程和网络环境。