Kubernetes学习指南(四)--创建对外服务的HTTP和HTTPS路由

565 阅读3分钟

Kubernetes学习指南(四)--创建对外服务的HTTP和HTTPS路由 Nginx-Ingress

Ingress 公开了从集群外部到集群内ServicesHTTPHTTPS路由,访问流量路由由Ingress资源上定义的规则控制。


Ingress: HTTP 7层路由机制

使用Ingress进行负载均衡时,Ingress Controller将基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint(即Pod)上,这样会跳过kube-proxy的转发功能.

如果Ingress Controller提供的是对外服务,则实际上实现的就是边缘路由器(边缘路由器是在网络的边界点用于与其他网络(例如Intemet)相连接的路由器)的功能.

    Internet
        |
   [ mywebsite.com (Ingress Controller) ]
   -----------|-----------|------------|
   /api       /web        /cmd
   |          |           |
   |          |           |
   ↓          ↓           ↓
[  API        WEB         CMD           ]
  • http://mywebsite.com/api的访问将被路由到后端APIService
  • http://mywebsite.com/web的访问将被路由到后端WEBService
  • http://mywebsite.com/cmd的访问将被路由到后端CMDService

创建Ingress Controller

环境准备

开始之前先明确机器所处环境,如果是在GCE,Azure,AWS等云服务提供商,可以直接使用云服务提供商的LoadBalancer,具体可以参考此链接.

以下例子是基于裸机(公网IP + 内网互联)组成,使用谷歌提供的Nginx-ingress-controller来创建Ingress Controller

Ingress Controller服务

Kubernetes中,Ingress Controller将以Pod的形式运行,监控ApiserverIngress接口,如果Service有发生CRUD,则Ingress Controller自动更新转发规则.

实现的基本逻辑如下:

  • 创建相对应权限的Role,监听Apiserver,获取全部Ingress的定义
  • 基于Ingress的定义,生成Nginx所需的配置文件/etc/nginx/nginx.conf
  • 执行nginx -s reload命令,重新加载nginx.conf配置文件的内容

本例使用谷歌提供的NGINX Ingress Controller 镜像来创建Ingress ControllerIngress ControllerDaemonset的形式进行创建,在每个Node上都创建一个Nginx服务,用来监听HTTP(80) HTTPS(443) 注:如果你的网络域有云厂商提供的负载均衡,请参考 https://kubernetes.github.io/ingress-nginx/deploy/ 中不同厂商的特定步骤

创建Nginx Ingress Controller

下载部署文件

wget -O nginx-ingress-controller.yaml https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.29.0/deploy/static/mandatory.yaml

## 或者直接下载修改完成的部署文件
wget -O nginx-ingress-controller.yaml https://raw.githubusercontent.com/charSLee013/Kubernetes-learn/master/chapter04/nginx-ingress-controller.yaml

修改如下:

          args:
            ...
            ...
            - --default-backend-service=$(POD_NAMESPACE)/nginx-errors   ## 默认错误导向
            - --v=3   ## debug模式,仅在调试下使用
  • 默认的backend,用于在客户端访问的URL地址不存在时能返回一个正确应答404应发.
  • 开启debug模式 --v=3,只适用于开发环境
  • 注释了LimitRange的性能限制,增大性能上限

部署命令

# kubectl apply -f https://raw.githubusercontent.com/charSLee013/Kubernetes-learn/master/chapter04/nginx-ingress-controller.yaml

namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
daemonset.apps/nginx-ingress-controller created
service/ingress-nginx created
service/nginx-errors created
deployment.apps/nginx-errors created
验证服务是否正常工作
  • 检查nginx-ingressnginx-errors是否启动成功
# kubectl get daemonset -n ingress-nginx -o wide
NAME                       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE    CONTAINERS                 IMAGES                                                                  SELECTOR
nginx-ingress-controller   3         3         3       3            3           <none>          4m4s   nginx-ingress-controller   quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.2   app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx

READY数量应该为Node机器总数

  • 如果有启动失败,可以通过Kubectl logs <POD_NAME>查看日志
#for p in `kubectl get pod -n ingress-nginx | grep "nginx-ingress-controller" | awk '{print $1}'`;do kubectl logs $p -n ingress-nginx;read -p "Enter Next Page" ;done;

...
...
I0216 21:39:18.514040       6 queue.go:122] skipping ingress-nginx/ingress-nginx sync (1581889155180651743 > 1581889128183115981)
I0216 21:39:18.514044       6 queue.go:122] skipping ingress-nginx/ingress-nginx sync (1581889155180651743 > 1581889131836726290)
I0216 21:39:18.514049       6 queue.go:122] skipping ingress-nginx/ingress-nginx sync (1581889155180651743 > 1581889132062227536)
Enter Next Page
  • curl访问任意Node80端口
#curl http://<外网IP地址>:80

<span>The page you're looking for could not be found.</span>

由于我们没有对 / 路径做任何转发规则,所以返回的default-bakcend-service(nginx-errors) 的应答

定义nginx-ingress域名路由转发策略

本例对mywebsite.com网站的访问设置Ingress策略,定义对其demo.mywebsite.com路径的转发到后端default/php-apache的规则

后端default/php-apache部署可以参考此文章

cat <<EOF > php-apache-ingress.yaml
# vi php-apache-ingress.yaml
---

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-simple
  namespace: default ## namespace必须跟转发后端处于同一个命名空间内
  annotations:
    kubernetes.io/ingress.class: "nginx"
    ## 将 /foo 重定向 成 /
    ## 默认情况下 demo.com/foo -> service/foo
    ## 重写后成为 demo.com/foo -> service/
    nginx.ingress.kubernetes.io/rewrite-target: /$1

    # 开启use-regex,启用path的正则匹配 
    # nginx.ingress.kubernetes.io/use-regex: "true"

spec:
  rules:
  - host: demo.mywebsite.com  ## 这里改成你的域名
    http:
      paths:
      - path: /
        backend:
          serviceName: "php-apache"
          servicePort: 80
EOF

kubectl apply -f php-apache-ingress.yaml

然后添加A记录指向Node机器的外网IP,我这里以cloudflare为例子

avatar

注意:要为所有的Node的机器添加A记录转发,有多台Node机器情况下可以根据实际情况做DNS负载

客户端访问http://demo.mywebsite.com

在客户端访问刚刚创建好的ingress策略

curl -I http://demo.mywebsite.com/

HTTP/1.1 200 OK
Date: Sun, 16 Feb 2020 23:41:35 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=d7de162fc1194de497afc9f33c02f2ce91581896495; expires=Tue, 17-Mar-20 23:41:35 GMT; path=/; domain=.mywebsite.com; HttpOnly; SameSite=Lax
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.14
CF-Cache-Status: DYNAMIC
Server: cloudflare
CF-RAY: 56635f8a0dfddd2e-SIN

HTTP路由设置成功,但由于我们没有设置TLS证书,当以HTTPS访问的时候会报错

如果域名是在cloudflare上管理的,可以在SSL/TLS功能内开启全网TLS加密功能

如图所示,一定要选择Full

avatar

一键安装nginx ingress

kubectl apply -f https://raw.githubusercontent.com/charSLee013/Kubernetes-learn/master/chapter04/nginx-ingress-controller.yaml

更多学习文章在点击访问