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,111 +1,41 @@
{ {
"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",
"Runtime": {
"Name": "io.containerd.runc.v2",
"Options": {
"type_url": "containerd.runc.v1.Options"
}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": { "process": {
"terminal": false,
"consoleSize": {
"height": 0,
"width": 0
},
"user": { "user": {
"uid": 0, "uid": 0,
"gid": 0, "gid": 0
"additionalGids": [
0
]
}, },
"args": [ "args": [ "echo", "$OUTPUT" ],
"/hello"
],
"env": [ "env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
], ],
"cwd": "/", "cwd": "/",
"capabilities": { "rlimits": [{
"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", "type": "RLIMIT_NOFILE",
"hard": 1024, "hard": 1024,
"soft": 1024 "soft": 1024
} }],
],
"noNewPrivileges": true "noNewPrivileges": true
}, },
"root": { "root": {
"path": "rootfs" "path": "$ROOTFS",
"readonly": false
}, },
"mounts": [ "hostname": "test",
{ "mounts": [{
"destination": "/proc", "destination": "/proc",
"type": "proc", "type": "proc",
"source": "proc", "source": "proc"
"options": [
"nosuid",
"noexec",
"nodev"
]
}, },
{ {
"destination": "/dev", "destination": "/dev",
@ -165,93 +95,39 @@
] ]
}, },
{ {
"destination": "/run", "destination": "/sys/fs/cgroup",
"type": "tmpfs", "type": "cgroup",
"source": "tmpfs", "source": "cgroup",
"options": [ "options": [
"nosuid", "nosuid",
"strictatime", "noexec",
"mode=755", "nodev",
"size=65536k" "relatime",
"ro"
] ]
} }
], ],
"hooks": {},
"linux": { "linux": {
"devices": [],
"cgroupsPath": "kata/vfiotest",
"resources": { "resources": {
"devices": [ "devices": [
{ {"allow":false,"access":"rwm"},
"allow": false, {"allow":true,"type":"c","major":1,"minor":3,"access":"rwm"},
"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, {"allow":true,"type":"c","major":5,"minor":0,"access":"rwm"},
"type": "c", {"allow":true,"type":"c","major":5,"minor":1,"access":"rwm"}
"major": 1,
"minor": 3,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 1,
"minor": 8,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 1,
"minor": 7,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 5,
"minor": 0,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 1,
"minor": 5,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 1,
"minor": 9,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 5,
"minor": 1,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 136,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"major": 5,
"minor": 2,
"access": "rwm"
}
] ]
}, },
"cgroupsPath": "/default/hello", "namespaces": [{
"namespaces": [
{
"type": "pid" "type": "pid"
}, },
{
"type": "network"
},
{ {
"type": "ipc" "type": "ipc"
}, },
@ -260,25 +136,18 @@
}, },
{ {
"type": "mount" "type": "mount"
},
{
"type": "network"
} }
], ],
"maskedPaths": [ "maskedPaths": [
"/proc/acpi",
"/proc/asound",
"/proc/kcore", "/proc/kcore",
"/proc/keys",
"/proc/latency_stats", "/proc/latency_stats",
"/proc/timer_list", "/proc/timer_list",
"/proc/timer_stats", "/proc/timer_stats",
"/proc/sched_debug", "/proc/sched_debug",
"/sys/firmware", "/sys/firmware"
"/sys/devices/virtual/powercap",
"/proc/scsi"
], ],
"readonlyPaths": [ "readonlyPaths": [
"/proc/asound",
"/proc/bus", "/proc/bus",
"/proc/fs", "/proc/fs",
"/proc/irq", "/proc/irq",
@ -287,4 +156,3 @@
] ]
} }
} }
}

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(())
}