Skip to content

Support EBS Task Attach non-root user mode #4757

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

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

kiryl1
Copy link

@kiryl1 kiryl1 commented Aug 15, 2025

Summary

Enables running ECS EC2 Tasks with EBS Task Attach Enabled as a Non Root User. The change allows the Non Root User inside of the running container to write to the attached EBS Volume.

Implementation details

  • For each container with EBSTA mounts, the Agent generates the appropriate GID
  • The GID is deterministically generated from the volume's SourceVolumeHostPath
  • The GID is added as a supplementary group to the container process via Docker's --group-add
  • After the CSI driver completes mounting the volume in NodeStageVolume, sets the mount point ownership to this GID using chown and sets permissions to 775 with setgid bit using chmod
  • Advertise a new agent capability ecs.capability.ebsta.non-root-user during instance registration. This helps ECS back-end find a capable instance during task placement.

Testing

New tests cover the changes: Yes

  • Updated existing and added new unit tests.
  • New functional E2E tests to come next.

Description for the changelog

Feature: Support EBS task attach non-root user mode

Additional Information

Does this PR include breaking model changes? If so, Have you added transformation functions? No

Does this PR include the addition of new environment variables in the README? No

Licensing

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@kiryl1 kiryl1 requested a review from a team as a code owner August 15, 2025 20:57
@kiryl1 kiryl1 changed the title Added EBSTA NRU Support EBS Task Attach non-root user mode Aug 15, 2025
nineonine
nineonine previously approved these changes Aug 18, 2025
if ebsConfig, ok := vol.(*taskresourcevolume.EBSTaskVolumeConfig); ok {
// This container mounts an EBS volume, generate GID from SourceVolumeHostPath
gid := utils.GenerateGIDFromPath(ebsConfig.SourceVolumeHostPath)
logger.Info("gid from task linux go " + strconv.Itoa(gid))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
logger.Info("gid from task linux go " + strconv.Itoa(gid))
logger.Debug("Generated a GID from EBS volume's host path", logger.Fields{field.TaskID: task.GetID(), "EBS SourceVolumeHostPath": ebsConfig.SourceVolumeHostPath, "GID": strconv(Itoa(gid)))

@@ -266,3 +267,8 @@ func (task *Task) BuildCNIConfigAwsvpc(includeIPAMConfig bool, cniConfig *ecscni
func (task *Task) BuildCNIConfigBridgeMode(cniConfig *ecscni.Config, containerName string) (*ecscni.Config, error) {
return nil, errors.New("unsupported platform")
}

// Not Supported for Windows
func (task *Task) getSupplementaryGroups(container *apicontainer.Container) []string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the EBS Task Attach feature as a whole supported for Windows?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -83,6 +83,7 @@ const (
capabilityServiceConnect = "service-connect-v1"
capabilityGpuDriverVersion = "gpu-driver-version"
capabilityEBSTaskAttach = "storage.ebs-task-volume-attach"
capabilityEBSTANonRootUser = "ebsta.non-root-user"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
capabilityEBSTANonRootUser = "ebsta.non-root-user"
capabilityEBSTANonRootUser = "storage.ebs-task-volume-attach-non-root-user"

to extend the existing capability prefix

OR

Suggested change
capabilityEBSTANonRootUser = "ebsta.non-root-user"
capabilityEBSTANonRootUser = "storage.ebsta-non-root-user"

if there are restrictions on the length of the key.

)

// GenerateGIDFromPath generates a GID in range [900000, 999999] from a string
func GenerateGIDFromPath(path string) int {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put this under ecs-agent/utils: https://github.com/aws/amazon-ecs-agent/tree/master/ecs-agent/utils. This would help all agents share the same code without duplication. Please run make gomod to update go mod dependencies.

gid := minGID + (int(num) % diff)

return gid
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unable to comment on the ecs-agent/daemonimages/csidriver/bin/ebs-csi-driver below. Please do not add binaries to this repo. I am not sure if this was intentional.

Comment on lines 262 to 263
minGID = 900000
maxGID = 999999
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are the min and max GID values restricted to this range?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to reduce the probability of collision with some already predefined GID.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, please add this as a code comment

@@ -245,9 +245,41 @@ func (d *nodeService) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
}
}
klog.V(4).InfoS("NodeStageVolume: successfully staged volume", "source", source, "volumeID", volumeID, "target", target, "fstype", fsType)

const ebsPathPrefix = "/mnt/ecs/ebs/"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this defined anywhere else today? If yes, please reuse it, if not, lets find a place to add this. At the very least, it should be a global const in this csi-driver package.

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

Successfully merging this pull request may close these issues.

4 participants