crossplane: XFN doesn't run on AWS Bottlerocket

What happened?

xfn container doesn’t start when running on the AWS Bottlerocket nodes - returning a possibly misleading message of ‘no space left on device’

How can we reproduce it?

create an EKS cluster running Bottlerocket and start with xfn enabled.

to further debug I tried to give it as many privileges as possible:

        xfn:
          args:
          - --debug
          cache:
            sizeLimit: 2Gi
          enabled: true
          securityContext:
            readOnlyRootFilesystem: false
            allowPrivilegeEscalation: true
            privileged: true
            hostPID: true
            hostIPC: true
            hostNetwork: true
            capabilities:
              add: ["SETUID", "SETGID", "SYS_ADMIN", "NET_ADMIN"]
            runAsUser: 0
            runAsGroup: 0

an strace of the xfn binary in the container results in: image

from https://manpages.ubuntu.com/manpages/impish/man7/user_namespaces.7.html

ENOSPC (since Linux 4.9; beforehand EUSERS)
              CLONE_NEWUSER was specified in the flags mask, and the call would cause  the  limit
              on the number of nested user namespaces to be exceeded.  See [user_namespaces](https://manpages.ubuntu.com/manpages/impish/man7/user_namespaces.7.html)(7).

the max_user_namespaces is set to 0:

image

from https://github.com/bottlerocket-os/bottlerocket/blob/develop/SECURITY_GUIDANCE.md

Bottlerocket does not currently support user namespaces. This means that UID 0 (root) inside the container is the same as UID 0 on the host.

I’m not sure if my lead is correct and if this actually relates to the user namespace so I could use a hand to further investigate the strace or any other leads.

What environment did it happen in?

Crossplane version: v1.11.2-stable Kube version:

Client Version: version.Info{Major:"1", Minor:"23+", GitVersion:"v1.23.13-eks-fb459a0", GitCommit:"55bd5d5cb7d32bc35e4e050f536181196fb8c6f7", GitTreeState:"clean", BuildDate:"2022-10-24T20:38:50Z", GoVersion:"go1.17.13", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"23+", GitVersion:"v1.23.16-eks-48e63af", GitCommit:"e6332a8a3feb9e0fe3db851878f88cb73d49dd7a", GitTreeState:"clean", BuildDate:"2023-01-24T19:18:15Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"linux/amd64"}

Thank you.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 16 (9 by maintainers)

Most upvoted comments

It does seem to work. Maybe others can test further.

[ssm-user@control]$ cat /proc/sys/user/max_user_namespaces
0
[ssm-user@control]$ exit

➜  test/container k logs -n crossplane-system  crossplane-77b6966474-7wknn crossplane | grep 'no space left on device'
2023-03-23T21:03:24Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562068", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:24Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562079"}, "reason": "ComposeResources"}
2023-03-23T21:03:25Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:25Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:25Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:25Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:26Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:26Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:34Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:34Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:50Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:50Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:04:22Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:04:22Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}

➜  test/container k delete -f claim.yaml
objectstorage.awsblueprints.io "standard-object-storage" deleted
[ssm-user@control]$ apiclient -u /settings -X PATCH -d '{"kernel": {"sysctl": {"vm.max_map_count": "262144", "user/max_user_namespaces": "16384"}}}'
[ssm-user@control]$ apiclient -u /tx/commit_and_apply -m POST
["settings.kernel.sysctl.user/max_user_namespaces","settings.kernel.sysctl.\"vm.max_map_count\""]
[ssm-user@control]$ cat /proc/sys/user/max_user_namespaces
16384
[ssm-user@control]$ exit

➜  test/container k apply -f claim.yaml
objectstorage.awsblueprints.io/standard-object-storage created
➜  test/container k logs -n crossplane-system  crossplane-77b6966474-7wknn crossplane | grep 'no space left on device'
2023-03-23T21:03:24Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562068", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:24Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562079"}, "reason": "ComposeResources"}
2023-03-23T21:03:25Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:25Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:25Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:25Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:26Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:26Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:34Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:34Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:03:50Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:03:50Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}
2023-03-23T21:04:22Z	DEBUG	crossplane	cannot compose resources	{"controller": "defined/compositeresourcedefinition.apiextensions.crossplane.io", "controller": "composite/xobjectstorages.awsblueprints.io", "request": "/standard-object-storage-ncnd2", "uid": "8059346e-5890-4902-934b-e407ddcf24f7", "version": "16562081", "name": "standard-object-storage-ncnd2", "error": "cannot run Composition Function pipeline: cannot run function \"quotable\": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device"}
2023-03-23T21:04:22Z	DEBUG	crossplane.events	cannot compose resources: cannot run Composition Function pipeline: cannot run function "quotable": cannot run container: rpc error: code = Unknown desc = cannot start spark: fork/exec /usr/local/bin/xfn: no space left on device	{"type": "Warning", "object": {"kind":"XObjectStorage","name":"standard-object-storage-ncnd2","uid":"8059346e-5890-4902-934b-e407ddcf24f7","apiVersion":"awsblueprints.io/v1alpha1","resourceVersion":"16562081"}, "reason": "ComposeResources"}

No new log messages with no space left on device

Bottlerocket (AMI ID ami-0a49771f6772955e6)

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
nodeGroups:
  - name: ng-bottlerocket
    instanceType: m5.large
    desiredCapacity: 3
    amiFamily: Bottlerocket
    ami: auto-ssm
    iam:
       attachPolicyARNs:
          - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
          - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
          - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
          - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
    ssh:
        allow: false
➜  test/container k get pod -n crossplane-system -o wide
NAME                                       READY   STATUS    RESTARTS   AGE   IP               NODE                                           NOMINATED NODE   READINESS GATES
crossplane-77b6966474-7wknn                2/2     Running   0          31m   192.168.80.137   ip-192-168-69-59.us-west-2.compute.internal    <none>           <none>
crossplane-rbac-manager-5666767cd6-lwftq   1/1     Running   0          31m   192.168.15.161   ip-192-168-16-243.us-west-2.compute.internal   <none>           <none>
➜  test/container k get node ip-192-168-69-59.us-west-2.compute.internal --show-labels
NAME                                          STATUS   ROLES    AGE   VERSION               LABELS
ip-192-168-69-59.us-west-2.compute.internal   Ready    <none>   56m   v1.24.9-eks-4f83af2   alpha.eksctl.io/nodegroup-name=ng-bottlerocket,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=m5.large,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=us-west-2,failure-domain.beta.kubernetes.io/zone=us-west-2c

Just confirming: it does seem to work fine with the adjustment to the kernel configuration, setting a non-zero limit of user namespaces.

In the TOML settings (launch template’s user data), for example:

[settings.kernel.sysctl]
"user.max_user_namespaces" = "16384"

Careful with the quotes on the left side, they’re necessary. Otherwise, the dot in the setting name will be interpreted as a new section within the TOML document.

Tested it out with a silly echo function, that just spits out stdin to stdout (needed a new image to make cat - the entrypoint, maybe configuring “command” and “args” would be a nice luxury once we get more important stuff out of the way during alpha/beta).

  functions:
  - name: ingress-function
    type: Container
    container:
      image: lcaparelli/echo-stdin:latest

Again thanks @nabuskey for the insight, sorry for missing it the first time around.

@LCaparelli thanks tested this today in one of our clusters - its working 😉

Folks, I opened a discussion in Bottlerocket’s repo: https://github.com/bottlerocket-os/bottlerocket/discussions/3318

From what I’ve been told there, it seems that the distro does support user namespaces, but limits it to 0 by default. This can be changed via user data, when launching the instance.

For the kernel feature specifically, user namespaces are supported today but disabled by default, meaning that user.max_user_namespaces is set to 0. This can be changed via user data at launch; if you change it, and all you need is the ability to create new user namespaces within a container, then that will work. The default limit of zero is motivated by the security risks of user namespaces: they imply the ability to create child processes with capabilities that the parent process doesn’t possess, which can expose a lot more kernel surface area to otherwise untrusted processes.

I still need to test this, but we might be able to make it work.

EDIT: just realized that’s what @nabuskey suggested. My bad 🙇

Looks like it is related to the number of configured available namespaces. Thank you very much for digging deep and providing relevant information.

This can be configured with

[settings.kernel.sysctl]
"user.max_user_namespaces" = "16384"

Looks like you can do it via cli too. See: https://github.com/bottlerocket-os/bottlerocket/pull/1158

If Bottlerocket doesn’t allow user namespaces this unfortunately isn’t likely to be something we can fix. This is part of why we think of xfn as the “reference” Composition Function runner and expect that other implementations that make different tradeoffs will exist.

@nabuskey I quickly checked the Bottlerocket doc

https://github.com/bottlerocket-os/bottlerocket/blob/develop/SECURITY_GUIDANCE.md#do-not-run-containers-as-uid-0

It says that Bottlerocket does not currently support user namespaces. I am not sure if the info is up to date, but it matches the debug output from the Issue description.

There is a good doc on security requirements for xfn runner https://docs.crossplane.io/knowledge-base/guides/composition-functions/#the-xfn-runner .

It says

Regardless of capabilities xfn always runs each Composition Function as an unprivileged user. That user will appear to be root inside the Composition Function container thanks to user_namespaces(7).

So it looks like if user namespaces are not supported by Bottlerocket in general then xfn runner will not work