docker Openshift Nginx权限问题[nginx:[emerg] mkdir()“/var/cache/nginx/client_temp”失败(13:许可被拒绝)]

7gcisfzg  于 2023-10-16  发布在  Docker
关注(0)|答案(8)|浏览(193)

我目前遇到了一个问题,试图在Openshift中设置nginx:alpine。
我的构建运行得很好,但我无法在权限被拒绝的情况下进行部署,并出现以下错误
2019/01/25 06:30:54 [emerg] 1#1:mkdir()“/var/cache/nginx/client_temp”失败(13:许可被拒绝)
nginx:[emerg] mkdir()“/var/cache/nginx/client_temp”失败(13:许可被拒绝)
现在我知道Openshift在权限方面有点棘手,因为容器在没有root权限的情况下运行,UID在运行时生成,这意味着它在/etc/passwd中不可用。但是用户是组根的一部分。这里描述了应该如何处理
https://docs.openshift.com/container-platform/3.3/creating_images/guidelines.html#openshift-container-platform-specific-guidelines
我甚至更进一步,为了测试的目的,使整个/var完全可访问(777),但我仍然得到错误。这就是我的Dockerfile的样子。

Dockerfile

FROM nginx:alpine

#Configure proxy settings
ENV HTTP_PROXY=http://my.proxy:port
ENV HTTPS_PROXY=http://my.proxy:port
ENV HTTP_PROXY_AUTH=basic:*:username:password

WORKDIR /app
COPY . .

# Install node.js
RUN apk update && \
    apk add nodejs npm python make curl g++

# Build Application
RUN npm install
RUN ./node_modules/@angular/cli/bin/ng build
COPY ./dist/my-app /usr/share/nginx/html

# Configure NGINX
COPY ./openshift/nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./openshift/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf

RUN chgrp -R root /var/cache/nginx /var/run /var/log/nginx && \
    chmod -R 777 /var
RUN sed -i.bak 's/^user/#user/' /etc/nginx/nginx.conf

EXPOSE 8080

有趣的是,这种方法似乎只是影响nginx的alpine版本。nginx:latest(我认为基于debian)没有问题,这里描述了设置它的方法
https://torstenwalter.de/openshift/nginx/2017/08/04/nginx-on-openshift.html
工作。(但我有一些其他问题,建立,所以我切换到高山)
你知道为什么还是不行吗?

kzmpq1sx

kzmpq1sx1#

我使用的是openshift,权限有限,所以我通过使用下面的nginx镜像(而不是nginx:latest)修复了这个问题。

FROM nginxinc/nginx-unprivileged
xpszyzbs

xpszyzbs2#

去解决这个问题。我认为这个Dockerfile中的问题是我使用了COPY命令来移动我的构建,而它并不存在。这是我的工作

Dockerfile

FROM nginx:alpine

LABEL maintainer="ReliefMelone"

WORKDIR /app
COPY . .

# Install node.js
RUN apk update && \
    apk add nodejs npm python make curl g++

# Build Application
RUN npm install
RUN ./node_modules/@angular/cli/bin/ng build --configuration=${BUILD_CONFIG}
RUN cp -r ./dist/. /usr/share/nginx/html

# Configure NGINX
COPY ./openshift/nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./openshift/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf

RUN chgrp -R root /var/cache/nginx /var/run /var/log/nginx && \
    chmod -R 770 /var/cache/nginx /var/run /var/log/nginx

EXPOSE 8080

CMD ["nginx", "-g", "daemon off;"]

请注意,在Build Application部分下,我现在执行

RUN cp -r ./dist/. /usr/share/nginx/html

而不是

COPY ./dist/my-app /usr/share/nginx/html

复制将不起作用,因为我之前在容器内部运行了ng build,dist也将仅存在于容器中,因此我需要在该容器内部执行复制命令

d6kp6zgx

d6kp6zgx3#

在我的nginx:alpine Dockerfile上有同样的错误
nginx:alpine映像中已经有一个名为nginx的用户。我的猜测是,用它来运行nginx会更干净。
我是这样解决的:

  • /var/cache/nginx的所有者设置为nginx(用户101,组101)
  • 创建一个/var/run/nginx.pid并将所有者也设置为nginx
  • 使用--chown=nginx:nginx将所有文件复制到图像
FROM nginx:alpine
RUN  touch /var/run/nginx.pid && \
     chown -R nginx:nginx /var/cache/nginx /var/run/nginx.pid
USER nginx
COPY --chown=nginx:nginx my/html/files /usr/share/nginx/html
COPY --chown=nginx:nginx config/myapp/default.conf /etc/nginx/conf.d/default.conf
...
k4aesqcs

k4aesqcs4#

如果你在这里是因为你没有部署一个示例舵图(例如:helm create mychart),就像@quasipolynomial建议的那样做,但是要更改部署文件,拉取正确的映像。

containters: 
    - image: nginxinc/nginx-unprivileged

更多关于官方非特权图像的信息:https://github.com/nginxinc/docker-nginx-unprivileged

eivnm1vs

eivnm1vs5#

可能是也可能不是朝着正确方向迈出的一步(对于那些来这里寻找关于[emerg] mkdir() ... failed错误的一般帮助的人特别有帮助)。
此解决方案从Builing nginx from source开始计数。
我花了大约七个小时才意识到这个解决方案与编译nginx时设置的前缀路径直接相关。
这就是我的配置抛出nginx的地方(作为一个非常简短的例子),从这个nginx source编译而来:

sudo ./auto/configure \
--prefix=/usr/local/nginx \
--http-client-body-temp-path=/tmp/nginx/client-body-temp \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi_temp

在没有意识到这一点的情况下,我将前缀设置为/usr/local/nginx,但将客户端主体临时路径fastcgi临时路径设置为/tmp/nginx内部的目录。
它基本上破坏了nginx访问正确文件的能力,因为临时路径与前缀路径不相关。
所以我通过(再次,超级简单的配置作为示例)修复了它:

sudo ./auto/configure \
--prefix=/usr/local/nginx \
--http-client-body-temp-path=/usr/local/nginx/client_body_temp \
--http-fastcgi-temp-path=/usr/local/nginx/fastcgi_temp \

进一步简化:

sudo ./auto/configure \
--prefix=/usr/local/nginx \
--http-client-body-temp-path=/client_body_temp \
--http-fastcgi-temp-path=/fastcgi_temp \

再次,不能保证**工作,但绝对是朝着正确方向迈出的一步。

brc7rcf0

brc7rcf06#

您可以使用nginx.conf文件更改文件夹。您可以在Running nginx as a non-root user部分阅读更多信息。

pxy2qtax

pxy2qtax7#

查找openshift uid和gid

$oc describe project <project_name>

输出:注解:

openshift.io/sa.scc.supplemental-groups=1001240000/10000
          openshift.io/sa.scc.uid-range=1001240000/10000

Nginx配置文件(示例):

nginx_default.conf

server {
    
      listen 4200;
      server_name supp-homolog.procuradoria.go.gov.br;
    
      sendfile on;
    
      default_type application/octet-stream;
    
      gzip on;
      gzip_http_version 1.1;
      gzip_disable      "MSIE [1-6]\.";
      gzip_min_length   1100;
      gzip_vary         on;
      gzip_proxied      expired no-cache no-store private auth;
      gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
      gzip_comp_level   9;
    
    
      root /usr/share/nginx/html;
    
    
      location / {
        try_files $uri $uri/ /index.html =404;
      }
    
    }

nginx.conf

user  root;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

设置Dockerfile

FROM nginx:alpine as build
 
RUN chgrp -R 1001240000 /var/cache/nginx /var/run /var/log/nginx && \
    chmod -R 770 /var/cache/nginx /var/run /var/log/nginx && \
    chown -R 1001240000 /run

COPY --chown=1001240000:1001240000 docker/dev/nginx.conf /etc/nginx/nginx.conf
COPY --chown=1001240000:1001240000 docker/dev/nginx_default.conf /etc/nginx/conf.d/default.conf

 HEALTHCHECK --interval=5s --timeout=3s CMD curl --fail http://localhost:4200/ || exit
 
 EXPOSE 4200
 CMD ["nginx", "-g", "daemon off;"]

部署示例

设置securityContext

kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
 [...]
spec:
  [...]
  template:
    [...]
    spec:
      containers:
        - name: nginx-test
          image: >-
            image-registry.openshift-image-registry.svc:5000/<project_name>/nginx-test:latest
          securityContext:
            runAsNonRoot: true
            runAsGroup: 1001240000
            runAsUser: 1001240000

Dockerfile(完整的angular示例)

从angular根文件夹:

$ podman build -t myapp . -f Dockerfile

Dockerfile

FROM node:18.17.1-alpine as build

RUN apk add tzdata
RUN apk add python3 make g++
ENV TZ America/Sao_Paulo
ENV NODE_OPTIONS=--max-old-space-size=8512

RUN chmod +x /usr/local/bin/node

FROM build as dev

WORKDIR /app

# Copy angular source files
COPY . /app

RUN npm install [email protected] -g  && npm install

# build (ng build), output to dist folder
RUN node --max_old_space_size=8512 ./node_modules/@angular/cli/bin/ng build --configuration development

FROM nginx:stable

RUN chgrp -R 1001240000 /var/cache/nginx /var/run /var/log/nginx && \
    chmod -R 770 /var/cache/nginx /var/run /var/log/nginx && \
    chown -R 1001240000 /run

COPY --from=dev --chown=1001240000:1001240000 /app/docker/dev/nginx.conf /etc/nginx/nginx.conf
COPY --from=dev --chown=1001240000:1001240000 /app/docker/dev/nginx_default.conf /etc/nginx/conf.d/default.conf

# Copy angular dist folder to nginx
COPY --from=dev --chown=1001240000:1001240000 /app/dist /usr/share/nginx/html

RUN find /usr/share/nginx/html/ -mindepth 1 -type d -exec chmod +x {} \;

HEALTHCHECK --interval=5s --timeout=3s CMD curl --fail http://localhost:4200/ || exit

EXPOSE 4200

CMD ["nginx", "-g", "daemon off;"]
lmyy7pcs

lmyy7pcs8#

运行下面的命令来解决上述问题。需要anyuid安全上下文约束。

oc adm policy add-scc-to-user anyuid system:serviceaccount:<NAMESPACE>:default

相关问题