|
| 1 | +--- |
| 2 | +title: Immagini |
| 3 | +content_type: concept |
| 4 | +weight: 10 |
| 5 | +--- |
| 6 | + |
| 7 | +<!-- overview --> |
| 8 | + |
| 9 | +L'immagine di un container rappresenta dati binari che incapsulano un'applicazione e |
| 10 | +tutte le sue dipendenze software. Le immagini sono costituite da pacchetti software |
| 11 | +eseguibili che possono essere avviati in modalità standalone e su cui si possono fare |
| 12 | +ipotesi ben precise circa l'ambiente in cui vengono eseguiti. |
| 13 | + |
| 14 | +Tipicamente viene creata un'immagine di un'applicazione ed effettuato il _push_ |
| 15 | +su un registry (un repository pubblico di immagini) prima di poterne fare riferimento esplicito in un |
| 16 | +{{< glossary_tooltip text="Pod" term_id="pod" >}} |
| 17 | + |
| 18 | +Questa pagina va a delineare nello specifico il concetto di immagine di un container. |
| 19 | + |
| 20 | +<!-- body --> |
| 21 | + |
| 22 | +## I nomi delle immagini |
| 23 | + |
| 24 | +Alle immagini dei container vengono normalmente attribuiti nomi come `pause`, `example/mycontainer`, o `kube-apiserver`. |
| 25 | +Le immagini possono anche contenere l'hostname del registry in cui le immagini sono pubblicate; |
| 26 | +ad esempio: `registro.fittizio.esempio/nomeimmagine`, |
| 27 | +ed è possibile che sia incluso nel nome anche il numero della porta; ad esempio: `registro.fittizio.esempio:10443/nomeimmagine`. |
| 28 | + |
| 29 | +Se non si specifica l'hostname di un registry, Kubernetes assume che ci si riferisca al registry pubblico di Docker. |
| 30 | + |
| 31 | +Dopo la parte relativa al nome dell'immagine si può aggiungere un _tag_ (come comunemente avviene per comandi come `docker` e `podman`). |
| 32 | +I tag permettono l'identificazione di differenti versioni della stessa serie di immagini. |
| 33 | + |
| 34 | +I tag delle immagini sono composti da lettere minuscole e maiuscole, numeri, underscore (`_`), |
| 35 | +punti (`.`), e trattini (`-`). |
| 36 | +Esistono regole aggiuntive relative a dove i caratteri separatori (`_`, `-`, and `.`) |
| 37 | +possano essere inseriti nel tag di un'immagine. |
| 38 | +Se non si specifica un tag, Kubernetes assume il tag `latest` che va a definire l'immagine disponibile più recente. |
| 39 | + |
| 40 | +{{< caution >}} |
| 41 | +Evitate di utilizzare il tag `latest` quando si rilasciano dei container in produzione, |
| 42 | +in quanto risulta difficile tracciare quale versione dell'immagine sia stata avviata e persino più difficile |
| 43 | +effettuare un rollback ad una versione precente. |
| 44 | + |
| 45 | +Invece, meglio specificare un tag specifico come ad esempio `v1.42.0`. |
| 46 | +{{< /caution >}} |
| 47 | + |
| 48 | +## Aggiornamento delle immagini |
| 49 | + |
| 50 | +Quando un {{< glossary_tooltip text="Deployment" term_id="deployment" >}}, |
| 51 | +{{< glossary_tooltip text="StatefulSet" term_id="statefulset" >}}, Pod, o qualsiasi altro |
| 52 | +oggetto che includa un Pod template viene creato per la prima volta, la policy di default per il pull di tutti i container nel Pod |
| 53 | +è impostata su `IfNotPresent` (se non presente) se non specificato diversamente. |
| 54 | +Questa policy permette al |
| 55 | +{{< glossary_tooltip text="kubelet" term_id="kubelet" >}} di evitare di fare il pull |
| 56 | +di un'immagine se questa è già presente. |
| 57 | + |
| 58 | +Se necessario, si può forzare il pull in ogni occasione in uno dei seguenti modi: |
| 59 | + |
| 60 | +- impostando `imagePullPolicy` (specifica per il pull delle immagini) del container su `Always` (sempre). |
| 61 | +- omettendo `imagePullPolicy` ed usando il tag `:latest` (più recente) per l'immagine da utilizzare; |
| 62 | + Kubernetes imposterà la policy su `Always` (sempre). |
| 63 | +- omettendo `imagePullPolicy` ed il tag per l'immagine da utilizzare. |
| 64 | +- abilitando l'admission controller [AlwaysPullImages](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages). |
| 65 | + |
| 66 | +{{< note >}} |
| 67 | +Il valore dell'impostazione `imagePullPolicy` del container è sempre presente quando l'oggetto viene creato per la prima volta |
| 68 | +e non viene aggiornato se il tag dell'immagine dovesse cambiare successivamente. |
| 69 | + |
| 70 | +Ad esempio, creando un Deployment con un'immagine il cui tag _non_ è |
| 71 | +`:latest`, e successivamente aggiornando il tag di quell'immagine a `:latest`, il campo |
| 72 | + `imagePullPolicy` _non_ cambierà su `Always`. |
| 73 | +È necessario modificare manualmente la policy di pull di ogni oggetto dopo la sua creazione. |
| 74 | +{{< /note >}} |
| 75 | + |
| 76 | +Quando `imagePullPolicy` è definito senza un valore specifico, esso è impostato su `Always`. |
| 77 | + |
| 78 | +## Multi-architecture support nelle immagini |
| 79 | + |
| 80 | +Oltre a fornire immagini binarie, un _container registry_ può fornire un [indice delle immagini disponibili per un container](http://github.com/opencontainers/image-spec/blob/master/image-index.md). |
| 81 | +L'indice di un'immagine può puntare a più [file manifest](http://github.com/opencontainers/image-spec/blob/master/manifest.md) ciascuno per una versione specifica dell'architettura di un container. |
| 82 | +L'idea è che si può avere un unico nome per una stessa immagine (ad esempio: `pause`, `example/mycontainer`, `kube-apiserver`) e permettere a diversi sistemi di recuperare l'immagine binaria corretta a seconda dell'architettura della macchina che la sta utilizzando. |
| 83 | + |
| 84 | + |
| 85 | +Kubernetes stesso tipicamente nomina le immagini dei container tramite il suffisso `-$(ARCH)`. |
| 86 | +Per la garantire la retrocompatibilità è meglio generare le vecchie immagini con dei suffissi. |
| 87 | +L'idea è quella di generare, ad esempio, l'immagine `pause` con un manifest che include tutte le architetture supportate, |
| 88 | +affiancata, ad esempio, da `pause-amd64` che è retrocompatibile per le vecchie configurazioni o per quei file YAML |
| 89 | +in cui sono specificate le immagini con i suffissi. |
| 90 | + |
| 91 | +## Utilizzare un private registry |
| 92 | + |
| 93 | +I private registry possono richiedere l'utilizzo di chiavi per accedere alle immagini in essi contenute. |
| 94 | +Le credenziali possono essere fornite in molti modi: |
| 95 | + - configurando i nodi in modo tale da autenticarsi al private registry |
| 96 | + - tutti i pod possono acquisire informazioni da qualsiasi private registry configurato |
| 97 | + - è necessario che l'amministratore del cluster configuri i nodi in tal senso |
| 98 | + - tramite pre-pulled images (immagini pre-caricate sui nodi) |
| 99 | + - tutti i pod possono accedere alle immagini salvate sulla cache del nodo a cui si riferiscono |
| 100 | + - è necessario effettuare l'accesso come root di sistema su ogni nodo per inserire questa impostazione |
| 101 | + - specificando _ImagePullSecrets_ su un determinato pod |
| 102 | + - solo i pod che forniscono le proprie chiavi hanno la possibilità di accedere al private registry |
| 103 | + - tramite estensioni locali o specifiche di un _Vendor_ |
| 104 | + - se si sta utilizzando una configurazione personalizzata del nodo oppure se manualmente, o tramite il _cloud provider_, |
| 105 | + si implementa un meccanismo di autenticazione del nodo presso il _container registry_. |
| 106 | + |
| 107 | +Di seguito la spiegazione dettagliata di queste opzioni. |
| 108 | + |
| 109 | +### Configurazione dei nodi per l'autenticazione ad un private registry |
| 110 | + |
| 111 | +Se si sta utilizzando Docker sui nodi, si può configurare il _Docker container runtime_ |
| 112 | +per autenticare il nodo presso un private container registry. |
| 113 | + |
| 114 | +Questo è un approccio possibile se si ha il controllo sulle configurazioni del nodo. |
| 115 | + |
| 116 | +{{< note >}} |
| 117 | +Kubernetes di default supporta solo le sezioni `auths` e `HttpHeaders` nelle configurazioni relative a Docker. |
| 118 | +Eventuali _helper_ per le credenziali di Docker (`credHelpers` o `credsStore`) non sono supportati. |
| 119 | +{{< /note >}} |
| 120 | + |
| 121 | + |
| 122 | +Docker salva le chiavi per i registri privati in `$HOME/.dockercfg` oppure nel file `$HOME/.docker/config.json`. |
| 123 | +Inserendo lo stesso file nella lista seguente, kubelet lo utilizzerà per recuperare le credenziali quando deve fare il _pull_ delle immagini. |
| 124 | + |
| 125 | +* `{--root-dir:-/var/lib/kubelet}/config.json` |
| 126 | +* `{cwd of kubelet}/config.json` |
| 127 | +* `${HOME}/.docker/config.json` |
| 128 | +* `/.docker/config.json` |
| 129 | +* `{--root-dir:-/var/lib/kubelet}/.dockercfg` |
| 130 | +* `{cwd of kubelet}/.dockercfg` |
| 131 | +* `${HOME}/.dockercfg` |
| 132 | +* `/.dockercfg` |
| 133 | + |
| 134 | +{{< note >}} |
| 135 | +Potrebbe essere necessario impostare `HOME=/root` esplicitamente come variabile d'ambiente del processo _kubelet_. |
| 136 | +{{< /note >}} |
| 137 | + |
| 138 | +Di seguito i passi consigliati per configurare l'utilizzo di un private registry da parte dei nodi del _cluster_. |
| 139 | +In questo esempio, eseguire i seguenti comandi sul proprio desktop/laptop: |
| 140 | + |
| 141 | + 1. Esegui `docker login [server]` per ogni _set_ di credenziali che vuoi utilizzare. Questo comando aggiornerà `$HOME/.docker/config.json` sul tuo PC. |
| 142 | + 1. Controlla il file `$HOME/.docker/config.json` in un editor di testo per assicurarti che contenga le credenziali che tu voglia utilizzare. |
| 143 | + 1. Recupera la lista dei tuoi nodi; ad esempio: |
| 144 | + - se vuoi utilizzare i nomi: `nodes=$( kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}' )` |
| 145 | + - se vuoi recuperare gli indirizzi IP: `nodes=$( kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}' )` |
| 146 | + 1. Copia il tuo file locale `.docker/config.json` in uno dei path sopra riportati nella lista di ricerca. |
| 147 | + - ad esempio, per testare il tutto: `for n in $nodes; do scp ~/.docker/config.json root@"$n":/var/lib/kubelet/config.json; done` |
| 148 | + |
| 149 | +{{< note >}} |
| 150 | +Per i cluster di produzione, utilizza un configuration management tool per poter applicare le impostazioni su tutti i nodi laddove necessario. |
| 151 | +{{< /note >}} |
| 152 | + |
| 153 | +Puoi fare una verifica creando un Pod che faccia uso di un'immagine privata; ad esempio: |
| 154 | + |
| 155 | +```shell |
| 156 | +kubectl apply -f - <<EOF |
| 157 | +apiVersion: v1 |
| 158 | +kind: Pod |
| 159 | +metadata: |
| 160 | + name: private-image-test-1 |
| 161 | +spec: |
| 162 | + containers: |
| 163 | + - name: uses-private-image |
| 164 | + image: $PRIVATE_IMAGE_NAME |
| 165 | + imagePullPolicy: Always |
| 166 | + command: [ "echo", "SUCCESS" ] |
| 167 | +EOF |
| 168 | +``` |
| 169 | +``` |
| 170 | +pod/private-image-test-1 created |
| 171 | +``` |
| 172 | +Se tutto funziona correttamente, pochi istanti dopo, si può lanciare il comando: |
| 173 | + |
| 174 | +```shell |
| 175 | +kubectl logs private-image-test-1 |
| 176 | +``` |
| 177 | +e verificare che il comando restituisca in output: |
| 178 | +``` |
| 179 | +SUCCESS |
| 180 | +``` |
| 181 | + |
| 182 | +Qualora si sospetti che il comando sia fallito, si può eseguire: |
| 183 | +```shell |
| 184 | +kubectl describe pods/private-image-test-1 | grep 'Failed' |
| 185 | +``` |
| 186 | +In caso di fallimento, l'output sarà simile al seguente: |
| 187 | +``` |
| 188 | + Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found |
| 189 | +``` |
| 190 | + |
| 191 | +Bisogna assicurarsi che tutti i nodi nel cluster abbiano lo stesso file `.docker/config.json`. |
| 192 | +Altrimenti i pod funzioneranno correttamente su alcuni nodi ma falliranno su altri. |
| 193 | +Ad esempio, se si utilizza l'autoscaling per i nodi, il template di ogni istanza |
| 194 | +devono includere il file `.docker/config.json` oppure montare un disco che lo contenga. |
| 195 | + |
| 196 | +Tutti i pod avranno accesso in lettura alle immagini presenti nel private registry |
| 197 | +una volta che le rispettive chiavi di accesso siano state aggiunte nel file `.docker/config.json`. |
| 198 | + |
| 199 | +### Immagini pre-pulled |
| 200 | + |
| 201 | +{{< note >}} |
| 202 | +Questo approccio è possibile se si ha il controllo sulla configurazione del nodo. |
| 203 | +Non funzionerà qualora il cloud provider gestisca i nodi e li sostituisca automaticamente. |
| 204 | +{{< /note >}} |
| 205 | + |
| 206 | +Kubelet di default prova a fare il pull di ogni immagine dal registry specificato. |
| 207 | +Tuttavia, qualora la proprietà `imagePullPolicy` (specifica di pull dell'immagine) del container sia impostata su `IfNotPresent` (vale a dire, se non è già presente) oppure su `Never` (mai), |
| 208 | +allora l'immagine locale è utilizzata (in via preferenziale o esclusiva, rispettivamente). |
| 209 | + |
| 210 | +Se si vuole fare affidamento a immagini pre-scaricate per non dover incorrere in una fase di autenticazione presso il registry, |
| 211 | +bisogna assicurarsi che tutti i nodi nel cluster abbiano scaricato le stesse versioni delle immagini. |
| 212 | + |
| 213 | +Questa procedura può essere utilizzata per accelerare il processo di creazione delle istanze o come alternativa all'autenticazione presso un private registry. |
| 214 | + |
| 215 | +Tutti i pod avranno accesso in lettura a qualsiasi immagine pre-scaricata. |
| 216 | + |
| 217 | +### Specificare la proprietà imagePullSecrets su un Pod |
| 218 | + |
| 219 | +{{< note >}} |
| 220 | +Questo approccio è quello consigliato per l'avvio di container a partire da immagini presenti in registri privati. |
| 221 | +{{< /note >}} |
| 222 | + |
| 223 | +Kubernetes da la possibilità di specificare le chiavi del _container registry_ su un Pod. |
| 224 | + |
| 225 | +#### Creare un Secret tramite Docker config |
| 226 | + |
| 227 | +Esegui il comando seguente, sostituendo i valori riportati in maiuscolo con quelli corretti: |
| 228 | + |
| 229 | +```shell |
| 230 | +kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL |
| 231 | +``` |
| 232 | + |
| 233 | +Se possiedi il file delle credenziali per Docker, anziché utilizzare il comando quì sopra |
| 234 | +puoi importare il file di credenziali come un Kubernetes |
| 235 | +{{< glossary_tooltip text="Secrets" term_id="secret" >}}. |
| 236 | +[Creare un Secret a partire da credenziali Docker](/docs/tasks/configure-pod-container/pull-image-private-registry/#registry-secret-existing-credentials) fornisce la spiegazione dettagliata su come fare. |
| 237 | + |
| 238 | +Ciò è particolarmente utile se si utilizzano più _container registry_ privati, |
| 239 | +in quanto il comando `kubectl create secret docker-registry` genera un Secret che |
| 240 | +funziona con un solo private registry. |
| 241 | + |
| 242 | +{{< note >}} |
| 243 | +I Pod possono fare riferimento ai Secret per il pull delle immagini soltanto nel proprio _namespace_, |
| 244 | +quindi questo procedimento deve essere svolto per ogni _namespace_. |
| 245 | +{{< /note >}} |
| 246 | + |
| 247 | +#### Fare riferimento ad imagePullSecrets in un Pod |
| 248 | + |
| 249 | +È possibile creare pod che referenzino quel Secret aggiungendo la sezione `imagePullSecrets` alla definizione del Pod. |
| 250 | + |
| 251 | +Ad esempio: |
| 252 | + |
| 253 | +```shell |
| 254 | +cat <<EOF > pod.yaml |
| 255 | +apiVersion: v1 |
| 256 | +kind: Pod |
| 257 | +metadata: |
| 258 | + name: foo |
| 259 | + namespace: awesomeapps |
| 260 | +spec: |
| 261 | + containers: |
| 262 | + - name: foo |
| 263 | + image: janedoe/awesomeapp:v1 |
| 264 | + imagePullSecrets: |
| 265 | + - name: myregistrykey |
| 266 | +EOF |
| 267 | + |
| 268 | +cat <<EOF >> ./kustomization.yaml |
| 269 | +resources: |
| 270 | +- pod.yaml |
| 271 | +EOF |
| 272 | +``` |
| 273 | + |
| 274 | +Questo deve esser fatto per ogni Pod che utilizzi un private registry. |
| 275 | + |
| 276 | +Comunque, le impostazioni relative a questo campo possono essere automatizzate inserendo la sezione _imagePullSecrets_ |
| 277 | +nella definizione della risorsa [ServiceAccount](/docs/tasks/configure-pod-container/configure-service-account/). |
| 278 | + |
| 279 | +Visitare la pagina [Aggiungere ImagePullSecrets ad un Service Account](/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account) per istruzioni più dettagliate. |
| 280 | + |
| 281 | +Puoi utilizzarlo in congiunzione al file `.docker/config.json` configurato per ogni nodo. In questo caso, si applicherà un _merge_ delle credenziali. |
| 282 | + |
| 283 | +## Casi d'uso |
| 284 | + |
| 285 | +Ci sono varie soluzioni per configurare i private registry. Di seguito, alcuni casi d'uso comuni e le soluzioni suggerite. |
| 286 | + |
| 287 | +1. Cluster in cui sono utilizzate soltanto immagini non proprietarie (ovvero _open-source_). In questo caso non sussiste il bisogno di nascondere le immagini. |
| 288 | + - Utilizza immagini pubbliche da Docker hub. |
| 289 | + - Nessuna configurazione richiesta. |
| 290 | + - Alcuni _cloud provider_ mettono in _cache_ o effettuano il _mirror_ di immagini pubbliche, il che migliora la disponibilità delle immagini e ne riduce il tempo di _pull_. |
| 291 | +1. Cluster con container avviati a partire da immagini proprietarie che dovrebbero essere nascoste a chi è esterno all'organizzazione, ma |
| 292 | + visibili a tutti gli utenti abilitati nel cluster. |
| 293 | + - Utilizza un private [Docker registry](http://docs.docker.com/registry/). |
| 294 | + - Esso può essere ospitato da [Docker Hub](http://hub.docker.com/signup), o da qualche altra piattaforma. |
| 295 | + - Configura manualmente il file .docker/config.json su ogni nodo come descritto sopra. |
| 296 | + - Oppure, avvia un private registry dietro il tuo firewall con accesso in lettura libero. |
| 297 | + - Non è necessaria alcuna configurazione di Kubernetes. |
| 298 | + - Utilizza un servizio di _container registry_ che controlli l'accesso alle immagini |
| 299 | + - Esso funzionerà meglio con una configurazione del cluster basata su _autoscaling_ che con una configurazione manuale del nodo. |
| 300 | + - Oppure, su un cluster dove la modifica delle configurazioni del nodo non è conveniente, utilizza `imagePullSecrets`. |
| 301 | +1. Cluster con immagini proprietarie, alcune delle quali richiedono un controllo sugli accessi. |
| 302 | + - Assicurati che l'_admission controller_ [AlwaysPullImages](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages) sia attivo. Altrimenti, tutti i Pod potenzialmente possono avere accesso a tutte le immagini. |
| 303 | + - Sposta i dati sensibili un un _Secret_, invece di inserirli in un'immagine. |
| 304 | +1. Un cluster multi-tenant dove ogni tenant necessiti di un private registry. |
| 305 | + - Assicurati che l'_admission controller_ [AlwaysPullImages](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages) sia attivo. Altrimenti, tutti i Pod di tutti i tenant potrebbero potenzialmente avere accesso a tutte le immagini. |
| 306 | + - Avvia un private registry che richieda un'autorizzazione all'accesso. |
| 307 | + - Genera delle credenziali di registry per ogni tenant, inseriscile in dei _Secret_, e popola i _Secret_ per ogni _namespace_ relativo ad ognuno dei tenant. |
| 308 | + - Il singolo tenant aggiunge così quel _Secret_ all'impostazione _imagePullSecrets_ di ogni _namespace_. |
| 309 | + |
| 310 | + |
| 311 | +Se si ha la necessità di accedere a più registri, si può generare un _Secret_ per ognuno di essi. |
| 312 | +Kubelet farà il _merge_ di ogni `imagePullSecrets` in un singolo file virtuale `.docker/config.json`. |
| 313 | + |
| 314 | +## {{% heading "whatsnext" %}} |
| 315 | + |
| 316 | +* Leggi [OCI Image Manifest Specification](http://github.com/opencontainers/image-spec/blob/master/manifest.md) |
0 commit comments