Ingress

概述


什么是Ingress

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

而 Ingress 就是为进入集群的请求提供路由规则的集合
Ingress_第2张图片

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

Ingress转发代理结构

常用的是使用Nginx Ingress控制器代理后端的Pod
Ingress_第3张图片

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

Ingress的组成部分

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

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

Ingress:为nginx创建虚拟主机

Ingress部署


下载yaml文件

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这一项,这样就无法让用户访问到。

安装Ingress

// 创建命名空间
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 

检查部署结果

如下表示部署成功:
这里写图片描述

Ingress测试

创建测试pod并发布

首先创建连个测试pod

kubectl run --image=httpd httpd
kubectl run --image=nginx nginx

Ingress_第4张图片

为两个pod创建service:

kubectl expose deployment nginx --port=80
kubectl expose deployment httpd --port=80

Ingress_第5张图片

分别修改两个pod的默认页面(这里过程略)。

从node节点访问测试

先从node节点通过cluster ip访问测试:
这里写图片描述

可能出现的问题:在一个node上只能访问到这个node上的pod,而访问不了其他node上的pod,解决办法是增加iptables规则:iptables -I FORWARD -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT

创建Ingress虚拟主机

创建一个Ingress虚拟主机,yaml文件如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: httpd-test
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: httpd
          servicePort: 80
  - host: bar.baz.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80

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

创建Ingress:

kubectl create -f http-ingress.yaml

查看创建的Ingress:

kubectl get ingress

这里写图片描述

可以看到Ingress已经绑定了两个虚拟主机。

通过域名访问

想要通过域名访问的话需要修改本机的hosts文件,首先查看下Ingress部署在了那个node节点上:
这里写图片描述

然后在本机的hosts文件中添加下面两条解析:

10.10.99.233 foo.bar.com
10.10.99.233 bar.baz.com

保存后就可以通过浏览器访问了:
Ingress_第6张图片
Ingress_第7张图片

Ingress-Controller的具体实现


部署好后,可以看到启动了一个nginx-ingress-controller的pod,其中运行有Ingress容器:
这里写图片描述

进入这个pod,使用ps查看具体运行的进程可以看到,其实是nginx做的负载均衡:
Ingress_第8张图片

在其中的nginx配置文件中(/etc/nginx/nginx.conf)的upstream段,可以看到代理的两个负载均衡段:
Ingress_第9张图片

这两个ip就是两个service endpoints的ip:
Ingress_第10张图片

Ingress控制器扩容


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

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

扩容到两个副本

看一下扩容情况:
这里写图片描述

成功扩容并且两个ingress分配在不同节点。

现在再修改hosts文件,制定域名为另一台node的ip:

10.10.99.228 foo.bar.com
10.10.99.228 bar.baz.com

也可以访问了。

Ingress通过TLS访问


创建CA

ca-csr.json:

{
    "CN": "MyName",
    "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"
                ]
            }
        }
    }
}

签证书:

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

创建server证书

server-csr.json:

{
    "CN": "www.mycompany.com",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Shenzhen",
            "ST": "Guangzhou"
        }
    ]
}

生成证书:

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 

查看下导入的证书:
这里写图片描述

创建https的yaml配置文件

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: https-test
spec:
  tls:
  - hosts:
    - www.mycompany.com
    secretName: ingress-https
  rules:
  - host: www.mycompany.com
    http:
      paths:
      - backend:
           serviceName: nginx
           servicePort: 80

创建https imgress:

kubectl create -f https-ingress.yaml

查看创建结果:
这里写图片描述

访问测试

首先修改hosts文件,指定成刚刚设置的虚拟主机的域名:

10.10.99.228 www.mycompany.com

然后在浏览器访问测试:
Ingress_第11张图片

你可能感兴趣的:(Kubernetes)