sigs.k8s.io/cluster-api-provider-azure@v1.14.3/docs/book/src/topics/custom-images.md (about)

     1  # Custom images
     2  
     3  This document will help you get a CAPZ Kubernetes cluster up and running with your custom image.
     4  
     5  ## Reference images
     6  
     7  An *image* defines the operating system and Kubernetes components that will populate the disk of each node in your cluster.
     8  
     9  By default, images offered by "capi" in the [Azure Marketplace][azure-marketplace] are used.
    10  
    11  You can list these *reference images* with this command:
    12  
    13  ```bash
    14  az vm image list --publisher cncf-upstream --offer capi --all -o table
    15  ```
    16  
    17  It is recommended to use the latest patch release of Kubernetes for a [supported minor release][supported-k8s].
    18  
    19  <aside class="note warning">
    20  
    21  <h1> Availability </h1>
    22  
    23  The Cluster API for Azure team publishes *reference images* for each Kubernetes release, for both Linux and Windows.
    24  
    25  Reference images for versions of Kubernetes which have known security issues or which are no longer [supported by Cluster API][supported-capi] will be removed from the Azure Marketplace.
    26  
    27  </aside>
    28  
    29  <aside class="note warning">
    30  
    31  <h1> Security </h1>
    32  
    33  The reference images are not updated with security fixes. They are intended only to facilitate testing and to help users try out Cluster API for Azure.
    34  
    35  The reference images should not be used in a production environment. It is highly recommended to [maintain your own custom image](#building-a-custom-image) instead.
    36  
    37  </aside>
    38  
    39  ## Building a custom image
    40  
    41  Cluster API uses the Kubernetes [Image Builder][image-builder] tools. You should use the [Azure images][image-builder-azure] from that project as a starting point for your custom image.
    42  
    43  [The Image Builder Book][capi-images] explains how to build the images defined in that repository, with instructions for [Azure CAPI Images][azure-capi-images] in particular.
    44  
    45  ### Operating system requirements
    46  
    47  For your custom image to work with Cluster API, it must meet the operating system requirements of the bootstrap provider. For example, the default `kubeadm` bootstrap provider has a set of [`preflight checks`][kubeadm-preflight-checks] that a VM is expected to pass before it can join the cluster.
    48  
    49  ### Kubernetes version requirements
    50  
    51  The reference images are each built to support a specific version of Kubernetes. When using your custom images based on them, take care to match the image to the `version:` field of the `KubeadmControlPlane` and `MachineDeployment` in the YAML template for your workload cluster.
    52  
    53  To upgrade to a new Kubernetes release with custom images requires this preparation:
    54  
    55  - create a new custom image which supports the Kubernetes release version
    56  - copy the existing `AzureMachineTemplate` and change its `image:` section to reference the new custom image
    57  - create the new `AzureMachineTemplate` on the management cluster
    58  - modify the existing `KubeadmControlPlane` and `MachineDeployment` to reference the new `AzureMachineTemplate` and update the `version:` field to match
    59  
    60  See [Upgrading clusters][upgrading-clusters] for more details.
    61  
    62  ## Creating a cluster from a custom image
    63  
    64  To use a custom image, it needs to be referenced in an `image:` section of your `AzureMachineTemplate`. See below for more specific examples.
    65  
    66  ### Using Azure Compute Gallery (Recommended)
    67  
    68  To use an image from the [Azure Compute Gallery][azure-compute-gallery], previously known as Shared Image Gallery (SIG), fill in the `resourceGroup`, `name`, `subscriptionID`, `gallery`, and `version` fields:
    69  
    70  ```yaml
    71  apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    72  kind: AzureMachineTemplate
    73  metadata:
    74    name: capz-compute-gallery-example
    75  spec:
    76    template:
    77      spec:
    78        image:
    79          computeGallery:
    80            resourceGroup: "cluster-api-images"
    81            name: "capi-1234567890"
    82            subscriptionID: "01234567-89ab-cdef-0123-4567890abcde"
    83            gallery: "ClusterAPI"
    84            version: "0.3.1234567890"
    85  ```
    86  
    87  If you build Azure CAPI images with the `make` targets in Image Builder, these required values are printed after a successful build. For example:
    88  
    89  ```bash
    90  $ make -C images/capi/ build-azure-sig-ubuntu-1804
    91  # many minutes later...
    92  ==> sig-ubuntu-1804:
    93  Build 'sig-ubuntu-1804' finished.
    94  
    95  ==> Builds finished. The artifacts of successful builds are:
    96  --> sig-ubuntu-1804: Azure.ResourceManagement.VMImage:
    97  
    98  OSType: Linux
    99  ManagedImageResourceGroupName: cluster-api-images
   100  ManagedImageName: capi-1234567890
   101  ManagedImageId: /subscriptions/01234567-89ab-cdef-0123-4567890abcde/resourceGroups/cluster-api-images/providers/Microsoft.Compute/images/capi-1234567890
   102  ManagedImageLocation: southcentralus
   103  ManagedImageSharedImageGalleryId: /subscriptions/01234567-89ab-cdef-0123-4567890abcde/resourceGroups/cluster-api-images/providers/Microsoft.Compute/galleries/ClusterAPI/images/capi-ubuntu-1804/versions/0.3.1234567890
   104  ```
   105  
   106  Please also see the [replication recommendations][replication-recommendations] for the Azure Compute Gallery.
   107  
   108  If the image you want to use is based on an image released by a third party publisher such as for example
   109  `Flatcar Linux` by `Kinvolk`, then you need to specify the `publisher`, `offer`, and `sku` fields as well:
   110  
   111  ```yaml
   112  apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
   113  kind: AzureMachineTemplate
   114  metadata:
   115    name: capz-compute-gallery-example
   116  spec:
   117    template:
   118      spec:
   119        image:
   120          computeGallery:
   121            resourceGroup: "cluster-api-images"
   122            name: "capi-1234567890"
   123            subscriptionID: "01234567-89ab-cdef-0123-4567890abcde"
   124            gallery: "ClusterAPI"
   125            version: "0.3.1234567890"
   126            plan:
   127              publisher: "kinvolk"
   128              offer: "flatcar-container-linux-free"
   129              sku: "stable"
   130  ```
   131  
   132  This will make API calls to create Virtual Machines or Virtual Machine Scale Sets to have the `Plan` correctly set.
   133  
   134  ### Using image ID
   135  
   136  To use a managed image resource by ID, only the `id` field must be set:
   137  
   138  ```yaml
   139  apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
   140  kind: AzureMachineTemplate
   141  metadata:
   142    name: capz-image-id-example
   143  spec:
   144    template:
   145      spec:
   146        image:
   147          id: "/subscriptions/01234567-89ab-cdef-0123-4567890abcde/resourceGroups/myResourceGroup/providers/Microsoft.Compute/images/myImage"
   148  ```
   149  
   150  A managed image resource can be created from a Virtual Machine. Please refer to Azure documentation on [creating a managed image][creating-managed-image] for more detail.
   151  
   152  Managed images support only 20 simultaneous deployments, so for most use cases Azure Compute Gallery is recommended.
   153  
   154  ### Using Azure Marketplace
   155  
   156  To use an image from [Azure Marketplace][azure-marketplace], populate the `publisher`, `offer`, `sku`, and `version` fields and, if this image is published by a third party publisher, set the `thirdPartyImage` flag to `true` so an image Plan can be generated for it. In the case of a third party image, you must accept the license terms with the [Azure CLI](https://learn.microsoft.com/cli/azure/vm/image/terms?view=azure-cli-latest) before consuming it.
   157  
   158  ```yaml
   159  apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
   160  kind: AzureMachineTemplate
   161  metadata:
   162    name: capz-marketplace-example
   163  spec:
   164    template:
   165      spec:
   166        image:
   167          marketplace:
   168            publisher: "example-publisher"
   169            offer: "example-offer"
   170            sku: "k8s-1dot18dot8-ubuntu-1804"
   171            version: "2020-07-25"
   172            thirdPartyImage: true
   173  ```
   174  
   175  ### Using Azure Community Gallery
   176  
   177  To use an image from [Azure Community Gallery][azure-community-gallery], set `name` field to gallery's public name and don't set `subscriptionID` and `resourceGroup` fields:
   178  
   179  ```yaml
   180  apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
   181  kind: AzureMachineTemplate
   182  metadata:
   183    name: capz-community-gallery-example
   184  spec:
   185    template:
   186      spec:
   187        image:
   188          computeGallery:
   189            gallery: testGallery-3282f15c-906a-4c4b-b206-eb3c51adb5be
   190            name: capi-flatcar-stable-3139.2.0
   191            version: 0.3.1651499183
   192  ```
   193  
   194  If the image you want to use is based on an image released by a third party publisher such as for example
   195  `Flatcar Linux` by `Kinvolk`, then you need to specify the `publisher`, `offer`, and `sku` fields as well:
   196  
   197  ```yaml
   198  apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
   199  kind: AzureMachineTemplate
   200  metadata:
   201    name: capz-community-gallery-example
   202  spec:
   203    template:
   204      spec:
   205        image:
   206          computeGallery:
   207            gallery: testGallery-3282f15c-906a-4c4b-b206-eb3c51adb5be
   208            name: capi-flatcar-stable-3139.2.0
   209            version: 0.3.1651499183
   210            plan:
   211              publisher: kinvolk
   212              offer: flatcar-container-linux-free
   213              sku: stable
   214  ```
   215  
   216  This will make API calls to create Virtual Machines or Virtual Machine Scale Sets to have the `Plan` correctly set.
   217  
   218  In the case of a third party image, you must accept the license terms with the [Azure CLI][azure-cli] before consuming it.
   219  
   220  ## Example: CAPZ with Mariner Linux
   221  
   222  To clarify how to use a custom image, let's look at an example of using [Mariner Linux][mariner] with CAPZ.
   223  
   224  Mariner is a minimal, open source Linux distribution, optimized for Azure. The [image-builder][image-builder] project has support for building Mariner images.
   225  
   226  ## Build Mariner with image-builder
   227  
   228  Populate an `az-creds.env` file with your Azure credentials:
   229  
   230  ```
   231  AZURE_SUBSCRIPTION_ID=xxxxxxx
   232  AZURE_TENANT_ID=xxxxxxx
   233  AZURE_CLIENT_ID=xxxxxxxx
   234  AZURE_CLIENT_SECRET=xxxxxx
   235  ```
   236  
   237  Then run image-builder, referencing those credentials as an environment file:
   238  
   239  ```shell
   240  docker run -it --rm --env-file azure-creds.env registry.k8s.io/scl-image-builder/cluster-node-image-builder-amd64:v0.1.17 build-azure-sig-mariner-2
   241  ```
   242  
   243  The entrypoint to this docker image is `make`. (You can clone the image-builder repository and run `make -C images/capi build-azure-sig-mariner-2` locally if you prefer.)
   244  
   245  This makefile target creates an Azure resource group called "cluster-api-images" in `southcentralus` by default. When it finishes, it will contain an Azure Compute Gallery with a Mariner image.
   246  
   247  ```shell
   248  # skipping output to show just the end of the build...
   249  ==> azure-arm.sig-mariner-2: Resource group has been deleted.
   250  ==> azure-arm.sig-mariner-2: Running post-processor: manifest
   251  Build 'azure-arm.sig-mariner-2' finished after 18 minutes 2 seconds.
   252  
   253  ==> Wait completed after 18 minutes 2 seconds
   254  
   255  ==> Builds finished. The artifacts of successful builds are:
   256  --> azure-arm.sig-mariner-2: Azure.ResourceManagement.VMImage:
   257  
   258  OSType: Linux
   259  ManagedImageResourceGroupName: cluster-api-images
   260  ManagedImageName: capi-mariner-2-1689801407
   261  ManagedImageId: /subscriptions/xxxxxxx-xxxx-xxx-xxx/resourceGroups/cluster-api-images/providers/Microsoft.Compute/images/capi-mariner-2-1689801407
   262  ManagedImageLocation: southcentralus
   263  ManagedImageSharedImageGalleryId: /subscriptions/xxxxxxx-xxxx-xxx-xxx/resourceGroups/cluster-api-images/providers/Microsoft.Compute/galleries/ClusterAPI1689801353abcd/images/capi-mariner-2/versions/0.3.1689801407
   264  SharedImageGalleryResourceGroup: cluster-api-images
   265  SharedImageGalleryName: ClusterAPI1689801353abcd
   266  SharedImageGalleryImageName: capi-mariner-2
   267  SharedImageGalleryImageVersion: 0.3.1689801407
   268  SharedImageGalleryReplicatedRegions: southcentralus
   269  ```
   270  
   271  ## Add the Mariner image to a CAPZ cluster template
   272  
   273  Edit your cluster template to add `image` fields to any AzureMachineTemplates:
   274  
   275  ```yaml
   276  apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
   277  kind: AzureMachineTemplate
   278  metadata:
   279    name: ${CLUSTER_NAME}-control-plane
   280    namespace: default
   281  spec:
   282    template:
   283      spec:
   284        image:
   285          computeGallery:
   286            resourceGroup: cluster-api-images
   287            name: capi-mariner-2
   288            subscriptionID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
   289            gallery: ClusterAPI1689801353abcd
   290            version: "0.3.1689801407"
   291  ```
   292  
   293  The last four fields are the `SharedImageGalleryImageName`, your Azure subscription ID, the `SharedImageGalleryName`, and the `SharedImageGalleryImageVersion` from the final output of the image-builder command above. Make sure to add this `image` section to both the control plane and worker node AzureMachineTemplates.
   294  
   295  ## Deploy a Mariner cluster
   296  
   297  Since our Compute Gallery image lives in `southcentralus`, our cluster should too. Set `AZURE_LOCATION=southcentralus` in your environment or in your template.
   298  
   299  Now you can deploy your CAPZ Mariner cluster as usual with `kubectl apply -f` or other means.
   300  
   301  Mariner stores CA certificates in an uncommon location, so we need to tell cloud-provider-azure's Helm chart where. Add this argument to the `helm` command you use to install cloud-provider-azure:
   302  
   303  ```shell
   304  --set-string cloudControllerManager.caCertDir=/etc/pki/tls
   305  ```
   306  
   307  That's it! You should now have a CAPZ cluster running Mariner Linux.
   308  
   309  
   310  [azure-cli]: https://learn.microsoft.com/cli/azure/vm/image/terms?view=azure-cli-latest
   311  [azure-community-gallery]: https://learn.microsoft.com/azure/virtual-machines/azure-compute-gallery#community
   312  [azure-marketplace]: https://learn.microsoft.com/azure/marketplace/marketplace-publishers-guide
   313  [azure-capi-images]: https://image-builder.sigs.k8s.io/capi/providers/azure.html
   314  [azure-compute-gallery]: https://learn.microsoft.com/azure/virtual-machines/linux/shared-image-galleries
   315  [capi-images]: https://image-builder.sigs.k8s.io/capi/capi.html
   316  [creating-managed-image]: https://learn.microsoft.com/azure/virtual-machines/linux/capture-image
   317  [creating-vm-offer]: https://docs.azure.cn/en-us/articles/azure-marketplace/imagepublishguide#5-azure-
   318  [image-builder]: https://github.com/kubernetes-sigs/image-builder
   319  [image-builder-azure]: https://github.com/kubernetes-sigs/image-builder/tree/master/images/capi/packer/azure
   320  [kubeadm-preflight-checks]: https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.md#preflight-checks
   321  [mariner]: https://microsoft.github.io/azurelinux/docs/
   322  [replication-recommendations]: https://learn.microsoft.com/azure/virtual-machines/linux/shared-image-galleries#scaling
   323  [supported-capi]: https://cluster-api.sigs.k8s.io/reference/versions.html#supported-kubernetes-versions
   324  [supported-k8s]: https://kubernetes.io/releases/version-skew-policy/#supported-versions
   325  [upgrading-clusters]: https://cluster-api.sigs.k8s.io/tasks/upgrading-clusters.html