序言

  从安全的角度,容器应该创建一个普通的用户来运行应用,这样在一定的程度上可以保障应用的安全。实现的方式也简单,在创建Dockerfile 中定义普通用户的UIDGID。在K8S YAML资源中使用runAsUser*(注意:值需要与Dockerfile所定义的一致,否则会提示权限问题)*来运行应用。

Dockerfile 创建普通用户

  • Debian 镜像
FROM node:slim

ARG USER=zhang3
ARG UID=1000
ARG GID=1000
ARG APP_HOME=/app

ENV APP_HOME $APP_HOME

RUN mkdir -p $APP_HOME \
    && chown $UID:$GID $APP_HOME \
    && groupadd -g $GID $USER \
    && useradd -d $APP_HOME -u $UID -g $GID -s /bin/bash $USER
    
#RUN useradd $USER -u $UID --create-home --user-group -d $APP_HOME

COPY --chown=$USER . $APP_HOME
USER $UID

WORKDIR $APP_HOME

ENTRYPOINT ["npm", "start"]
  • Alpine 镜像
FROM openjdk:8-jdk-alpine

LABEL maintainer="Qiu Shuhui<shuhui@vqiu.cn>"

ARG user=zhang3
ARG group=zhang3
ARG uid=1000
ARG gid=1000
ARG APP_HOME=/app

ENV APP_HOME $APP_HOME
ENV JAVA_OPTS "-server -Xms1024m -Xmx2048m -Djava.security.egd=file:/dev/./urandom"

RUN set -xe \
    && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
    && apk update \
    && apk add --no-cache ca-certificates ttf-dejavu fontconfig tzdata tini \
    && cp -rf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone

RUN set -xe \
    && mkdir -p $APP_HOME \
    && chown ${uid}:${gid} $APP_HOME \
    && addgroup -g ${gid} ${group} \
    && adduser -h "$APP_HOME" -u ${uid} -G ${group} -s /bin/bash -D ${user}

COPY --chown=$user xx.jar $APP_HOME/app.jar

USER $uid
WORKDIR $APP_HOME

ENTRYPOINT exec /sbin/tini -- java ${JAVA_OPTS} -jar /app.jar 

K8S 资源声明定义

...
spec:
  containers:
  - name: web
    image: xx/xx:latest
  securityContext:
    runAsNonRoot: true
    runAsUser: 10000
    runAsGroup: 10000
...