Lets try to analyze the following code:
github code reference link
case uid == nil && len(username) > 0:
return fmt.Errorf("container has runAsNonRoot and image has non-numeric user (%s), cannot verify user is non-root (pod: %q, container: %s)", username, format.Pod(pod), container.Name)
This is the code that print the error you see. You see the error because uid == nil
and at the same time username != ""
.
But why username has value and uid does not? Why couldn't they both have value?
It turns out that they couldn't because UID and the username are mutually exclusive. Have a look at the description of these parameters:
github code reference link:
// UID that will run the command(s). This is used as a default if no user is
// specified when creating the container. UID and the following user name
// are mutually exclusive.
Uid *Int64Value `protobuf:"bytes,5,opt,name=uid,proto3" json:"uid,omitempty"`
// User name that will run the command(s). This is used if UID is not set
// and no user is specified when creating container.
Username string `protobuf:"bytes,6,opt,name=username,proto3" json:"username,omitempty"`
So turns out it's not a bug. It's just how the container runtime interface standard got designed, and you can't do much about it.
What you could do is change the way you use USER instruction in Dockerfile.
Instead of using username with USER instruction, create a user with a known uid and use this uid instead, like in example below:
RUN useradd -r -u 1001 appuser
USER 1001