mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-07-17 17:02:42 +00:00
Merge pull request #5877 from openanolis/fix_start_bundle
runtime-rs: enable start container from bundle
This commit is contained in:
commit
e4645642d0
@ -257,6 +257,48 @@ This launches a BusyBox container named `hello`, and it will be removed by `--rm
|
|||||||
The `--cni` flag enables CNI networking for the container. Without this flag, a container with just a
|
The `--cni` flag enables CNI networking for the container. Without this flag, a container with just a
|
||||||
loopback interface is created.
|
loopback interface is created.
|
||||||
|
|
||||||
|
### Launch containers using `ctr` command line with rootfs bundle
|
||||||
|
|
||||||
|
#### Get rootfs
|
||||||
|
Use the script to create rootfs
|
||||||
|
```bash
|
||||||
|
ctr i pull quay.io/prometheus/busybox:latest
|
||||||
|
ctr i export rootfs.tar quay.io/prometheus/busybox:latest
|
||||||
|
|
||||||
|
rootfs_tar=rootfs.tar
|
||||||
|
bundle_dir="./bundle"
|
||||||
|
mkdir -p "${bundle_dir}"
|
||||||
|
|
||||||
|
# extract busybox rootfs
|
||||||
|
rootfs_dir="${bundle_dir}/rootfs"
|
||||||
|
mkdir -p "${rootfs_dir}"
|
||||||
|
layers_dir="$(mktemp -d)"
|
||||||
|
tar -C "${layers_dir}" -pxf "${rootfs_tar}"
|
||||||
|
for ((i=0;i<$(cat ${layers_dir}/manifest.json | jq -r ".[].Layers | length");i++)); do
|
||||||
|
tar -C ${rootfs_dir} -xf ${layers_dir}/$(cat ${layers_dir}/manifest.json | jq -r ".[].Layers[${i}]")
|
||||||
|
done
|
||||||
|
```
|
||||||
|
#### Get `config.json`
|
||||||
|
Use runc spec to generate `config.json`
|
||||||
|
```bash
|
||||||
|
cd ./bundle/rootfs
|
||||||
|
runc spec
|
||||||
|
mv config.json ../
|
||||||
|
```
|
||||||
|
Change the root `path` in `config.json` to the absolute path of rootfs
|
||||||
|
|
||||||
|
```JSON
|
||||||
|
"root":{
|
||||||
|
"path":"/root/test/bundle/rootfs",
|
||||||
|
"readonly": false
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Run container
|
||||||
|
```bash
|
||||||
|
sudo ctr run -d --runtime io.containerd.run.kata.v2 --config bundle/config.json hello
|
||||||
|
sudo ctr t exec --exec-id ${ID} -t hello sh
|
||||||
|
```
|
||||||
### Launch Pods with `crictl` command line
|
### Launch Pods with `crictl` command line
|
||||||
|
|
||||||
With the `crictl` command line of `cri-tools`, you can specify runtime class with `-r` or `--runtime` flag.
|
With the `crictl` command line of `cri-tools`, you can specify runtime class with `-r` or `--runtime` flag.
|
||||||
|
@ -68,11 +68,14 @@ impl ResourceManager {
|
|||||||
pub async fn handler_rootfs(
|
pub async fn handler_rootfs(
|
||||||
&self,
|
&self,
|
||||||
cid: &str,
|
cid: &str,
|
||||||
|
root: &oci::Root,
|
||||||
bundle_path: &str,
|
bundle_path: &str,
|
||||||
rootfs_mounts: &[Mount],
|
rootfs_mounts: &[Mount],
|
||||||
) -> Result<Arc<dyn Rootfs>> {
|
) -> Result<Arc<dyn Rootfs>> {
|
||||||
let inner = self.inner.read().await;
|
let inner = self.inner.read().await;
|
||||||
inner.handler_rootfs(cid, bundle_path, rootfs_mounts).await
|
inner
|
||||||
|
.handler_rootfs(cid, root, bundle_path, rootfs_mounts)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handler_volumes(
|
pub async fn handler_volumes(
|
||||||
|
@ -196,6 +196,7 @@ impl ResourceManagerInner {
|
|||||||
pub async fn handler_rootfs(
|
pub async fn handler_rootfs(
|
||||||
&self,
|
&self,
|
||||||
cid: &str,
|
cid: &str,
|
||||||
|
root: &oci::Root,
|
||||||
bundle_path: &str,
|
bundle_path: &str,
|
||||||
rootfs_mounts: &[Mount],
|
rootfs_mounts: &[Mount],
|
||||||
) -> Result<Arc<dyn Rootfs>> {
|
) -> Result<Arc<dyn Rootfs>> {
|
||||||
@ -205,6 +206,7 @@ impl ResourceManagerInner {
|
|||||||
self.hypervisor.as_ref(),
|
self.hypervisor.as_ref(),
|
||||||
&self.sid,
|
&self.sid,
|
||||||
cid,
|
cid,
|
||||||
|
root,
|
||||||
bundle_path,
|
bundle_path,
|
||||||
rootfs_mounts,
|
rootfs_mounts,
|
||||||
)
|
)
|
||||||
|
@ -51,16 +51,37 @@ impl RootFsResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn handler_rootfs(
|
pub async fn handler_rootfs(
|
||||||
&self,
|
&self,
|
||||||
share_fs: &Option<Arc<dyn ShareFs>>,
|
share_fs: &Option<Arc<dyn ShareFs>>,
|
||||||
hypervisor: &dyn Hypervisor,
|
hypervisor: &dyn Hypervisor,
|
||||||
sid: &str,
|
sid: &str,
|
||||||
cid: &str,
|
cid: &str,
|
||||||
|
root: &oci::Root,
|
||||||
bundle_path: &str,
|
bundle_path: &str,
|
||||||
rootfs_mounts: &[Mount],
|
rootfs_mounts: &[Mount],
|
||||||
) -> Result<Arc<dyn Rootfs>> {
|
) -> Result<Arc<dyn Rootfs>> {
|
||||||
match rootfs_mounts {
|
match rootfs_mounts {
|
||||||
|
// if rootfs_mounts is empty
|
||||||
|
mounts_vec if mounts_vec.is_empty() => {
|
||||||
|
if let Some(share_fs) = share_fs {
|
||||||
|
let share_fs_mount = share_fs.get_share_fs_mount();
|
||||||
|
// share fs rootfs
|
||||||
|
Ok(Arc::new(
|
||||||
|
share_fs_rootfs::ShareFsRootfs::new(
|
||||||
|
&share_fs_mount,
|
||||||
|
cid,
|
||||||
|
root.path.as_str(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.context("new share fs rootfs")?,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
return Err(anyhow!("share fs is unavailable"));
|
||||||
|
}
|
||||||
|
}
|
||||||
mounts_vec if is_single_layer_rootfs(mounts_vec) => {
|
mounts_vec if is_single_layer_rootfs(mounts_vec) => {
|
||||||
// Safe as single_layer_rootfs must have one layer
|
// Safe as single_layer_rootfs must have one layer
|
||||||
let layer = &mounts_vec[0];
|
let layer = &mounts_vec[0];
|
||||||
@ -86,7 +107,7 @@ impl RootFsResource {
|
|||||||
&share_fs_mount,
|
&share_fs_mount,
|
||||||
cid,
|
cid,
|
||||||
bundle_path,
|
bundle_path,
|
||||||
layer,
|
Some(layer),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.context("new share fs rootfs")?,
|
.context("new share fs rootfs")?,
|
||||||
|
@ -23,14 +23,18 @@ impl ShareFsRootfs {
|
|||||||
share_fs_mount: &Arc<dyn ShareFsMount>,
|
share_fs_mount: &Arc<dyn ShareFsMount>,
|
||||||
cid: &str,
|
cid: &str,
|
||||||
bundle_path: &str,
|
bundle_path: &str,
|
||||||
rootfs: &Mount,
|
rootfs: Option<&Mount>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let bundle_rootfs = format!("{}/{}", bundle_path, ROOTFS);
|
let bundle_rootfs = if let Some(rootfs) = rootfs {
|
||||||
rootfs.mount(&bundle_rootfs).context(format!(
|
let bundle_rootfs = format!("{}/{}", bundle_path, ROOTFS);
|
||||||
"mount rootfs from {:?} to {}",
|
rootfs.mount(&bundle_rootfs).context(format!(
|
||||||
&rootfs, &bundle_rootfs
|
"mount rootfs from {:?} to {}",
|
||||||
))?;
|
&rootfs, &bundle_rootfs
|
||||||
|
))?;
|
||||||
|
bundle_rootfs
|
||||||
|
} else {
|
||||||
|
bundle_path.to_string()
|
||||||
|
};
|
||||||
let mount_result = share_fs_mount
|
let mount_result = share_fs_mount
|
||||||
.share_rootfs(ShareFsRootfsConfig {
|
.share_rootfs(ShareFsRootfsConfig {
|
||||||
cid: cid.to_string(),
|
cid: cid.to_string(),
|
||||||
|
@ -17,6 +17,7 @@ use common::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use kata_sys_util::k8s::update_ephemeral_storage_type;
|
use kata_sys_util::k8s::update_ephemeral_storage_type;
|
||||||
|
|
||||||
use oci::{LinuxResources, Process as OCIProcess};
|
use oci::{LinuxResources, Process as OCIProcess};
|
||||||
use resource::ResourceManager;
|
use resource::ResourceManager;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
@ -85,23 +86,30 @@ impl Container {
|
|||||||
let sandbox_pidns = is_pid_namespace_enabled(&spec);
|
let sandbox_pidns = is_pid_namespace_enabled(&spec);
|
||||||
amend_spec(&mut spec, toml_config.runtime.disable_guest_seccomp).context("amend spec")?;
|
amend_spec(&mut spec, toml_config.runtime.disable_guest_seccomp).context("amend spec")?;
|
||||||
|
|
||||||
|
// get mutable root from oci spec
|
||||||
|
let mut root = match spec.root.as_mut() {
|
||||||
|
Some(root) => root,
|
||||||
|
None => return Err(anyhow!("spec miss root field")),
|
||||||
|
};
|
||||||
|
|
||||||
// handler rootfs
|
// handler rootfs
|
||||||
let rootfs = self
|
let rootfs = self
|
||||||
.resource_manager
|
.resource_manager
|
||||||
.handler_rootfs(&config.container_id, &config.bundle, &config.rootfs_mounts)
|
.handler_rootfs(
|
||||||
|
&config.container_id,
|
||||||
|
root,
|
||||||
|
&config.bundle,
|
||||||
|
&config.rootfs_mounts,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.context("handler rootfs")?;
|
.context("handler rootfs")?;
|
||||||
|
|
||||||
// update rootfs
|
// update rootfs
|
||||||
match spec.root.as_mut() {
|
root.path = rootfs
|
||||||
Some(root) => {
|
.get_guest_rootfs_path()
|
||||||
root.path = rootfs
|
.await
|
||||||
.get_guest_rootfs_path()
|
.context("get guest rootfs path")?;
|
||||||
.await
|
|
||||||
.context("get guest rootfs path")?
|
|
||||||
}
|
|
||||||
None => return Err(anyhow!("spec miss root field")),
|
|
||||||
};
|
|
||||||
let mut storages = vec![];
|
let mut storages = vec![];
|
||||||
if let Some(storage) = rootfs.get_storage().await {
|
if let Some(storage) = rootfs.get_storage().await {
|
||||||
storages.push(storage);
|
storages.push(storage);
|
||||||
|
Loading…
Reference in New Issue
Block a user