This commit is contained in:
sparkzky 2025-01-25 19:43:37 +08:00
parent 02d9cc020b
commit 550bbc546c
5 changed files with 328 additions and 7 deletions

1
Cargo.lock generated
View File

@ -1548,6 +1548,7 @@ dependencies = [
"containerd-client",
"env_logger",
"log",
"prost-types",
"serde",
"serde_json",
"tokio",

View File

@ -21,8 +21,8 @@ async fn main() -> std::io::Result<()> {
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(service.clone()))
.route("/create_container", web::post().to(create_container))
.route("/remove_container", web::post().to(remove_container))
.route("/create-container", web::post().to(create_container))
.route("/remove-container", web::post().to(remove_container))
.route("/containers", web::get().to(get_container_list))
// 更多路由配置...
})

290
container_spec.json Normal file
View File

@ -0,0 +1,290 @@
{
"ID": "hello",
"Labels": {
"io.containerd.image.config.stop-signal": "SIGTERM"
},
"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
},
"root": {
"path": "rootfs"
},
"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"
]
}
],
"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"
]
}
}
}

View File

@ -11,3 +11,4 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
log = "0.4"
env_logger = "0.10"
prost-types = "0.13.4"

View File

@ -1,13 +1,15 @@
use containerd_client::{
services::v1::{
container::Runtime, Container, CreateContainerRequest, CreateTaskRequest,
DeleteContainerRequest, DeleteTaskRequest, KillRequest, ListContainersRequest,
ListTasksRequest, StartRequest, WaitRequest,
DeleteContainerRequest, DeleteTaskRequest, GetImageRequest, KillRequest,
ListContainersRequest, ListTasksRequest, StartRequest, WaitRequest,
},
tonic::Request,
with_namespace, Client,
};
use prost_types::Any;
use std::{
collections::HashMap,
fs::{self, File},
sync::{Arc, Mutex},
time::Duration,
@ -34,6 +36,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 mut containers_client = self.client.lock().unwrap().containers();
let container = Container {
id: cid.to_string(),
@ -42,7 +49,7 @@ impl Service {
name: "io.containerd.runc.v2".to_string(),
options: None,
}),
spec: None,
// spec: Some(spec),
..Default::default()
};
@ -58,8 +65,6 @@ impl Service {
.expect("Failed to create container");
println!("Container: {:?} created", cid);
self.create_and_start_task(cid).await;
}
pub async fn remove_container(&self, container_id: String) {
@ -158,6 +163,25 @@ impl Service {
println!("Task: {:?} started", container_id);
}
pub async fn kill_task(&self, container_id: String) {
let mut tasks_client = self.client.lock().unwrap().tasks();
let kill_request = Request::new(KillRequest {
container_id: container_id.to_string(),
signal: 15,
all: true,
..Default::default()
});
tasks_client
.kill(kill_request)
.await
.expect("Failed to kill task");
}
pub async fn pause_task() {
todo!()
}
pub async fn resume_task() {
todo!()
}
pub async fn delete_task(&self, container_id: &str) {
let time_out = Duration::from_secs(30);
let mut tc = self.client.lock().unwrap().tasks();
@ -223,6 +247,8 @@ impl Service {
.collect())
}
pub async fn get_task_list() {}
pub fn prepare_image(&self) {
todo!()
}
@ -233,4 +259,7 @@ impl Service {
pub fn get_resolver(&self) {
todo!()
}
}
//容器是容器,要先启动,然后才能运行任务
//要想删除一个正在运行的Task必须先kill掉这个task然后才能删除。