-
Notifications
You must be signed in to change notification settings - Fork 244
feat: install Kubernetes to Flatcar from sysexts on MAR #7680
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
base: main
Are you sure you want to change the base?
Conversation
0f01d7a to
bb63179
Compare
bb63179 to
1edf82e
Compare
1edf82e to
9fafc40
Compare
9fafc40 to
e77233d
Compare
|
I am seeing a few persistent CI failures relating to sudo, which I haven't touched, at least not in this PR. |
| "matchDatasources": [ | ||
| "docker" | ||
| ], | ||
| "matchPackageNames": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
who would be the owner of such packages ? I'm not sure if they would have automatic assigned in the PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably Chewi + Jeremi as primary owners, and maybe us as secondary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that we need to be owners. These sysexts are published in tandem with their .deb and .rpm counterparts from the very same Dalec YAML definition. Adding sysext support is usually just a case of adding one line.
| shift 3 | ||
| done | ||
|
|
||
| systemd-sysext --no-reload refresh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where can I learn more on this, those sysext droppin how do they work ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also curious
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sysext man page is a good place to start: https://www.freedesktop.org/software/systemd/man/latest/systemd-sysext.html
Also, Lennart wrote a few blog posts around sysext use but these tend to be pretty specific. Here's one on creating extension overlays on the fly: https://0pointer.net/blog/testing-my-system-code-in-usr-without-modifying-usr.html (using subdirectories, not actual images like we do).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@djsly @cameronmeissner I'm also happy to jump on a call and talk you through the general concept if we get a few folks interested. I held a number of presentations on sysexts (the most recent one at FrOSCon 2025: https://app.media.ccc.de/v/froscon2025-3330-immutable_turtles_all_the_way_down ) and would be happy to ramp you up!
djsly
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left a few comments :)
| - path: /mnt/aks-sysext-rw/usr/local | ||
| - path: /mnt/aks-sysext-rw/usr/local/bin | ||
| - path: /mnt/aks-sysext-rw/usr/local/lib | ||
| - path: /mnt/aks-sysext-rw/usr/local/lib64 | ||
| - path: /mnt/aks-sysext-rw/usr/local/sbin | ||
| - path: /mnt/aks-sysext-rw/usr/local/share |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we making all these paths mutable/read-write? the only one we discussed potentially needing is /usr/share/ca-certificates i think, but not any of these /usr/local.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I was thinking it was /usr/local/share/ca-certificates. I thought I'd cover the rest of /usr/local just in case it helps with other extensions. I can extend this to /usr/share/ca-certificates. Up to you whether we cover the whole of /usr/local, but I think it doesn't hurt.
| files: | ||
| - path: /etc/extensions/aks-sysext/usr/lib/extension-release.d/extension-release.aks-sysext | ||
| mode: 0644 | ||
| - path: /mnt/aks-sysext/usr/lib/extension-release.d/extension-release.aks-sysext |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like we should keeps this together with the other AKS bits in /opt, rather than putting it in /mnt. That shouldn't run into the overlay stacking issues because we guarantee we won't be applying a sysext to /opt, as doing so would make it read-only.
| - path: /etc/extensions/aks-sysext | ||
| target: /mnt/aks-sysext | ||
| hard: false | ||
| - path: /mnt/aks-sysext/usr/local | ||
| target: /mnt/aks-sysext-rw/usr/local | ||
| hard: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the thinking behind this double indirection via symlinks? why /etc/extension/aks-sysext -> /mnt/aks-sysext -> /mnt/aks-sysext-rw rather than one level of symlink?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has to be a symlink rather than a real directory under /etc once confext comes into play. If it was /etc/extension/aks-sysext -> /mnt/aks-sysext with /mnt/aks-sysext/usr/local being a real directory, then it wouldn't be writeable.
parts/linux/cloud-init/artifacts/flatcar/cse_install_flatcar.sh
Outdated
Show resolved
Hide resolved
| local seName=$1 seURL=$2 desiredVer=$3 seMatch | ||
|
|
||
| seMatch=$(matchLocalSysext "${seName}" "${desiredVer}" "${seArch}") | ||
| if ! test -f "${seMatch}"; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why using test directly? if [ ! -f "${seMatch}" ]; then would be preferred
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote this months ago and can't remember. It possibly involved Copilot. 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, now I remember! It was so that I could mock the call in cse_install_flatcar_spec.sh. If you mock [, but then you can't use it inside the mock. Doing so possibly also had other explosive effects.
| fi | ||
|
|
||
| seMatch=$(matchLocalSysext "${seName}" "${desiredVer}" "${seArch}") | ||
| if ! test -f "${seMatch}"; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question here
| fi | ||
| } | ||
|
|
||
| installCredentialProviderPackageFromBootstrapProfileRegistry() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we really need this helper?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not having it would make the confusing logic in ensureKubelet even more confusing.
e77233d to
4bb4239
Compare
installStandaloneContainerd should never be called in this case.
We almost always pass `${OS}` so make this the default.
There are only really four outcomes here, install kubelet and kubectl from a URL, bootstrap profile registry, or package, or do nothing.
There are only really three outcomes here, install the credential provider from a URL, bootstrap profile registry, or package.
Flatcar will use the same logic but install these from MAR instead, so make the name a bit more generic.
Flatcar will use the same logic but install these from MAR instead, so make the name a bit more generic.
Flatcar is immutable so cannot use traditional packages. The sysexts are downloaded using ORAS at build time and the desired version is later "merged" by simply creating symlinks and calling systemd-sysext refresh. If a sysext for the requested Kubernetes version cannot be found locally at deployment time, ORAS is used to try and fetch one. Failing that, it falls back to downloading the regular binary tarballs. Sysexts are a systemd concept, so they have been published using systemd's architecture names rather than Docker's even though they are hosted in an OCI registry. The sysexts are built using Dalec from a distribution other than Flatcar, which is currently Azure Linux 3. Renovate has been configured to consider `azlinux3` part of the version so that different Kubernetes releases could potentially be built from different distributions. The use of `matchCurrentVersion` ensures that tags containing `azlinux3` (e.g. not `noble`) will only be applied against artifacts already using `azlinux3`. Switching distribution should be a manual change.
See previous commit for details.
Functions like installKubeletKubectlFromPkg exist in multiple distro scripts, so one script will shadow another. Only load the applicable scripts when required by grouping the tests for each distro. Defining BeforeEach as a function is not the correct way to use it, so such usage was doing nothing. You need to give it code as a string. Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
This was mostly written by Copilot, but it did a good job.
Hosting a directory-based sysext from /etc is a problem because Flatcar will use confext soon, which will make /etc an overlayfs. It is now hosted from /mnt/aks-sysext instead. Pointing the /usr/local/bin symlink at /opt/bin is also confusing because AKS now installs several binaries here. It just needs to point somewhere writeable, so this now points under /mnt/aks-sysext-rw. The symlink now covers the whole of /usr/local, not just /usr/local/bin, as there may be components that need to write to other directories. Nothing in Agent Baker should write to /usr/local now, but VM extensions may still do this. Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
Flatcar is breaking the OSProfile limit again, so savings need to be made somewhere. This helper function is only used in that one file. Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
It's a legacy file with .deb package data, and Flatcar needs to save space in OSProfile. Also the `MANIFEST_FILEPATH` references in the tests were unused. Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
4bb4239 to
b96f8d1
Compare
What this PR does / why we need it:
Following #7125, this installs kubelet, kubectl, and acr-credential-provider to Flatcar from systemd system extensions hosted on MAR.
Flatcar is immutable so cannot use traditional packages. The sysexts are downloaded using ORAS at build time and the desired version is later "merged" by simply creating symlinks and calling systemd-sysext refresh.
If a sysext for the requested Kubernetes version cannot be found locally at deployment time, ORAS is used to try and fetch one. Failing that, it falls back to downloading the regular binary tarballs.
Sysexts are a systemd concept, so they have been published using systemd's architecture names rather than Docker's even though they are hosted in an OCI registry.
The sysexts are built using Dalec from a distribution other than Flatcar, which is currently Azure Linux 3.
Renovate has been configured to consider
azlinux3part of the version so that different Kubernetes releases could potentially be built from different distributions. The use ofmatchCurrentVersionensures that tags containingazlinux3(e.g. notnoble) will only be applied against artifacts already usingazlinux3. Switching distribution should be a manual change.This also adjusts the "aks-sysext" hack currently applied to Flatcar that allows writing to /usr/local/bin. Despite efforts to use /opt/bin instead, it is likely that waagent will still need to write here for the time being. aks-sysext now allows writes to all of /usr/local rather than just /usr/local/bin. The underlying files are now written under /mnt rather than /etc because Flatcar is going to start using confexts, making /etc an overlayfs, which would cause issues here.
The rest is just renames, refactoring, and fixes to support the above.
Which issue(s) this PR fixes:
Fixes Flatcar for AKS work item #34435556