Ingress

一、     什么是Ingress

通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃。 

k8s ingress_ingress

而 Ingress 就是为进入集群的请求提供路由规则的集合 
k8s ingress_ingress_02

Ingress 可以给 service 提供集群外部访问的 URL、负载均衡、SSL 终止、HTTP 路由等。为了配置这些 Ingress 规则,集群管理员需要部署一个 Ingress controller,它监听 Ingress 和 service 的变化,并根据规则配置负载均衡并提供访问入口。

 

二、     Ingress代理结构

k8s ingress_ingress_03

用户的请求直接到达Ingress控制器,Ingress控制器是通过Nginx实现的负载均衡。Nginx通过关联的service名称获取到对应pod的ip(endpoint的ip)加入到Nginx的负载均衡中。

官方文档:https://github.com/kubernetes/ingress-nginx/tree/master/deploy

三、     Ingress组成部分

Nginx:实现负载均衡到pod的集合

Ingress Controller:从集群api获取services对应pod的ip到nginx配置文件中

Ingress:为nginx创建虚拟主机

四、     部署Ingress

下载ymal配置文件

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/default-backend.yaml

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/tcp-services-configmap.yaml

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/udp-services-configmap.yaml

如果启用了RBAC,那么还需要下面的两个:

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/rbac.yaml

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/with-rbac.yaml

 

修改镜像地址为国内镜像,国外的需要×××,网速你懂的。

default-backend.yaml

image: registry.cn-hangzhou.aliyuncs.com/google_containers/defaultbackend:1.4

 

with-rbac.yaml

image: lizhenliang/nginx-ingress-controller:0.9.0

添加hostNetwork: true在serviceAccountName: nginx-ingress-serviceaccount下边

默认官方下载的没有hostNetwork: true这一项,这样就无法让用户访问到,这是一个坑

 

开始安装

// 创建命名空间

kubectl create -f namespace.yaml

 

// 创建默认虚拟主机

kubectl create -f default-backend.yaml

kubectl get pod -n ingress-nginx

 

// 创建tcp和udp configmap

kubectl create -f tcp-services-configmap.yaml

kubectl create -f udp-services-configmap.yaml

 

// 创建rbac角色

kubectl create -f rbac.yaml

 

// 部署Ingress Controller

kubectl create -f with-rbac.yaml

 

查看是不是部署起来了

kubectl get pod  -n  ingress-nginx

k8s ingress_ingress_04

 

五、创建Ingress虚拟机

先创建两个测试的Pod,httpd和nginx

kubectl run --image=httpd httpd

kubectl run --image=nginx nginx

k8s ingress_k8s_05

为pod创建service发布服务:

kubectl expose deployment nginx --port=80

kubectl expose deployment httpd --port=80

k8s ingress_ingress_06

分别修改两个pod的默认页面,以后面的实验方便做准备

k8s ingress_k8s_07

 

在node节点上测试访问

k8s ingress_k8s_08

五、     创建ingress虚拟机

创建一个ymal文件 www-ingress.ymal

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: httpd-test

spec:

  rules:

  - host: www.httpd.com

    http:

      paths:

      - backend:

          serviceName: httpd

          servicePort: 80

  - host: www.nginx.com

    http:

      paths:

      - backend:

          serviceName: nginx

          servicePort: 80

 

serviceName指定了service的名称,servicePort指定了service的端口,并且都绑定了一个域名进行访问。

 

kubectl create -f www-ingress.ymal

kubectl get ingress

k8s ingress_ingress_09

Kubectl get pod –n ingress-nginx –o wide

k8s ingress_ingress_10

 

在本机hosts文件中添加如下解析:然后访问,如果成功,证明ingress虚拟机部署成功了。

192.168.117.50  www.httpd.com

192.168.117.50  www.nginx.com

 

六、     Ingress-Controller具体实现

我们已经部署成功了一个ingress虚拟机,那么它是怎么工作的呢?

kubectl get pod -n ingress-nginx -o wide

kubectl exec -ti nginx-ingress-controller-6f64dc8cfb-dbvxj -n ingress-nginx bash

我们使用上面的命令进入到ingress-nginx的控制器中去:

k8s ingress_k8s_11

k8s ingress_k8s_12

k8s ingress_k8s_13

可以看到,ingress使用nginx的upstream功能反向代理了node上的两个pod的endpoints ip和端口

 

七、     Ingress控制器扩容

现在的Ingress控制器只部署在了一个node节点上,这样的话无法通过访问另一个节点的ip来访问service,需要在扩容一个ingress:

kubectl scale --replicas=4  deploy/nginx-ingress-controller -n ingress-nginx

使用上面的命令扩容ingress为4个副本,这样可以保证我们4个Node节点上都有ingress控制器

k8s ingress_k8s_14

现在,我们把Host改成如下,然后去浏览器测试一下。

192.168.117.70  www.httpd.com

192.168.117.80  www.nginx.com

八、     配置Ingress通过TLS访问(Ingress https)

创建CA

ca-csr.json

{

    "CN": "yy",

    "key": {

        "algo": "rsa",

        "size": 2048

    },

    "names": [

        {

            "C": "CN",

            "L": "Shenzhen",

            "ST": "Guangzhou"

        }

    ]

}

 

ca-config.json

{

    "signing": {

        "default": {

            "expiry": "168h"

        },

        "profiles": {

            "www": {

                "expiry": "8760h",

                "usages": [

                    "signing",

                    "key encipherment",

                    "server auth"

                ]

            },

            "client": {

                "expiry": "8760h",

                "usages": [

                    "signing",

                    "key encipherment",

                    "client auth"

                ]

            }

        }

    }

}

 

server-csr.json

{

    "CN": "www.mycompany.com",

    "key": {

        "algo": "rsa",

        "size": 2048

    },

    "names": [

        {

            "C": "CN",

            "L": "Shenzhen",

            "ST": "Guangzhou"

        }

    ]

}

 

签发证书:

cfssl gencert --initca ca-csr.json | cfssljson -bare ca –

生成证书

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem --config=ca-config.json --profile=www server-csr.json | cfssljson -bare server

 

  将证书导入集群

  kubectl create secret tls ingress-https --key server-key.pem --cert server.pem

  kubectl get secret
  查看证书导入

k8s ingress_k8s_15

 

创建Https的ymal文件 https-ingress.ymal

apiVersion: extensions/v1beta1

kind: Ingress

metadata:

  name: https-test

spec:

  tls:

  - hosts:

    - www.yy.com

    secretName: ingress-https

  rules:

  - host: www.yy.com

    http:

      paths:

      - backend:

           serviceName: nginx

           servicePort: 80

 

kubectl create -f https-ingress.ymal

k8s ingress_k8s_16

浏览器访问,记得加Hosts,解析到任意的节点即可。

k8s ingress_k8s_17