{"id":26471322,"url":"https://github.com/adevinta/noe","last_synced_at":"2025-03-19T20:54:06.572Z","repository":{"id":171324736,"uuid":"636885066","full_name":"adevinta/noe","owner":"adevinta","description":"streamline multi arch k8s runtimes","archived":false,"fork":false,"pushed_at":"2025-01-13T09:05:58.000Z","size":244,"stargazers_count":52,"open_issues_count":9,"forks_count":7,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-01-13T09:39:07.894Z","etag":null,"topics":["amd64","arm64","container-image","k8s","kubernetes","multiarch-images","mutating-webhook"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adevinta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-05T22:11:26.000Z","updated_at":"2024-11-26T09:35:53.000Z","dependencies_parsed_at":"2023-10-20T13:39:08.267Z","dependency_job_id":"7f13f036-b525-4189-8fea-1a597e0c281b","html_url":"https://github.com/adevinta/noe","commit_stats":null,"previous_names":["adevinta/noe"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adevinta%2Fnoe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adevinta%2Fnoe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adevinta%2Fnoe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adevinta%2Fnoe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adevinta","download_url":"https://codeload.github.com/adevinta/noe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244506029,"owners_count":20463464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amd64","arm64","container-image","k8s","kubernetes","multiarch-images","mutating-webhook"],"created_at":"2025-03-19T20:54:05.899Z","updated_at":"2025-03-19T20:54:06.563Z","avatar_url":"https://github.com/adevinta.png","language":"Go","readme":"# Noe: Kubernetes Mutating Webhook for Node Architecture Selection\n\n**[Blog post announcing and explaining the effort behind Noe](https://medium.com/adevinta-tech-blog/transparently-providing-arm-nodes-to-4-000-engineers-c09c92314f2f)**\n\nNoe is a [Kubernetes mutating webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) that dynamically assigns node architectures to match the requirements of container images within a Pod. It simplifies mixed-architecture deployments (e.g. ARM and x86) by ensuring that Pods are scheduled on nodes capable of executing all their images.\n\n![Overview diagram](/noe_global_diagram.svg)\n\n## Features\n\n- Automatically adjusts node affinities based on container images' supported architectures\n- Improves deployment efficiency by removing the need for manual node selector configuration\n- Facilitates seamless mixed-architecture deployments by ensuring compatibility between ARM and x86 nodes\n\n## Running Tests\n\nRun all tests using the following command:\n\n```bash\ngo test ./...\n```\n\n## Installing Noe\n\nNoe provides a [Helm](https://helm.sh/) chart, available exclusively from the code repository. The simplest way to install it is to use [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) and define an application such as:\n\n```yaml\napiVersion: argoproj.io/v1alpha1\nkind: Application\nspec:\n  source:\n    repoURL: https://github.com/adevinta/noe.git\n    path: charts/noe\n    targetRevision: HEAD\n```\n\n### Helm chart values\n\nNoe's Helm chart is designed to work in standard configurations.\nBelow is a comprehensive guide on how to customize the Helm chart values to\nmatch your Kubernetes configuration.\n\n### Customise Noe deployed image\n\nThis section defines the Docker image details used by the deployment.\n\n```yaml\nimage:\n  registry: ghcr.io\n  repository: adevinta/noe\n  tag: latest\n```\n\n### Manage docker registries rate limits\n\nForces the use of registry proxies for specific images.\nThis helps better manage the requests to public docker registries and prevent\nrequests to be rate limited, or suffer from registries downtime.\n\nDefault:\n\n```yaml\nproxies: []\n```\n\nExample:\n```yaml\nproxies:\n  - docker.io=docker-proxy.company.corp\n  - quay.io=quay-proxy.company.corp\n```\n\n### Further pod scheduling constraints\n\n#### Ensure pod and nodes have similar labels\n\nSpecify a list of label names that pods must have in common with the node they run on.\nThose labels constraints are added to the node selectors computed by the architectures\nimages supports.\n\nDefault:\n\n```yaml\nmatchNodeLabels: []\n```\n\nExample:\n```yaml\nmatchNodeLabels:\n  - kubernetes.io/arch\n  - failure-domain.beta.kubernetes.io/region\n```\n\nWith this configuration, a pod with label `failure-domain.beta.kubernetes.io/region=eu-west-3`\nwould only be scheduled on nodes with label `failure-domain.beta.kubernetes.io/region=eu-west-3`.\nPods without any `failure-domain.beta.kubernetes.io/region` label will be scheduled on any node.\n\n#### Restrict image architectures\n\nList of architectures that can be scheduled. Any other architecture supported by images will be ignored.\n\nDefault:\n\n```yaml\nschedulableArchitectures: []\n```\n\nExample:\n\n```yaml\nschedulableArchitectures:\n  - amd64\n  - arm64\n```\n\n### Configuring accesses to private images\n\nWhile Noe handles the `imagePullSecret` fields, it can also be configured to transparently authenticate\nrequests to private registries.\nBecause of its design, it considers that node-level private registry authentication is consistent across the whole cluster.\n\n#### kubeletConfig\n\nConfiguration for the kubelet credentials configuration.\nAll those paths will automatically be mounted from the host to noe's container\nso Noe can retrieve image configurations.\n\nDefault:\n\n```yaml\nkubeletConfig:\n```\n\nExample:\n\n```yaml\nkubeletConfig:\n  binDir: /etc/eks/image-credential-provider\n  configDir: /etc/eks/image-credential-provider\n  config: config.json\n```\n\n#### containerdConfigPathCandidates\n\nPaths to the containerd configuration files.\nAll those paths will automatically be mounted from the host to noe's container\nso Noe can retrieve image configurations.\n\nDefault:\n\n```yaml\ncontainerdConfigPathCandidates:\n  - /etc/containerd\n```\n\n#### dockerConfigPathCandidates\n\nThis setting specifies the possible paths where the configuration files\nusing the Docker format can be found on the host.\nSpecifying those values will automatically mount the host paths inside\nNoe's containers.\n\nDefault:\n\n```yaml\ndockerConfigPathCandidates:\n  - /var/lib/kubelet/config.json\n```\n\n### Additional metadata\n\nYou can customize the labels and annotations of Kubernetes objects as followed.\nCustomizable objects are: `pod`, `issuer`, `certificate`, `mutatingwebhookconfiguration`, `rolebinding`, `clusterrole`, `clusterrolebinding`, `serviceaccount`, `deployment`\n\nDefault:\n\n```yaml\npod:\n  # labels:\n  #   some: label\n  # annotations:\n  #   some: annotations\n```\n\nExample:\n```yaml\npod:\n  labels:\n    app: my-application\n  annotations:\n    prometheus.io/scrape: \"true\"\n    prometheus.io/port: \"8080\"\n```\n\n## Hinting preferred and supported target architectures\n\nBy default, Noe will automatically select the appropriate architecture when only one is supported by all the containers in the Pod. \nIf more than one is available, Noe will select the system-defined preferred one if available. This preference can be chosen in the command line for Noe (defaults to `amd64` if unspecified): \n```\n./noe -preferred-arch amd64\n```\n\nThis preference can also be overridden at the Pod level by adding the label:\n```\nlabels:\n  arch.noe.adevinta.com/preferred: amd64\n```\n\nNoe will always prioritize a running Pod, so if the preference is not supported by all the containers in the Pod, the common architecture will be selected.\n\nYou can restrict the acceptable common architectures in the command line for Noe:\n```\n./noe -cluster-schedulable-archs amd64,arm64\n```\n\nIf you specify both a preferred architecture and a list of supported architectures in the command line, the default architecture must be part of the list. Otherwise Noe will fail to start.\n\nIf a preferred architecture is specified at the Pod level and is not compatible with the supported architectures listed in the command line, it will be ignored.\n\n## Troubleshooting guide\n\n\n### Image inspection\n\nThis guide explain how to inspect container images to verify the supported architectures in case Noe's selection is not as expected.\n\n1. Authenticate with the registry (if required)\n\n```bash\n# in case of using docker\ndocker login \u003cregistry-url\u003e\n```\n\n2. Inspect the manifest\n\n```bash\ndocker manifest inspect \u003cregitry\u003e/\u003crepository\u003e/\u003cimage\u003e:\u003ctag\u003e\n```\n\nfor example:\n\n```bash\ndocker manifest inspect docker.io/fluent/fluent-bit:2.1.10\n```\n\nYou should find the detail such as\n\n```json\n{\n\"manifests\": [\n  {\n    \"platform\": {\n      \"architecture\": \"amd64\",\n      \"os\": \"linux\"\n    }\n  },\n  {\n    \"platform\": {\n      \"architecture\": \"arm64\",\n      \"os\": \"linux\"\n    }\n  }\n]\n}\n```","funding_links":[],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadevinta%2Fnoe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadevinta%2Fnoe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadevinta%2Fnoe/lists"}