#作者:闫乾苓
文章目录
- 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.问题及背景
- 中间件巡检脚本生成报告需统一汇总至一台服务器,便于集中分析与管理。
- 巡检脚本需要集中存放,支持客户端下载更新,提高维护效率和一致性。
2.方案说明
- 在集中汇总服务器部署 Nginx,启用 WebDAV 模块以支持客户端使用 curl 上传巡检日志。
- Nginx 默认支持 HTTP 文件下载,用于客户端获取巡检脚本。
- 上传与下载过程通过 HTTP Basic 认证进行账户密码验证,确保安全性。
- 为加强数据传输安全,使用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