This commit is contained in:
sparkzky 2025-02-26 13:19:00 +08:00
parent 550bbc546c
commit ab94f96457
3 changed files with 454 additions and 288 deletions

View File

@ -1,290 +1,158 @@
{ {
"ID": "hello", "ociVersion": "1.0.0-rc2-dev",
"Labels": { "platform": {
"io.containerd.image.config.stop-signal": "SIGTERM" "os": "linux",
"arch": "amd64"
}, },
"Image": "docker.io/library/hello-world:latest", "process": {
"Runtime": { "terminal": false,
"Name": "io.containerd.runc.v2", "consoleSize": {
"Options": { "height": 0,
"type_url": "containerd.runc.v1.Options" "width": 0
}susu
},
"SnapshotKey": "hello",
"Snapshotter": "overlayfs",
"CreatedAt": "2025-01-25T10:08:43.259272017Z",
"UpdatedAt": "2025-01-25T10:08:43.259272017Z",
"Extensions": {},
"SandboxID": "",
"Spec": {
"ociVersion": "1.1.0",
"process": {
"user": {
"uid": 0,
"gid": 0,
"additionalGids": [
0
]
},
"args": [
"/hello"
],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"cwd": "/",
"capabilities": {
"bounding": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"effective": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
],
"permitted": [
"CAP_CHOWN",
"CAP_DAC_OVERRIDE",
"CAP_FSETID",
"CAP_FOWNER",
"CAP_MKNOD",
"CAP_NET_RAW",
"CAP_SETGID",
"CAP_SETUID",
"CAP_SETFCAP",
"CAP_SETPCAP",
"CAP_NET_BIND_SERVICE",
"CAP_SYS_CHROOT",
"CAP_KILL",
"CAP_AUDIT_WRITE"
]
},
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"noNewPrivileges": true
}, },
"root": { "user": {
"path": "rootfs" "uid": 0,
"gid": 0
}, },
"mounts": [ "args": [ "echo", "$OUTPUT" ],
{ "env": [
"destination": "/proc", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"type": "proc", "TERM=xterm"
"source": "proc",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/dev",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
{
"destination": "/dev/mqueue",
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev",
"ro"
]
},
{
"destination": "/run",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
}
], ],
"linux": { "cwd": "/",
"resources": { "rlimits": [{
"devices": [ "type": "RLIMIT_NOFILE",
{ "hard": 1024,
"allow": false, "soft": 1024
"access": "rwm" }],
}, "noNewPrivileges": true
{ },
"allow": true, "root": {
"type": "c", "path": "$ROOTFS",
"major": 1, "readonly": false
"minor": 3, },
"access": "rwm" "hostname": "test",
}, "mounts": [{
{ "destination": "/proc",
"allow": true, "type": "proc",
"type": "c", "source": "proc"
"major": 1, },
"minor": 8, {
"access": "rwm" "destination": "/dev",
}, "type": "tmpfs",
{ "source": "tmpfs",
"allow": true, "options": [
"type": "c", "nosuid",
"major": 1, "strictatime",
"minor": 7, "mode=755",
"access": "rwm" "size=65536k"
}, ]
{ },
"allow": true, {
"type": "c", "destination": "/dev/pts",
"major": 5, "type": "devpts",
"minor": 0, "source": "devpts",
"access": "rwm" "options": [
}, "nosuid",
{ "noexec",
"allow": true, "newinstance",
"type": "c", "ptmxmode=0666",
"major": 1, "mode=0620",
"minor": 5, "gid=5"
"access": "rwm" ]
}, },
{ {
"allow": true, "destination": "/dev/shm",
"type": "c", "type": "tmpfs",
"major": 1, "source": "shm",
"minor": 9, "options": [
"access": "rwm" "nosuid",
}, "noexec",
{ "nodev",
"allow": true, "mode=1777",
"type": "c", "size=65536k"
"major": 5, ]
"minor": 1, },
"access": "rwm" {
}, "destination": "/dev/mqueue",
{ "type": "mqueue",
"allow": true, "source": "mqueue",
"type": "c", "options": [
"major": 136, "nosuid",
"access": "rwm" "noexec",
}, "nodev"
{ ]
"allow": true, },
"type": "c", {
"major": 5, "destination": "/sys",
"minor": 2, "type": "sysfs",
"access": "rwm" "source": "sysfs",
} "options": [
] "nosuid",
}, "noexec",
"cgroupsPath": "/default/hello", "nodev",
"namespaces": [ "ro"
{ ]
"type": "pid" },
}, {
{ "destination": "/sys/fs/cgroup",
"type": "ipc" "type": "cgroup",
}, "source": "cgroup",
{ "options": [
"type": "uts" "nosuid",
}, "noexec",
{ "nodev",
"type": "mount" "relatime",
}, "ro"
{
"type": "network"
}
],
"maskedPaths": [
"/proc/acpi",
"/proc/asound",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/sys/firmware",
"/sys/devices/virtual/powercap",
"/proc/scsi"
],
"readonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
] ]
} }
],
"hooks": {},
"linux": {
"devices": [],
"cgroupsPath": "kata/vfiotest",
"resources": {
"devices": [
{"allow":false,"access":"rwm"},
{"allow":true,"type":"c","major":1,"minor":3,"access":"rwm"},
{"allow":true,"type":"c","major":1,"minor":5,"access":"rwm"},
{"allow":true,"type":"c","major":1,"minor":8,"access":"rwm"},
{"allow":true,"type":"c","major":1,"minor":9,"access":"rwm"},
{"allow":true,"type":"c","major":5,"minor":0,"access":"rwm"},
{"allow":true,"type":"c","major":5,"minor":1,"access":"rwm"}
]
},
"namespaces": [{
"type": "pid"
},
{
"type": "network"
},
{
"type": "ipc"
},
{
"type": "uts"
},
{
"type": "mount"
}
],
"maskedPaths": [
"/proc/kcore",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/sys/firmware"
],
"readonlyPaths": [
"/proc/asound",
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
} }
} }

View File

@ -1,3 +1,5 @@
pub mod spec;
use containerd_client::{ use containerd_client::{
services::v1::{ services::v1::{
container::Runtime, Container, CreateContainerRequest, CreateTaskRequest, container::Runtime, Container, CreateContainerRequest, CreateTaskRequest,
@ -36,11 +38,11 @@ impl Service {
} }
pub async fn create_container(&self, image: String, cid: String) { pub async fn create_container(&self, image: String, cid: String) {
// let spec = include_str!("../../container_spec.json").to_string(); let spec = include_str!("../../container_spec.json").to_string();
// let spec = Any { let spec = Any {
// type_url: "types.containerd.io/opencontainers/runtime-spec/1/Spec".to_string(), type_url: "types.containerd.io/opencontainers/runtime-spec/1/Spec".to_string(),
// value: spec.into_bytes(), value: spec.into_bytes(),
// }; };
let mut containers_client = self.client.lock().unwrap().containers(); let mut containers_client = self.client.lock().unwrap().containers();
let container = Container { let container = Container {
id: cid.to_string(), id: cid.to_string(),
@ -49,7 +51,7 @@ impl Service {
name: "io.containerd.runc.v2".to_string(), name: "io.containerd.runc.v2".to_string(),
options: None, options: None,
}), }),
// spec: Some(spec), spec: Some(spec),
..Default::default() ..Default::default()
}; };
@ -259,7 +261,6 @@ impl Service {
pub fn get_resolver(&self) { pub fn get_resolver(&self) {
todo!() todo!()
} }
} }
//容器是容器,要先启动,然后才能运行任务 //容器是容器,要先启动,然后才能运行任务
//要想删除一个正在运行的Task必须先kill掉这个task然后才能删除。 //要想删除一个正在运行的Task必须先kill掉这个task然后才能删除。

297
service/src/spec.rs Normal file
View File

@ -0,0 +1,297 @@
use serde::{Deserialize, Serialize};
use std::fs::File;
// 定义版本的常量
const VERSION_MAJOR: u32 = 1;
const VERSION_MINOR: u32 = 1;
const VERSION_PATCH: u32 = 0;
const VERSION_DEV: &str = ""; // 对应开发分支
const RWM: &str = "rwm";
const DEFAULT_ROOTFS_PATH: &str = "rootfs";
const DEFAULT_UNIX_ENV:&str="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
const PID_NAMESPACE: &str = "pid";
const NETWORK_NAMESPACE: &str = "network";
const MOUNT_NAMESPACE: &str = "mount";
const IPC_NAMESPACE: &str = "ipc";
const UTS_NAMESPACE: &str = "uts";
const USER_NAMESPACE: &str = "user";
const CGROUP_NAMESPACE: &str = "cgroup";
const TIME_NAMESPACE: &str = "time";
#[derive(Serialize, Deserialize, Debug)]
struct Spec {
ociVersion: String,
root: Root,
process: Process,
linux: Linux,
mounts: Vec<Mount>,
}
#[derive(Serialize, Deserialize, Debug)]
struct Root {
path: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct Process {
cwd: String,
noNewPrivileges: bool,
user: User,
capabilities: LinuxCapabilities,
rlimits: Vec<POSIXRlimit>,
}
#[derive(Serialize, Deserialize, Debug)]
struct User {
uid: u32,
gid: u32,
}
#[derive(Serialize, Deserialize, Debug)]
struct Mount {
destination: String,
type_: String,
source: String,
options: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug)]
struct LinuxCapabilities {
bounding: Vec<String>,
permitted: Vec<String>,
effective: Vec<String>,
}
#[derive(Serialize, Deserialize, Debug)]
struct POSIXRlimit {
#[serde(rename = "type")]
type_: String,
hard: u64,
soft: u64,
}
#[derive(Serialize, Deserialize, Debug)]
struct Linux {
masked_paths: Vec<String>,
readonly_paths: Vec<String>,
cgroups_path: String,
resources: LinuxResources,
namespaces: Vec<LinuxNamespace>,
}
#[derive(Serialize, Deserialize, Debug)]
struct LinuxResources {
devices: Vec<LinuxDeviceCgroup>,
}
#[derive(Serialize, Deserialize, Debug)]
struct LinuxDeviceCgroup {
allow: bool,
access: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct LinuxNamespace {
#[serde(rename = "type")]
type_: String,
}
pub fn default_unix_caps() -> Vec<String> {
vec![
String::from("CAP_CHOWN"),
String::from("CAP_DAC_OVERRIDE"),
String::from("CAP_FSETID"),
String::from("CAP_FOWNER"),
String::from("CAP_MKNOD"),
String::from("CAP_NET_RAW"),
String::from("CAP_SETGID"),
String::from("CAP_SETUID"),
String::from("CAP_SETFCAP"),
String::from("CAP_SETPCAP"),
String::from("CAP_NET_BIND_SERVICE"),
String::from("CAP_SYS_CHROOT"),
String::from("CAP_KILL"),
String::from("CAP_AUDIT_WRITE"),
]
}
fn default_masked_parhs() -> Vec<String> {
vec![
String::from("/proc/acpi"),
String::from("/proc/asound"),
String::from("/proc/kcore"),
String::from("/proc/keys"),
String::from("/proc/latency_stats"),
String::from("/proc/timer_list"),
String::from("/proc/timer_stats"),
String::from("/proc/sched_debug"),
String::from("/proc/scsi"),
String::from("/sys/firmware"),
String::from("/sys/devices/virtual/powercap"),
]
}
fn default_readonly_paths() -> Vec<String> {
vec![
String::from("/proc/bus"),
String::from("/proc/fs"),
String::from("/proc/irq"),
String::from("/proc/sys"),
String::from("/proc/sysrq-trigger"),
]
}
fn default_unix_namespaces() -> Vec<LinuxNamespace> {
vec![
LinuxNamespace {
type_: String::from(PID_NAMESPACE),
},
LinuxNamespace {
type_: String::from(IPC_NAMESPACE),
},
LinuxNamespace {
type_: String::from(UTS_NAMESPACE),
},
LinuxNamespace {
type_: String::from(MOUNT_NAMESPACE),
},
LinuxNamespace {
type_: String::from(NETWORK_NAMESPACE),
},
]
}
fn default_mounts() -> Vec<Mount> {
vec![
Mount {
destination: "/proc".to_string(),
type_: "proc".to_string(),
source: "proc".to_string(),
options: vec![],
},
Mount {
destination: "/dev".to_string(),
type_: "tmpfs".to_string(),
source: "tmpfs".to_string(),
options: vec![
"nosuid".to_string(),
"strictatime".to_string(),
"mode=755".to_string(),
"size=65536k".to_string(),
],
},
Mount {
destination: "/dev/pts".to_string(),
type_: "devpts".to_string(),
source: "devpts".to_string(),
options: vec![
"nosuid".to_string(),
"noexec".to_string(),
"newinstance".to_string(),
"ptmxmode=0666".to_string(),
"mode=0620".to_string(),
"gid=5".to_string(),
],
},
Mount {
destination: "/dev/shm".to_string(),
type_: "tmpfs".to_string(),
source: "shm".to_string(),
options: vec![
"nosuid".to_string(),
"noexec".to_string(),
"nodev".to_string(),
"mode=1777".to_string(),
"size=65536k".to_string(),
],
},
Mount {
destination: "/dev/mqueue".to_string(),
type_: "mqueue".to_string(),
source: "mqueue".to_string(),
options: vec![
"nosuid".to_string(),
"noexec".to_string(),
"nodev".to_string(),
],
},
Mount {
destination: "/sys".to_string(),
type_: "sysfs".to_string(),
source: "sysfs".to_string(),
options: vec![
"nosuid".to_string(),
"noexec".to_string(),
"nodev".to_string(),
"ro".to_string(),
],
},
Mount {
destination: "/sys/fs/cgroup".to_string(),
type_: "cgroup".to_string(),
source: "cgroup".to_string(),
options: vec![
"nosuid".to_string(),
"noexec".to_string(),
"nodev".to_string(),
"relatime".to_string(),
"ro".to_string(),
],
},
]
}
fn get_version() -> String {
format!(
"{}.{}.{}{}",
VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_DEV
)
}
fn populate_default_unix_spec(id: &str, ns: &str) -> Spec {
Spec {
ociVersion: get_version(),
root: Root {
path: DEFAULT_ROOTFS_PATH.to_string(),
},
process: Process {
cwd: String::from("/"),
noNewPrivileges: true,
user: User { uid: 0, gid: 0 },
capabilities: LinuxCapabilities {
bounding: default_unix_caps(),
permitted: default_unix_caps(),
effective: default_unix_caps(),
},
rlimits: vec![POSIXRlimit {
type_: String::from("RLIMIT_NOFILE"),
hard: 1024,
soft: 1024,
}],
},
linux: Linux {
masked_paths: default_masked_parhs(),
readonly_paths: default_readonly_paths(),
cgroups_path: format!("{}/{}", ns, id),
resources: LinuxResources {
devices: vec![LinuxDeviceCgroup {
allow: false,
access: String::from("rwm"),
}],
},
namespaces: default_unix_namespaces(),
},
mounts: default_mounts(),
}
}
fn save_spec_to_file(spec: &Spec, path: &str) -> Result<(), std::io::Error> {
let file = File::create(path)?;
serde_json::to_writer(file, spec)?;
Ok(())
}