Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating bootimages #381

Closed
cgwalters opened this issue Jul 8, 2019 · 15 comments
Closed

Updating bootimages #381

cgwalters opened this issue Jul 8, 2019 · 15 comments

Comments

@cgwalters
Copy link
Member

cgwalters commented Jul 8, 2019

THIS ISSUE IS MOVED TO openshift/enhancements#201


First, be sure you're familiar with os updates.

Currently, we have no default mechanism to update the bootimages once a cluster is installed. For example, as of 4.1.4 today, the way things work is that the installer pins RHCOS, and when a cluster is installed in e.g. AWS, the installer injects the AMI into the machinesets in openshift-machine-api. Nothing thereafter updates it. And because we haven't updated the pinned RHCOS for 4.1.X today every OpenShift install uses the 4.1.0 RHCOS bootimages. (More on that below)

Now, see:
openshift/origin#21998
for a PR which tries to embed this metadata into the release image. From there, we could imagine having e.g. the cluster API use it to update the machinesets.

However, the "fully managed AWS" environment is the easy one. We have to consider manual bare metal PXE setups as well as private OpenStack clouds. For private clouds like OpenStack (as well as AWS Outpost for that matter) one could imagine that we ship all of the images in a container, or perhaps a "pristine" disk image in a container, and also the tooling (cosa gf-oemid) to stamp it, as well as an operator to pull those bootimages and upload them to glance or private AWS.

The bare metal PXE case is unmanaged; we are probably just going to have to suffer and try to point people doing this towards managed metal.

As of today though, we will have to support upgrading OpenShift from the 4.1.0 bootimages for...quite a while.

@cgwalters
Copy link
Member Author

cgwalters commented Jul 8, 2019

For future reference, partially since it isn't easy to get the RHCOS version from the installer, here is the version information for 4.1.0:

payload-rhcos-4.1.0

$ oc adm release info --image-for=machine-os-content quay.io/openshift-release-dev/ocp-release@sha256:b8307ac0f3ec4ac86c3f3b52846425205022da52c16f56ec31cbe428501001d6
quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:53389c9b4a00d7afebb98f7bd9d20348deb1d77ca4baf194f0ae1b582b7e965b
$ oc image info quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:53389c9b4a00d7afebb98f7bd9d20348deb1d77ca4baf194f0ae1b582b7e965b
Name:       quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:53389c9b4a00d7afebb98f7bd9d20348deb1d77ca4baf194f0ae1b582b7e965b
Media Type: application/vnd.docker.distribution.manifest.v2+json
Created:    48d ago
Image Size: 627.9MB
OS:         linux
Arch:       amd64
Entrypoint: /noentry
Labels:     com.coreos.ostree-commit=d969dcf9e106044ba42a7dca0d445f5c2f1ba755276f433b4d166e6297627254
            version=410.8.20190520.0

Build info link

Installer 4.1.0 commit c6517384e71e5f09931c4da5e772fdec225d02ec

Inlined metadata JSON for full posterity
{
  "build-url": "https://art-jenkins.cloud.paas.upshift.redhat.com/job/art-jenkins/job/art-jenkins-rhcos-ootpa/1253/",
  "buildid": "410.8.20190520.0",
  "coreos-assembler.build-timestamp": "2019-05-20T23:20:23Z",
  "coreos-assembler.code-source": "container",
  "coreos-assembler.config-dirty": "false",
  "coreos-assembler.config-gitrev": "v3.1-49-g59527da4ef863e41e0f0a7bad8fff0674b84ebe3",
  "coreos-assembler.container-config-git": {
    "branch": "master",
    "commit": "59527da4ef863e41e0f0a7bad8fff0674b84ebe3",
    "dirty": "false",
    "origin": "https://gitlab.cee.redhat.com/coreos/redhat-coreos.git"
  },
  "coreos-assembler.container-image-git": {
    "branch": "rhcos-4.1",
    "commit": "10f9427f4fd21ff791df0d0e4971d9bcb01ba2fa",
    "dirty": "true",
    "origin": "https://github.com/coreos/coreos-assembler"
  },
  "coreos-assembler.image-config-checksum": "329f2b1a48a3395f8cb49cb78474aa31ded15a7f74a23b0c4dac03cf6baf55c8",
  "coreos-assembler.image-genver": "0",
  "coreos-assembler.image-input-checksum": "b4358fe1f2dba158d382005f60cb1b8576b739fb215e196eb3e75c68b57aed1f",
  "coreos-assembler.vm-iso-checksum": "e5f6e6f4b047e7a3b92dbcdae93ccee9a57b5e2dac029d8ea54f869dbc99cb43",
  "images": {
    "metal-bios": {
      "path": "rhcos-410.8.20190520.0-metal-bios.raw.gz",
      "sha256": "662fe69b6db719717d36a547828eb69b8f6a7787a99bcd4fdce408e083fc2ef4",
      "size": "719954527",
      "uncompressed-sha256": "312bcfca4ea966ee5167ac0c63f795768e7eb421a751e2d3d189b2e2ddd3d3e9",
      "uncompressed-size": "3317694464"
    },
    "metal-uefi": {
      "path": "rhcos-410.8.20190520.0-metal-uefi.raw.gz",
      "sha256": "ecf494ff4ef8c709a089e72a164e675739bc92c833f435d2b639285017c2004d",
      "size": "721567045",
      "uncompressed-sha256": "eb98b9d2e527117e692c4b7abe4be72bea9e7705bd572924155e62337bafccda",
      "uncompressed-size": "3317694464"
    },
    "qemu": {
      "path": "rhcos-410.8.20190520.0-qemu.qcow2",
      "sha256": "d22b308631bf9a13329f402fbb574dd4d07005a3c4c5d6f1505ecf2246a86676",
      "size": "719492230",
      "uncompressed-sha256": "e92ecd8ebe0c06a58cecf004733cf12fc835650beb2a6914c672d57e82d9011a",
      "uncompressed-size": "2018902016"
    },
    "openstack": {
      "path": "rhcos-410.8.20190520.0-openstack.qcow2",
      "sha256": "f2c22be84f262c60dfd75f0696987af683d1d384bb13b0cf95dc920986703dd6",
      "size": "719500193",
      "uncompressed-sha256": "280b1d7dce6bc67ffc03569b242ba741dbf2c7b645bdcb4e0f20b71792c45e77",
      "uncompressed-size": "2018967552"
    },
    "vmware": {
      "path": "rhcos-410.8.20190520.0-vmware.ova",
      "sha256": "eff088ec361f94258a4cd9400e8483b3fc14be7e205e645b372003e77de7ec3a",
      "size": "742717440"
    },
    "iso": {
      "path": "rhcos-410.8.20190520.0-installer.iso",
      "sha256": "92fdbc5c95410fea73c6b200f6a10d4a8e043dd6933628237a5aed093f88701b"
    },
    "kernel": {
      "path": "rhcos-410.8.20190520.0-installer-kernel",
      "sha256": "fc984907fdd3674f8412e3ba5d9cdad461f04b7f9ea5e2ca142e3292997ed6bb"
    },
    "initramfs": {
      "path": "rhcos-410.8.20190520.0-installer-initramfs.img",
      "sha256": "9cbbdc92b687f87b511191ea866fc8dd080598954bd1a9ab7ed7157ac6a2adcc"
    },
    "aws": {
      "path": "rhcos-410.8.20190520.0-aws.vmdk",
      "sha256": "71f4190916b5cb26b0230adb54809b10f8f694245ec3e743d1773efc0359f027",
      "size": "709180655",
      "uncompressed-sha256": "eef6764cc8f571a87fff715430220711bd0a90f4f88cc6141cfdbd412b654f81",
      "uncompressed-size": 742703616
    }
  },
  "name": "rhcos",
  "oscontainer": {
    "digest": "sha256:53389c9b4a00d7afebb98f7bd9d20348deb1d77ca4baf194f0ae1b582b7e965b",
    "image": "quay.io/openshift-release-dev/ocp-v4.0-art-dev"
  },
  "ostree-commit": "d969dcf9e106044ba42a7dca0d445f5c2f1ba755276f433b4d166e6297627254",
  "ostree-content-bytes-written": 349426209,
  "ostree-n-cache-hits": 18391,
  "ostree-n-content-total": 5576,
  "ostree-n-content-written": 1158,
  "ostree-n-metadata-total": 9537,
  "ostree-n-metadata-written": 3177,
  "ostree-timestamp": "2019-05-20T22:55:04Z",
  "ostree-version": "410.8.20190520.0",
  "pkgdiff": [
    [
      "libxkbcommon",
      1,
      {
        "PreviousPackage": [
          "libxkbcommon",
          "0.8.2-1.el8",
          "x86_64"
        ]
      }
    ],
    [
      "xkeyboard-config",
      1,
      {
        "PreviousPackage": [
          "xkeyboard-config",
          "2.24-3.el8",
          "noarch"
        ]
      }
    ],
    [
      "bind-export-libs",
      2,
      {
        "NewPackage": [
          "bind-export-libs",
          "32:9.11.4-17.P2.el8_0",
          "x86_64"
        ],
        "PreviousPackage": [
          "bind-export-libs",
          "32:9.11.4-16.P2.el8",
          "x86_64"
        ]
      }
    ],
    [
      "bind-libs",
      2,
      {
        "NewPackage": [
          "bind-libs",
          "32:9.11.4-17.P2.el8_0",
          "x86_64"
        ],
        "PreviousPackage": [
          "bind-libs",
          "32:9.11.4-16.P2.el8",
          "x86_64"
        ]
      }
    ],
    [
      "bind-libs-lite",
      2,
      {
        "NewPackage": [
          "bind-libs-lite",
          "32:9.11.4-17.P2.el8_0",
          "x86_64"
        ],
        "PreviousPackage": [
          "bind-libs-lite",
          "32:9.11.4-16.P2.el8",
          "x86_64"
        ]
      }
    ],
    [
      "bind-license",
      2,
      {
        "NewPackage": [
          "bind-license",
          "32:9.11.4-17.P2.el8_0",
          "noarch"
        ],
        "PreviousPackage": [
          "bind-license",
          "32:9.11.4-16.P2.el8",
          "noarch"
        ]
      }
    ],
    [
      "bind-utils",
      2,
      {
        "NewPackage": [
          "bind-utils",
          "32:9.11.4-17.P2.el8_0",
          "x86_64"
        ],
        "PreviousPackage": [
          "bind-utils",
          "32:9.11.4-16.P2.el8",
          "x86_64"
        ]
      }
    ],
    [
      "openshift-clients",
      2,
      {
        "NewPackage": [
          "openshift-clients",
          "4.1.0-201905191700.git.0.cb455d6.el8",
          "x86_64"
        ],
        "PreviousPackage": [
          "openshift-clients",
          "4.1.0-201905171742.git.0.27816e1.el8",
          "x86_64"
        ]
      }
    ],
    [
      "openshift-hyperkube",
      2,
      {
        "NewPackage": [
          "openshift-hyperkube",
          "4.1.0-201905191700.git.0.cb455d6.el8",
          "x86_64"
        ],
        "PreviousPackage": [
          "openshift-hyperkube",
          "4.1.0-201905171742.git.0.27816e1.el8",
          "x86_64"
        ]
      }
    ],
    [
      "python3-bind",
      2,
      {
        "NewPackage": [
          "python3-bind",
          "32:9.11.4-17.P2.el8_0",
          "noarch"
        ],
        "PreviousPackage": [
          "python3-bind",
          "32:9.11.4-16.P2.el8",
          "noarch"
        ]
      }
    ],
    [
      "microcode_ctl",
      3,
      {
        "NewPackage": [
          "microcode_ctl",
          "4:20180807a-2.20190507.1.el8_0",
          "x86_64"
        ],
        "PreviousPackage": [
          "microcode_ctl",
          "4:20190507-1.el8",
          "x86_64"
        ]
      }
    ]
  ],
  "ref": "tmpref-rhcos",
  "rpm-ostree-inputhash": "8e0b089341157a517e01a87d63878cbb5d32c3cccb97b91adfc4c2e0e154e48c",
  "summary": "OpenShift 4",
  "amis": [
    {
      "name": "ap-northeast-1",
      "hvm": "ami-0c63b39219b8123e5"
    },
    {
      "name": "ap-northeast-2",
      "hvm": "ami-073cba0913d2250a4"
    },
    {
      "name": "ap-south-1",
      "hvm": "ami-0270be11430101040"
    },
    {
      "name": "ap-southeast-1",
      "hvm": "ami-06eb9d35ede4f08a3"
    },
    {
      "name": "ap-southeast-2",
      "hvm": "ami-0d980796ce258b5d5"
    },
    {
      "name": "ca-central-1",
      "hvm": "ami-0f907257d1686e3f7"
    },
    {
      "name": "eu-central-1",
      "hvm": "ami-02fdd627029c0055b"
    },
    {
      "name": "eu-west-1",
      "hvm": "ami-0d4839574724ed3fa"
    },
    {
      "name": "eu-west-2",
      "hvm": "ami-053073b95aa285347"
    },
    {
      "name": "eu-west-3",
      "hvm": "ami-09deb5deb6567bcd5"
    },
    {
      "name": "sa-east-1",
      "hvm": "ami-068a2000546e1889d"
    },
    {
      "name": "us-east-1",
      "hvm": "ami-046fe691f52a953f9"
    },
    {
      "name": "us-east-2",
      "hvm": "ami-0649fd5d42859bdfc"
    },
    {
      "name": "us-west-1",
      "hvm": "ami-0c1d2b5606111ac8c"
    },
    {
      "name": "us-west-2",
      "hvm": "ami-00745fcbb14a863ed"
    }
  ]
}

@cgwalters
Copy link
Member Author

One thing I wanted to write about here was that I would swear this bug was caused by UPI installs having a different bootimage than IPI, but I just used the 4.1.0 installer and it appeared to boot the same version...

@cgwalters
Copy link
Member Author

cgwalters commented Jul 8, 2019

Oh wait, I see...actually, there are indeed different checksums for the oscontainer for IPI:

# rpm-ostree status
...
Deployments:
* pivot://quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:53389c9b4a00d7afebb98f7bd9d20348deb1d77ca4baf194f0ae1b582b7e965b
              CustomOrigin: Managed by pivot tool
                   Version: 410.8.20190520.0 (2019-05-20T22:55:04Z)

  pivot://docker-registry-default.cloud.registry.upshift.redhat.com/redhat-coreos/ootpa@sha256:683a6a866a8ec789fedb5da63b6a2ff68c1b0788ec90e7def778f0c4c13197a4
              CustomOrigin: Provisioned from oscontainer
                   Version: 410.8.20190520.0 (2019-05-20T20:10:04Z)
# 

Yet...they have the same version number 😢 What I suspect happened here is that the RHCOS build failed at some point after pushing the oscontainer, leading to version number reuse, which is a known issue with the pipeline.

cgwalters added a commit to cgwalters/machine-config-operator that referenced this issue Jul 26, 2019
Currently, the MCO only supports rebooting for config changes;
the MCC sets the `desiredConfig` annotation, and the MCD implicitly
takes `currentConfig != desiredConfig` as permission to reboot.

However, we have cases where we want to support drain+reboot
for non-config changes.

The first major motivating reason for this is to handle kernel
arguments injected via initial MachineConfig objects.  Until
we do more work, because `pivot` as shipped with OpenShift 4.1.0
doesn't know about `MachineConfig` (and we have no mechanism
right now to update the bootimages: openshift/os#381 )
what will happen is the MCD will land on the nodes and then
go degraded, because the kernel arguments don't match what is
expected.

Now, we really want to handle kernel arguments at the first boot,
and that will be done eventually.

But this gives us a mechanism to reconcile rather than go degraded.
Previously if we'd had the MCD start a reboot on its own, we could
exceed the "maxUnavailable" as defined by the pool, break master
etcd consistency etc.

In other words, reboots need to be managed via the MCC too.

For the MCD, the `reboot-requested` source of truth is the systemd
journal, as it gives us an easy way to "scope" a reboot request
to a given boot.

The flow here is:

- MCC sets desiredConfig
- MCD notices desiredConfig, logs request in journal
- MCD gets its own journal message, adds `reboot-requested` annotation
- MCC approves reboot via `reboot-approved` annotation
- MCD reboots
- MCD notices it has reboot annotation, checks to see if it's in the journal; it's not, so `reboot-requested` flag is removed
- MCC notices node has `reboot-approved` without `reboot-requested`, removes `reboot-approved`

This ensures that config changes are always testing the "reboot request"
API.

For now, we expose that API as `/usr/libexec/machine-config-daemon request-reboot <reason>`.
For example, one could use `oc debug node` in a loop and run that on each node
to perform a rolling reboot of the hosts.
@cgwalters
Copy link
Member Author

Because we have an unfortunate common use of private Google Docs for technical discussion, here's a link to an important relevant one "Lifecycle of RHCOS image source": https://url.corp.redhat.com/7aa24cd

@DanyC97
Copy link

DanyC97 commented Jul 31, 2019

Because we have an unfortunate common use of private Google Docs for technical discussion, here's a link to an important relevant one "Lifecycle of RHCOS image source": https://url.corp.redhat.com/7aa24cd

i suspect this doc can't be made public ? would love to read about it .. if possible

@enxebre
Copy link
Member

enxebre commented Aug 1, 2019

@cgwalters I'd propose we support "machine.Spec.ProviderSpec.ami=managed"

  • "Managed" means "the expected version from mco upgrade management view of the world".
  • When "machine.Spec.ProviderSpec.ami=managed" we let the actuator fetch the given ami version exposed by the mco in a config map.
  • The installer will ship with the machineSets ami pointing to "managed".
  • As a user you still have the choice to opt out and pin to a specific ami if that’s your desire

The patter extrapolates for all providers.
Question: Where is the current mco ami available so we can consume it? Is there already a configMap exposing it?

@cgwalters
Copy link
Member Author

Question: Where is the current mco ami available so we can consume it? Is there already a configMap exposing it?

This is noted in the issue description above:

Now, see: openshift/origin#21998
for a PR which tries to embed this metadata into the release image. From there, we could imagine having e.g. the cluster API use it to update the machinesets.

@cgwalters
Copy link
Member Author

cgwalters commented Aug 1, 2019

Some terms:

The linked issue there talks about a model where the meta.json from the build (or at least the bootimage information) is injected into either a distinct container, or the machine-os-content.

A tricky question we need to answer here is - what do we do about the case of "oscontainer only" builds, where we didn't produce updated bootimages? Is the "release update bootimage" unset, or does it carry the same thing as the previous bootimage information?

Now...I don't think we can inject this data into machine-os-content for the reasons outlined in the origin PR. So that leaves us with the path of:

  • new layered container on top of machine-os-content
  • Distinct container machine-os-bootimage-data ?
  • Embedding this in the release image itself at build time (what the origin PR was doing)

This also gets into the tricky issue of machine-os-content promotion, and how the release update bootimages are tested.

The complexity here spikes fast because we have to think about all three of the installer pinned bootimage, the machine-os-content, and the release update bootimages. I guess what'd ideally end up happening if we make it all work out is that the installer pinned bootimage is now only used for the bootstrap node...except because masters aren't provisioned by machine API today, we'd likely end up only using the release update bootimages for workers, unless the installer learns how to parse the release image.

@wking
Copy link
Member

wking commented Aug 2, 2019

I guess what'd ideally end up happening if we make it all work out is that the installer pinned bootimage is now only used for the bootstrap node...except because masters aren't provisioned by machine API today...

Do you expect we'll need to address bootimage updates before we get machine-API-provisioned control planes working? I'm not clear on the relative timing, but that would help reduce some of the complexity.

@cgwalters
Copy link
Member Author

Do you expect we'll need to address bootimage updates before we get machine-API-provisioned control planes working? I'm not clear on the relative timing, but that would help reduce some of the complexity.

Offhand...they seem parallelizable?

@wking
Copy link
Member

wking commented Aug 3, 2019

If you get machine-API-created control planes, then you don't have to involve the installer in the selection of cluster bootimages. The installer would just pick whatever bootimage it needed for bootstrapping, and the machine-API could manage bootimage selection and upgrades for the cluster without needing to involve anyone else in that behavior.

@cgwalters
Copy link
Member Author

I wrote some of this originally here but implementation proposals are probably better here.

First, let's just say we will create machine-os-bootimages which will have a configmap with the COSA meta.json.

How about we add this image to the MCO, and have the (ART) RHCOS pipeline update it via automatically-submitted PRs? (Implementation point; PR submission would be async of build completion)

cgwalters added a commit to cgwalters/machine-config-operator that referenced this issue Oct 7, 2019
Today the RHCOS bootimages come "prepivoted"; they have a custom
origin set to the `machine-os-content` that matches.  The idea
here is to avoid an extra reboot.

In practice we're always going to be updating and rebooting today,
because we don't have a mechanism to update bootimages:
openshift/os#381

I plan to change the RHCOS build system to stop "prepivoting"; the
oscontainer will be pushed *after* the bootimages.  This breaks
a complicated dependency and ensures that the RHCOS "source of truth"
is the cosa storage.

Also, this allows one to use the MCD when e.g. booting Fedora CoreOS.

Closes: openshift#981
@cgwalters
Copy link
Member Author

@abhinavdahiya and I discussed trying to get rhcos.json inside the release payload for 4.5.
And to write an enhancement for the UX around having this extractable via oc adm as a replacement for openshift/installer#2092

A later (but parallelizable) task is the idea to ship tooling to turn machine-os-content into a bootimage (subset of cosa) as a derived image from machine-os-content. This is a subset of what https://github.com/coreos/coreos-assembler does - we'd basically take the ostree repo from that and run create_disk.sh.

For this ideally we support a choice of:

  • Run with KVM
  • Run privileged and use loopback mounts

With a fallback of:

  • Run with qemu full emulation (~10x slowdown)

@cgwalters
Copy link
Member Author

@cgwalters
Copy link
Member Author

Going to move this issue over there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants