Provisioning di Fedora CoreOS su Oracle Cloud Infrastructure (OCI)

Questa guida mostra come effettuare il provisioning di nuovi nodi Fedora CoreOS (FCOS) su Oracle Cloud Infrastructure. Attualmente, le immagini di Fedora CoreOS non sono pubblicate direttamente su Oracle Cloud Infrastructure. Pertanto, è necessario prima scaricare l’immagine di Fedora CoreOS per Oracle Cloud Infrastructure, quindi caricarla nel proprio account come https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/importingcustomimagelinux.htm[immagine personalizzata.

Prerequisiti

Prima di effettuare il provisioning di una macchina FCOS, è necessario disporre di un file di configurazione Ignition contenente le proprie personalizzazioni. Se non ne hai uno, consulta la guida Creazione di un file Ignition.

Fedora CoreOS dispone di un utente predefinito chiamato core che può essere utilizzato per esplorare il sistema operativo. Se desideri utilizzarlo, completa la sua configurazione fornendo, ad esempio, una chiave SSH.

Se non desideri utilizzare Ignition per iniziare, puoi sfruttare il supporto offerto da Afterburn.

Devi inoltre avere accesso a un account Oracle Cloud Infrastructure. Gli esempi riportati di seguito utilizzano lo strumento da riga di comando oci e jq come processore JSON da riga di comando.

Questa guida attualmente copre solo le forme Virtual Machine e non quelle Bare Metal. Consulta il problema #414 per maggiori dettagli

Download di un’immagine per Oracle Cloud Infrastructure

Fedora CoreOS è progettato per aggiornarsi automaticamente, con programmi differenti a seconda dello stream. Una volta scelto lo stream rilevante, scarica, verifica e decomprimi l’ultima immagine per Oracle Cloud Infrastructure:

ARCH="x86_64"    # or "aarch64"
STREAM="stable"  # or "testing", "next"
coreos-installer download -s $STREAM -a $ARCH -p oraclecloud -f qcow2.xz --decompress
Sia le architetture x86\_64 che aarch64 sono supportate su Oracle Cloud Infrastructure.

In alternativa, puoi scaricare manualmente un’immagine per Oracle Cloud Infrastructure dalla pagina di download.

Caricamento dell’immagine su Oracle Cloud Infrastructure

Identify the ID of your root compartment.

Listing the compartments in your tenancy.
oci iam compartment list
ROOT_COMPARTMENT_ID=<root_compartment_id>
The root compartment OCID is the same as your tenancy OCID. You can find this information in your CLI configuration at ~/.oci/config or in the Cloud Console.

If you only have one tenant/root compartment you can use the following command to get that information more easily.

Set root compartment id based on the first compartment in list.
ROOT_COMPARTMENT_ID=$(oci iam compartment list |
                      jq --raw-output '.data[0]."compartment-id"')
Create a new compartment for testing.
COMPARTMENT_ID=$(oci iam compartment create                \
                 --name fedora-coreos-test                 \
                 --compartment-id $ROOT_COMPARTMENT_ID     \
                 --description "Fedora CoreOS compartment" \
                 | jq -r '.data.id')
Create a storage bucket for the image upload.
BUCKET_NAME="fedora-coreos"
oci os bucket create --compartment-id $COMPARTMENT_ID --name $BUCKET_NAME
Upload the image to the storage bucket.
FCOS_VERSION='...'
IMAGE_NAME="fedora-coreos-${FCOS_VERSION}-oraclecloud.${ARCH}.qcow2"
FILE_PATH="./${IMAGE_NAME}"
oci os object put --bucket-name $BUCKET_NAME --file $FILE_PATH
View the object in the bucket.
oci os object list -bn $BUCKET_NAME
Import the image as a custom image and remember its ID.
NAMESPACE=$(oci os ns get | jq -r '.data')
IMAGE_ID=$(oci compute image import from-object               \
           --compartment-id $COMPARTMENT_ID                   \
           --namespace $NAMESPACE                             \
           --bucket-name $BUCKET_NAME                         \
           --name $IMAGE_NAME                                 \
           --display-name "Fedora CoreOS $FCOS_VERSION $ARCH" \
           --launch-mode PARAVIRTUALIZED                      \
           --source-image-type QCOW2                          \
           --operating-system "Linux"                         \
           | jq -r '.data.id')

Wait until the import is completed.

Loop until the image becomes available.
while true; do
    state=$(oci compute image get --image-id $IMAGE_ID |
            jq -r '.data."lifecycle-state"')
    echo "$(date): $state"
    [ "$state" == "AVAILABLE" ] && break || sleep 30
done

The image needs to be configured so the platform knows what it is capable of. Here we’ll pull the default version 1.2 capability set and configure some additional ones. Note that some of these are architecture specific, but don’t hurt because they also have to be opted in at runtime anyway.

Configure additional image capabilities.
GLOBAL_CAP_ID=$(
    oci compute global-image-capability-schema list --all | jq -r '.data[0].id')
GLOBAL_CAP_VERSION_NAME=$(
    oci compute global-image-capability-schema-version list --all \
    --global-image-capability-schema-id $GLOBAL_CAP_ID            \
    --display-name 1.2 | jq -r '.data[0].name')

oci compute image-capability-schema create \
    --global-image-capability-schema-version-name $GLOBAL_CAP_VERSION_NAME \
    --compartment-id $COMPARTMENT_ID --image-id $IMAGE_ID --schema-data '{
    "Compute.AMD_SecureEncryptedVirtualization": {
        "default-value": true,
        "descriptor-type": "boolean",
        "source": "IMAGE"
    },
    "Compute.SecureBoot": {
        "default-value": true,
        "descriptor-type": "boolean",
        "source": "IMAGE"
    },
    "Storage.Iscsi.MultipathDeviceSupported": {
        "default-value": true,
        "descriptor-type": "boolean",
        "source": "IMAGE"
    }
}'

Now we can mark the image as compatible with appropriate VM shapes.

Remove default compatible shapes.
oci compute image-shape-compatibility-entry \
    list --image-id $IMAGE_ID | jq -r '.data[].shape' |
while read shape; do
    [[ "$shape" =~ Generic ]] && continue # Can't remove Generic shapes
    echo "Removing $shape from $IMAGE_ID"
    oci compute image-shape-compatibility-entry remove \
        --force --image-id $IMAGE_ID --shape-name "${shape}"
done
Mark as compatible with appropriate VM shapes.
shapes_info=$(oci compute shape list --compartment-id $COMPARTMENT_ID | jq -r '.data[]')

# Limit to VM shapes only
# https://github.com/coreos/fedora-coreos-tracker/issues/414#issuecomment-1795808614
vm_shapes_info=$(jq -r 'select(.shape | select(startswith("VM")))' <<< "$shapes_info")

# Determine x86_64 and aarch64 shapes
amd64_shape_ids=$(jq -r 'select(."processor-description"  |
                                contains("AMD", "Intel")) |
                                .shape' <<< "$vm_shapes_info")
arm64_shape_ids=$(jq -r 'select(."processor-description" |
                                contains("Ampere"))      |
                                .shape' <<< "$vm_shapes_info")

# Apply the appropriate shapes to the IMAGE
[ "$ARCH" == "x86_64" ] && shape_ids="$amd64_shape_ids"
[ "$ARCH" == "aarch64" ] && shape_ids="$arm64_shape_ids"
for shape in $shape_ids; do
    oci compute image-shape-compatibility-entry add \
        --image-id $IMAGE_ID --shape-name "${shape}"
done
List all the compatible shapes for an image.
oci compute image-shape-compatibility-entry list --image-id $IMAGE_ID | jq -r '.data[].shape'

Avvio di un’istanza

Create a Virtual Cloud Network.
NETWORK_ID=$(oci network vcn create        \
    --compartment-id $COMPARTMENT_ID       \
    --display-name "fedora-coreos-network" \
    --cidr-blocks '["10.0.0.0/16"]'        \
    --dns-label "myfcos"                   \
    --wait-for-state AVAILABLE | jq -r '.data.id')
Create a Subnet.
SUBNET_ID=$(oci network subnet create     \
    --compartment-id $COMPARTMENT_ID      \
    --display-name "fedora-coreos-subnet" \
    --cidr-block "10.0.0.0/24"            \
    --vcn-id $NETWORK_ID                  \
    --dns-label "subnet1"                 \
    --wait-for-state AVAILABLE | jq -r '.data.id')
Create an Internet Gateway.
GATEWAY_ID=$(oci network internet-gateway create \
    --compartment-id $COMPARTMENT_ID             \
    --display-name "fedora-coreos-gateway"       \
    --vcn-id $NETWORK_ID                         \
    --is-enabled true | jq -r '.data.id')
Add a Rule to the Route Table.
ROUTE_TABLE_ID=$(oci network route-table list \
    --compartment-id $COMPARTMENT_ID          \
    --vcn-id $NETWORK_ID | jq -r '.data[0].id')

oci network route-table update \
    --rt-id $ROUTE_TABLE_ID    \
    --force --route-rules      \
    '[{"cidrBlock":"0.0.0.0/0","networkEntityId":"'"${GATEWAY_ID}"'"}]'

You can now choose an availability domain or just set it to be the first one in the region.

Pick an availability domain.
AVAILABILITY_DOMAIN=$(oci iam availability-domain list | jq -r '.data[0].name')
View all possible domains with oci iam availability-domain list.

Now we can launch an instance. If you just want SSH access you can skip providing an Ignition configuration to the instance.

Launching an instance without an Ignition configuration.
NAME=fedora-coreos
SHAPE=VM.Standard.E5.Flex # or VM.Standard.A1.Flex for aarch64
SSHKEYS="/path/to/authorized_keys" # path to authorized_keys file

INSTANCE_ID=$(oci compute instance launch               \
    --compartment-id $COMPARTMENT_ID                    \
    --availability-domain $AVAILABILITY_DOMAIN          \
    --display-name $NAME                                \
    --image-id $IMAGE_ID                                \
    --shape $SHAPE                                      \
    --shape-config '{"ocpus": '2', "memoryInGBs": '4'}' \
    --subnet-id $SUBNET_ID                              \
    --assign-public-ip true                             \
    --ssh-authorized-keys-file $SSHKEYS                 \
    --wait-for-state TERMINATED                         \
    --wait-for-state RUNNING | jq -r '.data.id')
The free tier eligible VM.Standard.E2.1.Micro shape has less than the recommended amount of memory for Fedora CoreOS to run. For a free tier eligible instance it is recommended to use the ARM based VM.Standard.A1.Flex shape.
Launching an instance with customizations and an Ignition configuration.
NAME=fedora-coreos
SHAPE=VM.Standard.E5.Flex      # or VM.Standard.A1.Flex for aarch64
DISK=50                        # size of boot volume in GBs
OCPUS=2                        # number of allocated OCPUs
MEMORY=4                       # size of memory in GBs
INSTANCE_HOSTNAME=mycoreos     # hostname for the instance
USERDATA="/path/to/config.ign" # path to your Ignition config
                               # that sets a ssh key

INSTANCE_ID=$(oci compute instance launch               \
    --compartment-id $COMPARTMENT_ID                    \
    --availability-domain $AVAILABILITY_DOMAIN          \
    --display-name $NAME                                \
    --image-id $IMAGE_ID                                \
    --shape $SHAPE                                      \
    --shape-config                                      \
    '{"ocpus": '${OCPUS}', "memoryInGBs": '${MEMORY}'}' \
    --subnet-id $SUBNET_ID                              \
    --assign-public-ip true                             \
    --hostname-label $INSTANCE_HOSTNAME                 \
    --boot-volume-size-in-gbs $DISK                     \
    --user-data-file $USERDATA                          \
    --wait-for-state TERMINATED                         \
    --wait-for-state RUNNING | jq -r '.data.id')
While the Oracle Cloud Infrastructure documentation mentions cloud-init, Fedora CoreOS does not support cloud-init. It accepts only Ignition configuration files. When using the Cloud Console, an Ignition configuration can be placed into "Cloud-init script" field.
To enable SecureBoot you can pass additional config via --platform-config '{"type": "AMD_VM", "isSecureBootEnabled": true}' or --platform-config '{"type": "INTEL_VM", "isSecureBootEnabled": true}' or depending on the processor type of your instance. Enabling Secureboot isn’t currently possible for ARM instances.
Get the public IP address of the instance.
PUBLIC_IP=$(oci compute instance list-vnics --instance-id $INSTANCE_ID |
            jq -r '.data[0]."public-ip"')
echo "The instance public IPV4 is: $PUBLIC_IP"

Ora dovresti poter effettuare l’accesso SSH all’istanza utilizzando l’indirizzo IP associato.

SSH into the running instance.
ssh "core@${PUBLIC_IP}"