K8s部署Nginx集群,通过Ingress实现HTTPS域名访问过程
架构
客户端 → Ingress Controller (处理 TLS) → Service: nginx → Nginx Pod (提供静态内容)
service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
我们创建的 Service 类型默认是 ClusterIP,Ingress 控制器可以通过 ClusterIP 访问到 Pod。
secret存储TLS证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=dong.nginx.com" kubectl create secret tls nginx-ssl-cert --cert=tls.crt --key=tls.key --namespace=default
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
tls:
- hosts:
- dong.nginx.com
secretName: nginx-tls-secret
rules:
- host: dong.nginx.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
在Ingress配置中,设置了注解nginx.ingress.kubernetes.io/force-ssl-redirect: "true",这会导致Ingress控制器将HTTP请求重定向到HTTPS。
我们使用的是kubernetes.io/ingress.class: "nginx",这通常是由NGINX Ingress控制器处理的。NGINX Ingress控制器默认会监听80和443端口,并且当你配置了TLS和强制重定向时,80端口的请求会被重定向到443。
在host字段中指定了域名,需要通过域名才可以访问(只有Host头匹配的请求才会被路由到此服务,如果直接访问Ingress Controller的IP,由于缺少Host头,请求不会被正确路由)。
访问 HTTP 端口 -> 被告知“请走 HTTPS”
返回308永久重定向,说明HTTP被强制跳转到HTTPS,这是常见的做法。服务器明确告诉客户端:“你访问的这个 http 地址已经不再使用了,请永久地使用另一个地址(通常是 https 地址)来访问我。”这是现代Web服务的标准做法,为了安全,强制将不安全的 HTTP 协议跳转到安全的 HTTPS 协议。
308 重定向需要客户端(如浏览器)自动跟随重定向,但 curl 默认不会自动跟随重定向。
Ingress Controller:处理 TLS 终止和路由
通常 Ingress 控制器会使用它自己的 TLS 证书,而 Pod 内部的 nginx 不需要配置 SSL,可以只作为静态文件服务器,因为 Ingress 控制器会处理 SSL 终止。
在Kubernetes中,通常访问服务是通过Ingress控制器提供的入口。Ingress控制器会监听80和443端口(或者你配置的其他端口),然后根据Ingress规则路由流量。
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
autoindex off;
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public";
}
}
在 ConfigMap 中,我们只配置了一个 HTTP 服务器(监听 80 端口),并且没有配置 SSL。因此,Pod 内的 nginx 只会处理 HTTP 流量。而 Ingress 控制器会将 HTTPS 流量终止并转发给 Service(即 Pod)的 80 端口。
nginx-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: html-pvc
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
存储管理-PV动态供给见–有状态应用-MySQL主从复制集群
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-web-cluster
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: config
mountPath: /etc/nginx/conf.d
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: config
configMap:
name: nginx-config
- name: html
persistentVolumeClaim:
claimName: html-pvc
用户访问
访问前需要在用户的主机上修改hosts文件进行域名解析,添加:Ingress节点IP 及 域名。
通过Ingress节点IP地址(kubectl get ingress)加上Ingress控制器的Service上(kubectl get svc -n ingress-nginx)的暴露端口,用户可以从集群外部访问Ingress控制器。(这里需要通过域名访问或者携带主机头,如下:)
curl -H "Host:dong.nginx.com" https://192.168.1.73:31237 -k #证书是自签名的,不在curl的CA信任库中,需要通过-k或--insecure选项来跳过证书验证
当前Ingress-controller的服务类型是NodePort,它会在每个节点上开放一个端口,所以访问时必须带上端口号。
1.http://dong.nginx.com:31441 → 308 重定向到 HTTPS
2.https://dong.nginx.com:31237 → Ingress → Service:nginx → Nginx Pod → 返回网页内容
curl默认不会跟随重定向。所以,当您使用curl访问HTTP时,您看到的是308重定向的响应体,而不是跟随重定向后的内容。
在浏览器中访问http://dong.nginx.com:31441,浏览器会自动重定向到HTTPS并显示页面,用户不会看到308的页面。
# 1. 查看重定向信息 curl -I http://dong.nginx.com:31441 # 2. 自动跟随重定向获取最终内容 curl -L http://dong.nginx.com:31441 # 3. 或者使用详细模式查看整个过程 curl -v -L http://dong.nginx.com:31441
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
kubernetes需要默认的serviceaccount的原因解析
这篇文章主要介绍了kubernetes为何需要默认的serviceaccount,ServiceAccount 是 Kubernetes 中的一种重要概念,它的实际使用场景包括很多,本文给大家讲解的非常详细,需要的朋友可以参考下2023-04-04
k8s 中的 service 如何找到绑定的 Pod 及实现 
service 是一组具有相同 label pod 集合的抽象,集群内外的各个服务可以通过 service 进行互相通信,这篇文章主要介绍了k8s 中的 service 如何找到绑定的 Pod 以及如何实现 Pod 负载均衡,需要的朋友可以参考下2022-10-10


最新评论