Cloud-init

De MediaWiki
Ir a la navegación Ir a la búsqueda

Cloud-init

O termo cloud computing foi definido como un modelo para facer posible o acceso a rede axeitado e baixo demanda a un conxunto de recursos de computación configurables e compartidos (por exemplo, redes, servidores, almacenamento, aplicacións e servizos...) onde o seu aprovisionamento e liberación pode realizarse con rapidez e cun mínimo esforzo de xestión e interacción por parte do proveedor do cloud. A orixe do térmo está no gráfico de uso común para representar Internet como se fose unha nube (cloud). Os recursos de computación (hardware e software) destos modelos están dispoñibles a través de Internet.

Cloud computing

Fig. Cloud computing. Fonte: Wikipedia . Licenza CC

Unha característica do cloud computing especialmente interesante para a nosa docencia é a súa capacidade de creación, inicio e configuración de máquinas virtuais (instancias) dun xeito moi rápido e automatizado. Nos sistemas cloud empréganse 'cloud images' que veñen sendo plantillas de sistemas operativos preconfigurados que permiten iniciar novas instancias. A modo de exemplo, Canonical proporciona imaxes cloud de Ubuntu a través de https://cloud-images.ubuntu.com.

Ubuntu Cloud Images

Fig. Imaxes cloud de Ubuntu - https://cloud-images.ubuntu.com/

Ubuntu Cloud Images

Fig. Imaxes cloud de Ubuntu Focal Fossa - https://cloud-images.ubuntu.com/focal/current/

Cada instancia ó crearse é un clon idéntico de calquera outra instancia xa que son creadas a partir da mesma imaxe; sendo normal que desexemos configurar as nosas instancias despois de arrincar para instalar algúns paquetes, crear usuarios e/ou grupos, iniciar servizos, ... Aquí é onde entran dúas tecnoloxías:

User data
permite a un usuario pasar información contida nun arquivo local a unha instancia no momento do lanzamento.
Cloud-init
para facer algo útil cos user-data, a imaxe da máquina virtual debe estar preparada para correr un servizo ó arrincar que recolla esa información e execute as accións pertinentes en base ó seu contido. Cloud-init é unha ferramenta deseñada para facer isto; xa que ó arrincar a instancia, aplicará os user-data que se lle pasen. Cloud-init soporta varios formatos para recibir os user-data, sendo os shell scripts e os arquivos cloud-config os máis usados.

Despois de traballar con contedores LXC podemos deducir que moito do falado neste punto élle de aplicación:

  • Arrincamos contedores a partir de imaxes cloud dispoñibles en repositorios.
  • Ó crearse un contedor temos unha nova instancia semellante á imaxe de partida e semellante a todos os contedores creados a partir da mesma plantilla.
  • A creación e inicio das instancias é moi rápida, sendo posible facer lanzamentos masivos de contedores en pouco tempo. O mesmo acontece coa destrucción dos contedores.

O que queda por ver é como facer os despregues conseguindo instancias personalizadas en base ás nosas necesidades; e como unha tecnoloxía orientada á nube como é LXC/Incus, está preparada para aproveitarse de user-data e cloud-init.

No seguinte vídeo pode verse como en minuto e medio creamos unha máquina Ubuntu Server e grazas a cloud-init entre outras cousas:

  • Creamos un usuario administrador chamado magasix.
  • Autorizamos unha identidade dixital para acceder por ssh como magasix.
  • Configuramos a rede.
  • Instalamos apache+php+mysql.
  • Configuramos os repositorios desexados e indicamos que se empregue un servidor apt-cacher-ng.
  • Configuramos a zona horaria a Europa/Madrid.

No vídeo, executamos o comando:

tail -f /var/log/cloud-init-output.log 

Así veremos as accións que está a desenvolver cloud-init:

Escenario 1: cloud-config para crear un contedor LXC que no momento do seu primeiro inicio se configure automáticamente

Nesta práctica usaremos user-data e cloud-init para crear un contedor LXC que no momento do seu primeiro inicio se configure automáticamente de xeito que:

  • Teña o nome do equipo nos arquivos hostname e hosts.
  • Configure o servizo ssh para non permitir o acceso a root, permitir únicamente acceso mediante claves dixitais e non facer resolucións dns inversas para acelerar o proceso de login.
  • Teña un usuario administrador cunha identidade dixital autorizada para acceder por ssh.
  • Teña a configuración de rede correcta.
  • Teña os repositorios desexados.
  • Teña configurado o uso dun servidor apt-cacher-ng.
  • Teña instalado Apache con soporte php.

Preparación do escenario

Tómase como punto de partida o estado do equipo apt-cacher-ng ó remate do escenario anterior. Non hai que crear o contedor asir06 xa que o obxectivo do escenario é a súa creación e configuración.

Para aqueles que se animaron a probar o uso de projects e co gallo de ter algo organizados os contedores, pódese crear o contedor asir06 no project APT-CACHER creado no escenario 8A. Podemos verificar o project no que estamos con:

$ incus project list
+----------------------+--------+----------+---------+
|         NAME         | IMAGES | PROFILES | USED BY |
+----------------------+--------+----------+---------+
| APT-CACHER (current) | NO     | YES      | 8       |
+----------------------+--------+----------+---------+
| default              | YES    | YES      | 33      |
+----------------------+--------+----------+---------+

E no caso de non estar nel, podemos ir a él facendo:

$ incus project switch APT-CACHER
IMPORTANTE- Esta práctica hai que facela usando contedores xa que non funciona nas imaxes Ubuntu usadas en Virtualbox.

Cloud-config

Como sinala a documentación de cloud-init, cloud-config é a forma máis sinxela de proporcionar user-data á instancia, xa que o usuario pode especificar o que quere nun arquivo de texto cun formato fácilmente entendible polos humanos. O que si é obrigatario é que o arquivo respecte a sintaxe YAML; polo que é moi boa idea verificar a sintaxe, cousa que nos faremos antes de utilizalo para lanzar unha instancia.

NOTA: o arquivo config.yml pode descargarse dende a seguinte ligazón: config.yml

Comezamos creando no equipo anfitrión dos contedores un arquivo de nome config.yml cun editor de texto e escribindo a primeira liña:

#cloud-config

Unha vez posta a primeira liña obrigatoria, imos indicar o nome que terá o noso contedor:

  1. cloud-config
  2. Configurar /etc/hostname e /etc/hosts

hostname: asir06 fqdn: asir06.platega.example manage_etc_hosts: true

A continuación imos crear un usuario administrador cun contrasinal e cunha identidade dixital autorizada para acceder vía ssh. Para facelo precisamos coñecer:

O contrasinal cifrado: podemos xerar o contrasinal cifrado usando a utilidade mkpasswd presente na maioría das distribucións Linux. No caso de non tela instalada procedemos á súa instalación:

$ sudo apt install whois
$ mkpasswd --method=sha-512
Contraseña: 
$6$HjlvGV7JIzh$fsf2cYeU39dGnK3h45NL9Xgg1R6mzBPMUn.e5KuFaraYAsevr/msF/F8/.ZdZPLJtYxbsvb3HCJ3bRKgzrRfq0

A clave pública da identidade dixital a autorizar: lembrando o aprendido no apartado de Autenticación por claves do módulo de Seguridade por escuridade fronte a securización do servizo, unha identidade dixital tiña dúas claves, a privada e a pública. O que precisamos agora é o contido da clave pública que no meu caso chámase id_rsa.pub:

$ ls -lahF .ssh/
total 36K
drwx------  2 magasix magasix 4,0K nov  7 01:44 ./
drwxr-xr-x 40 magasix magasix 4,0K nov 10 19:37 ../
-rw-rw-r--  1 magasix magasix  524 oct 29 02:12 config
-rw-------  1 magasix magasix 3,3K oct 29 01:45 id_rsa
-rw-------  1 magasix magasix 3,2K oct 29 02:03 id_rsa_asir01
-rw-r--r--  1 magasix magasix  756 oct 29 02:03 id_rsa_asir01.pub
-rw-r--r--  1 magasix magasix  759 oct 29 01:45 id_rsa.pub
-rw-------  1 magasix magasix 1,1K nov 10 13:31 known_hosts
...
$ cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3uNp/L2xHX/XJgf9jHe9MSAs/TN2njwhDlXZh9Fv6JJaVQN74OK5lSfZeF7ToHNN3KP7V/EuVHseDE1Ct8HApdRXke1zUX6UDR/KAq2DPvrHT3KPLgM6iJZEPG5Ww8rI9DU8oU95o7hQUkmIsvbJsc0QmnjJ+Fv/+EVfnuSQ7IRybPrR5DnlxTKjR3cNtaFQ3aAfIzxFAVq+GSLvn38kkoL2gyInYEkb/5M2e9D2mcxmS4qbQbvJU8t0wuo1uOIECCSnqlobCxxueAP9eejGYxtugmgg3Gwxsz7nCCafbJDYx1NGgq4ZwenxBKhPzqJvVCfyVm7kr58OZh2DHwcZVS8RKELFnniVWXB21W541EvhiI07gqQXbySZzCOizmu46VxkscoCAaoclL9/QGfGuI6du5VvGgo/qEkPBYKWFp3PSEks56AtT1JesSbYvo62r6heI8volpZrag9CgzaVTB8M89InzzQxZyliaa0u7D5Uj6gOp51aivWRMXoESO/IUVc1cc9Sc/oECGBZ/qsPkk+2PLbwb5W5k+Oi2YBT6UOnywtI12E5ise+iJ8NqzeacVT8Hs/P8QxfXmFCn/Q49Z5DmObZmfDVqOk7wmO1OZSdGXtbUbwhqS4LnWnXNmd6MlkPM11VS1Tc7R6MkZVCvQ5UtmGJ5nLet2ucZwKWPyQ== Identidade manuel - curso platega

Unha vez obtidos os datos, engadimos ó arquivo config.yml os datos para crear un usuario (no meu caso chamareino magasix) e que reempraza o usuario ubuntu que por defecto ten a imaxe cloud. Dúas cousas importantes:

As tabulacións son espazos en branco e non tabulacións. Fixarse que a clave pública autorizada é unha única liña aínda que por espazo nos apuntamentos poida parecer que son varias liñas:#cloud-config

  1. Configurar /etc/hostname e /etc/hosts

hostname: asir06 fqdn: asir06.platega.example manage_etc_hosts: true

  1. Usuario

users:

 - name: magasix
   lock_passwd: false
   passwd: $6$571sUrFFS2MTd$FFpgMgYcwl4TkMTWP0M8Qe.0UcAw.gUpqbgGsNQTpMWNN5harLSUKTAHOpPxoKARZRreDJAqY1EfQEUORDpHF1
   ssh-authorized-keys:
     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3uNp/L2xHX/XJgf9jHe9MSAs/TN2njwhDlXZh9Fv6JJaVQN74OK5lSfZeF7ToHNN3KP7V/EuVHseDE1Ct8HApdRXke1zUX6UDR/KAq2DPvrHT3KPLgM6iJZEPG5Ww8rI9DU8oU95o7hQUkmIsvbJsc0QmnjJ+Fv/+EVfnuSQ7IRybPrR5DnlxTKjR3cNtaFQ3aAfIzxFAVq+GSLvn38kkoL2gyInYEkb/5M2e9D2mcxmS4qbQbvJU8t0wuo1uOIECCSnqlobCxxueAP9eejGYxtugmgg3Gwxsz7nCCafbJDYx1NGgq4ZwenxBKhPzqJvVCfyVm7kr58OZh2DHwcZVS8RKELFnniVWXB21W541EvhiI07gqQXbySZzCOizmu46VxkscoCAaoclL9/QGfGuI6du5VvGgo/qEkPBYKWFp3PSEks56AtT1JesSbYvo62r6heI8volpZrag9CgzaVTB8M89InzzQxZyliaa0u7D5Uj6gOp51aivWRMXoESO/IUVc1cc9Sc/oECGBZ/qsPkk+2PLbwb5W5k+Oi2YBT6UOnywtI12E5ise+iJ8NqzeacVT8Hs/P8QxfXmFCn/Q49Z5DmObZmfDVqOk7wmO1OZSdGXtbUbwhqS4LnWnXNmd6MlkPM11VS1Tc7R6MkZVCvQ5UtmGJ5nLet2ucZwKWPyQ== Identidade manuel - curso platega
   sudo: ['ALL=(ALL) NOPASSWD:ALL']
   groups: sudo
   shell: /bin/bash

A continuación imos indicar o contido do arquivo de configuración para usar ó apt-cacher-ng usando write_files:

  1. cloud-config
  2. Configurar /etc/hostname e /etc/hosts

hostname: asir06 fqdn: asir06.platega.example manage_etc_hosts: true

  1. Usuario

users:

- name: magasix
  lock_passwd: false
  passwd: $6$571sUrFFS2MTd$FFpgMgYcwl4TkMTWP0M8Qe.0UcAw.gUpqbgGsNQTpMWNN5harLSUKTAHOpPxoKARZRreDJAqY1EfQEUORDpHF1
  ssh-authorized-keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD033pPV59uD6U2DxkMvtKTv+xXL/YuZr62HoKK9NC0eQa+EgiRt94ZC7k4WFNbf9AtmDHPO1y5C/LI5V0lqXGoAkwHFO2CzNrdnGNxBSCeNgk92gdtWpJ8GPSwqci6Vmk7TSJ6JscRMI5Dwg8Q9JbvRsncwkNzHQ1jV4dnmK3KAc3Wusg3xBeeKIZALgHswWv18VGCMvaTt6QLMLMqjW6sw4MCarygBK30o33BvZUbO9zq6yy4TVjw6ws3789TyI38lLOQ/wyfSapFzryK/1yi6XJzpk2LbCv5NgcmtrjsitxEgT8yrLfPunoIzhjdWZRVIPyLCrg4r0e3d/eTip3D1Uuycl1ud8WeWw7b9fe9rPbBUA5C21fsUQiTB+bMTN/vXzMdEXr2Wjup830d0x8Ia4a8koE9SP+v8Bo/lANmlN1lxOnDCuWLQR3O/FGoVlEiX0RGYLuVrzY216PMP7juEqM1dLZvJ3mwzT9xonTx+boMcPeVT4cNFiaJuCBTwnZDKfnZiQ8BdAVNkMjaDjf/qjWSZOltXYP0azOQhK/i15iol4cMKLfmYA1dj36vnkUa1k9jBeUgKRNaqxNiZByzy7tpR7nb+UYiGgnF28jKzlLsYuD+YlqRn7ipHmzdLfHMURO35CwwMQhon6VVKwKOA1m0pHp6+++n9OnoP9eRuw== Identidade manuel - curso platega
  sudo: ['ALL=(ALL) NOPASSWD:ALL']
  groups: sudo
  shell: /bin/bash

write_files:

 - path: /etc/apt/apt.conf.d/01apt-cacher-ng
   content: |
     Acquire::http { Proxy "http://192.0.2.20:3142"; }

A continuación imos indicar que se conserve o contido do /etc/apt/sources.list,

  1. cloud-config
  2. Configurar /etc/hostname e /etc/hosts

hostname: asir06 fqdn: asir06.platega.example manage_etc_hosts: true

  1. Usuario

users:

- name: magasix
  lock_passwd: false
  passwd: $6$571sUrFFS2MTd$FFpgMgYcwl4TkMTWP0M8Qe.0UcAw.gUpqbgGsNQTpMWNN5harLSUKTAHOpPxoKARZRreDJAqY1EfQEUORDpHF1
  ssh-authorized-keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD033pPV59uD6U2DxkMvtKTv+xXL/YuZr62HoKK9NC0eQa+EgiRt94ZC7k4WFNbf9AtmDHPO1y5C/LI5V0lqXGoAkwHFO2CzNrdnGNxBSCeNgk92gdtWpJ8GPSwqci6Vmk7TSJ6JscRMI5Dwg8Q9JbvRsncwkNzHQ1jV4dnmK3KAc3Wusg3xBeeKIZALgHswWv18VGCMvaTt6QLMLMqjW6sw4MCarygBK30o33BvZUbO9zq6yy4TVjw6ws3789TyI38lLOQ/wyfSapFzryK/1yi6XJzpk2LbCv5NgcmtrjsitxEgT8yrLfPunoIzhjdWZRVIPyLCrg4r0e3d/eTip3D1Uuycl1ud8WeWw7b9fe9rPbBUA5C21fsUQiTB+bMTN/vXzMdEXr2Wjup830d0x8Ia4a8koE9SP+v8Bo/lANmlN1lxOnDCuWLQR3O/FGoVlEiX0RGYLuVrzY216PMP7juEqM1dLZvJ3mwzT9xonTx+boMcPeVT4cNFiaJuCBTwnZDKfnZiQ8BdAVNkMjaDjf/qjWSZOltXYP0azOQhK/i15iol4cMKLfmYA1dj36vnkUa1k9jBeUgKRNaqxNiZByzy7tpR7nb+UYiGgnF28jKzlLsYuD+YlqRn7ipHmzdLfHMURO35CwwMQhon6VVKwKOA1m0pHp6+++n9OnoP9eRuw== Identidade manuel - curso platega
  sudo: ['ALL=(ALL) NOPASSWD:ALL']
  groups: sudo
  shell: /bin/bash

write_files:

 - path: /etc/apt/apt.conf.d/01apt-cacher-ng
   content: |
     Acquire::http { Proxy "http://192.0.2.20:3142"; }
  1. Conservar repositorios e instalar paquetes

apt:

 preserve_sources_list: true

packages:

 - net-tools
 - apache2
 - php
 - php-cli
 - php-common
 - libapache2-mod-php
 - php-gd
 - php-curl
 - php-mbstring
 - php-xmlrpc
 - php-soap 
 - php-xml
 - php-intl
 - php-mysql
 - php-zip
 - mysql-client
 - openssh-server
 - sudo
 - bash
 - bash-completion

Configuración de ssh e apache

A continuación indicamos na seccion runcmd comandos a executar no primeiro inicio da máquina e que no noso exemplo servirán para:

Configurar o servizo ssh: Bloqueamos o acceso a root. Habilitamos o acceso por contrasinal Configurar que non se fagan resolucións inversas para acelerar o proceso de autenticación. Habilitar o servizo https en Apache Crear un arquivo info.php no DocumentRoot do sitio web activo no servidor web. Reiniciar o servizo ssh e Apache para aplicar a nova configuración.

  1. cloud-config
  2. Configurar /etc/hostname e /etc/hosts

hostname: asir06 fqdn: asir06.platega.example manage_etc_hosts: true

  1. Usuario

users:

- name: magasix
  lock_passwd: false
  passwd: $6$571sUrFFS2MTd$FFpgMgYcwl4TkMTWP0M8Qe.0UcAw.gUpqbgGsNQTpMWNN5harLSUKTAHOpPxoKARZRreDJAqY1EfQEUORDpHF1
  ssh-authorized-keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD033pPV59uD6U2DxkMvtKTv+xXL/YuZr62HoKK9NC0eQa+EgiRt94ZC7k4WFNbf9AtmDHPO1y5C/LI5V0lqXGoAkwHFO2CzNrdnGNxBSCeNgk92gdtWpJ8GPSwqci6Vmk7TSJ6JscRMI5Dwg8Q9JbvRsncwkNzHQ1jV4dnmK3KAc3Wusg3xBeeKIZALgHswWv18VGCMvaTt6QLMLMqjW6sw4MCarygBK30o33BvZUbO9zq6yy4TVjw6ws3789TyI38lLOQ/wyfSapFzryK/1yi6XJzpk2LbCv5NgcmtrjsitxEgT8yrLfPunoIzhjdWZRVIPyLCrg4r0e3d/eTip3D1Uuycl1ud8WeWw7b9fe9rPbBUA5C21fsUQiTB+bMTN/vXzMdEXr2Wjup830d0x8Ia4a8koE9SP+v8Bo/lANmlN1lxOnDCuWLQR3O/FGoVlEiX0RGYLuVrzY216PMP7juEqM1dLZvJ3mwzT9xonTx+boMcPeVT4cNFiaJuCBTwnZDKfnZiQ8BdAVNkMjaDjf/qjWSZOltXYP0azOQhK/i15iol4cMKLfmYA1dj36vnkUa1k9jBeUgKRNaqxNiZByzy7tpR7nb+UYiGgnF28jKzlLsYuD+YlqRn7ipHmzdLfHMURO35CwwMQhon6VVKwKOA1m0pHp6+++n9OnoP9eRuw== Identidade manuel - curso platega
  sudo: ['ALL=(ALL) NOPASSWD:ALL']
  groups: sudo
  shell: /bin/bash

write_files:

 - path: /etc/apt/apt.conf.d/01apt-cacher-ng
   content: |
     Acquire::http { Proxy "http://192.0.2.20:3142"; }
  1. Conservar repositorios e instalar paquetes

apt:

 preserve_sources_list: true

packages:

 - net-tools
 - apache2
 - php
 - php-cli
 - php-common
 - libapache2-mod-php
 - php-gd
 - php-curl
 - php-mbstring
 - php-xmlrpc
 - php-soap 
 - php-xml
 - php-intl
 - php-mysql
 - php-zip
 - mysql-client
 - openssh-server
 - sudo
 - bash
 - bash-completion
  1. Executar comandos no primeiro inicio

runcmd:

 - sed -i "s%#PermitRootLogin prohibit-password%PermitRootLogin no%g" /etc/ssh/sshd_config
 - sed -i "s%PasswordAuthentication yes%PasswordAuthentication yes%g" /etc/ssh/sshd_config
 - sed -i "3iUseDNS no" /etc/ssh/sshd_config
 - a2enmod ssl
 - a2ensite default-ssl.conf
 - echo '<?php phpinfo(); ?>' > /var/www/html/info.php
 - systemctl restart sshd
 - systemctl restart apache2

Configuración da zona horaria

Para rematar indicamos zona horaria e locale:

  1. cloud-config
  2. Configurar /etc/hostname e /etc/hosts

hostname: asir06 fqdn: asir06.platega.example manage_etc_hosts: true

  1. Usuario

users:

- name: magasix
  lock_passwd: false
  passwd: $6$571sUrFFS2MTd$FFpgMgYcwl4TkMTWP0M8Qe.0UcAw.gUpqbgGsNQTpMWNN5harLSUKTAHOpPxoKARZRreDJAqY1EfQEUORDpHF1
  ssh-authorized-keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD033pPV59uD6U2DxkMvtKTv+xXL/YuZr62HoKK9NC0eQa+EgiRt94ZC7k4WFNbf9AtmDHPO1y5C/LI5V0lqXGoAkwHFO2CzNrdnGNxBSCeNgk92gdtWpJ8GPSwqci6Vmk7TSJ6JscRMI5Dwg8Q9JbvRsncwkNzHQ1jV4dnmK3KAc3Wusg3xBeeKIZALgHswWv18VGCMvaTt6QLMLMqjW6sw4MCarygBK30o33BvZUbO9zq6yy4TVjw6ws3789TyI38lLOQ/wyfSapFzryK/1yi6XJzpk2LbCv5NgcmtrjsitxEgT8yrLfPunoIzhjdWZRVIPyLCrg4r0e3d/eTip3D1Uuycl1ud8WeWw7b9fe9rPbBUA5C21fsUQiTB+bMTN/vXzMdEXr2Wjup830d0x8Ia4a8koE9SP+v8Bo/lANmlN1lxOnDCuWLQR3O/FGoVlEiX0RGYLuVrzY216PMP7juEqM1dLZvJ3mwzT9xonTx+boMcPeVT4cNFiaJuCBTwnZDKfnZiQ8BdAVNkMjaDjf/qjWSZOltXYP0azOQhK/i15iol4cMKLfmYA1dj36vnkUa1k9jBeUgKRNaqxNiZByzy7tpR7nb+UYiGgnF28jKzlLsYuD+YlqRn7ipHmzdLfHMURO35CwwMQhon6VVKwKOA1m0pHp6+++n9OnoP9eRuw== Identidade manuel - curso platega
  sudo: ['ALL=(ALL) NOPASSWD:ALL']
  groups: sudo
  shell: /bin/bash

write_files:

 - path: /etc/apt/apt.conf.d/01apt-cacher-ng
   content: |
     Acquire::http { Proxy "http://192.0.2.20:3142"; }
  1. Conservar repositorios e instalar paquetes

apt:

 preserve_sources_list: true

packages:

 - net-tools
 - apache2
 - php
 - php-cli
 - php-common
 - libapache2-mod-php
 - php-gd
 - php-curl
 - php-mbstring
 - php-xmlrpc
 - php-soap 
 - php-xml
 - php-intl
 - php-mysql
 - php-zip
 - mysql-client
 - bash-completion
  1. Executar comandos no primeiro inicio

runcmd:

 - sed -i "s%#PermitRootLogin prohibit-password%PermitRootLogin no%g" /etc/ssh/sshd_config
 - sed -i "s%PasswordAuthentication yes%PasswordAuthentication no%g" /etc/ssh/sshd_config
 - sed -i "3iUseDNS no" /etc/ssh/sshd_config
 - a2enmod ssl
 - a2ensite default-ssl.conf
 - echo '<?php phpinfo(); ?>' > /var/www/html/info.php
 - systemctl restart sshd
 - systemctl restart apache2
  1. Zona horaria e locale

timezone: Europe/Madrid locale: es_ES.UTF-8

Verificando a sintaxe

Unha vez creado o arquivo imos a http://www.yamllint.com/ ou https://codebeautify.org/yaml-validator para validar a sintaxe; xa que non é a primeira vez que por culpa dunha mala sintaxe, non funciona a inicialización do contedor. Copiamos&pegamos o contido do noso config.yml e prememos en Go.

Validación do YAML

Fig. Verificando a sintaxe YAML.

Lanzando o contedor

Unha vez verificada a sintaxe podemos proseguir e preparnos para lanzar o contedor. É moi importante ter en conta que as imaxes cloud Ubuntu que empregamos veñen con cloud-init configurado para esperar que o contedor reciba unha configuración rede inicial por dhcp. No caso de non ter un servidor dhcp temos que indicalo cun parámetro de configuración:

Si hai servidor dhcp (o normal cando creamos redes lxd e é o noso caso) podemos lanzar o contedor executando: asir@incus:~$ incus launch images:ubuntu/22.04/cloud asir06 -c user.user-data="$(cat config.yml)" -p WAN Si non hai servidor dhcp: hai que facer dúas cousas: Engadir un bloque bootcmd no config.yml para configurar a rede do equipo nada máis arrincar o contedor.

  1. executar comandos ó iniciar o contedor

bootcmd:

- ip addr add dev eth0 192.0.2.26/24
- ip route add default via 192.0.2.1
- [sh, -c, "echo 'nameserver 8.8.8.8' > /etc/resolv.conf"]
- [sh, -c, "echo 'nameserver 8.8.4.4' >> /etc/resolv.conf"] 

Indicar a cloud-init coa propiedade user.network_mode=link-local que a configuración rede farase a man e non por dhcp. magasix@lxd:~$ incus launch images:ubuntu/22.04/cloud asir06 -c user.user-data="$(cat config.yml)" -c user.network_mode=link-local -p WAN Hai diferenzas entre bootcmd e runcmd:

bootcmd execútase moi pronto no inicio do contedor e sempre se executa en cada inicio. runmcd execútase máis tarde e únicamente no primeiro inicio do contedor. Podemos facer comprobacións de que todo foi ben unha vez rematado o aprovisionamento:

asir@incus:~$ incus exec asir06 -- cloud-init status status: done asir@incus:~$ incus exec asir06 bash root@asir06:~# cat /etc/hostname asir06 root@asir06:~# cat /etc/hosts

  1. Your system has configured 'manage_etc_hosts' as True.
  2. As a result, if you wish for changes to this file to persist
  3. then you will need to either
  4. a.) make changes to the master file in /etc/cloud/templates/hosts.debian.tmpl
  5. b.) change or remove the value of 'manage_etc_hosts' in
  6. /etc/cloud/cloud.cfg or cloud-config from user-data

127.0.1.1 asir06.platega.example asir06 127.0.0.1 localhost

  1. The following lines are desirable for IPv6 capable hosts
1 localhost ip6-localhost ip6-loopback

ff02::1 ip6-allnodes ff02::2 ip6-allrouters root@asir06:~# cat /etc/apt/apt.conf.d/01apt-cacher-ng Acquire::http { Proxy "http://192.0.2.20:3142"; } root@asir06:~# ss -ltn State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 511 *:44 *:* LISTEN 0 511 *:80 *:* LISTEN 0 128 [::]:22 [::]:* root@asir06:~# dpkg -l | grep -i php ii libapache2-mod-php 2:8.3+94+ubuntu22.04.1+deb.sury.org+2 all server-side, HTML-embedded scripting language (Apache 2 module) (default) ii libapache2-mod-php8.3 8.3.7-2+ubuntu22.04.1+deb.sury.org+1 amd64 server-side, HTML-embedded scripting language (Apache 2 module) ii php 2:8.3+94+ubuntu22.04.1+deb.sury.org+2 all server-side, HTML-embedded scripting language (default) ii php-cli 2:8.3+94+ubuntu22.04.1+deb.sury.org+2 all command-line interpreter for the PHP scripting language (default) ii php-common 2:94+ubuntu22.04.1+deb.sury.org+2 all Common files for PHP packages ... root@asir06:~#

Tamén podemos verificar que é posible conectarse por ssh usando a identidade dixital autorizada accedendo pola IP asignada por DHCP ó contedor asir06, no meu caso a 135:

$ incus ls
+---------------+---------+--------------------+------+-----------+-----------+
|     NAME      |  STATE  |        IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+---------------+---------+--------------------+------+-----------+-----------+
| apt-cacher-ng | RUNNING | 192.0.2.20 (eth0)  |      | CONTAINER | 0         |
+---------------+---------+--------------------+------+-----------+-----------+
...
+---------------+---------+--------------------+------+-----------+-----------+
| asir06        | RUNNING | 192.0.2.144 (eth0) |      | CONTAINER | 0         |
+---------------+---------+--------------------+------+-----------+-----------+
$ ssh -i ~/.ssh/id_rsa magasix@192.0.2.26
The authenticity of host '192.0.2.144 (192.0.2.144)' can't be established.
ED25519 key fingerprint is SHA256:vympcjMRG0K4man1csRAsg0KNT47pT3gj9iP7OXJfjc.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.0.2.144' (ED25519) to the list of known hosts.
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 6.5.0-35-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information disabled due to load higher than 1.0

Expanded Security Maintenance for Applications is not enabled.

16 updates can be applied immediately.
8 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

Cloud-init e power_state

Pode ser interesante reiniciar o contedor ó remate do proceso para ver o comportamento do contedor fronte ós reinicios. É posible reiniciar o contedor a través de scripts ou runcmd pero facelo con power_state asegura que todas as accións de cloud-init remataron antes de reiniciar. Para configurar o reinicio automático engadiriamos as seguintes liñas no config.yml:

  1. reinicio ó rematar

power_state:

 mode: reboot

Desta forma poderiamos esquecernos dalgúns comandos do bloque runcmd xa que co reinicio do contedor os cambios indicados xa se aplicarían:

  1. Executar comandos no primeiro inicio

runcmd:

 - sed -i "s%#PermitRootLogin prohibit-password%PermitRootLogin no%g" /etc/ssh/sshd_config
 - sed -i "s%PasswordAuthentication yes%PasswordAuthentication yes%g" /etc/ssh/sshd_config
 - sed -i "3iUseDNS no" /etc/ssh/sshd_config
 - a2enmod ssl
 - a2ensite default-ssl.conf
 - echo '<?php phpinfo(); ?>' > /var/www/html/info.php
  1. - systemctl restart sshd
  2. - systemctl restart apache2

Ademais do reinicio pódese configurar o apagado e un tempo de retardo.

Configuración de rede

Por defecto o contedor recibe a configuración de rede por dhcp, pero podemos personalizala usando calquera das seguintes opcións:

Con user.network-config

Usando user.network-config podemos pasarlle información a cloud-init para que configure a rede do contedor. Facemos dous arquivos:

En primeiro lugar temos o config.yml feito en apartados anteriores

En segundo lugar temos un novo arquivo network.yml onde definimos a configuración de rede:

#cloud-config
version: 1
config:
  - type: physical
    name: eth0
    subnets:
      - type: static
        ipv4: true
        address: 192.0.2.26
        netmask: 255.255.255.0
        gateway: 192.0.2.1
        control: auto
  - type: nameserver
    address:
      - 8.8.8.8
      - 8.8.4.4

Procedemos á creación do contedo pasándolle o config.yml e o network.yml:

$ incus launch images:ubuntu/22.04/cloud asir06 -c user.user-data="$(cat config.yml)" -c user.network-config="$(cat network.yml)" -p WAN

O resultado é un contedor coa configuración de rede esperada e gardada en /etc/network/interfaces.d/50-cloud-init.cfg

# cat /etc/netplan/50-cloud-init.yaml 
# This file is generated from information provided by the datasource.  Changes
# to it will not persist across an instance reboot.  To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    version: 2
    ethernets:
        eth0:
            addresses:
            - 192.0.2.26/24
            nameservers:
                addresses:
                - 8.8.8.8
                - 8.8.4.4
                search: []
            routes:
            -   to: default
                via: 192.0.2.1
# resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 13 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 8.8.8.8
       DNS Servers: 8.8.8.8 8.8.4

Sen user.network-config

Outra forma é modificar o config.yml para escribir a configuración de rede nun arquivo de configuración, e aplicar os cambios para que teña efecto sen necesidade de reiniciar o contedor:

NOTA. o arquivo config.yml coa parte de rede pode descargarse dende a seguinte ligazón: config_con_rede.yml
#cloud-config
# Configurar /etc/hostname e /etc/hosts
hostname: asir06
fqdn: asir06.platega.example
manage_etc_hosts: true
# Usuario
users:
 - name: magasix
   lock_passwd: false
   passwd: $6$571sUrFFS2MTd$FFpgMgYcwl4TkMTWP0M8Qe.0UcAw.gUpqbgGsNQTpMWNN5harLSUKTAHOpPxoKARZRreDJAqY1EfQEUORDpHF1
   ssh-authorized-keys:
     - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQD033pPV59uD6U2DxkMvtKTv+xXL/YuZr62HoKK9NC0eQa+EgiRt94ZC7k4WFNbf9AtmDHPO1y5C/LI5V0lqXGoAkwHFO2CzNrdnGNxBSCeNgk92gdtWpJ8GPSwqci6Vmk7TSJ6JscRMI5Dwg8Q9JbvRsncwkNzHQ1jV4dnmK3KAc3Wusg3xBeeKIZALgHswWv18VGCMvaTt6QLMLMqjW6sw4MCarygBK30o33BvZUbO9zq6yy4TVjw6ws3789TyI38lLOQ/wyfSapFzryK/1yi6XJzpk2LbCv5NgcmtrjsitxEgT8yrLfPunoIzhjdWZRVIPyLCrg4r0e3d/eTip3D1Uuycl1ud8WeWw7b9fe9rPbBUA5C21fsUQiTB+bMTN/vXzMdEXr2Wjup830d0x8Ia4a8koE9SP+v8Bo/lANmlN1lxOnDCuWLQR3O/FGoVlEiX0RGYLuVrzY216PMP7juEqM1dLZvJ3mwzT9xonTx+boMcPeVT4cNFiaJuCBTwnZDKfnZiQ8BdAVNkMjaDjf/qjWSZOltXYP0azOQhK/i15iol4cMKLfmYA1dj36vnkUa1k9jBeUgKRNaqxNiZByzy7tpR7nb+UYiGgnF28jKzlLsYuD+YlqRn7ipHmzdLfHMURO35CwwMQhon6VVKwKOA1m0pHp6+++n9OnoP9eRuw== Identidade manuel - curso platega
   sudo: ['ALL=(ALL) NOPASSWD:ALL']
   groups: sudo
   shell: /bin/bash
write_files:
  - path: /etc/netplan/50-cloud-init.yaml
    content: |
      network:
        version: 2
        ethernets:
          eth0:
            addresses: [192.0.2.26/24]
            nameservers:
              addresses: [8.8.8.8,8.8.4.4]
            routes:
              - to: default
                via: 192.0.2.1
  - path: /etc/apt/apt.conf.d/01apt-cacher-ng
    content: |
      Acquire::http { Proxy "http://192.0.2.20:3142"; }
# Conservar repositorios e instalar paquetes
apt:
  preserve_sources_list: true
packages:
  - net-tools
  - apache2
  - php
  - php-cli
  - php-common
  - libapache2-mod-php
  - php-gd
  - php-curl
  - php-mbstring
  - php-xmlrpc
  - php-soap 
  - php-xml
  - php-intl
  - php-mysql
  - php-zip
  - mysql-client
  - openssh-server
  - sudo
  - bash
  - bash-completion
# Executar comandos no primeiro inicio
runcmd:
  - sed -i "s%#PermitRootLogin prohibit-password%PermitRootLogin no%g" /etc/ssh/sshd_config
  - sed -i "s%PasswordAuthentication yes%PasswordAuthentication yes%g" /etc/ssh/sshd_config
  - sed -i "3iUseDNS no" /etc/ssh/sshd_config
  - a2enmod ssl
  - a2ensite default-ssl.conf
  - echo '<?php phpinfo(); ?>' > /var/www/html/info.php
  - systemctl restart sshd
  - systemctl restart apache2
  - netplan apply
# Zona horaria e locale
timezone: Europe/Madrid
locale: es_ES.UTF-8

E procedemos á creación do contedor:

incus launch images:ubuntu/22.04/cloud asir06 -c user.user-data="$(cat config_con_rede.yml)"

Para rematar este apartado, indicar que hai diferentes maneiras de facer algunhas das cousas que configuramos (p.e. o que comentamos sobre a rede), pero podemos ver

  • como é posible lanzar un contedor e personalizar a súa configuración de xeito automático no primeiro inicio.
  • no último exemplo, con cloud-init, user.user-data, user.network-config e grazas a apt-cacher-ng, en aproximadamente un minuto un servidor Apache con php correndo.

Escenario 2: cloud-config para despregue masivo de contedores cun script de xestión

Referencias