kubernetes:部署Ingress Controller

kubernetes:部署Ingress Controller

大概分为三个部分

  • Pod与Ingress的关系
  • Ingress Controller
  • Ingress 实现HTTP与HTTPS

在上面接触到了NodePortLoadBalancer可以把应用暴露给外界进行访问,能感觉到需要提前规划端口,应用越来越多就会变得很麻烦,并且每个Service都会给你创建一个负载均衡,维护成本有点高,Ingress就是一个全局的负载均衡器,能提供统一的访问入口,他可以通过域名或URL将请求转发到不同的Service,他支持七层的负载均衡,而之前提到的那些都是四层的,Ingress是授权请求入站访问到集群的规则集合,具体的实现是由Ingress Controller来完成的,先了解一下PodIngress的关系。

Pod与Ingress的关系

Ingress是通过Service来关联Pod的,通过你指定的Service来绑定一组pod,通过Ingress Controller来实现Pod的负载均衡,Ingress只是定义了规则,负载均衡是由控制器(Controller)来完成的,他支持四层和七层的转发

Ingress Controller

具体帮你提供全局负载均衡,了解一下访问流程,用户会先访问Ingress控制器定义的规则,这个规则你可以理解为nginx配置文件写的各个虚拟主机,用户请求会先到达Ingress控制器,控制器是在node上运行的,然后再到具体的pod,我们用的是Ingress-nginx,这个官方维护的,其实还有很多,具体还有哪些可以看一下官方文档,下面部署一下Ingress-nginx

https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml

需要改两处,一处是镜像地址,默认的下载特别慢,慢到你无法想象,第二个就是要使用主机网络,所以我改了这些。

[root@k8s01 yml]# egrep -i  "image|hostNetwork" -C 1 mandatory.yaml 
    spec:
      hostNetwork: true
      # wait up to five minutes for the drain of connections
--
        - name: nginx-ingress-controller
          image: registry.cn-shenzhen.aliyuncs.com/google_containers_hw/nginx-ingress-controller:0.30.0
          args:

生产环境下建议指定一下服务约束,测试无所谓了

[root@k8s01 yml]# kubectl create -f mandatory.yaml 
[root@k8s01 yml]# kubectl get pods -n ingress-nginx
NAME                                      READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-775bfffd-22jmz   1/1     Running   0          95s
[root@k8s01 yml]# 

好了,运行状态,这个控制器就能帮你实现全局的负载均衡,下面开始定义Ingress的规则了

Ingress定义HTTP

想通过Ingress暴露你的服务你必须是使用域名的,这个就比较蛋疼了,像是我们这里暴露接口出去都是没有域名的,而且暴露端口出去的时候比较多,后期真的用K8S考虑加域名吧,下面是一个实例,直接在官网扒过来的,顺便改了改。

[root@k8s01 yml]# cat ingress_http.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: www.opesn.com
spec:
  rules:
  - host: www.opesn.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-service
          servicePort: 80
[root@k8s01 yml]# 

host那一行改成你的域名,serviceName也就是你要通过这个Ingress把哪个Service暴露出去,我写的就是nginx-service,我之前创建的,servicePort就是Service内部端口,也就是80,看一下这个Service

[root@k8s01 yml]# kubectl get service nginx-service 
NAME            TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
nginx-service   NodePort   10.0.0.169   <none>        80:30010/TCP   2d22h
[root@k8s01 yml]# 

直接创建

[root@k8s01 yml]# kubectl create -f ingress_http.yaml 
ingress.extensions/www.opesn.com created
[root@k8s01 yml]# kubectl get ingresses.extensions 
NAME            HOSTS           ADDRESS   PORTS   AGE
www.opesn.com   www.opesn.com             80      17s
[root@k8s01 yml]# 


[root@k8s01 yml]# echo '192.168.10.92 www.opesn.com' >>/etc/hosts
[root@k8s01 yml]# curl -I www.opesn.com
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Mon, 01 Jun 2020 08:32:50 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

[root@k8s01 yml]# 

说白了这就是一个nginx的容器,你操作Ingress控制器他就会创建相对应的upsteam配置,不过这个upstream地址池是动态的,配置不是写在文件里的,而是写在了内存里,原理就是这样,如果还有别的域名继续写配置文件创建规则就行了,下面看看https的。

Ingress 定义HTTPS

既然是https了,就需要有证书了,我刚刚创建的域名是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 delete -f ingress_http.yaml 
ingress.extensions "www.opesn.com" deleted
[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就是用默认的证书了。

总结一下Ingress支持四层七层负载均衡转发,支持自定义Service访问策略,支持TLS,但是只支持基于域名的网站访问,所以还是建议用这种方式去暴露你的服务

posted @ 2020-06-15 09:27  helloord  阅读(1724)  评论(0编辑  收藏  举报