Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ deploy/standalone/output/
# dedicated Docker stages.
src/distill-fs/target/
src/sandboxd/output/
src/yuanrong/
src/yuanrong/*
!src/yuanrong/LICENSE

# Python caches and package outputs.
**/__pycache__/
Expand Down
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ the sandbox bridge. YuanRong receives `INSTANCE_IP` in Kubernetes or the
default-route interface address in standalone mode; `AKERNEL_NODE_IP` is the
explicit override for multi-homed environments.

Node deployments keep openYuanRong's in-node address aligned with sandboxd's
actual bridge state. Kubernetes renders `node.sandboxIPRange` into sandboxd's
`ip_range`; standalone reads the same setting from `sandboxd_config.toml` when
preparing networking. The YuanRong bootstrap waits with a bounded timeout for
`sandbox0` and passes its assigned IPv4 address to `yr start --local_ip`.

The standalone sandboxd filestore is a loop-mounted XFS image under the
bind-mounted `deploy/standalone/data/` directory. Explicit `storage_mb` quotas
use this local-disk filestore; omitting `storage_mb` retains the configured
Expand Down
182 changes: 182 additions & 0 deletions builder/config/yr/config.toml.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
{#
AKernel runtime profile template.

Deployment values are resolved from the CLI-provided env mapping. Strings
containing Python CLI runtime expressions remain escaped for its second
rendering pass.
#}
{% macro toml_string(value) -%}
"{%- for char in value -%}
{%- set encoded = char | tojson -%}
{{- char if encoded | length == 14 else encoded[1:-1] -}}
{%- endfor -%}"
{%- endmacro %}
{% set role = env["AKERNEL_ROLE"] %}
{% set cluster_roles = ["master", "master-core", "frontend"] %}
{% set node_roles = ["node", "standalone"] %}
{% if role not in cluster_roles + node_roles %}
{{ unsupported_akernel_role }}
{% endif %}
{% set is_cluster = role in cluster_roles %}
{% set is_node = role in node_roles %}
{% set is_agent = role == "node" %}
{% set is_standalone = role == "standalone" %}
{% set has_master_mode = not is_agent %}
{% set enable_metrics = env.get("ENABLE_METRICS", "false") | lower %}
{% set enable_trace = env.get("ENABLE_TRACE", "false") | lower %}
{% set traefik_enable_tls = "true" if env.get("TRAEFIK_ENABLE_TLS", "false") | lower == "true" else "false" %}
{% set configured_host_ip = env.get("YR_NODE_IP", "") | trim %}
{% set configured_local_ip = env.get("YR_LOCAL_IP", "") | trim %}
{% set runtime_hostname = "{{ hostname }}" %}

# Generated at startup from builder/config/yr/config.toml.jinja.

[values]
node_id = "{{ runtime_hostname }}"
{% if configured_host_ip %}
host_ip = {{ toml_string(configured_host_ip) }}
{% endif %}
{% if configured_local_ip %}
local_ip = {{ toml_string(configured_local_ip) }}
{% endif %}
{% if is_cluster %}
cpu_num = 1
memory_num = 3904
shared_memory_num = 4096
deploy_path = "/home/yuanrong/master"
{% else %}
cpu_num = {{ env["YR_CPU_MILLICORES"] }}
memory_num = {{ env["YR_COMPONENT_MEMORY_MB"] }}
shared_memory_num = {{ env["YR_SHARED_MEMORY_MB"] }}
{% endif %}

[values.fs.log]
path = "{{ '/home/yuanrong/master/log' if is_cluster else '/home/yuanrong/logs' }}"

[values.fs.tls]
base_path = "/home/yuanrong/.cert"

{% if not is_standalone %}
[values.etcd]
enable_multi_master = true
{% endif %}

{% if is_cluster %}
[[values.etcd.address]]
ip = {{ toml_string(env["ETCD_ADDRESS"]) }}
port = {{ env.get("ETCD_PORT", "2379") }}
peer_port = {{ env.get("ETCD_PEER_PORT", "2378") }}
{% endif %}

[values.frontend]
ssl_enable = true
client_auth_type = "NoClientCert"
frontend_lease_bypass = true
enable_function_token_auth = true
enable_func_token_auth = true
{% if role == "frontend" %}
meta_service_address = {{ toml_string(env["META_SERVICE_ADDRESS"]) }}
{% endif %}
iam_server_address = "127.0.0.1:31113"

[values.meta_service]
port = 31111

{% if has_master_mode %}
[mode.master]
ds_master = false
frontend = {{ "true" if role in ["master", "frontend", "standalone"] else "false" }}
function_master = {{ "true" if role in ["master", "master-core", "standalone"] else "false" }}
function_scheduler = false
meta_service = {{ "true" if role in ["master", "master-core", "standalone"] else "false" }}
iam_server = {{ "true" if role in ["master", "frontend", "standalone"] else "false" }}
{% endif %}

[ds_worker.args]
{% if is_cluster %}
rpc_thread_num = 128
{% endif %}
{% if is_node %}
node_timeout_s = 30
client_dead_timeout_s = 60
heartbeat_interval_ms = 1000
node_dead_timeout_s = 120
log_dir = "/home/yuanrong/logs"
{% endif %}

[function_master.args]
services_path = "/home/yuanrong/deploy/process/services.yaml"
metrics_config_file = "/home/yuanrong/metrics/metrics_config.json"
traefik_enable_tls = {{ traefik_enable_tls }}
traefik_http_entry_point = {{ toml_string(env.get("TRAEFIK_HTTP_ENTRYPOINT", "websecure")) }}
traefik_forward_timeout_ms = 3000
{% if enable_metrics == "true" and (is_cluster or is_standalone) %}
enable_metrics = true
{% endif %}
{% if enable_trace == "true" and (is_cluster or is_standalone) %}
enable_trace = true
trace_config = {{ toml_string(env["YR_TRACE_CONFIG_CONTENT"]) }}
{% endif %}
{% if is_cluster %}
enable_traefik_provider = {{ "true" if env.get("TRAEFIK_MODE", "etcd") == "http" else "false" }}
system_timeout = 300000
schedule_relaxed = 20
{% elif is_standalone %}
system_timeout = 60000
{% endif %}

[function_proxy.args]
services_path = "/home/yuanrong/deploy/process/services.yaml"
enable_inherit_env = false
npu_collection_mode = "off"
metrics_config_file = "/home/yuanrong/metrics/metrics_config.json"
enable_direct_routing = false
force_low_reliability_instance = true
traefik_enable_tls = {{ traefik_enable_tls }}
{% if enable_metrics == "true" %}
enable_metrics = true
{% endif %}
{% if enable_trace == "true" %}
enable_trace = true
trace_config = {{ toml_string(env["YR_TRACE_CONFIG_CONTENT"]) }}
{% endif %}
{% if is_node %}
enable_traefik_registry = {{ "true" if env.get("TRAEFIK_MODE", "etcd") == "etcd" else "false" }}
traefik_http_entrypoint = {{ toml_string(env.get("TRAEFIK_HTTP_ENTRYPOINT", "websecure")) }}
{% endif %}
log_expiration_enable = true
log_expiration_time_threshold = {{ 10 if is_agent else 7200 }}
log_expiration_cleanup_interval = {{ 10 if is_agent else 600 }}
log_expiration_max_file_count = {{ 50 if is_agent else 256 }}
{% if is_cluster %}
system_timeout = 300000
pseudo_data_plane = true
{% elif is_node %}
system_timeout = 60000
fc_agent_mgr_retry_times = 30
fc_agent_mgr_retry_cycle = 60000
runtime_logs_dir = "/home/yuanrong/logs"
{% endif %}
{% if is_agent %}
metrics_collector_type = "external"
{% endif %}

# The CLI exposes the meta-service component port separately from values.meta_service.
[meta_service]
port = 31111

[iam_server.args]
token_expired_time_span = 604800
ssl_enable = true
iam_ssl_enable = true
local_listen_port = 31113
local_ip = "127.0.0.1"
{% if enable_trace == "true" and (is_cluster or is_standalone) %}
enable_trace = true
{% endif %}

{% if enable_trace == "true" and (is_cluster or is_standalone) %}
[frontend.env]
ENABLE_TRACE = "true"
TRACE_CONFIG = {{ toml_string(env["YR_TRACE_CONFIG_CONTENT"]) }}
{% endif %}
62 changes: 47 additions & 15 deletions builder/node.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ ARG AKERNEL_NODE_BASE_IMAGE=ubuntu:24.04
ARG AKERNEL_RUNTIME_IMAGE=akernel-runtime:local
ARG SANDBOXD_BUILD_IMAGE=golang:1.25.5-bookworm
ARG DISTILL_FS_BUILD_IMAGE=rust:1.85.0-bookworm
ARG OPEN_YR_VERSION=0.9.3
ARG OPEN_YR_VERSION=0.9.4
ARG OPEN_YR_CORE_WHEEL_URL=
ARG OPEN_YR_CORE_WHEEL_SHA256=
ARG OPEN_YR_RELEASE_BASE_URL=https://github.com/openYuanrong-mirror/yuanrong/releases/download
ARG OPEN_YR_CORE_AMD64_SHA256=dd472bfa60d3d934056801ae011db7b1993cb19c5681da2395e7f1e2d84e58c3
ARG OPEN_YR_CORE_ARM64_SHA256=4a3468d189e155e1759e2b47ace4b468d9036e76b4b750a1d47d7d13d143563e
ARG OPEN_YR_CORE_AMD64_SHA256=cd64c08bbf6aabfa4fe747a28205e7b215e1340aa11e120bc7680263b0a41cfb
ARG OPEN_YR_CORE_ARM64_SHA256=5d9ad34a852bee2da8208738731061cb1a928588412d0b907354b44c7391b29f
ARG GVISOR_RELEASE=release-20260706.0
ARG GVISOR_RELEASE_BASE_URL=https://storage.googleapis.com/gvisor/releases
ARG LIBNVIDIA_CONTAINER_VERSION=1.19.1-1
ARG KATA_BUILD_IMAGE=ubuntu:24.04
ARG KATA_RELEASE=4.0.0
ARG KATA_AMD64_SHA256=2c3b9dfeba355582b40aee462b12916c9740654d0230f696adf719d67b063a8c
ARG KATA_RELEASE_BASE_URL=https://github.com/kata-containers/kata-containers/releases/download
ARG KATA_LICENSE_URL=https://raw.githubusercontent.com/kata-containers/kata-containers/${KATA_RELEASE}/LICENSE
ARG OTELCOL_CONTRIB_VERSION=0.120.0
ARG OTELCOL_CONTRIB_URL=https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v${OTELCOL_CONTRIB_VERSION}/otelcol-contrib_${OTELCOL_CONTRIB_VERSION}_linux_amd64.tar.gz
ARG AKERNEL_VERSION=unknown
Expand All @@ -28,6 +29,7 @@ FROM ${KATA_BUILD_IMAGE} AS kata-runtime
ARG KATA_RELEASE
ARG KATA_AMD64_SHA256
ARG KATA_RELEASE_BASE_URL
ARG KATA_LICENSE_URL
ARG TARGETARCH
RUN set -eux; \
test "${TARGETARCH:-amd64}" = "amd64"; \
Expand All @@ -50,8 +52,8 @@ RUN set -eux; \
ln -sfn configuration-dragonball.toml \
/kata/opt/kata/share/defaults/kata-containers/runtime-rs/configuration.toml; \
mkdir -p /kata/opt/kata/share/licenses/kata-containers; \
curl -fSL --retry 10 --retry-delay 2 --retry-all-errors \
"https://raw.githubusercontent.com/kata-containers/kata-containers/${KATA_RELEASE}/LICENSE" \
curl -fSL --max-time 30 --retry 10 --retry-delay 2 --retry-all-errors \
"${KATA_LICENSE_URL}" \
-o /kata/opt/kata/share/licenses/kata-containers/LICENSE; \
rm -f "${archive}"

Expand Down Expand Up @@ -124,6 +126,7 @@ RUN apt-get update && \
procps \
python3 \
python3-pip \
python3-venv \
systemd \
systemd-sysv \
tzdata \
Expand Down Expand Up @@ -188,6 +191,10 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \


ENV YR_INSTALLATION_DIR=/home/yuanrong
ENV PATH=/opt/openyuanrong/bin:${PATH}

COPY ./builder/config/yr/config.toml.jinja /etc/yuanrong/config.toml.jinja
COPY ./src/yuanrong/LICENSE /usr/share/licenses/openyuanrong/LICENSE

# Install the complete, language-runtime-free openYuanRong control plane from
# its checksum-pinned core wheel. A URL and checksum pair may override the
Expand Down Expand Up @@ -217,21 +224,46 @@ RUN set -eux; \
test -z "${OPEN_YR_CORE_WHEEL_SHA256}"; \
fi; \
wheel="/tmp/${wheel_name}"; \
target=/tmp/openyuanrong-core; \
curl -fSL --retry 10 --retry-delay 2 --retry-all-errors \
"${wheel_url}" -o "${wheel}"; \
echo "${wheel_sha} ${wheel}" | sha256sum -c -; \
python3 -m pip install \
--break-system-packages \
python3 -m venv /opt/openyuanrong; \
/opt/openyuanrong/bin/python -m pip install \
--no-cache-dir \
--no-deps \
--target "${target}" \
--index-url "${PIP_INDEX_URL}" \
"${wheel}"; \
test -x "${target}/yr/functionsystem/bin/yr"; \
mkdir -p "${YR_INSTALLATION_DIR}"; \
cp -a "${target}/yr/." "${YR_INSTALLATION_DIR}/"; \
rm -rf "${target}" "${wheel}"; \
ln -sfn "${YR_INSTALLATION_DIR}/functionsystem/bin/yr" /usr/bin/yr
site_packages="$(/opt/openyuanrong/bin/python -c 'import site; print(site.getsitepackages()[0])')"; \
base_py="${site_packages}/yr/cli/component/base.py"; \
launcher_py="${site_packages}/yr/cli/system_launcher.py"; \
sed -i \
's/logger.info(f"Environment: {full_env}")/logger.info(f"Environment keys: {sorted(full_env)}")/' \
"${base_py}"; \
sed -i 's/"env_vars": comp.env_vars,/"env_vars": {},/' "${launcher_py}"; \
/opt/openyuanrong/bin/python -c "import yr"; \
/opt/openyuanrong/bin/yr --help; \
/opt/openyuanrong/bin/yr config render --help; \
AKERNEL_ROLE=node \
HOSTNAME=build-smoke \
YR_NODE_IP=127.0.0.1 \
YR_LOCAL_IP=172.17.0.1 \
ETCD_ADDRESS=127.0.0.1 \
ETCD_PORT=2379 \
ETCD_PEER_PORT=2380 \
META_SERVICE_ADDRESS=127.0.0.1:31111 \
YR_MASTER_ADDRESS=http://127.0.0.1:22770 \
YR_CPU_MILLICORES=1000 \
YR_COMPONENT_MEMORY_MB=1024 \
YR_SHARED_MEMORY_MB=512 \
YR_LOG_PATH=/home/yuanrong/logs \
ENABLE_METRICS=false \
ENABLE_TRACE=false \
TRAEFIK_MODE=http \
TRAEFIK_ENABLE_TLS=false \
TRAEFIK_HTTP_ENTRYPOINT=websecure \
/opt/openyuanrong/bin/yr config render \
-t /etc/yuanrong/config.toml.jinja \
-o /tmp/openyuanrong-config.toml; \
rm -f "${wheel}" /tmp/openyuanrong-config.toml

COPY --from=runtime-image /yr-runtime-rootfs.img ${YR_INSTALLATION_DIR}/yr-runtime-rootfs.img

Expand Down
Loading