Aller au contenu

Conteneurs Windows et Linux

Installation de containerd + nerdctl pour les conteneurs Windows natifs et de WSL2 + Docker Engine pour les conteneurs Linux. Sans Docker Desktop.


Nested Virtualization

Les conteneurs Windows en mode Hyper-V isolation necessitent la nested virtualization, qui n'est pas disponible sur tous les types de VM GCP. Les conteneurs en mode process isolation (par défaut sur Server 2022) fonctionnent sans cette limitation.

Rôle containers (Windows natif)

Variables par défaut

Créez roles/containers/defaults/main.yml :

containers_enabled: true
containerd_version: "1.7"
nerdctl_version: "1.7"
container_test_image: "mcr.microsoft.com/windows/nanoserver:ltsc2022"

Tâches principales

Créez roles/containers/tasks/main.yml :

---
- name: Activer la feature Containers
  ansible.windows.win_feature:
    name: Containers
    state: present
  register: container_feature

- name: Redemarrer si necessaire
  ansible.windows.win_reboot:
  when: container_feature.reboot_required

- name: Creer le repertoire containerd
  ansible.windows.win_file:
    path: C:\containerd
    state: directory

- name: Telecharger containerd
  ansible.windows.win_get_url:
    url: "https://github.com/containerd/containerd/releases/download/v{{ containerd_version }}/containerd-{{ containerd_version }}-windows-amd64.tar.gz"
    dest: C:\containerd\containerd.tar.gz

- name: Extraire containerd
  community.windows.win_unzip:
    src: C:\containerd\containerd.tar.gz
    dest: C:\containerd
    creates: C:\containerd\bin\containerd.exe

- name: Ajouter containerd au PATH
  ansible.windows.win_path:
    elements:
      - C:\containerd\bin
    scope: machine

- name: Generer la configuration containerd
  ansible.windows.win_command: "C:\\containerd\\bin\\containerd.exe config default"
  register: containerd_config

- name: Ecrire la configuration containerd
  ansible.windows.win_copy:
    content: "{{ containerd_config.stdout }}"
    dest: C:\containerd\config.toml

- name: Installer containerd comme service Windows
  ansible.windows.win_command: "C:\\containerd\\bin\\containerd.exe --register-service"
  args:
    creates: C:\containerd\containerd.log

- name: Demarrer le service containerd
  ansible.windows.win_service:
    name: containerd
    start_mode: auto
    state: started

- name: Telecharger nerdctl
  ansible.windows.win_get_url:
    url: "https://github.com/containerd/nerdctl/releases/download/v{{ nerdctl_version }}/nerdctl-{{ nerdctl_version }}-windows-amd64.tar.gz"
    dest: C:\containerd\nerdctl.tar.gz

- name: Extraire nerdctl
  community.windows.win_unzip:
    src: C:\containerd\nerdctl.tar.gz
    dest: C:\containerd\bin
    creates: C:\containerd\bin\nerdctl.exe

- name: Validation du role
  ansible.builtin.include_tasks: validate.yml
  tags: [validate]

Assertions

Créez roles/containers/tasks/validate.yml :

---
# --- Niveau 1 : technique ---
- name: "Assert : Feature Containers activee"
  ansible.windows.win_feature:
    name: Containers
    state: present
  check_mode: true
  register: feat_check
  failed_when: feat_check.changed

- name: "Assert : containerd en cours d'execution"
  ansible.windows.win_service:
    name: containerd
  register: ctrd_status
  failed_when: ctrd_status.state != "running"

- name: "Assert : nerdctl disponible"
  ansible.windows.win_command: nerdctl --version
  changed_when: false

# --- Niveau 2 : cas d'usage ---
- name: "Assert : Pull et run d'un conteneur Windows"
  ansible.windows.win_shell: |
    nerdctl pull {{ container_test_image }}
    nerdctl run --rm {{ container_test_image }} cmd /c echo ok
  changed_when: false

Rôle wsl2

Variables par défaut

Créez roles/wsl2/defaults/main.yml :

wsl2_enabled: true
wsl2_distro: "Ubuntu"
wsl2_default_user: "vdi-user"
wsl2_memory_limit: "4GB"
wsl2_processors: 2
wsl2_install_docker: true

Tâches principales

Créez roles/wsl2/tasks/main.yml :

---
- name: Activer la feature VirtualMachinePlatform
  ansible.windows.win_feature:
    name: VirtualMachinePlatform
    state: present
  register: vmp_feature

- name: Activer la feature Microsoft-Windows-Subsystem-Linux
  ansible.windows.win_optional_feature:
    name: Microsoft-Windows-Subsystem-Linux
    state: present
  register: wsl_feature

- name: Redemarrer si necessaire
  ansible.windows.win_reboot:
  when: vmp_feature.reboot_required or wsl_feature.reboot_required

- name: Definir WSL2 comme version par defaut
  ansible.windows.win_command: wsl --set-default-version 2

- name: Installer la distribution
  ansible.windows.win_command: "wsl --install -d {{ wsl2_distro }} --no-launch"

- name: Configurer les limites WSL2
  ansible.windows.win_copy:
    dest: "C:\\Users\\{{ vdi_user }}\\.wslconfig"
    content: |
      [wsl2]
      memory={{ wsl2_memory_limit }}
      processors={{ wsl2_processors }}
      swap=0

- name: Installer Docker Engine dans WSL2
  ansible.builtin.include_tasks: docker-wsl2.yml
  when: wsl2_install_docker

- name: Validation du role
  ansible.builtin.include_tasks: validate.yml
  tags: [validate]

Installation Docker Engine dans WSL2

Créez roles/wsl2/tasks/docker-wsl2.yml :

---
- name: Installer Docker Engine dans WSL2
  ansible.windows.win_shell: |
    wsl -d {{ wsl2_distro }} -u root -- bash -c '
      apt-get update &&
      apt-get install -y ca-certificates curl &&
      install -m 0755 -d /etc/apt/keyrings &&
      curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc &&
      chmod a+r /etc/apt/keyrings/docker.asc &&
      echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.list &&
      apt-get update &&
      apt-get install -y docker-ce docker-ce-cli containerd.io &&
      usermod -aG docker {{ wsl2_default_user }}
    '

Assertions WSL2

Créez roles/wsl2/tasks/validate.yml :

---
# --- Niveau 1 : technique ---
- name: "Assert : WSL2 installe"
  ansible.windows.win_command: wsl --status
  changed_when: false

- name: "Assert : Distribution {{ wsl2_distro }} presente"
  ansible.windows.win_shell: "wsl -l -v | Select-String '{{ wsl2_distro }}'"
  changed_when: false

# --- Niveau 2 : cas d'usage ---
- name: "Assert : Docker fonctionne dans WSL2"
  ansible.windows.win_shell: "wsl -d {{ wsl2_distro }} -- docker run --rm hello-world"
  changed_when: false
  when: wsl2_install_docker

- name: "Assert : Conteneur Linux accessible"
  ansible.windows.win_shell: |
    wsl -d {{ wsl2_distro }} -- docker run --rm -d -p 8080:80 nginx
    Start-Sleep -Seconds 3
    Invoke-WebRequest -Uri http://localhost:8080 -UseBasicParsing
    wsl -d {{ wsl2_distro }} -- docker stop $(wsl -d {{ wsl2_distro }} -- docker ps -q)
  changed_when: false
  when: wsl2_install_docker