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
相关推荐
小小鱼儿小小林1 小时前
免费一键自动化申请、续期、部署、监控所有 SSL/TLS 证书,ALLinSSL开源免费的 SSL 证书自动化管理平台
开源·自动化·ssl
RW~1 小时前
Minio安装配置,桶权限设置,nginx代理 https minio
运维·nginx·https·minio
CodeWithMe4 小时前
Nginx入门进阶:从零到高手的实战指南
运维·nginx
Ahlson4 小时前
【fnNAS】docker的nginx配置html
nginx·docker·容器·fnnas
亦舒.7 小时前
宝塔面板Nginx手动配置负载均衡实战指南
运维·nginx·负载均衡
&如歌的行板&7 小时前
如何在postman中动态请求k8s中的pod ip(基于nacos)
云原生·容器·kubernetes
云妙算8 小时前
K8s 弹性伸缩踩坑实录:周末 2 天烧掉 10 万元!?
云原生·kubernetes
deming_su9 小时前
轻松上手:使用Nginx实现高效负载均衡
运维·nginx·负载均衡
qq_49244844610 小时前
Java 访问HTTP,信任所有证书,解决SSL报错问题
java·http·ssl