원클릭으로
fabric-containers
Deploy Docker containers and Kubernetes clusters on FABRIC nodes
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Deploy Docker containers and Kubernetes clusters on FABRIC nodes
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Run iPerf3 network performance benchmarks with optional CPU pinning and SmartNIC optimization
Generate FABRIC testbed environment setup, configuration validation, and SSH key management code
Connect FABRIC to external testbeds via facility ports and set up port mirroring
Provision and flash Xilinx U280 FPGAs on FABRIC nodes
Provision GPU nodes on FABRIC with driver installation and CUDA setup
Show available FABRIC testbed skills and which one to use
| name | fabric-containers |
| description | Deploy Docker containers and Kubernetes clusters on FABRIC nodes |
| allowed-tools | ["Read","Grep","Glob","Write","Edit","Bash"] |
When invoked, generate code for container-based workloads on FABRIC. Two main capabilities:
Help the user choose the right approach and generate complete setup code.
FABRIC provides Docker-ready OS images:
docker_rocky_8 — Rocky Linux 8 with Docker pre-configureddocker_ubuntu_20 — Ubuntu 20.04 with Docker pre-configurednode.add_post_boot_upload_directory('node_tools', '.')
node.add_post_boot_execute('node_tools/enable_docker.sh {{ _self_.image }}')
node.add_post_boot_upload_directory('docker_containers', '.')
node.add_post_boot_execute('cd docker_containers/my_app ; docker compose up -d')
from fabrictestbed_extensions.fablib.fablib import FablibManager
fablib = FablibManager()
slice = fablib.new_slice(name="docker-experiment")
node = slice.add_node(
name="docker-node",
site=fablib.get_random_site(),
cores=4,
ram=16,
disk=100,
image="docker_rocky_8",
)
node.add_fabnet()
# Enable Docker via post-boot
node.add_post_boot_upload_directory('node_tools', '.')
node.add_post_boot_execute('node_tools/enable_docker.sh {{ _self_.image }}')
slice.submit()
# Run a container
node = slice.get_node(name="docker-node")
stdout, stderr = node.execute(
"docker run -d -it "
"--name my_container "
"fabrictestbed/slice-vm-rocky8-multitool:0.0.1"
)
# View containers
stdout, stderr = node.execute("docker ps -a")
print(stdout)
# Execute commands in container
stdout, stderr = node.execute("docker exec my_container ip addr list")
print(stdout)
slice = fablib.new_slice(name="compose-experiment")
node = slice.add_node(
name="app-node",
site=fablib.get_random_site(),
cores=4,
ram=16,
disk=100,
image="docker_rocky_8",
)
# Upload and start Docker + application
node.add_post_boot_upload_directory('node_tools', '.')
node.add_post_boot_execute('node_tools/enable_docker.sh {{ _self_.image }}')
node.add_post_boot_upload_directory('docker_containers', '.')
node.add_post_boot_execute('cd docker_containers/my_app ; docker compose up -d')
slice.submit()
from fabrictestbed_extensions.fablib.fablib import FablibManager
fablib = FablibManager()
[site1, site2] = fablib.get_random_sites(count=2)
slice = fablib.new_slice(name="k8s-cluster")
# Create L3 networks for each site
net1 = slice.add_l3network(name="net1", type="IPv4")
net2 = slice.add_l3network(name="net2", type="IPv4")
# Controller node
ctrlr = slice.add_node(
name="controller",
site=site1,
cores=8,
ram=32,
disk=100,
image="default_ubuntu_22",
)
iface = ctrlr.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface.set_mode("auto")
net1.add_interface(iface)
ctrlr.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net1.get_gateway())
# Worker nodes
worker1 = slice.add_node(
name="worker1",
site=site1,
cores=8,
ram=32,
disk=100,
image="default_ubuntu_22",
)
iface1 = worker1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface1.set_mode("auto")
net1.add_interface(iface1)
worker1.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net1.get_gateway())
worker2 = slice.add_node(
name="worker2",
site=site2,
cores=8,
ram=32,
disk=100,
image="default_ubuntu_22",
)
iface2 = worker2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface2.set_mode("auto")
net2.add_interface(iface2)
worker2.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net2.get_gateway())
slice.submit()
nodes = slice.get_nodes()
# Generate SSH keys on all nodes
for n in nodes:
n.execute('ssh-keygen -t rsa -N "" -f /home/ubuntu/.ssh/id_rsa', quiet=True)
n.execute('sudo ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa', quiet=True)
# Collect public keys
keys = {}
for n in nodes:
ubuntu_key, _ = n.execute("cat /home/ubuntu/.ssh/id_rsa.pub", quiet=True)
root_key, _ = n.execute("sudo cat /root/.ssh/id_rsa.pub", quiet=True)
keys[n.get_name()] = {"ubuntu": ubuntu_key.strip(), "root": root_key.strip()}
# Distribute keys
for n in nodes:
for other_name, node_keys in keys.items():
if other_name == n.get_name():
continue
n.execute(f'echo "{node_keys["ubuntu"]}" >> /home/ubuntu/.ssh/authorized_keys')
n.execute(
f"sudo sh -c 'echo \"{node_keys['root']}\" >> /root/.ssh/authorized_keys'"
)
# Build IP map from dataplane interfaces
node_ips = {}
for n in nodes:
for iface in n.get_interfaces():
ip = iface.get_ip_addr()
if ip:
node_ips[n.get_name()] = str(ip)
break
# Update /etc/hosts on all nodes
for n in nodes:
for name, ip in node_ips.items():
n.execute(f"sudo sh -c 'echo \"{ip} {name}\" >> /etc/hosts'")
# Upload K8s install scripts to all nodes
for n in nodes:
n.upload_directory(local_directory_path="./node_tools", remote_directory_path=".")
# Step 1: Install prerequisites (containerd, etc.)
for n in nodes:
n.execute(
"sudo ./node_tools/k8s_pre_install.sh",
quiet=True,
output_file=f"logs/{n.get_name()}_pre_install.log",
)
# Step 2: Wait for reboot and reconfigure network
slice.wait_ssh()
for n in nodes:
n.config()
# Step 3: Install kubelet, kubeadm, kubectl
for n in nodes:
n.execute(
"sudo ./node_tools/k8s_install.sh",
quiet=True,
output_file=f"logs/{n.get_name()}_install.log",
)
ctrlr = slice.get_node(name="controller")
ctrlr_addr = node_ips["controller"]
# Configure kubelet to use dataplane IP
ctrlr.execute(f"sudo node_tools/k8s_kubelet.sh {ctrlr_addr}")
# Initialize control plane
ctrlr.execute(f"node_tools/k8s_init_control_plane.sh {ctrlr_addr}")
# Deploy Flannel CNI (patched for IPv6 management networks)
ctrlr.execute(f"node_tools/k8s_flannel.sh {ctrlr_addr}")
# Verify
stdout, _ = ctrlr.execute("node_tools/k8s_status.sh")
print(stdout)
# Get join command from controller
join_command, _ = ctrlr.execute("kubeadm token create --print-join-command")
# Join workers
for n in nodes:
if n.get_name() == "controller":
continue
n.execute(f"sudo {join_command.strip()}")
# Verify cluster
stdout, _ = ctrlr.execute("kubectl get nodes -o wide")
print(stdout)
# Deploy nginx
ctrlr.execute("kubectl apply -f node_tools/pod.yml")
# Expose via NodePort
ctrlr.execute("kubectl apply -f node_tools/service_nodeport.yml")
# Check status
stdout, _ = ctrlr.execute("kubectl get pods -o wide")
print(stdout)
import os
local_port = "30080"
target_host = f"{ctrlr.get_username()}@{ctrlr.get_management_ip()}"
key_file = os.path.basename(fablib.get_default_slice_public_key_file())[:-4]
print(
f"ssh -L 127.0.0.1:{local_port}:127.0.0.1:{local_port} "
f"-i {key_file} -F ssh_config {target_host}"
)
print(f"Then browse: http://127.0.0.1:{local_port}")
docker_rocky_8 or docker_ubuntu_20 for pre-configured Docker{{ _self_.image }} template variable for OS detectionslice.wait_ssh() then node.config() to restore networkingnode.pin_cpu() and node.numa_tune() for performance-sensitive workloads