K8s环境下基于Nginx WebDAV与TLS/SSL的文件上传下载部署指南

#作者:闫乾苓

文章目录

  • 1.问题及背景
  • 2.方案说明
  • 3.部署步骤
    • [3.1 制作TLS/SSL私有证书](#3.1 制作TLS/SSL私有证书)
    • [3.2 创建访问nginx账户密码文件并创建secret](#3.2 创建访问nginx账户密码文件并创建secret)
    • [3.3 为TLS/SSL私有证书创建secret](#3.3 为TLS/SSL私有证书创建secret)
    • [3.4 为Nginx 配置文件创建confimap](#3.4 为Nginx 配置文件创建confimap)
    • [3.5 使用deployment,svc部署nginx](#3.5 使用deployment,svc部署nginx)
    • [3.6 客户端curl上传下载文件](#3.6 客户端curl上传下载文件)

1.问题及背景

  1. 中间件巡检脚本生成报告需统一汇总至一台服务器,便于集中分析与管理。
  2. 巡检脚本需要集中存放,支持客户端下载更新,提高维护效率和一致性。

2.方案说明

  1. 在集中汇总服务器部署 Nginx,启用 WebDAV 模块以支持客户端使用 curl 上传巡检日志。
  2. Nginx 默认支持 HTTP 文件下载,用于客户端获取巡检脚本。
  3. 上传与下载过程通过 HTTP Basic 认证进行账户密码验证,确保安全性。
  4. 为加强数据传输安全,使用https。

3.部署步骤

3.1 制作TLS/SSL私有证书

使用自有CA签发的私有证书(Private CA + Signed Certificate),需要创建一个根CA(Root CA),然后用这个CA去签发服务器证书。

这样做的好处是:你可以将CA证书安装到多个客户端的信任库中,这样所有由该CA签发的证书都会被信任。更适合内部网络、企业内网服务、局域网部署等。

3.1.1生成自有CA私钥

需要使用openssl命令,如果系统中没有,可以使用如下命令进行安装:

复制代码
~# yum install openssl

~# openssl genpkey -algorithm RSA -out ca.key -aes256
记录输入的密码(生成环境部署时,密码请自行替换):abc@888.com

命令执行完成后生成如下文件:

复制代码
-rw------- 1 root root 1.9K  6月  6 11:12 ca.key

3.1.2 生成CA证书(自签)

交互式命令需要提供的内容请参考以下内容:

复制代码
~# openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:InternalCA
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:MyInternalRootCA
Email Address []:mail@cmc.com
执行完成后,会生成一个根CA证书文件:
-rw-r--r-- 1 root root 1.5K  6月  6 11:14 ca.crt

(可选)查看证书内容
~# openssl x509 -in ca.crt -text -noout
这会显示证书详细信息,包括颁发者、有效期、公钥、指纹等。
3.1.3生成服务器私钥和CSR
~# openssl genpkey -algorithm RSA -out server.key
生成的私钥
-rw------- 1 root root 1.7K  6月  6 11:15 server.key

~# openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany IT Department
Organizational Unit Name (eg, section) []:SA    
Common Name (e.g. server FQDN or YOUR name) []:report.server.com
Email Address []:mail@server.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

注意:Common Name (e.g. server FQDN or YOUR name) []: 输入的内容需要和nginx要使用的域名保持一致。

以下两行直接回车,可以不输入。

复制代码
A challenge password []:
An optional company name []:

命令执行完成后生成如下文件:

复制代码
-rw-r--r-- 1 root root 1.1K  6月  6 11:21 server.csr

3.1.4使用自有CA签发服务器证书

复制代码
-days 3650 指定证书有效期为10年
~# openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
Signature ok
subject=C = CN, ST = Beijing, L = Beijing, O = MyCompany IT Department, OU = SA, CN = report.server.com, emailAddress = mail@server.com
Getting CA Private Key
Enter pass phrase for ca.key:  #输入第一步创建CA私钥时的密码

命令执行完成后生成的文件如下:

复制代码
-rw------- 1 root root 1.7K  6月  6 11:15 server.key
-rw-r--r-- 1 root root 1.4K  6月  6 11:27 server.crt

3.2 创建访问nginx账户密码文件并创建secret

安装htpasswd命令的软件包:

复制代码
~# yum install -y httpd-tools

使用htpasswd命令创建账户并设置密码,-c 指定文件名,user为用户名,请自行替换。

复制代码
~# htpasswd -c htpasswd user
New password: 
Re-type new password: 
Adding password for user user

在k8s环境为此文件创建secret

复制代码
~# kubectl create secret generic nginx-webdav-basic-auth --from-file=htpasswd

~# kubectl get secret
NAME                      TYPE     DATA   AGE
nginx-webdav-basic-auth   Opaque   1      11s

3.3 为TLS/SSL私有证书创建secret

复制代码
kubectl create secret generic nginx-webdav-tls-certs \
  --from-file=ca.crt \
  --from-file=server.crt \
  --from-file=server.key

它会将本地的三个文件:

  • ca.crt(CA证书)
  • server.crt(服务器证书)
  • server.key(服务器私钥)
    打包成一个 Kubernetes Secret 对象,名为:nginx-webdav-tls-certs
    Pod挂载时Secret 中的每个 key(即文件名)都会被挂载到 /etc/nginx/certs/ 目录下作为一个独立文件。

3.4 为Nginx 配置文件创建confimap

Nginx.conf示例配置文件如下,生产环境请更加实际情况进行调整:

复制代码
worker_processes 1;

events {
    worker_connections 1024;
}

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

    server {
        listen 443 ssl;
        server_name report.server.com;

        ssl_certificate     /etc/nginx/certs/server.crt;
        ssl_certificate_key /etc/nginx/certs/server.key;

        ssl_client_certificate /etc/nginx/certs/ca.crt;
        ssl_verify_client optional;

        # 文件下载配置
        location /down/ {
            alias /data/down/;  # 注意结尾的斜杠
            autoindex on;                           # 自动列出目录内容(可选)
            auth_basic "Restricted";
            auth_basic_user_file /etc/nginx/htpasswd;
        }

    # WebDAV相关配置(上传)    
        location /upload {
            # 启用WebDAV
            dav_methods PUT DELETE MKCOL COPY MOVE;

            # 允许创建新文件和目录
            create_full_put_path on;

            # 设置谁可以访问这个位置
            dav_access user:rw group:rw all:r;

            # 设置上传文件的存储目录
            alias /data/nginx_upload_data;

            # 允许浏览器访问现有文件(GET 请求)
            autoindex off;  # 关闭目录列表(更安全)
            add_header Content-Disposition "inline";  # 浏览器内直接显示文件(非强制下载)
        
            # 限制仅允许 GET 和 WebDAV 方法
            if ($request_method !~ ^(GET|HEAD|PUT|DELETE|MKCOL|COPY|MOVE)$) {
                return 405;
            }

            # 可选:限制上传文件的最大尺寸
            client_max_body_size 50M;

            # 确保只有授权用户才能进行上传
            auth_basic "Restricted";
            auth_basic_user_file /etc/nginx/htpasswd;
        }
    }
}

创建configmap

复制代码
~# kubectl create configmap nginx-webdav-conf --from-file=nginx.conf

~# kubectl get cm
NAME                DATA   AGE
nginx-webdav-conf   1      2d18h

3.5 使用deployment,svc部署nginx

deployment示例中只设置了1个pod副本,并通过nodeName指定了pod固定调度的k8s node节点,文件持久存储使用HostPath,如需设置多个副本,为保证文件下载文件统一管理,建议使用nfs等共享存储方案

deployment.yaml 示例内容如下:

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: report-nginx-webdav
  labels:
    app: report-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: report-nginx
  template:
    metadata:
      labels:
        app: report-nginx
    spec:
      nodeName: worker3 
      containers:
        - name: nginx
          image: nginx:1.27.5
          ports:
            - containerPort: 443
          volumeMounts:
            - name: tls-certs
              mountPath: /etc/nginx/certs
              readOnly: true
            - name: basic-auth
              mountPath: /etc/nginx/htpasswd
              subPath: htpasswd
              readOnly: true             
            - name: custom-config
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf
              readOnly: true
            - name: download-data
              mountPath: /data/down
            - name: upload-data
              mountPath: /data/nginx_upload_data

      volumes:
        - name: tls-certs
          secret:
            secretName: nginx-webdav-tls-certs
        - name: basic-auth
          secret:
            secretName: nginx-webdav-basic-auth
        - name: custom-config
          configMap:
            name: nginx-webdav-conf
        - name: download-data
          hostPath:
            path: /data/report-nginx-data/down
            type: Directory
        - name: upload-data
          hostPath:
            path: /data/report-nginx-data/upload
            type: Directory

svc yaml 示例内容如下,生产环境看根据实际环境调整svc对外开放端口的方式:

复制代码
apiVersion: v1
kind: Service
metadata:
  name: nginx-webdav-ssl-svc
spec:
  type: NodePort
  selector:
    app: report-nginx
  ports:
    - protocol: TCP
      port: 443
      targetPort: 443
      nodePort: 30043

namenode指定的主机节点创建hostpath目录,并设置为Nginx pod内nginx 的uid,gid
~# mkdir /data/report-nginx-data/{down,upload} -p
~# chown -R 101:101 report-nginx-data/

部署deployment, svc

复制代码
~# kubectl apply -f deployment.yaml -f svc.yaml

~# kubectl get pod
NAME                          READY   STATUS    RESTARTS        AGE
pod/report-nginx-webdav-5f977c7bfc-mpfcg   1/1     Running   1 (2d21h ago)   2d21h

~# kubectl get svc
NAME        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
nginx-webdav-ssl-svc   NodePort    10.110.106.124   <none>        443:30043/TCP   2d21h

3.6 客户端curl上传下载文件

客户端访问服务器端https时,需要指定CA证书去验证TLS/SSL证书,所以需要把自签的私有CA证书复制到客户端,在使用curl访问时指定。

复制代码
-rw------- 1 root root 1.9K  6月  6 11:12 ca.key

另外为将htpasswd创建的基于Nginx Basic Auth 的账户和密码,访问的服务器域名存入一个文件中,方便使用。

复制代码
~# vim .netrc 
machine report.server.com
login user
password abc.888.com

上传文件到服务器upload目录示例命令:

复制代码
~# curl --cacert ca.crt --netrc-file .netrc --upload-file file01.txt https://report.server.com:30043/upload/

从服务器down目录下载脚本到本地示例命令:

复制代码
~# curl --cacert ca.crt --netrc-file .netrc -o file02.sh https://report.server.com:30043/down/file02.sh
相关推荐
蝎子莱莱爱打怪24 分钟前
GitLab CI/CD + Docker Registry + K8s 部署完整实战指南
后端·docker·kubernetes
闲云一鹤3 小时前
nginx 快速入门教程 - 写给前端的你
前端·nginx·前端工程化
蝎子莱莱爱打怪3 天前
Centos7中一键安装K8s集群以及Rancher安装记录
运维·后端·kubernetes
何中应3 天前
Nginx转发请求错误
前端·后端·nginx
芝士雪豹只抽瑞克五4 天前
Nginx 高性能Web服务器笔记
服务器·nginx
阿里云云原生4 天前
Kubernetes 官方再出公告,强调立即迁移 Ingress NGINX
kubernetes
失重外太空啦4 天前
nginx
运维·nginx
至此流年莫相忘4 天前
Kubernetes实战篇之配置与存储
云原生·容器·kubernetes
天蓝不会忘记024 天前
lvs,haproxy,keepalived,nginx,tomcat介绍和实验
nginx·tomcat·lvs