From 7947f5226792f7d8224e9ac5c47bef380c199a33 Mon Sep 17 00:00:00 2001 From: Yikun Jiang Date: Thu, 1 Jun 2023 14:59:06 +0800 Subject: [PATCH] Use libnss_wrapper to fake passwd entry to resolve random UID problem Signed-off-by: Yikun Jiang --- 3.4.0/scala2.12-java11-ubuntu/Dockerfile | 3 +- 3.4.0/scala2.12-java11-ubuntu/entrypoint.sh | 41 ++++++++++++--------- Dockerfile.template | 3 +- entrypoint.sh.template | 41 ++++++++++++--------- 4 files changed, 50 insertions(+), 38 deletions(-) diff --git a/3.4.0/scala2.12-java11-ubuntu/Dockerfile b/3.4.0/scala2.12-java11-ubuntu/Dockerfile index a680106..aa754b7 100644 --- a/3.4.0/scala2.12-java11-ubuntu/Dockerfile +++ b/3.4.0/scala2.12-java11-ubuntu/Dockerfile @@ -24,7 +24,7 @@ RUN groupadd --system --gid=${spark_uid} spark && \ RUN set -ex; \ apt-get update; \ ln -s /lib /lib64; \ - apt install -y gnupg2 wget bash tini libc6 libpam-modules krb5-user libnss3 procps net-tools gosu; \ + apt install -y gnupg2 wget bash tini libc6 libpam-modules krb5-user libnss3 procps net-tools gosu libnss-wrapper; \ mkdir -p /opt/spark; \ mkdir /opt/spark/python; \ mkdir -p /opt/spark/examples; \ @@ -33,7 +33,6 @@ RUN set -ex; \ touch /opt/spark/RELEASE; \ chown -R spark:spark /opt/spark; \ echo "auth required pam_wheel.so use_uid" >> /etc/pam.d/su; \ - chgrp root /etc/passwd && chmod ug+rw /etc/passwd; \ rm -rf /var/cache/apt/*; \ rm -rf /var/lib/apt/lists/* diff --git a/3.4.0/scala2.12-java11-ubuntu/entrypoint.sh b/3.4.0/scala2.12-java11-ubuntu/entrypoint.sh index 6def3f9..08fc925 100755 --- a/3.4.0/scala2.12-java11-ubuntu/entrypoint.sh +++ b/3.4.0/scala2.12-java11-ubuntu/entrypoint.sh @@ -15,23 +15,28 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -# Check whether there is a passwd entry for the container UID -myuid=$(id -u) -mygid=$(id -g) -# turn off -e for getent because it will return error code in anonymous uid case -set +e -uidentry=$(getent passwd $myuid) -set -e - -# If there is no passwd entry for the container UID, attempt to create one -if [ -z "$uidentry" ] ; then - if [ -w /etc/passwd ] ; then - echo "$myuid:x:$myuid:$mygid:${SPARK_USER_NAME:-anonymous uid}:$SPARK_HOME:/bin/false" >> /etc/passwd - else - echo "Container ENTRYPOINT failed to add passwd entry for anonymous UID" - fi -fi +attempt_setup_fake_passwd_entry() { + # Check whether there is a passwd entry for the container UID + local myuid; myuid="$(id -u)" + # If there is no passwd entry for the container UID, attempt to fake one + # You can also refer to the https://github.com/docker-library/official-images/pull/13089#issuecomment-1534706523 + # It's to resolve OpenShift random UID case. + # See also: https://github.com/docker-library/postgres/pull/448 + if ! getent passwd "$myuid" &> /dev/null; then + local wrapper + for wrapper in {/usr,}/lib{/*,}/libnss_wrapper.so; do + if [ -s "$wrapper" ]; then + NSS_WRAPPER_PASSWD="$(mktemp)" + NSS_WRAPPER_GROUP="$(mktemp)" + export LD_PRELOAD="$wrapper" NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + local mygid; mygid="$(id -g)" + printf 'spark:x:%s:%s:${SPARK_USER_NAME:-anonymous uid}:%s:/bin/false\n' "$myuid" "$mygid" "$SPARK_HOME" > "$NSS_WRAPPER_PASSWD" + printf 'spark:x:%s:\n' "$mygid" > "$NSS_WRAPPER_GROUP" + break + fi + done + fi +} if [ -z "$JAVA_HOME" ]; then JAVA_HOME=$(java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home' | awk '{print $3}') @@ -85,6 +90,7 @@ case "$1" in --deploy-mode client "$@" ) + attempt_setup_fake_passwd_entry # Execute the container CMD under tini for better hygiene exec $(switch_spark_if_root) /usr/bin/tini -s -- "${CMD[@]}" ;; @@ -105,6 +111,7 @@ case "$1" in --resourceProfileId $SPARK_RESOURCE_PROFILE_ID --podName $SPARK_EXECUTOR_POD_NAME ) + attempt_setup_fake_passwd_entry # Execute the container CMD under tini for better hygiene exec $(switch_spark_if_root) /usr/bin/tini -s -- "${CMD[@]}" ;; diff --git a/Dockerfile.template b/Dockerfile.template index d1188bc..fc67534 100644 --- a/Dockerfile.template +++ b/Dockerfile.template @@ -24,7 +24,7 @@ RUN groupadd --system --gid=${spark_uid} spark && \ RUN set -ex; \ apt-get update; \ ln -s /lib /lib64; \ - apt install -y gnupg2 wget bash tini libc6 libpam-modules krb5-user libnss3 procps net-tools gosu; \ + apt install -y gnupg2 wget bash tini libc6 libpam-modules krb5-user libnss3 procps net-tools gosu libnss-wrapper; \ mkdir -p /opt/spark; \ mkdir /opt/spark/python; \ mkdir -p /opt/spark/examples; \ @@ -33,7 +33,6 @@ RUN set -ex; \ touch /opt/spark/RELEASE; \ chown -R spark:spark /opt/spark; \ echo "auth required pam_wheel.so use_uid" >> /etc/pam.d/su; \ - chgrp root /etc/passwd && chmod ug+rw /etc/passwd; \ rm -rf /var/cache/apt/*; \ rm -rf /var/lib/apt/lists/* diff --git a/entrypoint.sh.template b/entrypoint.sh.template index 6def3f9..08fc925 100644 --- a/entrypoint.sh.template +++ b/entrypoint.sh.template @@ -15,23 +15,28 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -# Check whether there is a passwd entry for the container UID -myuid=$(id -u) -mygid=$(id -g) -# turn off -e for getent because it will return error code in anonymous uid case -set +e -uidentry=$(getent passwd $myuid) -set -e - -# If there is no passwd entry for the container UID, attempt to create one -if [ -z "$uidentry" ] ; then - if [ -w /etc/passwd ] ; then - echo "$myuid:x:$myuid:$mygid:${SPARK_USER_NAME:-anonymous uid}:$SPARK_HOME:/bin/false" >> /etc/passwd - else - echo "Container ENTRYPOINT failed to add passwd entry for anonymous UID" - fi -fi +attempt_setup_fake_passwd_entry() { + # Check whether there is a passwd entry for the container UID + local myuid; myuid="$(id -u)" + # If there is no passwd entry for the container UID, attempt to fake one + # You can also refer to the https://github.com/docker-library/official-images/pull/13089#issuecomment-1534706523 + # It's to resolve OpenShift random UID case. + # See also: https://github.com/docker-library/postgres/pull/448 + if ! getent passwd "$myuid" &> /dev/null; then + local wrapper + for wrapper in {/usr,}/lib{/*,}/libnss_wrapper.so; do + if [ -s "$wrapper" ]; then + NSS_WRAPPER_PASSWD="$(mktemp)" + NSS_WRAPPER_GROUP="$(mktemp)" + export LD_PRELOAD="$wrapper" NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP + local mygid; mygid="$(id -g)" + printf 'spark:x:%s:%s:${SPARK_USER_NAME:-anonymous uid}:%s:/bin/false\n' "$myuid" "$mygid" "$SPARK_HOME" > "$NSS_WRAPPER_PASSWD" + printf 'spark:x:%s:\n' "$mygid" > "$NSS_WRAPPER_GROUP" + break + fi + done + fi +} if [ -z "$JAVA_HOME" ]; then JAVA_HOME=$(java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home' | awk '{print $3}') @@ -85,6 +90,7 @@ case "$1" in --deploy-mode client "$@" ) + attempt_setup_fake_passwd_entry # Execute the container CMD under tini for better hygiene exec $(switch_spark_if_root) /usr/bin/tini -s -- "${CMD[@]}" ;; @@ -105,6 +111,7 @@ case "$1" in --resourceProfileId $SPARK_RESOURCE_PROFILE_ID --podName $SPARK_EXECUTOR_POD_NAME ) + attempt_setup_fake_passwd_entry # Execute the container CMD under tini for better hygiene exec $(switch_spark_if_root) /usr/bin/tini -s -- "${CMD[@]}" ;;