预备知识:

 

- k8s基本操作命令

- yaml文件格式

- linux基础操作(增加执行权限,移动文件,执行命令)

- 负载均衡和nat知识

 

之前我们已经创建好了存储卷,容器,服务,hpa,但是目前的项目还没有一个统一的ip可以对外网服务,这就是ingress要做到事情。

我们回忆一下,如果没有一个统一的入口,我们将要怎么处理k8s集群中的每一个服务呢,第一种想到的就是创建服务的时候,为每一个服务创建一个slb负载均衡器。阿里云的slb除了收取流量费用之外,还会收取实例费用,所以成本会有所提升。并且配置起来也比较麻烦。另外服务多了以后,管理维护都变得困难。ingress就是用来解决这些问题

什么是ingress

ingress(在kubernetes v1.1时添加)暴露从集群外到集群内服务的HTTP或HTTPS路由。定义在ingress资源上的规则控制流量的路由方式。

 

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

 

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

 

**题外话**:Ingress 控制器有各种类型,包括 Google Cloud Load Balancer, Nginx,Contour,Istio,等等。它还有各种插件,比如 cert-manager (它可以为你的服务自动提供 SSL 证书)/

 

ingress 如何解决问题

思考用现有知识解决问题:

采用 NodePort 方式暴露服务面临问题是,服务一旦多起来,NodePort 在每个节点上开启的端口会及其庞大,而且难以维护;这时,我们可以能否使用一个Nginx直接对内进行转发呢?我们知道,Pod与Pod之间是可以互相通信的,简单的猜测就是可以使用 DaemonSet 在每个 Node 开启一个pod,绑定一个service,监听node的80端口,然后写好规则,因为 Nginx 外面绑定了宿主机 80 端口(就像 NodePort),本身又在集群内,那么向后直接转发到相应 Service 就行了,如下图所示:

 

 

 

k8s ingress 设置 k8s创建ingress_阿里云k8s创建ingress

DaemonSet的作用

DaemonSet好比Kubernetes集群Node的守护进程,可以保证在每个Node上(或者一部分Node上)都运行同一个Pod且只运行一个。适用的场景主要是一些agent,如日志收集的agent、监控的agent等。

域名分配及动态更新问题

从上面的方法,采用 Nginx-Pod 似乎已经解决了问题,但是其实这里面有一个很大缺陷:当每次有新服务加入又该如何修改 Nginx 配置呢??我们知道使用Nginx可以通过虚拟主机域名进行区分不同的服务,而每个服务通过upstream进行定义不同的负载均衡池,在日常使用中只需要修改nginx.conf即可实现,那在K8S中又该如何实现这种方式的调度呢?此时 Ingress 出现了,Ingress 包含两大组件:Ingress Controller 和 Ingress。

  • ingress 简单的理解就是你原来需要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yaml 创建,每次不要去改 Nginx 了,直接改 yaml 然后创建/更新就行了;
  • Ingress Controller 这东西就是解决 “Nginx 的处理方式” 的;Ingress Controoler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下,工作流程如下图:

k8s ingress 设置 k8s创建ingress_k8s ingress_02

 

在云端,首先我们有一个外部的负载均衡器slb把请求调度到一个nodePort类型的Service(ingress-nginx)上,然后nodePort类型的Service(ingress-nginx)又把它调度到内部的叫做ingressController的Pod上,ingressCtroller根据ingress中的定义(虚拟主机还是URL),每一组主机名或者URL都对应后端的Service。

 

创建ingress

 

在阿里云上,ingressCtroller是默认创建好了的,对应的service也是创建好了的,我们只需要创建ingress(也就是对应的转发规则)就可以了

如果想要查看可以通过如下命令:

#查看kube-system命名空间中的pod 里面有  nginx-ingress-controller
kubectl get pod -n kube-system -o wide
#查看service
kubectl get svc -n kube-system
#查看nginx-ingress-lb service的描述
kubectl describe svc nginx-ingress-lb -n kube-system

 

创建ingress文件:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ebk-ing
spec:
  rules:
  - host: c.wap.cn
    http:
      paths:
      - path: /
        backend:
          serviceName: c-wap-svc
          servicePort: 80
  - host: b.api.cn
    http:
      paths:
      - path: /
        backend:
          serviceName: b-api-svc
          servicePort: 80

如上文件,分别创建了两个网站,c.wap.cn对应service:c-wap-svc。b.api.cn对应service:b-api-svc

创建命令:

kubectl apply -f ingress.yml