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",
"Labels": {
"io.containerd.image.config.stop-signal": "SIGTERM"
"ociVersion": "1.0.0-rc2-dev",
"platform": {
"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": {
"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
"process": {
"terminal": false,
"consoleSize": {
"height": 0,
"width": 0
},
"root": {
"path": "rootfs"
"user": {
"uid": 0,
"gid": 0
},
"mounts": [
{
"destination": "/proc",
"type": "proc",
"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"
]
}
"args": [ "echo", "$OUTPUT" ],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"linux": {
"resources": {
"devices": [
{
"allow": false,
"access": "rwm"
},
{
"allow": true,
"type": "c",
"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": [
{
"type": "pid"
},
{
"type": "ipc"
},
{
"type": "uts"
},
{
"type": "mount"
},
{
"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"
"cwd": "/",
"rlimits": [{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}],
"noNewPrivileges": true
},
"root": {
"path": "$ROOTFS",
"readonly": false
},
"hostname": "test",
"mounts": [{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
{
"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": "/sys/fs/cgroup",
"type": "cgroup",
"source": "cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
]
}
],
"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::{
services::v1::{
container::Runtime, Container, CreateContainerRequest, CreateTaskRequest,
@ -36,11 +38,11 @@ impl Service {
}
pub async fn create_container(&self, image: String, cid: String) {
// let spec = include_str!("../../container_spec.json").to_string();
// let spec = Any {
// type_url: "types.containerd.io/opencontainers/runtime-spec/1/Spec".to_string(),
// value: spec.into_bytes(),
// };
let spec = include_str!("../../container_spec.json").to_string();
let spec = Any {
type_url: "types.containerd.io/opencontainers/runtime-spec/1/Spec".to_string(),
value: spec.into_bytes(),
};
let mut containers_client = self.client.lock().unwrap().containers();
let container = Container {
id: cid.to_string(),
@ -49,7 +51,7 @@ impl Service {
name: "io.containerd.runc.v2".to_string(),
options: None,
}),
// spec: Some(spec),
spec: Some(spec),
..Default::default()
};
@ -259,7 +261,6 @@ impl Service {
pub fn get_resolver(&self) {
todo!()
}
}
//容器是容器,要先启动,然后才能运行任务
//要想删除一个正在运行的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(())
}