大概分为三个部分
- Pod与Ingress的关系
- Ingress Controller
- Ingress 实现HTTP与HTTPS
在上面接触到了NodePort
和LoadBalancer
可以把应用暴露给外界进行访问,能感觉到需要提前规划端口,应用越来越多就会变得很麻烦,并且每个Service
都会给你创建一个负载均衡,维护成本有点高,Ingress
就是一个全局的负载均衡器,能提供统一的访问入口,他可以通过域名或URL
将请求转发到不同的Service
,他支持七层的负载均衡,而之前提到的那些都是四层的,Ingress
是授权请求入站访问到集群的规则集合,具体的实现是由Ingress Controller
来完成的,先了解一下Pod
和Ingress
的关系。
Pod与Ingress的关系
Ingress
是通过Service
来关联Pod
的,通过你指定的Service
来绑定一组pod
,通过Ingress Controller
来实现Pod
的负载均衡,Ingress
只是定义了规则,负载均衡是由控制器(Controller)来完成的,他支持四层和七层的转发
Ingress Controller
具体帮你提供全局负载均衡,了解一下访问流程,用户会先访问Ingress
控制器定义的规则,这个规则你可以理解为nginx
配置文件写的各个虚拟主机,用户请求会先到达Ingress
控制器,控制器是在node
上运行的,然后再到具体的pod
,我们用的是Ingress-nginx
,这个官方维护的,其实还有很多,具体还有哪些可以看一下官方文档,下面部署一下Ingress-nginx
ingress controller相关信息地址:https://github.com/kubernetes/ingress-nginx
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.46.0/deploy/static/provider/baremetal/deploy.yaml
国内用户需要修改镜像地址
containers:
- name: controller
image: acicn/ingress-nginx-controller:v0.46.0
imagePullPolicy: IfNotPresent
还需要添加使用宿主机网络的参数:ingress-controller 将会使用宿主机网络的 80 和 443 端口。
spec: dnsPolicy: ClusterFirst hostNetwork: true containers: - name: controller image: acicn/ingress-nginx-controller:v0.46.0 imagePullPolicy: IfNotPresent lifecycle: preStop: exec: command: - /wait-shutdown args:
部署安装
kubectl apply -f deploy.yaml
$ kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-ptkwd 0/1 Completed 0 2m59s
ingress-nginx-admission-patch-zdqzp 0/1 Completed 0 2m59s
ingress-nginx-controller-76fc46c57b-t897c 0/1 Running 0 2m59s
验证使用 Ingress
创建tomcat的deployment、service
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deploy
namespace: testing
spec:
replicas: 2
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:8.0.50-jre8-alpine
ports:
- containerPort: 8080
name: httpport
- containerPort: 8009
name: ajpport
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
namespace: testing
labels:
name: tomcat-svc
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 30443
selector:
app: tomcat
创建tomcat-ingress
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: tomcat namespace: testing annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: tomcat.ingress.com http: paths: - path: backend: serviceName: tomcat-svc servicePort: 80
查看结果
[root@k8s-master tls]# curl -I http://tomcat.ingress.com:30443 HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Content-Type: text/html;charset=UTF-8 Transfer-Encoding: chunked Date: Tue, 29 Jun 2021 07:30:43 GMT
Ingress 定义HTTPS
1、案例一
#生成私钥 openssl genrsa -out tls.key 2048 # 根据私钥生成tls证书,注意CN是域名的形式 openssl req -new -x509 -key tls.key -out tls.cert -days 360 -subj /CN=tomcat.ingress.com # 根据生成的key和cert创建secret kubectl create secret tls -n testing nginx-tls --cert=tls.cert --key=tls.key
修改 Ingress 规则
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: tomcat-ingress-tls namespace: testing annotations: kubernetes.io/ingress.class: "nginx" spec: tls: - hosts: - tomcat.ingress.com secretName: nginx-tls rules: - host: tomcat.ingress.com http: paths: - path: backend: serviceName: tomcat-svc servicePort: 80
2、案例二
刚刚创建的域名是www.opesn.com
,所以我直接用我的证书了,而且是可信任的撒,需要创建一个secret
来保存tls
证书信息,下面开始吧。
[root@k8s01 opesn]# ll total 8 -rw-r--r-- 1 root root 1675 Jun 1 16:38 2536473_www.opesn.com.key -rw-r--r-- 1 root root 3667 Jun 1 16:38 2536473_www.opesn.com.pem [root@k8s01 opesn]# kubectl create secret tls opesn.com --cert=2536473_www.opesn.com.pem --key=2536473_www.opesn.com.key secret/opesn.com created [root@k8s01 opesn]# kubectl get secrets opesn.com NAME TYPE DATA AGE opesn.com kubernetes.io/tls 2 16s [root@k8s01 opesn]#
这就创建完了,在secrets
里也阔以看到了,有两个数字信息,下面编写一下Ingress
规则。
[root@k8s01 yml]# cat ingress_ssl.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: www.opesn.com-ssl spec: tls: - hosts: - www.opesn.com secretName: opesn.com rules: - host: www.opesn.com http: paths: - path: / backend: serviceName: nginx-service servicePort: 80
注意一下tls
那里的配置,别的就和上面一样了,在创建之前先把之前的删了,
[root@k8s01 yml]# kubectl create -f ingress_ssl.yaml ingress.extensions/www.opesn.com-ssl created [root@k8s01 yml]# kubectl get ingresses.extensions NAME HOSTS ADDRESS PORTS AGE www.opesn.com-ssl www.opesn.com 80, 443 2m54s [root@k8s01 yml]# [root@k8s01 yml]# curl -I www.opesn.com HTTP/1.1 308 Permanent Redirect Server: nginx/1.17.8 Date: Mon, 01 Jun 2020 08:52:34 GMT Content-Type: text/html Content-Length: 171 Connection: keep-alive Location: https://www.opesn.com/ [root@k8s01 yml]# curl -I https://www.opesn.com HTTP/1.1 200 OK Server: nginx/1.17.8 Date: Mon, 01 Jun 2020 08:49:35 GMT Content-Type: text/html Content-Length: 612 Connection: keep-alive Vary: Accept-Encoding Last-Modified: Tue, 14 Apr 2020 14:19:26 GMT ETag: "5e95c66e-264" Accept-Ranges: bytes Strict-Transport-Security: max-age=15724800; includeSubDomains [root@k8s01 yml]#
可以看到以非https
方式访问他帮你重定向到https
了,重定向状态码为308
,事实证明没问题,如果你的证书是自签的,使用curl -k
参数可以忽略证书问题,如果证书指定错了,k8s
就是用默认的证书了。