mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-04-11 22:42:14 +00:00
Compare commits
31 Commits
burgerdev/
...
2.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f82291926 | ||
|
|
5d3610e25f | ||
|
|
ed01ac3e0c | ||
|
|
9266c2460a | ||
|
|
7086f91e1f | ||
|
|
0a7befa645 | ||
|
|
eff70d2eea | ||
|
|
dd26aa5838 | ||
|
|
260f59df38 | ||
|
|
9a32a3e16d | ||
|
|
123f7d53cb | ||
|
|
aa213fdc28 | ||
|
|
c0bdba2350 | ||
|
|
1b3cf2fb7d | ||
|
|
59b9e5d0f8 | ||
|
|
828a304883 | ||
|
|
70734dfa17 | ||
|
|
f170df6201 | ||
|
|
d3690952e6 | ||
|
|
7f7c794da4 | ||
|
|
3f1b7c9127 | ||
|
|
68cad37720 | ||
|
|
7c9067cc9d | ||
|
|
dba86ef31a | ||
|
|
0e2df80bda | ||
|
|
8c4e187049 | ||
|
|
3bcdc26008 | ||
|
|
79831fafaf | ||
|
|
3212c7ae00 | ||
|
|
7f7c3fc8ec | ||
|
|
c9053ea3fb |
@@ -18,7 +18,9 @@ function install_yq() {
|
|||||||
GOPATH=${GOPATH:-${HOME}/go}
|
GOPATH=${GOPATH:-${HOME}/go}
|
||||||
local yq_path="${GOPATH}/bin/yq"
|
local yq_path="${GOPATH}/bin/yq"
|
||||||
local yq_pkg="github.com/mikefarah/yq"
|
local yq_pkg="github.com/mikefarah/yq"
|
||||||
[ -x "${GOPATH}/bin/yq" ] && return
|
local yq_version=3.4.1
|
||||||
|
|
||||||
|
[ -x "${GOPATH}/bin/yq" ] && [ "`${GOPATH}/bin/yq --version`"X == "yq version ${yq_version}"X ] && return
|
||||||
|
|
||||||
read -r -a sysInfo <<< "$(uname -sm)"
|
read -r -a sysInfo <<< "$(uname -sm)"
|
||||||
|
|
||||||
@@ -56,8 +58,6 @@ function install_yq() {
|
|||||||
die "Please install curl"
|
die "Please install curl"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local yq_version=3.4.1
|
|
||||||
|
|
||||||
## NOTE: ${var,,} => gives lowercase value of var
|
## NOTE: ${var,,} => gives lowercase value of var
|
||||||
local yq_url="https://${yq_pkg}/releases/download/${yq_version}/yq_${goos,,}_${goarch}"
|
local yq_url="https://${yq_pkg}/releases/download/${yq_version}/yq_${goos,,}_${goarch}"
|
||||||
curl -o "${yq_path}" -LSsf "${yq_url}"
|
curl -o "${yq_path}" -LSsf "${yq_url}"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
* [Appendices](#appendices)
|
* [Appendices](#appendices)
|
||||||
* [The constraints challenge](#the-constraints-challenge)
|
* [The constraints challenge](#the-constraints-challenge)
|
||||||
|
|
||||||
---
|
***
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
@@ -94,7 +94,9 @@ This section lists items that might be possible to fix.
|
|||||||
### checkpoint and restore
|
### checkpoint and restore
|
||||||
|
|
||||||
The runtime does not provide `checkpoint` and `restore` commands. There
|
The runtime does not provide `checkpoint` and `restore` commands. There
|
||||||
are discussions about using VM save and restore to give [`criu`](https://github.com/checkpoint-restore/criu)-like functionality, which might provide a solution.
|
are discussions about using VM save and restore to give us a
|
||||||
|
`[criu](https://github.com/checkpoint-restore/criu)`-like functionality,
|
||||||
|
which might provide a solution.
|
||||||
|
|
||||||
Note that the OCI standard does not specify `checkpoint` and `restore`
|
Note that the OCI standard does not specify `checkpoint` and `restore`
|
||||||
commands.
|
commands.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ There are several kinds of Kata configurations and they are listed below.
|
|||||||
| `io.katacontainers.config.runtime.disable_new_netns` | `boolean` | determines if a new netns is created for the hypervisor process |
|
| `io.katacontainers.config.runtime.disable_new_netns` | `boolean` | determines if a new netns is created for the hypervisor process |
|
||||||
| `io.katacontainers.config.runtime.internetworking_model` | string| determines how the VM should be connected to the container network interface. Valid values are `macvtap`, `tcfilter` and `none` |
|
| `io.katacontainers.config.runtime.internetworking_model` | string| determines how the VM should be connected to the container network interface. Valid values are `macvtap`, `tcfilter` and `none` |
|
||||||
| `io.katacontainers.config.runtime.sandbox_cgroup_only`| `boolean` | determines if Kata processes are managed only in sandbox cgroup |
|
| `io.katacontainers.config.runtime.sandbox_cgroup_only`| `boolean` | determines if Kata processes are managed only in sandbox cgroup |
|
||||||
|
| `io.katacontainers.config.runtime.enable_pprof` | `boolean` | enables Golang `pprof` for `containerd-shim-kata-v2` process |
|
||||||
|
|
||||||
## Agent Options
|
## Agent Options
|
||||||
| Key | Value Type | Comments |
|
| Key | Value Type | Comments |
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Wants=kata-containers.target
|
|||||||
StandardOutput=tty
|
StandardOutput=tty
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=@BINDIR@/@AGENT_NAME@
|
ExecStart=@BINDIR@/@AGENT_NAME@
|
||||||
LimitNOFILE=infinity
|
LimitNOFILE=1048576
|
||||||
# ExecStop is required for static agent tracing; in all other scenarios
|
# ExecStop is required for static agent tracing; in all other scenarios
|
||||||
# the runtime handles shutting down the VM.
|
# the runtime handles shutting down the VM.
|
||||||
ExecStop=/bin/sync ; /usr/bin/systemctl --force poweroff
|
ExecStop=/bin/sync ; /usr/bin/systemctl --force poweroff
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ use oci::State as OCIState;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::os::unix::io::FromRawFd;
|
use std::os::unix::io::FromRawFd;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use slog::{info, o, Logger};
|
use slog::{info, o, Logger};
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ use crate::sync_with_async::{read_async, write_async};
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use rlimit::{setrlimit, Resource, Rlim};
|
use rlimit::{setrlimit, Resource, Rlim};
|
||||||
use tokio::io::AsyncBufReadExt;
|
use tokio::io::AsyncBufReadExt;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
|
||||||
@@ -106,6 +108,9 @@ pub type Config = CreateOpts;
|
|||||||
type NamespaceType = String;
|
type NamespaceType = String;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
// This locker ensures the child exit signal will be received by the right receiver.
|
||||||
|
pub static ref WAIT_PID_LOCKER: Arc<Mutex<bool>> = Arc::new(Mutex::new(false));
|
||||||
|
|
||||||
static ref NAMESPACES: HashMap<&'static str, CloneFlags> = {
|
static ref NAMESPACES: HashMap<&'static str, CloneFlags> = {
|
||||||
let mut m = HashMap::new();
|
let mut m = HashMap::new();
|
||||||
m.insert("user", CloneFlags::CLONE_NEWUSER);
|
m.insert("user", CloneFlags::CLONE_NEWUSER);
|
||||||
@@ -1467,6 +1472,8 @@ async fn execute_hook(logger: &Logger, h: &Hook, st: &OCIState) -> Result<()> {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// Avoid the exit signal to be reaped by the global reaper.
|
||||||
|
let _wait_locker = WAIT_PID_LOCKER.lock().await;
|
||||||
let mut child = tokio::process::Command::new(path)
|
let mut child = tokio::process::Command::new(path)
|
||||||
.args(args.iter())
|
.args(args.iter())
|
||||||
.envs(env.iter())
|
.envs(env.iter())
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ lazy_static! {
|
|||||||
m.insert("rprivate", MsFlags::MS_PRIVATE | MsFlags::MS_REC);
|
m.insert("rprivate", MsFlags::MS_PRIVATE | MsFlags::MS_REC);
|
||||||
m.insert("slave", MsFlags::MS_SLAVE);
|
m.insert("slave", MsFlags::MS_SLAVE);
|
||||||
m.insert("rslave", MsFlags::MS_SLAVE | MsFlags::MS_REC);
|
m.insert("rslave", MsFlags::MS_SLAVE | MsFlags::MS_REC);
|
||||||
|
m.insert("unbindable", MsFlags::MS_UNBINDABLE);
|
||||||
|
m.insert("runbindable", MsFlags::MS_UNBINDABLE | MsFlags::MS_REC);
|
||||||
m
|
m
|
||||||
};
|
};
|
||||||
static ref OPTIONS: HashMap<&'static str, (bool, MsFlags)> = {
|
static ref OPTIONS: HashMap<&'static str, (bool, MsFlags)> = {
|
||||||
@@ -93,17 +95,6 @@ lazy_static! {
|
|||||||
m.insert("nodiratime", (false, MsFlags::MS_NODIRATIME));
|
m.insert("nodiratime", (false, MsFlags::MS_NODIRATIME));
|
||||||
m.insert("bind", (false, MsFlags::MS_BIND));
|
m.insert("bind", (false, MsFlags::MS_BIND));
|
||||||
m.insert("rbind", (false, MsFlags::MS_BIND | MsFlags::MS_REC));
|
m.insert("rbind", (false, MsFlags::MS_BIND | MsFlags::MS_REC));
|
||||||
m.insert("unbindable", (false, MsFlags::MS_UNBINDABLE));
|
|
||||||
m.insert(
|
|
||||||
"runbindable",
|
|
||||||
(false, MsFlags::MS_UNBINDABLE | MsFlags::MS_REC),
|
|
||||||
);
|
|
||||||
m.insert("private", (false, MsFlags::MS_PRIVATE));
|
|
||||||
m.insert("rprivate", (false, MsFlags::MS_PRIVATE | MsFlags::MS_REC));
|
|
||||||
m.insert("shared", (false, MsFlags::MS_SHARED));
|
|
||||||
m.insert("rshared", (false, MsFlags::MS_SHARED | MsFlags::MS_REC));
|
|
||||||
m.insert("slave", (false, MsFlags::MS_SLAVE));
|
|
||||||
m.insert("rslave", (false, MsFlags::MS_SLAVE | MsFlags::MS_REC));
|
|
||||||
m.insert("relatime", (false, MsFlags::MS_RELATIME));
|
m.insert("relatime", (false, MsFlags::MS_RELATIME));
|
||||||
m.insert("norelatime", (true, MsFlags::MS_RELATIME));
|
m.insert("norelatime", (true, MsFlags::MS_RELATIME));
|
||||||
m.insert("strictatime", (false, MsFlags::MS_STRICTATIME));
|
m.insert("strictatime", (false, MsFlags::MS_STRICTATIME));
|
||||||
@@ -192,7 +183,7 @@ pub fn init_rootfs(
|
|||||||
|
|
||||||
let mut bind_mount_dev = false;
|
let mut bind_mount_dev = false;
|
||||||
for m in &spec.mounts {
|
for m in &spec.mounts {
|
||||||
let (mut flags, data) = parse_mount(&m);
|
let (mut flags, pgflags, data) = parse_mount(&m);
|
||||||
if !m.destination.starts_with('/') || m.destination.contains("..") {
|
if !m.destination.starts_with('/') || m.destination.contains("..") {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
"the mount destination {} is invalid",
|
"the mount destination {} is invalid",
|
||||||
@@ -234,13 +225,15 @@ pub fn init_rootfs(
|
|||||||
// effective.
|
// effective.
|
||||||
// first check that we have non-default options required before attempting a
|
// first check that we have non-default options required before attempting a
|
||||||
// remount
|
// remount
|
||||||
if m.r#type == "bind" {
|
if m.r#type == "bind" && !pgflags.is_empty() {
|
||||||
for o in &m.options {
|
|
||||||
if let Some(fl) = PROPAGATION.get(o.as_str()) {
|
|
||||||
let dest = secure_join(rootfs, &m.destination);
|
let dest = secure_join(rootfs, &m.destination);
|
||||||
mount(None::<&str>, dest.as_str(), None::<&str>, *fl, None::<&str>)?;
|
mount(
|
||||||
}
|
None::<&str>,
|
||||||
}
|
dest.as_str(),
|
||||||
|
None::<&str>,
|
||||||
|
pgflags,
|
||||||
|
None::<&str>,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -657,26 +650,27 @@ pub fn ms_move_root(rootfs: &str) -> Result<bool> {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_mount(m: &Mount) -> (MsFlags, String) {
|
fn parse_mount(m: &Mount) -> (MsFlags, MsFlags, String) {
|
||||||
let mut flags = MsFlags::empty();
|
let mut flags = MsFlags::empty();
|
||||||
|
let mut pgflags = MsFlags::empty();
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
|
|
||||||
for o in &m.options {
|
for o in &m.options {
|
||||||
match OPTIONS.get(o.as_str()) {
|
if let Some(v) = OPTIONS.get(o.as_str()) {
|
||||||
Some(v) => {
|
|
||||||
let (clear, fl) = *v;
|
let (clear, fl) = *v;
|
||||||
if clear {
|
if clear {
|
||||||
flags &= !fl;
|
flags &= !fl;
|
||||||
} else {
|
} else {
|
||||||
flags |= fl;
|
flags |= fl;
|
||||||
}
|
}
|
||||||
}
|
} else if let Some(fl) = PROPAGATION.get(o.as_str()) {
|
||||||
|
pgflags |= *fl;
|
||||||
None => data.push(o.clone()),
|
} else {
|
||||||
|
data.push(o.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(flags, data.join(","))
|
(flags, pgflags, data.join(","))
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function constructs a canonicalized path by combining the `rootfs` and `unsafe_path` elements.
|
// This function constructs a canonicalized path by combining the `rootfs` and `unsafe_path` elements.
|
||||||
@@ -922,7 +916,7 @@ pub fn finish_rootfs(cfd_log: RawFd, spec: &Spec) -> Result<()> {
|
|||||||
|
|
||||||
for m in spec.mounts.iter() {
|
for m in spec.mounts.iter() {
|
||||||
if m.destination == "/dev" {
|
if m.destination == "/dev" {
|
||||||
let (flags, _) = parse_mount(m);
|
let (flags, _, _) = parse_mount(m);
|
||||||
if flags.contains(MsFlags::MS_RDONLY) {
|
if flags.contains(MsFlags::MS_RDONLY) {
|
||||||
mount(
|
mount(
|
||||||
Some("/dev"),
|
Some("/dev"),
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ async fn handle_sigchild(logger: Logger, sandbox: Arc<Mutex<Sandbox>>) -> Result
|
|||||||
info!(logger, "handling signal"; "signal" => "SIGCHLD");
|
info!(logger, "handling signal"; "signal" => "SIGCHLD");
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
// Avoid reaping the undesirable child's signal, e.g., execute_hook's
|
||||||
|
// The lock should be released immediately.
|
||||||
|
rustjail::container::WAIT_PID_LOCKER.lock().await;
|
||||||
let result = wait::waitpid(
|
let result = wait::waitpid(
|
||||||
Some(Pid::from_raw(-1)),
|
Some(Pid::from_raw(-1)),
|
||||||
Some(WaitPidFlag::WNOHANG | WaitPidFlag::__WALL),
|
Some(WaitPidFlag::WNOHANG | WaitPidFlag::__WALL),
|
||||||
|
|||||||
@@ -150,6 +150,10 @@ block_device_driver = "@DEFBLOCKSTORAGEDRIVER_ACRN@"
|
|||||||
|
|
||||||
#debug_console_enabled = true
|
#debug_console_enabled = true
|
||||||
|
|
||||||
|
# Agent connection dialing timeout value in seconds
|
||||||
|
# (default: 30)
|
||||||
|
#dial_timeout = 30
|
||||||
|
|
||||||
[netmon]
|
[netmon]
|
||||||
# If enabled, the network monitoring process gets started when the
|
# If enabled, the network monitoring process gets started when the
|
||||||
# sandbox is created. This allows for the detection of some additional
|
# sandbox is created. This allows for the detection of some additional
|
||||||
|
|||||||
@@ -165,6 +165,10 @@ block_device_driver = "virtio-blk"
|
|||||||
|
|
||||||
#debug_console_enabled = true
|
#debug_console_enabled = true
|
||||||
|
|
||||||
|
# Agent connection dialing timeout value in seconds
|
||||||
|
# (default: 30)
|
||||||
|
#dial_timeout = 30
|
||||||
|
|
||||||
[netmon]
|
[netmon]
|
||||||
# If enabled, the network monitoring process gets started when the
|
# If enabled, the network monitoring process gets started when the
|
||||||
# sandbox is created. This allows for the detection of some additional
|
# sandbox is created. This allows for the detection of some additional
|
||||||
|
|||||||
@@ -287,6 +287,10 @@ kernel_modules=[]
|
|||||||
|
|
||||||
#debug_console_enabled = true
|
#debug_console_enabled = true
|
||||||
|
|
||||||
|
# Agent connection dialing timeout value in seconds
|
||||||
|
# (default: 30)
|
||||||
|
#dial_timeout = 30
|
||||||
|
|
||||||
[netmon]
|
[netmon]
|
||||||
# If enabled, the network monitoring process gets started when the
|
# If enabled, the network monitoring process gets started when the
|
||||||
# sandbox is created. This allows for the detection of some additional
|
# sandbox is created. This allows for the detection of some additional
|
||||||
|
|||||||
@@ -437,6 +437,10 @@ kernel_modules=[]
|
|||||||
|
|
||||||
#debug_console_enabled = true
|
#debug_console_enabled = true
|
||||||
|
|
||||||
|
# Agent connection dialing timeout value in seconds
|
||||||
|
# (default: 30)
|
||||||
|
#dial_timeout = 30
|
||||||
|
|
||||||
[netmon]
|
[netmon]
|
||||||
# If enabled, the network monitoring process gets started when the
|
# If enabled, the network monitoring process gets started when the
|
||||||
# sandbox is created. This allows for the detection of some additional
|
# sandbox is created. This allows for the detection of some additional
|
||||||
|
|||||||
@@ -389,13 +389,6 @@ EXAMPLES:
|
|||||||
if verbose {
|
if verbose {
|
||||||
kataLog.Logger.SetLevel(logrus.InfoLevel)
|
kataLog.Logger.SetLevel(logrus.InfoLevel)
|
||||||
}
|
}
|
||||||
ctx, err := cliContextToContext(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
span, _ := katautils.Trace(ctx, "check")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
if !context.Bool("no-network-checks") && os.Getenv(noNetworkEnvVar) == "" {
|
if !context.Bool("no-network-checks") && os.Getenv(noNetworkEnvVar) == "" {
|
||||||
cmd := RelCmdCheck
|
cmd := RelCmdCheck
|
||||||
@@ -407,8 +400,7 @@ EXAMPLES:
|
|||||||
if os.Geteuid() == 0 {
|
if os.Geteuid() == 0 {
|
||||||
kataLog.Warn("Not running network checks as super user")
|
kataLog.Warn("Not running network checks as super user")
|
||||||
} else {
|
} else {
|
||||||
|
err := HandleReleaseVersions(cmd, version, context.Bool("include-all-releases"))
|
||||||
err = HandleReleaseVersions(cmd, version, context.Bool("include-all-releases"))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -424,7 +416,7 @@ EXAMPLES:
|
|||||||
return errors.New("check: cannot determine runtime config")
|
return errors.New("check: cannot determine runtime config")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setCPUtype(runtimeConfig.HypervisorType)
|
err := setCPUtype(runtimeConfig.HypervisorType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -437,7 +429,6 @@ EXAMPLES:
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = hostIsVMContainerCapable(details)
|
err = hostIsVMContainerCapable(details)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
|
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/utils"
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/utils"
|
||||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||||
exp "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/experimental"
|
exp "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/experimental"
|
||||||
@@ -448,14 +447,6 @@ var kataEnvCLICommand = cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
ctx, err := cliContextToContext(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
span, _ := katautils.Trace(ctx, "kata-env")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
return handleSettings(defaultOutputFile, context)
|
return handleSettings(defaultOutputFile, context)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"sync"
|
"sync"
|
||||||
@@ -26,7 +25,6 @@ import (
|
|||||||
clientUtils "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/client"
|
clientUtils "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"go.opentelemetry.io/otel/label"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -38,10 +36,8 @@ const (
|
|||||||
|
|
||||||
subCommandName = "exec"
|
subCommandName = "exec"
|
||||||
// command-line parameters name
|
// command-line parameters name
|
||||||
paramRuntimeNamespace = "runtime-namespace"
|
|
||||||
paramDebugConsolePort = "kata-debug-port"
|
paramDebugConsolePort = "kata-debug-port"
|
||||||
defaultKernelParamDebugConsoleVPortValue = 1026
|
defaultKernelParamDebugConsoleVPortValue = 1026
|
||||||
defaultRuntimeNamespace = "k8s.io"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -57,34 +53,16 @@ var kataExecCLICommand = cli.Command{
|
|||||||
Name: subCommandName,
|
Name: subCommandName,
|
||||||
Usage: "Enter into guest by debug console",
|
Usage: "Enter into guest by debug console",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
|
||||||
Name: paramRuntimeNamespace,
|
|
||||||
Usage: "Namespace that containerd or CRI-O are using for containers. (Default: k8s.io, only works for containerd)",
|
|
||||||
},
|
|
||||||
cli.Uint64Flag{
|
cli.Uint64Flag{
|
||||||
Name: paramDebugConsolePort,
|
Name: paramDebugConsolePort,
|
||||||
Usage: "Port that debug console is listening on. (Default: 1026)",
|
Usage: "Port that debug console is listening on. (Default: 1026)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
ctx, err := cliContextToContext(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
span, _ := katautils.Trace(ctx, subCommandName)
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
namespace := context.String(paramRuntimeNamespace)
|
|
||||||
if namespace == "" {
|
|
||||||
namespace = defaultRuntimeNamespace
|
|
||||||
}
|
|
||||||
span.SetAttributes(label.Key("namespace").String(namespace))
|
|
||||||
|
|
||||||
port := context.Uint64(paramDebugConsolePort)
|
port := context.Uint64(paramDebugConsolePort)
|
||||||
if port == 0 {
|
if port == 0 {
|
||||||
port = defaultKernelParamDebugConsoleVPortValue
|
port = defaultKernelParamDebugConsoleVPortValue
|
||||||
}
|
}
|
||||||
span.SetAttributes(label.Key("port").Uint64(port))
|
|
||||||
|
|
||||||
sandboxID := context.Args().Get(0)
|
sandboxID := context.Args().Get(0)
|
||||||
|
|
||||||
@@ -92,9 +70,8 @@ var kataExecCLICommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
span.SetAttributes(label.Key("sandbox").String(sandboxID))
|
conn, err := getConn(sandboxID, port)
|
||||||
|
|
||||||
conn, err := getConn(namespace, sandboxID, port)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -177,9 +154,8 @@ func (s *iostream) Read(data []byte) (n int, err error) {
|
|||||||
return s.conn.Read(data)
|
return s.conn.Read(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConn(namespace, sandboxID string, port uint64) (net.Conn, error) {
|
func getConn(sandboxID string, port uint64) (net.Conn, error) {
|
||||||
socketAddr := filepath.Join(string(filepath.Separator), "containerd-shim", namespace, sandboxID, "shim-monitor.sock")
|
client, err := kataMonitor.BuildShimClient(sandboxID, defaultTimeout)
|
||||||
client, err := kataMonitor.BuildUnixSocketClient(socketAddr, defaultTimeout)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -190,7 +166,7 @@ func getConn(namespace, sandboxID string, port uint64) (net.Conn, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("Failed to get %s: %d", socketAddr, resp.StatusCode)
|
return nil, fmt.Errorf("Failure from %s shim-monitor: %d", sandboxID, resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|||||||
38
src/runtime/cli/kata-metrics.go
Normal file
38
src/runtime/cli/kata-metrics.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2021 Apple Inc.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
kataMonitor "github.com/kata-containers/kata-containers/src/runtime/pkg/kata-monitor"
|
||||||
|
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var kataMetricsCLICommand = cli.Command{
|
||||||
|
Name: "metrics",
|
||||||
|
Usage: "gather metrics associated with infrastructure used to run a sandbox",
|
||||||
|
UsageText: "metrics <sandbox id>",
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
|
||||||
|
sandboxID := context.Args().Get(0)
|
||||||
|
|
||||||
|
if err := katautils.VerifyContainerID(sandboxID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the metrics!
|
||||||
|
metrics, err := kataMonitor.GetSandboxMetrics(sandboxID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", metrics)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -27,9 +27,6 @@ import (
|
|||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"go.opentelemetry.io/otel"
|
|
||||||
"go.opentelemetry.io/otel/label"
|
|
||||||
otelTrace "go.opentelemetry.io/otel/trace"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// specConfig is the name of the file holding the containers configuration
|
// specConfig is the name of the file holding the containers configuration
|
||||||
@@ -125,6 +122,7 @@ var runtimeCommands = []cli.Command{
|
|||||||
kataCheckCLICommand,
|
kataCheckCLICommand,
|
||||||
kataEnvCLICommand,
|
kataEnvCLICommand,
|
||||||
kataExecCLICommand,
|
kataExecCLICommand,
|
||||||
|
kataMetricsCLICommand,
|
||||||
factoryCLICommand,
|
factoryCLICommand,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,10 +130,6 @@ var runtimeCommands = []cli.Command{
|
|||||||
// parsing occurs.
|
// parsing occurs.
|
||||||
var runtimeBeforeSubcommands = beforeSubcommands
|
var runtimeBeforeSubcommands = beforeSubcommands
|
||||||
|
|
||||||
// runtimeAfterSubcommands is the function to run after the command-line
|
|
||||||
// has been parsed.
|
|
||||||
var runtimeAfterSubcommands = afterSubcommands
|
|
||||||
|
|
||||||
// runtimeCommandNotFound is the function to handle an invalid sub-command.
|
// runtimeCommandNotFound is the function to handle an invalid sub-command.
|
||||||
var runtimeCommandNotFound = commandNotFound
|
var runtimeCommandNotFound = commandNotFound
|
||||||
|
|
||||||
@@ -168,10 +162,6 @@ func init() {
|
|||||||
|
|
||||||
// setupSignalHandler sets up signal handling, starting a go routine to deal
|
// setupSignalHandler sets up signal handling, starting a go routine to deal
|
||||||
// with signals as they arrive.
|
// with signals as they arrive.
|
||||||
//
|
|
||||||
// Note that the specified context is NOT used to create a trace span (since the
|
|
||||||
// first (root) span must be created in beforeSubcommands()): it is simply
|
|
||||||
// used to pass to the crash handling functions to finalise tracing.
|
|
||||||
func setupSignalHandler(ctx context.Context) {
|
func setupSignalHandler(ctx context.Context) {
|
||||||
signals.SetLogger(kataLog)
|
signals.SetLogger(kataLog)
|
||||||
|
|
||||||
@@ -181,10 +171,6 @@ func setupSignalHandler(ctx context.Context) {
|
|||||||
signal.Notify(sigCh, sig)
|
signal.Notify(sigCh, sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
dieCb := func() {
|
|
||||||
katautils.StopTracing(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
sig := <-sigCh
|
sig := <-sigCh
|
||||||
@@ -198,7 +184,6 @@ func setupSignalHandler(ctx context.Context) {
|
|||||||
|
|
||||||
if signals.FatalSignal(nativeSignal) {
|
if signals.FatalSignal(nativeSignal) {
|
||||||
kataLog.WithField("signal", sig).Error("received fatal signal")
|
kataLog.WithField("signal", sig).Error("received fatal signal")
|
||||||
signals.Die(dieCb)
|
|
||||||
} else if debug && signals.NonFatalSignal(nativeSignal) {
|
} else if debug && signals.NonFatalSignal(nativeSignal) {
|
||||||
kataLog.WithField("signal", sig).Debug("handling signal")
|
kataLog.WithField("signal", sig).Debug("handling signal")
|
||||||
signals.Backtrace()
|
signals.Backtrace()
|
||||||
@@ -210,18 +195,6 @@ func setupSignalHandler(ctx context.Context) {
|
|||||||
// setExternalLoggers registers the specified logger with the external
|
// setExternalLoggers registers the specified logger with the external
|
||||||
// packages which accept a logger to handle their own logging.
|
// packages which accept a logger to handle their own logging.
|
||||||
func setExternalLoggers(ctx context.Context, logger *logrus.Entry) {
|
func setExternalLoggers(ctx context.Context, logger *logrus.Entry) {
|
||||||
var span otelTrace.Span
|
|
||||||
|
|
||||||
// Only create a new span if a root span already exists. This is
|
|
||||||
// required to ensure that this function will not disrupt the root
|
|
||||||
// span logic by creating a span before the proper root span has been
|
|
||||||
// created.
|
|
||||||
|
|
||||||
if otelTrace.SpanFromContext(ctx) != nil {
|
|
||||||
span, ctx = katautils.Trace(ctx, "setExternalLoggers")
|
|
||||||
defer span.End()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set virtcontainers logger.
|
// Set virtcontainers logger.
|
||||||
vci.SetLogger(ctx, logger)
|
vci.SetLogger(ctx, logger)
|
||||||
|
|
||||||
@@ -244,7 +217,6 @@ func beforeSubcommands(c *cli.Context) error {
|
|||||||
var configFile string
|
var configFile string
|
||||||
var runtimeConfig oci.RuntimeConfig
|
var runtimeConfig oci.RuntimeConfig
|
||||||
var err error
|
var err error
|
||||||
var traceFlushFunc func()
|
|
||||||
|
|
||||||
katautils.SetConfigOptions(name, defaultRuntimeConfiguration, defaultSysConfRuntimeConfiguration)
|
katautils.SetConfigOptions(name, defaultRuntimeConfiguration, defaultSysConfRuntimeConfiguration)
|
||||||
|
|
||||||
@@ -270,7 +242,6 @@ func beforeSubcommands(c *cli.Context) error {
|
|||||||
// Issue: https://github.com/kata-containers/runtime/issues/2428
|
// Issue: https://github.com/kata-containers/runtime/issues/2428
|
||||||
|
|
||||||
ignoreConfigLogs := false
|
ignoreConfigLogs := false
|
||||||
var traceRootSpan string
|
|
||||||
|
|
||||||
subCmdIsCheckCmd := (c.NArg() >= 1 && ((c.Args()[0] == "kata-check") || (c.Args()[0] == "check")))
|
subCmdIsCheckCmd := (c.NArg() >= 1 && ((c.Args()[0] == "kata-check") || (c.Args()[0] == "check")))
|
||||||
if subCmdIsCheckCmd {
|
if subCmdIsCheckCmd {
|
||||||
@@ -302,16 +273,13 @@ func beforeSubcommands(c *cli.Context) error {
|
|||||||
cmdName := c.Args().First()
|
cmdName := c.Args().First()
|
||||||
if c.App.Command(cmdName) != nil {
|
if c.App.Command(cmdName) != nil {
|
||||||
kataLog = kataLog.WithField("command", cmdName)
|
kataLog = kataLog.WithField("command", cmdName)
|
||||||
|
|
||||||
// Name for the root span (used for tracing) now the
|
|
||||||
// sub-command name is known.
|
|
||||||
traceRootSpan = name + " " + cmdName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since a context is required, pass a new (throw-away) one - we
|
ctx, err := cliContextToContext(c)
|
||||||
// cannot use the main context as tracing hasn't been enabled yet
|
if err != nil {
|
||||||
// (meaning any spans created at this point will be silently ignored).
|
return err
|
||||||
setExternalLoggers(context.Background(), kataLog)
|
}
|
||||||
|
setExternalLoggers(ctx, kataLog)
|
||||||
|
|
||||||
if c.NArg() == 1 && (c.Args()[0] == "kata-env" || c.Args()[0] == "env") {
|
if c.NArg() == 1 && (c.Args()[0] == "kata-env" || c.Args()[0] == "env") {
|
||||||
// simply report the logging setup
|
// simply report the logging setup
|
||||||
@@ -325,20 +293,6 @@ func beforeSubcommands(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
if !subCmdIsCheckCmd {
|
if !subCmdIsCheckCmd {
|
||||||
debug = runtimeConfig.Debug
|
debug = runtimeConfig.Debug
|
||||||
|
|
||||||
if traceRootSpan != "" {
|
|
||||||
// Create the tracer.
|
|
||||||
//
|
|
||||||
// Note: no spans are created until the command-line has been parsed.
|
|
||||||
// This delays collection of trace data slightly but benefits the user by
|
|
||||||
// ensuring the first span is the name of the sub-command being
|
|
||||||
// invoked from the command-line.
|
|
||||||
traceFlushFunc, err = setupTracing(c, traceRootSpan, &runtimeConfig)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer traceFlushFunc()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args := strings.Join(c.Args(), " ")
|
args := strings.Join(c.Args(), " ")
|
||||||
@@ -377,36 +331,6 @@ func handleShowConfig(context *cli.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupTracing(context *cli.Context, rootSpanName string, config *oci.RuntimeConfig) (func(), error) {
|
|
||||||
flush, err := katautils.CreateTracer(name, config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, err := cliContextToContext(context)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the root span now that the sub-command name is
|
|
||||||
// known.
|
|
||||||
//
|
|
||||||
// Note that this "Before" function is called (and returns)
|
|
||||||
// before the subcommand handler is called. As such, we cannot
|
|
||||||
// "Finish()" the span here - that is handled in the .After
|
|
||||||
// function.
|
|
||||||
tracer := otel.Tracer("kata")
|
|
||||||
newCtx, span := tracer.Start(ctx, rootSpanName)
|
|
||||||
|
|
||||||
span.SetAttributes(label.Key("subsystem").String("runtime"))
|
|
||||||
|
|
||||||
// Add tracer to metadata and update the context
|
|
||||||
context.App.Metadata["tracer"] = tracer
|
|
||||||
context.App.Metadata["context"] = newCtx
|
|
||||||
|
|
||||||
return flush, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// add supported experimental features in context
|
// add supported experimental features in context
|
||||||
func addExpFeatures(clictx *cli.Context, runtimeConfig oci.RuntimeConfig) error {
|
func addExpFeatures(clictx *cli.Context, runtimeConfig oci.RuntimeConfig) error {
|
||||||
ctx, err := cliContextToContext(clictx)
|
ctx, err := cliContextToContext(clictx)
|
||||||
@@ -420,22 +344,11 @@ func addExpFeatures(clictx *cli.Context, runtimeConfig oci.RuntimeConfig) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx = exp.ContextWithExp(ctx, exps)
|
ctx = exp.ContextWithExp(ctx, exps)
|
||||||
// Add tracer to metadata and update the context
|
// Add experimental features to metadata and update the context
|
||||||
clictx.App.Metadata["context"] = ctx
|
clictx.App.Metadata["context"] = ctx
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func afterSubcommands(c *cli.Context) error {
|
|
||||||
ctx, err := cliContextToContext(c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
katautils.StopTracing(ctx)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// function called when an invalid command is specified which causes the
|
// function called when an invalid command is specified which causes the
|
||||||
// runtime to error.
|
// runtime to error.
|
||||||
func commandNotFound(c *cli.Context, command string) {
|
func commandNotFound(c *cli.Context, command string) {
|
||||||
@@ -502,7 +415,6 @@ func createRuntimeApp(ctx context.Context, args []string) error {
|
|||||||
app.Flags = runtimeFlags
|
app.Flags = runtimeFlags
|
||||||
app.Commands = runtimeCommands
|
app.Commands = runtimeCommands
|
||||||
app.Before = runtimeBeforeSubcommands
|
app.Before = runtimeBeforeSubcommands
|
||||||
app.After = runtimeAfterSubcommands
|
|
||||||
app.EnableBashCompletion = true
|
app.EnableBashCompletion = true
|
||||||
|
|
||||||
// allow sub-commands to access context
|
// allow sub-commands to access context
|
||||||
@@ -578,12 +490,5 @@ func cliContextToContext(c *cli.Context) (context.Context, error) {
|
|||||||
func main() {
|
func main() {
|
||||||
// create a new empty context
|
// create a new empty context
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
dieCb := func() {
|
|
||||||
katautils.StopTracing(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer signals.HandlePanic(dieCb)
|
|
||||||
|
|
||||||
createRuntime(ctx)
|
createRuntime(ctx)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils"
|
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,14 +13,6 @@ var versionCLICommand = cli.Command{
|
|||||||
Name: "version",
|
Name: "version",
|
||||||
Usage: "display version details",
|
Usage: "display version details",
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
ctx, err := cliContextToContext(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
span, _ := katautils.Trace(ctx, "version")
|
|
||||||
defer span.End()
|
|
||||||
|
|
||||||
cli.VersionPrinter(context)
|
cli.VersionPrinter(context)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/containerd/namespaces"
|
|
||||||
cdshim "github.com/containerd/containerd/runtime/v2/shim"
|
cdshim "github.com/containerd/containerd/runtime/v2/shim"
|
||||||
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
|
||||||
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
|
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
|
||||||
@@ -129,11 +128,7 @@ func decodeAgentMetrics(body string) []*dto.MetricFamily {
|
|||||||
|
|
||||||
func (s *service) startManagementServer(ctx context.Context, ociSpec *specs.Spec) {
|
func (s *service) startManagementServer(ctx context.Context, ociSpec *specs.Spec) {
|
||||||
// metrics socket will under sandbox's bundle path
|
// metrics socket will under sandbox's bundle path
|
||||||
metricsAddress, err := socketAddress(ctx, s.id)
|
metricsAddress := SocketAddress(s.id)
|
||||||
if err != nil {
|
|
||||||
shimMgtLog.WithError(err).Error("failed to create socket address")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
listener, err := cdshim.NewSocket(metricsAddress)
|
listener, err := cdshim.NewSocket(metricsAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -166,7 +161,7 @@ func (s *service) startManagementServer(ctx context.Context, ociSpec *specs.Spec
|
|||||||
svr.Serve(listener)
|
svr.Serve(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
// mountServeDebug provides a debug endpoint
|
// mountPprofHandle provides a debug endpoint
|
||||||
func (s *service) mountPprofHandle(m *http.ServeMux, ociSpec *specs.Spec) {
|
func (s *service) mountPprofHandle(m *http.ServeMux, ociSpec *specs.Spec) {
|
||||||
|
|
||||||
// return if not enabled
|
// return if not enabled
|
||||||
@@ -188,10 +183,8 @@ func (s *service) mountPprofHandle(m *http.ServeMux, ociSpec *specs.Spec) {
|
|||||||
m.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
|
m.Handle("/debug/pprof/trace", http.HandlerFunc(pprof.Trace))
|
||||||
}
|
}
|
||||||
|
|
||||||
func socketAddress(ctx context.Context, id string) (string, error) {
|
// SocketAddress returns the address of the abstract domain socket for communicating with the
|
||||||
ns, err := namespaces.NamespaceRequired(ctx)
|
// shim management endpoint
|
||||||
if err != nil {
|
func SocketAddress(id string) string {
|
||||||
return "", err
|
return filepath.Join(string(filepath.Separator), "run", "vc", id, "shim-monitor")
|
||||||
}
|
|
||||||
return filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim-monitor.sock"), nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ func watchOOMEvents(ctx context.Context, s *service) {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-s.ctx.Done():
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
containerID, err := s.sandbox.GetOOMEvent(ctx)
|
containerID, err := s.sandbox.GetOOMEvent(ctx)
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ func (km *KataMonitor) aggregateSandboxMetrics(encoder expfmt.Encoder) error {
|
|||||||
for sandboxID, namespace := range sandboxes {
|
for sandboxID, namespace := range sandboxes {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(sandboxID, namespace string, results chan<- []*dto.MetricFamily) {
|
go func(sandboxID, namespace string, results chan<- []*dto.MetricFamily) {
|
||||||
sandboxMetrics, err := km.getSandboxMetrics(sandboxID, namespace)
|
sandboxMetrics, err := getParsedMetrics(sandboxID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
monitorLog.WithError(err).WithField("sandbox_id", sandboxID).Errorf("failed to get metrics for sandbox")
|
monitorLog.WithError(err).WithField("sandbox_id", sandboxID).Errorf("failed to get metrics for sandbox")
|
||||||
}
|
}
|
||||||
@@ -229,13 +229,12 @@ func (km *KataMonitor) aggregateSandboxMetrics(encoder expfmt.Encoder) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getSandboxMetrics will get sandbox's metrics from shim
|
func getParsedMetrics(sandboxID string) ([]*dto.MetricFamily, error) {
|
||||||
func (km *KataMonitor) getSandboxMetrics(sandboxID, namespace string) ([]*dto.MetricFamily, error) {
|
body, err := doGet(sandboxID, defaultTimeout, "metrics")
|
||||||
body, err := km.doGet(sandboxID, namespace, defaultTimeout, "metrics")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -243,6 +242,16 @@ func (km *KataMonitor) getSandboxMetrics(sandboxID, namespace string) ([]*dto.Me
|
|||||||
return parsePrometheusMetrics(sandboxID, body)
|
return parsePrometheusMetrics(sandboxID, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSandboxMetrics will get sandbox's metrics from shim
|
||||||
|
func GetSandboxMetrics(sandboxID string) (string, error) {
|
||||||
|
body, err := doGet(sandboxID, defaultTimeout, "metrics")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(body), nil
|
||||||
|
}
|
||||||
|
|
||||||
// parsePrometheusMetrics will decode metrics from Prometheus text format
|
// parsePrometheusMetrics will decode metrics from Prometheus text format
|
||||||
// and return array of *dto.MetricFamily with an ASC order
|
// and return array of *dto.MetricFamily with an ASC order
|
||||||
func parsePrometheusMetrics(sandboxID string, body []byte) ([]*dto.MetricFamily, error) {
|
func parsePrometheusMetrics(sandboxID string, body []byte) ([]*dto.MetricFamily, error) {
|
||||||
|
|||||||
@@ -87,13 +87,8 @@ func (km *KataMonitor) GetAgentURL(w http.ResponseWriter, r *http.Request) {
|
|||||||
commonServeError(w, http.StatusBadRequest, err)
|
commonServeError(w, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
namespace, err := km.getSandboxNamespace(sandboxID)
|
|
||||||
if err != nil {
|
|
||||||
commonServeError(w, http.StatusBadRequest, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := km.doGet(sandboxID, namespace, defaultTimeout, "agent-url")
|
data, err := doGet(sandboxID, defaultTimeout, "agent-url")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
commonServeError(w, http.StatusBadRequest, err)
|
commonServeError(w, http.StatusBadRequest, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
shim "github.com/kata-containers/kata-containers/src/runtime/containerd-shim-v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -33,16 +35,13 @@ func getSandboxIDFromReq(r *http.Request) (string, error) {
|
|||||||
return "", fmt.Errorf("sandbox not found in %+v", r.URL.Query())
|
return "", fmt.Errorf("sandbox not found in %+v", r.URL.Query())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (km *KataMonitor) buildShimClient(sandboxID, namespace string, timeout time.Duration) (*http.Client, error) {
|
// BuildShimClient builds and returns an http client for communicating with the provided sandbox
|
||||||
socketAddr, err := km.getMonitorAddress(sandboxID, namespace)
|
func BuildShimClient(sandboxID string, timeout time.Duration) (*http.Client, error) {
|
||||||
if err != nil {
|
return buildUnixSocketClient(shim.SocketAddress(sandboxID), timeout)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return BuildUnixSocketClient(socketAddr, timeout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildUnixSocketClient build http client for Unix socket
|
// buildUnixSocketClient build http client for Unix socket
|
||||||
func BuildUnixSocketClient(socketAddr string, timeout time.Duration) (*http.Client, error) {
|
func buildUnixSocketClient(socketAddr string, timeout time.Duration) (*http.Client, error) {
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
DisableKeepAlives: true,
|
DisableKeepAlives: true,
|
||||||
Dial: func(proto, addr string) (conn net.Conn, err error) {
|
Dial: func(proto, addr string) (conn net.Conn, err error) {
|
||||||
@@ -61,8 +60,8 @@ func BuildUnixSocketClient(socketAddr string, timeout time.Duration) (*http.Clie
|
|||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (km *KataMonitor) doGet(sandboxID, namespace string, timeoutInSeconds time.Duration, urlPath string) ([]byte, error) {
|
func doGet(sandboxID string, timeoutInSeconds time.Duration, urlPath string) ([]byte, error) {
|
||||||
client, err := km.buildShimClient(sandboxID, namespace, timeoutInSeconds)
|
client, err := BuildShimClient(sandboxID, timeoutInSeconds)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ type agent struct {
|
|||||||
Debug bool `toml:"enable_debug"`
|
Debug bool `toml:"enable_debug"`
|
||||||
Tracing bool `toml:"enable_tracing"`
|
Tracing bool `toml:"enable_tracing"`
|
||||||
DebugConsoleEnabled bool `toml:"debug_console_enabled"`
|
DebugConsoleEnabled bool `toml:"debug_console_enabled"`
|
||||||
|
DialTimeout uint32 `toml:"dial_timeout"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type netmon struct {
|
type netmon struct {
|
||||||
@@ -471,6 +472,10 @@ func (a agent) debugConsoleEnabled() bool {
|
|||||||
return a.DebugConsoleEnabled
|
return a.DebugConsoleEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a agent) dialTimout() uint32 {
|
||||||
|
return a.DialTimeout
|
||||||
|
}
|
||||||
|
|
||||||
func (a agent) debug() bool {
|
func (a agent) debug() bool {
|
||||||
return a.Debug
|
return a.Debug
|
||||||
}
|
}
|
||||||
@@ -920,6 +925,7 @@ func updateRuntimeConfigAgent(configPath string, tomlConf tomlConfig, config *oc
|
|||||||
TraceType: agent.traceType(),
|
TraceType: agent.traceType(),
|
||||||
KernelModules: agent.kernelModules(),
|
KernelModules: agent.kernelModules(),
|
||||||
EnableDebugConsole: agent.debugConsoleEnabled(),
|
EnableDebugConsole: agent.debugConsoleEnabled(),
|
||||||
|
DialTimeout: agent.dialTimout(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ type KataAgentConfig struct {
|
|||||||
ContainerPipeSize uint32
|
ContainerPipeSize uint32
|
||||||
TraceMode string
|
TraceMode string
|
||||||
TraceType string
|
TraceType string
|
||||||
|
DialTimeout uint32
|
||||||
KernelModules []string
|
KernelModules []string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +237,7 @@ type kataAgent struct {
|
|||||||
keepConn bool
|
keepConn bool
|
||||||
dynamicTracing bool
|
dynamicTracing bool
|
||||||
dead bool
|
dead bool
|
||||||
|
dialTimout uint32
|
||||||
kmodules []string
|
kmodules []string
|
||||||
|
|
||||||
vmSocket interface{}
|
vmSocket interface{}
|
||||||
@@ -344,6 +346,7 @@ func (k *kataAgent) init(ctx context.Context, sandbox *Sandbox, config KataAgent
|
|||||||
disableVMShutdown = k.handleTraceSettings(config)
|
disableVMShutdown = k.handleTraceSettings(config)
|
||||||
k.keepConn = config.LongLiveConn
|
k.keepConn = config.LongLiveConn
|
||||||
k.kmodules = config.KernelModules
|
k.kmodules = config.KernelModules
|
||||||
|
k.dialTimout = config.DialTimeout
|
||||||
|
|
||||||
return disableVMShutdown, nil
|
return disableVMShutdown, nil
|
||||||
}
|
}
|
||||||
@@ -1794,7 +1797,7 @@ func (k *kataAgent) connect(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
k.Logger().WithField("url", k.state.URL).Info("New client")
|
k.Logger().WithField("url", k.state.URL).Info("New client")
|
||||||
client, err := kataclient.NewAgentClient(k.ctx, k.state.URL)
|
client, err := kataclient.NewAgentClient(k.ctx, k.state.URL, k.dialTimout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
k.dead = true
|
k.dead = true
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -62,15 +62,21 @@ type dialer func(string, time.Duration) (net.Conn, error)
|
|||||||
// model, and mediates communication between AF_UNIX sockets (on the host end)
|
// model, and mediates communication between AF_UNIX sockets (on the host end)
|
||||||
// and AF_VSOCK sockets (on the guest end).
|
// and AF_VSOCK sockets (on the guest end).
|
||||||
// - mock://<path>. just for test use.
|
// - mock://<path>. just for test use.
|
||||||
func NewAgentClient(ctx context.Context, sock string) (*AgentClient, error) {
|
func NewAgentClient(ctx context.Context, sock string, timeout uint32) (*AgentClient, error) {
|
||||||
grpcAddr, parsedAddr, err := parse(sock)
|
grpcAddr, parsedAddr, err := parse(sock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialTimeout := defaultDialTimeout
|
||||||
|
if timeout > 0 {
|
||||||
|
dialTimeout = time.Duration(timeout) * time.Second
|
||||||
|
agentClientLog.WithField("timeout", timeout).Debug("custom dialing timeout has been set")
|
||||||
|
}
|
||||||
|
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
var d = agentDialer(parsedAddr)
|
var d = agentDialer(parsedAddr)
|
||||||
conn, err = d(grpcAddr, defaultDialTimeout)
|
conn, err = d(grpcAddr, dialTimeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -92,7 +98,7 @@ func NewAgentClient(ctx context.Context, sock string) (*AgentClient, error) {
|
|||||||
grpc.WithStreamInterceptor(otgrpc.OpenTracingStreamClientInterceptor(tracer)))
|
grpc.WithStreamInterceptor(otgrpc.OpenTracingStreamClientInterceptor(tracer)))
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(ctx, defaultDialTimeout)
|
ctx, cancel := context.WithTimeout(ctx, dialTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
conn, err := grpc.DialContext(ctx, grpcAddr, dialOpts...)
|
conn, err := grpc.DialContext(ctx, grpcAddr, dialOpts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -768,8 +768,8 @@ func (q *qemu) setupVirtioMem() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 1024 is size for nvdimm
|
// backend memory size must be multiple of 2Mib
|
||||||
sizeMB := int(maxMem) - int(q.config.MemorySize)
|
sizeMB := (int(maxMem) - int(q.config.MemorySize)) >> 2 << 2
|
||||||
|
|
||||||
share, target, memoryBack, err := q.getMemArgs()
|
share, target, memoryBack, err := q.getMemArgs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -2043,8 +2043,9 @@ func (q *qemu) resizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSiz
|
|||||||
var addMemDevice memoryDevice
|
var addMemDevice memoryDevice
|
||||||
if q.config.VirtioMem && currentMemory != reqMemMB {
|
if q.config.VirtioMem && currentMemory != reqMemMB {
|
||||||
q.Logger().WithField("hotplug", "memory").Debugf("resize memory from %dMB to %dMB", currentMemory, reqMemMB)
|
q.Logger().WithField("hotplug", "memory").Debugf("resize memory from %dMB to %dMB", currentMemory, reqMemMB)
|
||||||
sizeByte := (reqMemMB - q.config.MemorySize) * 1024 * 1024
|
sizeByte := uint64(reqMemMB - q.config.MemorySize)
|
||||||
err := q.qmpMonitorCh.qmp.ExecQomSet(q.qmpMonitorCh.ctx, "virtiomem0", "requested-size", uint64(sizeByte))
|
sizeByte = sizeByte * 1024 * 1024
|
||||||
|
err := q.qmpMonitorCh.qmp.ExecQomSet(q.qmpMonitorCh.ctx, "virtiomem0", "requested-size", sizeByte)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, memoryDevice{}, err
|
return 0, memoryDevice{}, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -686,13 +686,13 @@ func (s *Sandbox) Delete(ctx context.Context) error {
|
|||||||
|
|
||||||
for _, c := range s.containers {
|
for _, c := range s.containers {
|
||||||
if err := c.delete(ctx); err != nil {
|
if err := c.delete(ctx); err != nil {
|
||||||
return err
|
s.Logger().WithError(err).WithField("cid", c.id).Debug("failed to delete container")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !rootless.IsRootless() {
|
if !rootless.IsRootless() {
|
||||||
if err := s.cgroupsDelete(); err != nil {
|
if err := s.cgroupsDelete(); err != nil {
|
||||||
return err
|
s.Logger().WithError(err).Error("failed to cleanup cgroups")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,8 @@ readonly -a systemd_files=(
|
|||||||
# Set a default value
|
# Set a default value
|
||||||
AGENT_INIT=${AGENT_INIT:-no}
|
AGENT_INIT=${AGENT_INIT:-no}
|
||||||
|
|
||||||
# Align image to (size in MB) according to different architecture.
|
# Align image to 128M
|
||||||
case "$(uname -m)" in
|
readonly mem_boundary_mb=128
|
||||||
aarch64) readonly mem_boundary_mb=16 ;;
|
|
||||||
*) readonly mem_boundary_mb=128 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# shellcheck source=../scripts/lib.sh
|
# shellcheck source=../scripts/lib.sh
|
||||||
source "${lib_file}"
|
source "${lib_file}"
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
* [How to use Kata workloads for `ccloudvm`](#how-to-use-kata-workloads-for-ccloudvm)
|
* [How to use Kata workloads for `ccloudvm`](#how-to-use-kata-workloads-for-ccloudvm)
|
||||||
* [Create Docker\* and Kata Containers virtualized environment](#create-docker-and-kata-containers-virtualized-environment)
|
* [Create Docker\* and Kata Containers virtualized environment](#create-docker-and-kata-containers-virtualized-environment)
|
||||||
---
|
|
||||||
|
***
|
||||||
|
|
||||||
The [ccloudvm](https://github.com/intel/ccloudvm/) tool is a command
|
The [ccloudvm](https://github.com/intel/ccloudvm/) tool is a command
|
||||||
to create development and demo environments. The tool sets up these development
|
to create development and demo environments. The tool sets up these development
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ spec:
|
|||||||
katacontainers.io/kata-runtime: cleanup
|
katacontainers.io/kata-runtime: cleanup
|
||||||
containers:
|
containers:
|
||||||
- name: kube-kata-cleanup
|
- name: kube-kata-cleanup
|
||||||
image: katadocker/kata-deploy:2.1.0-rc0
|
image: katadocker/kata-deploy:2.1.0
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
command: [ "bash", "-c", "/opt/kata-artifacts/scripts/kata-deploy.sh reset" ]
|
command: [ "bash", "-c", "/opt/kata-artifacts/scripts/kata-deploy.sh reset" ]
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
bases:
|
||||||
|
- ../../base
|
||||||
|
|
||||||
|
patchesStrategicMerge:
|
||||||
|
- mount_k3s_conf.yaml
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: kubelet-kata-cleanup
|
||||||
|
namespace: kube-system
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: kube-kata-cleanup
|
||||||
|
volumeMounts:
|
||||||
|
- name: containerd-conf
|
||||||
|
mountPath: /etc/containerd/
|
||||||
|
volumes:
|
||||||
|
- name: containerd-conf
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/rancher/k3s/agent/etc/containerd/
|
||||||
@@ -16,7 +16,7 @@ spec:
|
|||||||
serviceAccountName: kata-label-node
|
serviceAccountName: kata-label-node
|
||||||
containers:
|
containers:
|
||||||
- name: kube-kata
|
- name: kube-kata
|
||||||
image: katadocker/kata-deploy:2.1.0-rc0
|
image: katadocker/kata-deploy:2.1.0
|
||||||
imagePullPolicy: Always
|
imagePullPolicy: Always
|
||||||
lifecycle:
|
lifecycle:
|
||||||
preStop:
|
preStop:
|
||||||
|
|||||||
Reference in New Issue
Block a user