mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-05-01 21:24:36 +00:00
agent: sandbox shared pid namespace support
Add support shareProcessNamespace. BTW, this commit only support shared pid namespace by sharing the infrastructure pause container's pid namespace with other containers, instead of creating a new pid namespace different from pause container. Fixes: #342 Signed-off-by: fupan.lfp <fupan.lfp@antfin.com>
This commit is contained in:
parent
afcf269c9b
commit
c6e4d092d6
@ -65,6 +65,11 @@ impl Namespace {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_pid(mut self) -> Self {
|
||||||
|
self.ns_type = NamespaceType::PID;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_root_dir(mut self, dir: &str) -> Self {
|
pub fn set_root_dir(mut self, dir: &str) -> Self {
|
||||||
self.persistent_ns_dir = dir.to_string();
|
self.persistent_ns_dir = dir.to_string();
|
||||||
self
|
self
|
||||||
|
@ -79,6 +79,7 @@ impl agentService {
|
|||||||
let cid = req.container_id.clone();
|
let cid = req.container_id.clone();
|
||||||
|
|
||||||
let mut oci_spec = req.OCI.clone();
|
let mut oci_spec = req.OCI.clone();
|
||||||
|
let use_sandbox_pidns = req.get_sandbox_pidns();
|
||||||
|
|
||||||
let sandbox;
|
let sandbox;
|
||||||
let mut s;
|
let mut s;
|
||||||
@ -121,7 +122,7 @@ impl agentService {
|
|||||||
s.container_mounts.insert(cid.clone(), m);
|
s.container_mounts.insert(cid.clone(), m);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_container_namespaces(&s, &mut oci)?;
|
update_container_namespaces(&s, &mut oci, use_sandbox_pidns)?;
|
||||||
|
|
||||||
// Add the root partition to the device cgroup to prevent access
|
// Add the root partition to the device cgroup to prevent access
|
||||||
update_device_cgroup(&mut oci)?;
|
update_device_cgroup(&mut oci)?;
|
||||||
@ -162,6 +163,7 @@ impl agentService {
|
|||||||
|
|
||||||
ctr.start(p)?;
|
ctr.start(p)?;
|
||||||
|
|
||||||
|
s.update_shared_pidns(&ctr)?;
|
||||||
s.add_container(ctr);
|
s.add_container(ctr);
|
||||||
info!(sl!(), "created container!");
|
info!(sl!(), "created container!");
|
||||||
|
|
||||||
@ -1478,7 +1480,11 @@ pub fn start<S: Into<String>>(s: Arc<Mutex<Sandbox>>, host: S, port: u16) -> ttr
|
|||||||
// path set by the spec, since we will always ignore it. Indeed, it makes no
|
// path set by the spec, since we will always ignore it. Indeed, it makes no
|
||||||
// sense to rely on the namespace path provided by the host since namespaces
|
// sense to rely on the namespace path provided by the host since namespaces
|
||||||
// are different inside the guest.
|
// are different inside the guest.
|
||||||
fn update_container_namespaces(sandbox: &Sandbox, spec: &mut Spec) -> Result<()> {
|
fn update_container_namespaces(
|
||||||
|
sandbox: &Sandbox,
|
||||||
|
spec: &mut Spec,
|
||||||
|
sandbox_pidns: bool,
|
||||||
|
) -> Result<()> {
|
||||||
let linux = match spec.linux.as_mut() {
|
let linux = match spec.linux.as_mut() {
|
||||||
None => {
|
None => {
|
||||||
return Err(
|
return Err(
|
||||||
@ -1488,14 +1494,8 @@ fn update_container_namespaces(sandbox: &Sandbox, spec: &mut Spec) -> Result<()>
|
|||||||
Some(l) => l,
|
Some(l) => l,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut pidNs = false;
|
|
||||||
|
|
||||||
let namespaces = linux.namespaces.as_mut_slice();
|
let namespaces = linux.namespaces.as_mut_slice();
|
||||||
for namespace in namespaces.iter_mut() {
|
for namespace in namespaces.iter_mut() {
|
||||||
if namespace.r#type == NSTYPEPID {
|
|
||||||
pidNs = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if namespace.r#type == NSTYPEIPC {
|
if namespace.r#type == NSTYPEIPC {
|
||||||
namespace.path = sandbox.shared_ipcns.path.clone();
|
namespace.path = sandbox.shared_ipcns.path.clone();
|
||||||
continue;
|
continue;
|
||||||
@ -1505,13 +1505,19 @@ fn update_container_namespaces(sandbox: &Sandbox, spec: &mut Spec) -> Result<()>
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// update pid namespace
|
||||||
|
let mut pid_ns = LinuxNamespace::default();
|
||||||
|
pid_ns.r#type = NSTYPEPID.to_string();
|
||||||
|
|
||||||
if !pidNs && !sandbox.sandbox_pid_ns {
|
// Use shared pid ns if useSandboxPidns has been set in either
|
||||||
let mut pid_ns = LinuxNamespace::default();
|
// the create_sandbox request or create_container request.
|
||||||
pid_ns.r#type = NSTYPEPID.to_string();
|
// Else set this to empty string so that a new pid namespace is
|
||||||
linux.namespaces.push(pid_ns);
|
// created for the container.
|
||||||
|
if sandbox_pidns && sandbox.sandbox_pidns.is_some() {
|
||||||
|
pid_ns.path = String::from(sandbox.sandbox_pidns.as_ref().unwrap().path.as_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linux.namespaces.push(pid_ns);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,11 @@
|
|||||||
use crate::linux_abi::*;
|
use crate::linux_abi::*;
|
||||||
use crate::mount::{get_mount_fs_type, remove_mounts, TYPEROOTFS};
|
use crate::mount::{get_mount_fs_type, remove_mounts, TYPEROOTFS};
|
||||||
use crate::namespace::Namespace;
|
use crate::namespace::Namespace;
|
||||||
|
use crate::namespace::NSTYPEPID;
|
||||||
use crate::network::Network;
|
use crate::network::Network;
|
||||||
use libc::pid_t;
|
use libc::pid_t;
|
||||||
use netlink::{RtnlHandle, NETLINK_ROUTE};
|
use netlink::{RtnlHandle, NETLINK_ROUTE};
|
||||||
|
use oci::LinuxNamespace;
|
||||||
use protocols::agent::OnlineCPUMemRequest;
|
use protocols::agent::OnlineCPUMemRequest;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rustjail::cgroups;
|
use rustjail::cgroups;
|
||||||
@ -34,10 +36,10 @@ pub struct Sandbox {
|
|||||||
pub pci_device_map: HashMap<String, String>,
|
pub pci_device_map: HashMap<String, String>,
|
||||||
pub shared_utsns: Namespace,
|
pub shared_utsns: Namespace,
|
||||||
pub shared_ipcns: Namespace,
|
pub shared_ipcns: Namespace,
|
||||||
|
pub sandbox_pidns: Option<Namespace>,
|
||||||
pub storages: HashMap<String, u32>,
|
pub storages: HashMap<String, u32>,
|
||||||
pub running: bool,
|
pub running: bool,
|
||||||
pub no_pivot_root: bool,
|
pub no_pivot_root: bool,
|
||||||
pub sandbox_pid_ns: bool,
|
|
||||||
pub sender: Option<Sender<i32>>,
|
pub sender: Option<Sender<i32>>,
|
||||||
pub rtnl: Option<RtnlHandle>,
|
pub rtnl: Option<RtnlHandle>,
|
||||||
}
|
}
|
||||||
@ -58,10 +60,10 @@ impl Sandbox {
|
|||||||
pci_device_map: HashMap::new(),
|
pci_device_map: HashMap::new(),
|
||||||
shared_utsns: Namespace::new(&logger),
|
shared_utsns: Namespace::new(&logger),
|
||||||
shared_ipcns: Namespace::new(&logger),
|
shared_ipcns: Namespace::new(&logger),
|
||||||
|
sandbox_pidns: None,
|
||||||
storages: HashMap::new(),
|
storages: HashMap::new(),
|
||||||
running: false,
|
running: false,
|
||||||
no_pivot_root: fs_type.eq(TYPEROOTFS),
|
no_pivot_root: fs_type.eq(TYPEROOTFS),
|
||||||
sandbox_pid_ns: false,
|
|
||||||
sender: None,
|
sender: None,
|
||||||
rtnl: Some(RtnlHandle::new(NETLINK_ROUTE, 0).unwrap()),
|
rtnl: Some(RtnlHandle::new(NETLINK_ROUTE, 0).unwrap()),
|
||||||
})
|
})
|
||||||
@ -191,6 +193,30 @@ impl Sandbox {
|
|||||||
self.containers.insert(c.id.clone(), c);
|
self.containers.insert(c.id.clone(), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_shared_pidns(&mut self, c: &LinuxContainer) -> Result<()> {
|
||||||
|
// Populate the shared pid path only if this is an infra container and
|
||||||
|
// sandbox_pidns has not been passed in the create_sandbox request.
|
||||||
|
// This means a separate pause process has not been created. We treat the
|
||||||
|
// first container created as the infra container in that case
|
||||||
|
// and use its pid namespace in case pid namespace needs to be shared.
|
||||||
|
if self.sandbox_pidns.is_none() && self.containers.len() == 0 {
|
||||||
|
let init_pid = c.init_process_pid;
|
||||||
|
if init_pid == -1 {
|
||||||
|
return Err(ErrorKind::ErrorCode(String::from(
|
||||||
|
"Failed to setup pid namespace: init container pid is -1",
|
||||||
|
))
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut pid_ns = Namespace::new(&self.logger).as_pid();
|
||||||
|
pid_ns.path = format!("/proc/{}/ns/pid", init_pid);
|
||||||
|
|
||||||
|
self.sandbox_pidns = Some(pid_ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_container(&mut self, id: &str) -> Option<&mut LinuxContainer> {
|
pub fn get_container(&mut self, id: &str) -> Option<&mut LinuxContainer> {
|
||||||
self.containers.get_mut(id)
|
self.containers.get_mut(id)
|
||||||
}
|
}
|
||||||
@ -553,4 +579,21 @@ mod tests {
|
|||||||
s.add_container(linux_container);
|
s.add_container(linux_container);
|
||||||
assert!(s.get_container("some_id").is_some());
|
assert!(s.get_container("some_id").is_some());
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn update_shared_pidns() {
|
||||||
|
skip_if_not_root!();
|
||||||
|
let logger = slog::Logger::root(slog::Discard, o!());
|
||||||
|
let mut s = Sandbox::new(&logger).unwrap();
|
||||||
|
let test_pid = 9999;
|
||||||
|
|
||||||
|
let mut linux_container = create_linuxcontainer();
|
||||||
|
linux_container.init_process_pid = test_pid;
|
||||||
|
|
||||||
|
s.update_shared_pidns(&linux_container).unwrap();
|
||||||
|
|
||||||
|
assert!(s.sandbox_pidns.is_some());
|
||||||
|
|
||||||
|
let ns_path = format!("/proc/{}/ns/pid", test_pid);
|
||||||
|
assert_eq!(s.sandbox_pidns.unwrap().path, ns_path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user