two/main/demarrage/premier-vpc.html
2026-09-09 21:52:29 +00:00

1028 lines
No EOL
43 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="fr" data-content_root="../" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Premier VPC, premier subnet, première VM &#8212; Documentation two 0.1.0</title>
<script data-cfasync="false">
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
</script>
<!--
this give us a css class that will be invisible only if js is disabled
-->
<noscript>
<style>
.pst-js-only { display: none !important; }
</style>
</noscript>
<!-- Loaded before other Sphinx assets -->
<link href="../_static/styles/theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link href="../_static/styles/pydata-sphinx-theme.css?digest=8878045cc6db502f8baf" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=8f2a1f02" />
<link rel="stylesheet" type="text/css" href="../_static/styles/sphinx-book-theme.css?v=3c74b3bc" />
<!-- So that users can add custom icons -->
<script src="../_static/scripts/fontawesome.js?digest=8878045cc6db502f8baf"></script>
<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf" />
<link rel="preload" as="script" href="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf" />
<script src="../_static/documentation_options.js?v=57395fb6"></script>
<script src="../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="../_static/scripts/sphinx-book-theme.js?v=fab101a9"></script>
<script src="../_static/translations.js?v=e6b791cb"></script>
<script src="https://cdn.jsdelivr.net/npm/d3@7.9.0/dist/d3.min.js"></script>
<script type="module">import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11.12.1/dist/mermaid.esm.min.mjs";
const initStyles = () => {
const defaultStyle = document.createElement('style');
defaultStyle.textContent = `pre.mermaid {
/* Same as .mermaid-container > pre */
display: block;
width: 100%;
}
pre.mermaid > svg {
/* Same as .mermaid-container > pre > svg */
height: 500px;
width: 100%;
max-width: 100% !important;
}`;
document.head.appendChild(defaultStyle);
const fullscreenStyle = document.createElement('style');
fullscreenStyle.textContent = `.mermaid-container {
display: flex;
flex-direction: row;
width: 100%;
}
.mermaid-container > pre {
display: block;
width: 100%;
}
.mermaid-container > pre > svg {
height: 500px;
width: 100%;
max-width: 100% !important;
}
.mermaid-fullscreen-btn {
width: 28px;
height: 28px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
font-size: 14px;
line-height: 1;
padding: 0;
color: #333;
}
.mermaid-fullscreen-btn:hover {
opacity: 100% !important;
background: rgba(255, 255, 255, 1);
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.3);
transform: scale(1.1);
}
.mermaid-fullscreen-btn.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.3);
color: #e0e0e0;
}
.mermaid-fullscreen-btn.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 3px 10px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal {
display: none;
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 95vw;
height: 100vh;
background: rgba(255, 255, 255, 0.98);
z-index: 9999;
padding: 20px;
overflow: auto;
}
.mermaid-fullscreen-modal.dark-theme {
background: rgba(0, 0, 0, 0.98);
}
.mermaid-fullscreen-modal.active {
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen {
position: relative;
width: 95vw;
height: 90vh;
max-width: 95vw;
max-height: 90vh;
background: white;
border-radius: 8px;
padding: 20px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
overflow: auto;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen.dark-theme {
background: #1a1a1a;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.8);
}
.mermaid-container-fullscreen pre.mermaid {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.mermaid-container-fullscreen .mermaid svg {
height: 100% !important;
width: 100% !important;
cursor: grab;
}
.mermaid-fullscreen-close {
position: fixed !important;
top: 20px !important;
right: 20px !important;
width: 40px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 50%;
cursor: pointer;
z-index: 10000;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
transition: all 0.2s;
font-size: 24px;
line-height: 1;
color: #333;
}
.mermaid-fullscreen-close:hover {
background: white;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
transform: scale(1.1);
}
.mermaid-fullscreen-close.dark-theme {
background: rgba(50, 50, 50, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
color: #e0e0e0;
}
.mermaid-fullscreen-close.dark-theme:hover {
background: rgba(60, 60, 60, 1);
box-shadow: 0 6px 16px rgba(255, 255, 255, 0.2);
}
.mermaid-fullscreen-modal .mermaid-fullscreen-btn {
display: none !important;
}`;
document.head.appendChild(fullscreenStyle);
}
// Detect if page has dark background
const isDarkTheme = () => {
// We use a set of heuristics:
// 1. Check for common dark mode classes or attributes
// 2. Check computed background color brightness
if (document.documentElement.classList.contains('dark') ||
document.documentElement.getAttribute('data-theme') === 'dark' ||
document.body.classList.contains('dark') ||
document.body.getAttribute('data-theme') === 'dark') {
// console.log("Dark theme detected via class/attribute");
return true;
}
if (document.documentElement.classList.contains('light') ||
document.documentElement.getAttribute('data-theme') === 'light' ||
document.body.classList.contains('light') ||
document.body.getAttribute('data-theme') === 'light') {
// console.log("Light theme detected via class/attribute");
return false;
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
// console.log("Dark theme detected via prefers-color-scheme");
return true;
}
const bgColor = window.getComputedStyle(document.body).backgroundColor;
const match = bgColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)/);
if (match) {
const r = parseInt(match[1]);
const g = parseInt(match[2]);
const b = parseInt(match[3]);
const brightness = (r * 299 + g * 587 + b * 114) / 1000;
// console.log("Background color brightness:", brightness);
return brightness < 128;
}
// console.log("No dark or light theme detected, defaulting to light theme");
return false;
};
let darkTheme = isDarkTheme();
let modal = null;
let modalContent = null;
let previousScrollOffset = [window.scrollX, window.scrollY];
const runMermaid = async (rerun) => {
console.log("Running mermaid diagrams, rerun =", rerun);
// clear all existing mermaid charts
let all_mermaids = document.querySelectorAll(".mermaid");
if (rerun) {
all_mermaids.forEach((el) => {
if(!el.hasAttribute("data-original-code")) {
// store original code
// console.log(`Storing original code for first run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
if(el.getAttribute("data-processed") === "true") {
// remove and restore original
el.removeAttribute("data-processed");
// console.log(`Restoring original code for re-run: `, el.getAttribute('data-original-code'));
el.innerHTML = el.getAttribute('data-original-code');
} else {
// store original code
// console.log(`Storing original code for re-run: `, el.innerHTML);
el.setAttribute('data-original-code', el.innerHTML);
}
});
await mermaid.run();
}
all_mermaids = document.querySelectorAll(".mermaid");
const mermaids_processed = document.querySelectorAll(".mermaid[data-processed='true']");
if ("False" === "True") {
const mermaids_to_add_zoom = -1 === -1 ? all_mermaids.length : -1;
if(mermaids_to_add_zoom > 0) {
var svgs = d3.selectAll("");
if(all_mermaids.length !== mermaids_processed.length) {
setTimeout(() => runMermaid(false), 200);
return;
} else if(svgs.size() !== mermaids_to_add_zoom) {
setTimeout(() => runMermaid(false), 200);
return;
} else {
svgs.each(function() {
var svg = d3.select(this);
svg.html("<g class='wrapper'>" + svg.html() + "</g>");
var inner = svg.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svg.call(zoom);
});
}
}
} else if(all_mermaids.length !== mermaids_processed.length) {
// Wait for mermaid to process all diagrams
setTimeout(() => runMermaid(false), 200);
return;
}
// Stop here if not adding fullscreen capability
if ("True" !== "True") return;
if (modal !== null ) {
// Destroy existing modal
modal.remove();
modal = null;
modalContent = null;
}
modal = document.createElement('div');
modal.className = 'mermaid-fullscreen-modal' + (darkTheme ? ' dark-theme' : '');
modal.setAttribute('role', 'dialog');
modal.setAttribute('aria-modal', 'true');
modal.setAttribute('aria-label', 'Fullscreen diagram viewer');
modal.innerHTML = `
<button class="mermaid-fullscreen-close${darkTheme ? ' dark-theme' : ''}" aria-label="Close fullscreen">✕</button>
<div class="mermaid-container-fullscreen${darkTheme ? ' dark-theme' : ''}"></div>
`;
document.body.appendChild(modal);
modalContent = modal.querySelector('.mermaid-container-fullscreen');
const closeBtn = modal.querySelector('.mermaid-fullscreen-close');
const closeModal = () => {
modal.classList.remove('active');
modalContent.innerHTML = '';
document.body.style.overflow = ''
window.scrollTo({left: previousScrollOffset[0], top: previousScrollOffset[1], behavior: 'instant'});
};
closeBtn.addEventListener('click', closeModal);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && modal.classList.contains('active')) {
closeModal();
}
});
document.querySelectorAll('.mermaid').forEach((mermaidDiv) => {
if (mermaidDiv.parentNode.classList.contains('mermaid-container') ||
mermaidDiv.closest('.mermaid-fullscreen-modal')) {
// Already processed, adjust button class if needed
const existingBtn = mermaidDiv.parentNode.querySelector('.mermaid-fullscreen-btn');
if (existingBtn) {
existingBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
}
return;
}
const container = document.createElement('div');
container.className = 'mermaid-container';
mermaidDiv.parentNode.insertBefore(container, mermaidDiv);
container.appendChild(mermaidDiv);
const fullscreenBtn = document.createElement('button');
fullscreenBtn.className = 'mermaid-fullscreen-btn' + (darkTheme ? ' dark-theme' : '');
fullscreenBtn.setAttribute('aria-label', 'View diagram in fullscreen');
fullscreenBtn.textContent = '⛶';
fullscreenBtn.style.opacity = '50%';
// Calculate dynamic position based on diagram's margin and padding
const diagramStyle = window.getComputedStyle(mermaidDiv);
const marginTop = parseFloat(diagramStyle.marginTop) || 0;
const marginRight = parseFloat(diagramStyle.marginRight) || 0;
const paddingTop = parseFloat(diagramStyle.paddingTop) || 0;
const paddingRight = parseFloat(diagramStyle.paddingRight) || 0;
fullscreenBtn.style.top = `${marginTop + paddingTop + 4}px`;
fullscreenBtn.style.right = `${marginRight + paddingRight + 4}px`;
fullscreenBtn.addEventListener('click', () => {
previousScrollOffset = [window.scroll, window.scrollY];
const clone = mermaidDiv.cloneNode(true);
modalContent.innerHTML = '';
modalContent.appendChild(clone);
const svg = clone.querySelector('svg');
if (svg) {
svg.removeAttribute('width');
svg.removeAttribute('height');
svg.style.width = '100%';
svg.style.height = 'auto';
svg.style.maxWidth = '100%';
svg.style.sdisplay = 'block';
if ("False" === "True") {
setTimeout(() => {
const g = svg.querySelector('g');
if (g) {
var svgD3 = d3.select(svg);
svgD3.html("<g class='wrapper'>" + svgD3.html() + "</g>");
var inner = svgD3.select("g");
var zoom = d3.zoom().on("zoom", function(event) {
inner.attr("transform", event.transform);
});
svgD3.call(zoom);
}
}, 100);
}
}
modal.classList.add('active');
document.body.style.overflow = 'hidden';
});
container.appendChild(fullscreenBtn);
});
};
const load = async () => {
initStyles();
await runMermaid(true);
const reRunIfThemeChanges = async () => {
const newDarkTheme = isDarkTheme();
if (newDarkTheme !== darkTheme) {
darkTheme = newDarkTheme;
console.log("Theme change detected, re-running mermaid with", darkTheme ? "dark" : "default", "theme");
await mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
await runMermaid(true);
}
};
// Update theme classes when theme changes
const themeObserver = new MutationObserver(reRunIfThemeChanges);
themeObserver.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
themeObserver.observe(document.body, {
attributes: true,
attributeFilter: ['class', 'style', 'data-theme']
});
};
console.log("Initializing mermaid with", darkTheme ? "dark" : "default", "theme");
mermaid.initialize(
{...JSON.parse(
`{"startOnLoad": false}`
),
...{ darkMode: darkTheme, theme: darkTheme ? 'dark' : 'default' },
}
);
window.addEventListener("load", load);
window.runMermaid = runMermaid;</script>
<script>DOCUMENTATION_OPTIONS.pagename = 'demarrage/premier-vpc';</script>
<script>
DOCUMENTATION_OPTIONS.theme_version = '0.16.1';
DOCUMENTATION_OPTIONS.theme_switcher_json_url = 'https://syonad.g3e.fr/two/switcher.json';
DOCUMENTATION_OPTIONS.theme_switcher_version_match = 'main';
DOCUMENTATION_OPTIONS.show_version_warning_banner =
false;
</script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Recherche" href="../search.html" />
<link rel="next" title="Déploiement d’un cluster" href="../deploiement/index.html" />
<link rel="prev" title="Installation d’un hyperviseur" href="installation.html" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="docsearch:language" content="fr"/>
<meta name="docsearch:version" content="0.1" />
</head>
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Passer au contenu principal</a></div>
<div id="pst-scroll-pixel-helper"></div>
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
<i class="fa-solid fa-arrow-up"></i>Haut de page</button>
<dialog id="pst-search-dialog">
<form class="bd-search d-flex align-items-center"
action="../search.html"
method="get">
<i class="fa-solid fa-magnifying-glass"></i>
<input type="search"
class="form-control"
name="q"
placeholder="Search..."
aria-label="Search..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"/>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
</form>
</dialog>
<div class="pst-async-banner-revealer d-none">
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Alerte de version"></aside>
</div>
<header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
</header>
<div class="bd-container">
<div class="bd-container__inner bd-page-width">
<dialog id="pst-primary-sidebar-modal"></dialog>
<div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar">
<div class="sidebar-header-items sidebar-primary__section">
</div>
<div class="sidebar-primary-items__start sidebar-primary__section">
<div class="sidebar-primary-item">
<a class="navbar-brand logo" href="../index.html">
<p class="title logo__title">Documentation two 0.1.0</p>
</a></div>
<div class="sidebar-primary-item"><ul class="navbar-icon-links"
aria-label="Icon Links">
<li class="nav-item">
<a href="https://git.g3e.fr/syonad/two" title="Dépôt" class="nav-link pst-navbar-icon" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><i class="fa-solid fa-code-branch fa-lg" aria-hidden="true"></i>
<span class="sr-only">Dépôt</span></a>
</li>
</ul></div>
<div class="sidebar-primary-item">
<div class="version-switcher__container dropdown pst-js-only">
<button id="pst-version-switcher-button-2"
type="button"
class="version-switcher__button btn btn-sm dropdown-toggle"
data-bs-toggle="dropdown"
aria-haspopup="listbox"
aria-controls="pst-version-switcher-list-2"
aria-label="Version switcher list"
>
Choose version <!-- this text may get changed later by javascript -->
<span class="caret"></span>
</button>
<div id="pst-version-switcher-list-2"
class="version-switcher__menu dropdown-menu list-group-flush py-0"
role="listbox" aria-labelledby="pst-version-switcher-button-2">
<!-- dropdown will be populated by javascript on page load -->
</div>
</div></div>
<div class="sidebar-primary-item">
<button class="btn search-button-field search-button__button pst-js-only" title="Recherche" aria-label="Recherche" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Recherche</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button></div>
<div class="sidebar-primary-item"><nav class="bd-links bd-docs-nav" aria-label="Main">
<div class="bd-toc-item navbar-nav active">
<ul class="nav bd-sidenav bd-sidenav__home-link">
<li class="toctree-l1">
<a class="reference internal" href="../index.html">
two
</a>
</li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Mise en œuvre</span></p>
<ul class="current nav bd-sidenav">
<li class="toctree-l1 current active has-children"><a class="reference internal" href="index.html">Démarrage</a><details open="open"><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="installation.html">Installation d’un hyperviseur</a></li>
<li class="toctree-l2 current active"><a class="current reference internal" href="#">Premier VPC, premier subnet, première VM</a></li>
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../deploiement/index.html">Déploiement d’un cluster</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="../deploiement/architecture-cluster.html">Architecture du cluster</a></li>
<li class="toctree-l2"><a class="reference internal" href="../deploiement/image-qcow2.html">Construction de l’image qcow2</a></li>
<li class="toctree-l2"><a class="reference internal" href="../deploiement/routeurs.html">Routeurs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../deploiement/premier-hyperviseur.html">Premier hyperviseur</a></li>
<li class="toctree-l2"><a class="reference internal" href="../deploiement/route-reflector.html">VM route reflector</a></li>
</ul>
</details></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Exploitation</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1 has-children"><a class="reference internal" href="../exploitation/index.html">Exploitation</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="../exploitation/configuration.html">Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exploitation/services.html">Services systemd</a></li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../exploitation/api-agent/index.html">API de l’agent</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l3"><a class="reference internal" href="../exploitation/api-agent/asynchronisme.html">Modèle asynchrone et codes de retour</a></li>
<li class="toctree-l3"><a class="reference internal" href="../exploitation/api-agent/reference.html">Référence</a></li>
</ul>
</details></li>
<li class="toctree-l2"><a class="reference internal" href="../exploitation/observabilite.html">Observabilité</a></li>
<li class="toctree-l2"><a class="reference internal" href="../exploitation/diagnostic.html">Diagnostic</a></li>
</ul>
</details></li>
</ul>
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Interne</span></p>
<ul class="nav bd-sidenav">
<li class="toctree-l1 has-children"><a class="reference internal" href="../concepts/index.html">Concepts</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="../concepts/vpc-subnet-vm.html">VPC, subnet et VM</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/modes-reseau.html">Modes réseau</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/cycle-de-vie.html">Cycle de vie des ressources</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/metadata-cloud-init.html">Metadata et cloud-init</a></li>
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../architecture/index.html">Architecture</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="../architecture/vue-densemble.html">Vue d’ensemble</a></li>
<li class="toctree-l2"><a class="reference internal" href="../architecture/stockage.html">Schéma des clés</a></li>
<li class="toctree-l2"><a class="reference internal" href="../architecture/contraintes.html">Invariants et pièges</a></li>
</ul>
</details></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../versions/index.html">Versions</a><details><summary><span class="toctree-toggle" role="presentation"><i class="fa-solid fa-chevron-down"></i></span></summary><ul>
<li class="toctree-l2"><a class="reference internal" href="../versions/0.2.0.html">Bael</a></li>
<li class="toctree-l2"><a class="reference internal" href="../versions/0.1.0.html">Michael</a></li>
</ul>
</details></li>
</ul>
</div>
</nav></div>
</div>
<div class="sidebar-primary-items__end sidebar-primary__section">
<div class="sidebar-primary-item">
<div id="ethical-ad-placement"
class="flat"
data-ea-publisher="readthedocs"
data-ea-type="readthedocs-sidebar"
data-ea-manual="true">
</div></div>
</div>
</div>
<main id="main-content" class="bd-main" role="main">
<div class="sbt-scroll-pixel-helper"></div>
<div class="bd-content">
<div class="bd-article-container">
<div class="bd-header-article d-print-none">
<div class="header-article-items header-article__inner">
<div class="header-article-items__start">
<div class="header-article-item"><button class="sidebar-toggle primary-toggle btn btn-sm" title="Toggle primary sidebar" data-bs-placement="bottom" data-bs-toggle="tooltip">
<span class="fa-solid fa-bars"></span>
</button></div>
</div>
<div class="header-article-items__end">
<div class="header-article-item">
<div class="article-header-buttons">
<button onclick="toggleFullScreen()"
class="btn btn-sm btn-fullscreen-button pst-navbar-icon"
title="Mode plein écran"
data-bs-placement="bottom" data-bs-toggle="tooltip"
>
<span class="btn__icon-container">
<i class="fas fa-expand"></i>
</span>
</button>
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Thème" data-bs-title="Thème" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Clair"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Sombre"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="Paramètres système"></i>
</button>
<button class="btn btn-sm pst-navbar-icon search-button search-button__button pst-js-only" title="Recherche" aria-label="Recherche" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass fa-lg"></i>
</button>
<button class="sidebar-toggle secondary-toggle btn btn-sm pst-navbar-icon" title="Toggle secondary sidebar" data-bs-placement="bottom" data-bs-toggle="tooltip">
<span class="fa-solid fa-list"></span>
</button>
</div></div>
</div>
</div>
</div>
<div id="jb-print-docs-body" class="onlyprint">
<h1>Premier VPC, premier subnet, première VM</h1>
<!-- Table of contents -->
<div id="print-main-content">
<div id="jb-print-toc">
<div>
<h2> Contenu </h2>
</div>
<nav aria-label="Page">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#ce-que-l-on-construit">Ce que l’on construit</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#le-vpc">1. Le VPC</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#le-subnet">2. Le subnet</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#la-vm">3. La VM</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#verifier">4. Vérifier</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#supprimer">5. Supprimer</a></li>
</ul>
</nav>
</div>
</div>
</div>
<div id="searchbox"></div>
<article class="bd-article">
<section id="premier-vpc-premier-subnet-premiere-vm">
<h1>Premier VPC, premier subnet, première VM<a class="headerlink" href="#premier-vpc-premier-subnet-premiere-vm" title="Lien vers cette rubrique">#</a></h1>
<p>Ce tutoriel crée de bout en bout une VM joignable, sur un hyperviseur où l’agent est installé et
répond. Il suppose l’API sur <code class="docutils literal notranslate"><span class="pre">127.0.0.1:8080</span></code> et une image disque déjà présente sur l’host.</p>
<p>Tout se passe sur un <strong>seul nœud</strong> : un subnet ne s’étend à d’autres hyperviseurs qu’une fois le
plan de contrôle du cluster en place, cf. <a class="reference internal" href="../deploiement/architecture-cluster.html"><span class="doc">Architecture du cluster</span></a>.</p>
<section id="ce-que-l-on-construit">
<h2>Ce que l’on construit<a class="headerlink" href="#ce-que-l-on-construit" title="Lien vers cette rubrique">#</a></h2>
<pre class="mermaid">
graph LR
subgraph netns vp-admin
BR[&quot;br-sn000001&lt;br/&gt;10.1.1.1&quot;]
MD[&quot;metadata&#64;i-web&lt;br/&gt;169.254.169.254&quot;]
end
VM[&quot;VM i-web&lt;br/&gt;10.1.1.2&quot;] --- BR
BR --- MD
BR --- VXLAN[&quot;VXLAN vni 1&lt;br/&gt;br-000000&quot;]
</pre><p>Le VPC est un network namespace ; le subnet y pose un bridge porteur de la gateway ; la VM s’y
raccroche par un tap, reçoit son adresse en DHCP et son cloud-init depuis le serveur de metadata
du netns.</p>
</section>
<section id="le-vpc">
<h2>1. Le VPC<a class="headerlink" href="#le-vpc" title="Lien vers cette rubrique">#</a></h2>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:8080/vpcs<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s1">'Content-Type: application/json'</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"name": "vp-admin", "cidr": "192.168.0.0/16"}'</span>
</pre></div>
</div>
<p>Le <code class="docutils literal notranslate"><span class="pre">cidr</span></code> est l’espace d’adressage global du VPC : c’est lui qui sera annoncé aux VM comme
route interne, quel que soit le mode du subnet.</p>
<p>La réponse est un <strong>202</strong> : la création est acceptée, pas terminée.</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>curl<span class="w"> </span>-s<span class="w"> </span>http://127.0.0.1:8080/vpcs/vp-admin
</pre></div>
</div>
<p>Attendez <code class="docutils literal notranslate"><span class="pre">&quot;state&quot;:</span> <span class="pre">&quot;running&quot;</span></code> avant l’étape suivante — un subnet dont le VPC parent n’est pas
prêt est refusé en <strong>422</strong>. Le modèle d’attente est décrit dans <a class="reference internal" href="../exploitation/api-agent/asynchronisme.html"><span class="doc">Modèle asynchrone et codes de retour</span></a>.</p>
</section>
<section id="le-subnet">
<h2>2. Le subnet<a class="headerlink" href="#le-subnet" title="Lien vers cette rubrique">#</a></h2>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:8080/subnets<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s1">'Content-Type: application/json'</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"name": "sn-000001",</span>
<span class="s1"> "vpc": "vp-admin",</span>
<span class="s1"> "mode": "vxlan",</span>
<span class="s1"> "vxlan_id": 1,</span>
<span class="s1"> "iface_type": "vms",</span>
<span class="s1"> "interface_ip": "10.1.1.1",</span>
<span class="s1"> "cidr": "10.1.0.0/23"}'</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">iface_type</span></code> est une clé <strong>logique</strong> résolue dans la configuration de l’agent (section
<code class="docutils literal notranslate"><span class="pre">interfaces</span></code>) vers un bridge physique de l’host ; une clé inconnue retombe sur
<code class="docutils literal notranslate"><span class="pre">default_interface</span></code>. <code class="docutils literal notranslate"><span class="pre">interface_ip</span></code> est la gateway du subnet, portée par le bridge créé dans
le netns.</p>
<p>Les modes disponibles et leurs conséquences sur le routage sont détaillés dans
<a class="reference internal" href="../concepts/modes-reseau.html"><span class="doc">Modes réseau</span></a>.</p>
<p>Là encore, attendez <code class="docutils literal notranslate"><span class="pre">running</span></code> :</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>curl<span class="w"> </span>-s<span class="w"> </span>http://127.0.0.1:8080/subnets/sn-000001
</pre></div>
</div>
</section>
<section id="la-vm">
<h2>3. La VM<a class="headerlink" href="#la-vm" title="Lien vers cette rubrique">#</a></h2>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://127.0.0.1:8080/vms<span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-H<span class="w"> </span><span class="s1">'Content-Type: application/json'</span><span class="w"> </span><span class="se">\</span>
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"name": "i-web",</span>
<span class="s1"> "memory": 2048,</span>
<span class="s1"> "cpus": 2,</span>
<span class="s1"> "uefi": true,</span>
<span class="s1"> "metadata": {"sshkey": "ssh-ed25519 AAAA…",</span>
<span class="s1"> "user_data": "'</span><span class="s2">"</span><span class="k">$(</span>base64<span class="w"> </span>&lt;<span class="w"> </span>user-data.yml<span class="w"> </span><span class="p">|</span><span class="w"> </span>tr<span class="w"> </span>-d<span class="w"> </span><span class="s1">'\n'</span><span class="k">)</span><span class="s2">"</span><span class="s1">'"},</span>
<span class="s1"> "interfaces": [{"subnet": "sn-000001", "ip": "10.1.1.2", "primary": true}],</span>
<span class="s1"> "storage": [{"path": "/var/lib/two/volumes/i-web.qcow2", "dev": "vda"}]}'</span>
</pre></div>
</div>
<p>Quatre points qui coûtent du temps quand on les découvre en production :</p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">user_data</span></code> est <strong>encodé en base64</strong></dt><dd><p>Un base64 invalide est rejeté en 400 plutôt que servi vide. L’agent n’interprète jamais ce
contenu.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">password</span></code> est un <strong>hash</strong>, pas un mot de passe</dt><dd><p>Le champ attend la valeur de la clé <code class="docutils literal notranslate"><span class="pre">passwd</span></code> de cloud-config (<code class="docutils literal notranslate"><span class="pre">$6$…</span></code>). Sans <code class="docutils literal notranslate"><span class="pre">password</span></code>
ni <code class="docutils literal notranslate"><span class="pre">sshkey</span></code>, aucun compte n’est créé.</p>
</dd>
<dt>Exactement une interface est <code class="docutils literal notranslate"><span class="pre">primary</span></code></dt><dd><p>Elle porte la route par défaut et le serveur de metadata. L’ordre du tableau détermine le
slot PCI (<code class="docutils literal notranslate"><span class="pre">0x03</span> <span class="pre">+</span> <span class="pre">index</span></code>), donc le nom de l’interface dans le guest. Tous les subnets d’une
VM doivent appartenir au même VPC.</p>
</dd>
<dt>Un seul disque <code class="docutils literal notranslate"><span class="pre">vdX</span></code></dt><dd><p>Les disques supplémentaires passent par <code class="docutils literal notranslate"><span class="pre">sdX</span></code>. La carte PCI en dépend — voir
<a class="reference internal" href="../architecture/contraintes.html"><span class="doc">Invariants et pièges</span></a>.</p>
</dd>
</dl>
</section>
<section id="verifier">
<h2>4. Vérifier<a class="headerlink" href="#verifier" title="Lien vers cette rubrique">#</a></h2>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>curl<span class="w"> </span>-s<span class="w"> </span>http://127.0.0.1:8080/vms/i-web
</pre></div>
</div>
<p>En <code class="docutils literal notranslate"><span class="pre">running</span></code>, la VM est démarrée et le serveur de metadata est en place. Le provisionnement
cloud-init, lui, se déroule dans le guest ; on l’observe par la console série :</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>socat<span class="w"> </span>-,raw,echo<span class="o">=</span><span class="m">0</span><span class="w"> </span>UNIX-CONNECT:/run/two/vms/serial/i-web.sock
</pre></div>
</div>
<p>Puis, depuis l’host :</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>ssh<span class="w"> </span>syonad@10.1.1.2
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>En mode <code class="docutils literal notranslate"><span class="pre">vxlan</span></code>, la VM vit dans le netns du VPC : elle n’est pas joignable depuis l’host
sans route explicite. En mode <code class="docutils literal notranslate"><span class="pre">bridge</span></code>, elle l’est directement.</p>
</div>
</section>
<section id="supprimer">
<h2>5. Supprimer<a class="headerlink" href="#supprimer" title="Lien vers cette rubrique">#</a></h2>
<p>Dans l’ordre inverse — un VPC dont il reste des subnets est refusé en <strong>409</strong> :</p>
<div class="highlight-bash notranslate"><div class="highlight"><pre><span></span>curl<span class="w"> </span>-X<span class="w"> </span>DELETE<span class="w"> </span>http://127.0.0.1:8080/vms/i-web
curl<span class="w"> </span>-X<span class="w"> </span>DELETE<span class="w"> </span>http://127.0.0.1:8080/subnets/sn-000001
curl<span class="w"> </span>-X<span class="w"> </span>DELETE<span class="w"> </span>http://127.0.0.1:8080/vpcs/vp-admin
</pre></div>
</div>
<p>La suppression d’une VM ne touche <strong>jamais</strong> aux fichiers disque.</p>
<div class="admonition warning">
<p class="admonition-title">Avertissement</p>
<p><code class="docutils literal notranslate"><span class="pre">instance-id</span></code> vaut le nom de la VM. Recréer une VM du même nom sur le même disque fait que
cloud-init la reconnaît et <strong>n’applique pas</strong> le user-data. Pour rejouer un provisionnement,
changez de nom ou repartez d’un disque neuf.</p>
</div>
</section>
</section>
</article>
<footer class="prev-next-footer d-print-none">
<div class="prev-next-area">
<a class="left-prev"
href="installation.html"
title="page précédente">
<i class="fa-solid fa-angle-left"></i>
<div class="prev-next-info">
<p class="prev-next-subtitle">précédent</p>
<p class="prev-next-title">Installation d’un hyperviseur</p>
</div>
</a>
<a class="right-next"
href="../deploiement/index.html"
title="page suivante">
<div class="prev-next-info">
<p class="prev-next-subtitle">suivant</p>
<p class="prev-next-title">Déploiement d’un cluster</p>
</div>
<i class="fa-solid fa-angle-right"></i>
</a>
</div>
</footer>
</div>
<dialog id="pst-secondary-sidebar-modal"></dialog>
<div id="pst-secondary-sidebar" class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
<div class="sidebar-secondary-item"><div
id="pst-page-navigation-heading-2"
class="page-toc tocsection onthispage">
<i class="fa-solid fa-list"></i> Contenu
</div>
<nav id="pst-page-toc-nav" class="page-toc" aria-labelledby="pst-page-navigation-heading-2">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#ce-que-l-on-construit">Ce que l’on construit</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#le-vpc">1. Le VPC</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#le-subnet">2. Le subnet</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#la-vm">3. La VM</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#verifier">4. Vérifier</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#supprimer">5. Supprimer</a></li>
</ul>
</nav></div>
</div></div>
</div>
<footer class="bd-footer-content">
<div class="bd-footer-content__inner container">
<div class="footer-item">
<p class="component-author">
Par Nicolas Boufidjeline
</p>
</div>
<div class="footer-item">
<p class="copyright">
© Copyright 2026, Nicolas Boufidjeline.
<br/>
</p>
</div>
<div class="footer-item">
</div>
<div class="footer-item">
</div>
</div>
</footer>
</main>
</div>
</div>
<!-- Scripts loaded after <body> so the DOM is not blocked -->
<script defer src="../_static/scripts/bootstrap.js?digest=8878045cc6db502f8baf"></script>
<script defer src="../_static/scripts/pydata-sphinx-theme.js?digest=8878045cc6db502f8baf"></script>
<footer class="bd-footer">
</footer>
</body>
</html>