> 技术文档 > K8s环境下基于Nginx WebDAV与TLS/SSL的文件上传下载部署指南_kubernetes 下载和上传文件

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

#作者:闫乾苓

文章目录

  • 1.问题及背景
  • 2.方案说明
  • 3.部署步骤
    • 3.1 制作TLS/SSL私有证书
    • 3.2 创建访问nginx账户密码文件并创建secret
    • 3.3 为TLS/SSL私有证书创建secret
    • 3.4 为Nginx 配置文件创建confimap
    • 3.5 使用deployment,svc部署nginx
    • 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.crtEnter pass phrase for ca.key:You are about to be asked to enter information that will be incorporatedinto 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 blankFor some fields there will be a default value,If you enter \'.\', the field will be left blank.-----Country Name (2 letter code) [AU]:CNState or Province Name (full name) [Some-State]:BeijingLocality Name (eg, city) []:BeijingOrganization Name (eg, company) [Internet Widgits Pty Ltd]:InternalCAOrganizational Unit Name (eg, section) []:ITCommon Name (e.g. server FQDN or YOUR name) []:MyInternalRootCAEmail 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.csrYou are about to be asked to enter information that will be incorporatedinto 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 blankFor some fields there will be a default value,If you enter \'.\', the field will be left blank.-----Country Name (2 letter code) [AU]:CNState or Province Name (full name) [Some-State]:BeijingLocality Name (eg, city) []:BeijingOrganization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany IT DepartmentOrganizational Unit Name (eg, section) []:SA Common Name (e.g. server FQDN or YOUR name) []:report.server.comEmail Address []:mail@server.comPlease enter the following \'extra\' attributesto be sent with your certificate requestA 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.crtSignature oksubject=C = CN, ST = Beijing, L = Beijing, O = MyCompany IT Department, OU = SA, CN = report.server.com, emailAddress = mail@server.comGetting CA Private KeyEnter 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 userNew 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 secretNAMETYPE DATA AGEnginx-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 cmNAME DATA AGEnginx-webdav-conf 1 2d18h

3.5 使用deployment,svc部署nginx

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

deployment.yaml 示例内容如下:

apiVersion: apps/v1kind: Deploymentmetadata: name: report-nginx-webdav labels: app: report-nginxspec: 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: v1kind: Servicemetadata: name: nginx-webdav-ssl-svcspec: type: NodePort selector: app: report-nginx ports: - protocol: TCP port: 443 targetPort: 443 nodePort: 30043namenode指定的主机节点创建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 podNAME READY STATUS RESTARTS AGEpod/report-nginx-webdav-5f977c7bfc-mpfcg 1/1 Running 1 (2d21h ago) 2d21h~# kubectl get svcNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEnginx-webdav-ssl-svc NodePort 10.110.106.124  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.comlogin userpassword 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