作者: LemonNan

Ingress

在 Service 篇介绍的是基于4层网络进行的负载均衡, 四层网络转发不够灵活, 无法根据接口路径相关的信息进行路由转发, so, 今天介绍的就是基于 Ingress 的7层路由转发.



介绍

Ingress 是 K8s 中暴露服务的一种方式, 而暴露的服务要对外可用的话, 则需要 Ingress Controller 和 Ingress (负载均衡的规则). Ingress Controller 是一个负载均衡的控制器, 负责转发请求, 如果符合Ingress的配置规则则会被转发至对应的后端服务, 如果没有匹配规则或者规则对应的后端服务不存在, 则会被转发到 Ingress Controller 的默认后端上.



操作的基础

最近的文章都是基于 minikube 进行的操作, 所以时不时的需要进入到 minikube 里面进行一些操作的验证, 所以把进入 minikube 的操作记录在这.

# minikube 默认用户名:docker 密码:tcuser , 我的地址是 192.168.99.100
ssh docker@192.168.99.100



Ingress 的路径类型

  • ImplementationSpecific (默认): 对于这种类型,匹配取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 PrefixExact 类型作相同处理。
  • Exact:精确匹配 URL 路径,且对大小写敏感。
  • Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配对大小写敏感,并且对路径中的元素逐个完成。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。


使用

启动Ingress Controller

由于是在 minikube 的环境下, 所以只需要执行以下命令, 就可以启动一个 Ingress controller.

# 启动 ingress 控制器
minikube addons enable ingress
# 查看
kubectl get pods -n kube-system

查看的时候, 会有类似以下的输出, 倒数第二个就是 Ingress controller(第一次开启的时候, 天知道我等了多久才启动起来)

NAME                                        READY   STATUS    RESTARTS   AGE
coredns-d5947d4b-fsjhr                      1/1     Running   57         65d
coredns-d5947d4b-kqdfl                      1/1     Running   57         65d
default-http-backend-68449d5b4-wfxgl        1/1     Running   2          15h
etcd-minikube                               1/1     Running   31         65d
kube-addon-manager-minikube                 1/1     Running   32         65d
kube-apiserver-minikube                     1/1     Running   31         65d
kube-controller-manager-minikube            1/1     Running   29         58d
kube-proxy-z4qhh                            1/1     Running   31         65d
kube-scheduler-minikube                     1/1     Running   32         65d
kubernetes-dashboard-6bb54dcddd-c8ksr       1/1     Running   55         65d
nginx-ingress-controller-586cdc477c-txz8q   1/1     Running   1          15h
storage-provisioner                         1/1     Running   57         65d



配置 Ingress 规则

# Ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  rules:
  - http:
      paths:
      - path: /nginx    # nginx 开头的接口都被路由到 svc-nginx 下对应的pod
        backend:
          serviceName: svc-nginx
          servicePort: 80
      - path: /tomcat   # tomcat 开头的接口都被路由到 svc-tomcat 下对应的pod
        backend:
          serviceName: svc-tomcat
          servicePort: 80



创建 Service

nginx

创建 nginx pod 和 service

# nginx.yaml
apiVersion: v1          
kind: Pod               # 创建的是Pod类型
metadata:               # 元数据, 一些基础信息
  name: pod-nginx       # 名称
  labels:
    name: label-pod-nginx # 标签
spec:
  containers:
  - name: pod-nginx     # 容器名称
    image: nginx:latest # 使用的镜像
    ports:
    - containerPort: 80 # 容器监听的端口号
---
apiVersion: v1
kind: Service
metadata:
  name: svc-nginx
  namespace: default      # 命名空间,不填默认为 default
  labels:
    name: label-svc-nginx # service 的标签
  annotations:
    name: anno-nginx
spec:
  selector: 
    name : label-pod-nginx  # 管理具有 nginx 标签的 Pod 
  type: ClusterIP   # 不填默认 ClusterIP, 用于集群内部 Pod 访问, 在 Node 上 kube-proxy 通过设置的规则进行转发
  # clusterIP: 172.18.0.1 # 虚拟IP, type = ClusterIP 时, 可以不指定,不指定系统自动分发;
                        # type=LoadBalancer 时, 必须指定
  sessionAffinity:  ClientIP # 是否支持 session, 默认为空. 可选 ClientIP, 表示将同一个客户端(根据客户端IP决定)请求到一个 Pod 上
  ports:
  - name: p80       # 端口名称 
    protocol: TCP   # 协议
    port: 80      # service 对外暴露的端口
    targetPort: 80  # 后端 Pod 端口



tomcat

创建 tomcat pod 和 service, 注意这里tomcat的默认端口是 8080

apiVersion: v1          
kind: Pod               # 创建的是Pod类型
metadata:               # 元数据, 一些基础信息
  name: pod-tomcat       # 名称
  labels:
    name: label-pod-tomcat # 标签
spec:
  containers:
  - name: pod-tomcat     # 容器名称
    image: tomcat:latest # 使用的镜像
    ports:
    - containerPort: 80 # 容器监听的端口号
---
apiVersion: v1
kind: Service
metadata:
  name: svc-tomcat
  namespace: default      # 命名空间,不填默认为 default
  labels:
    name: label-svc-tomcat # service 的标签
  annotations:
    name: anno-tomcat
spec:
  selector: 
    name : label-pod-tomcat  # 管理具有 tomcat 标签的 Pod 
  type: ClusterIP   # 不填默认 ClusterIP, 用于集群内部 Pod 访问, 在 Node 上 kube-proxy 通过设置的规则进行转发
  # clusterIP: 172.18.0.1 # 虚拟IP, type = ClusterIP 时, 可以不指定,不指定系统自动分发;
                        # type=LoadBalancer 时, 必须指定
  sessionAffinity:  ClientIP # 是否支持 session, 默认为空. 可选 ClientIP, 表示将同一个客户端(根据客户端IP决定)请求到一个 Pod 上
  ports:
  - name: p80       # 端口名称 
    protocol: TCP   # 协议
    port: 80      # service 对外暴露的端口
    targetPort: 8080  # 后端 Pod 端口, tomcat 默认是 8080 端口



访问服务

curl

创建成功后, 开始通过 Ingress controller 访问服务.

使用 curl 进行访问, 这里加了参数 -L 和 -k .

-L 是为了让 Ingress controller 返回了重定向的 Http 状态码之后, 会再访问一次. 这里的话返回的状态码是 308(308 状态码表明目标资源被永久的移动到了一个新的 URI,任何未来对这个资源的引用都应该使用新的 URI, 并且原本的Http Method(比如Post) 不允许修改).

-k 表示不校验 Https 证书

Kubernetes ingress 应用配置 kubernetes ingress controller_linux


不加参数的话, 会出现下面的输出信息, 得到一个 308状态码并且不处理重定向

# curl 192.168.99.100/tomcat/xx
<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx/1.15.9</center>
</body>
</html>



浏览器

这里都是 404, 是因为对应路径下面都没有相应的服务提供.

nginx

Kubernetes ingress 应用配置 kubernetes ingress controller_linux_02



tomcat

Kubernetes ingress 应用配置 kubernetes ingress controller_nginx_03



根据请求域名路由

接下来开始修改配置文件, 使得能 根据请求域名路由到不同的后端服务 .

之前是在同一个域名下面, 根据接口路径进行路由, 这次是根据请求头中的域名进行路由, 不同域名路由到不同的后端服务上.

首先需要在 hosts 文件中添加两行:

192.168.99.100 tomcat.whn.com 192.168.99.100 nginx.whn.com

这里 Ingress name 跟之前是一样的, 所以需要先删掉之前的 ingress.

kubectl delete ingress test-ingress



创建新的 ingress

# Ingress-host.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  rules:
  - host: nginx.whn.com	# 浏览器的访问地址
    http:
      paths:
      - path: 
        backend:
          serviceName: svc-nginx
          servicePort: 80
  - host: tomcat.whn.com 	# 浏览器的访问地址
    http:
      paths:
      - path: /
        backend:
          serviceName: svc-tomcat
          servicePort: 80

接下来在浏览器通过 nginx.whn.comtomcat.whn.com 分别访问 后端的 nginx 服务和 tomcat 服务



访问 nginx

Kubernetes ingress 应用配置 kubernetes ingress controller_linux_04


访问 tomcat

tomcat这里的话, latest 是tomcat9, webapps 下默认是空的, 当时还确认了半天有没有配置错误, 后来才发现 webapps 下没有内容, 内容在另一个 webapps.dist 下 , 只需要把 webapps.dist 下的内容移到 webapps 或者直接改名文件夹, 再通过浏览器访问 tomcat.whn.com 就能访问到 tomcat 的首页.

Kubernetes ingress 应用配置 kubernetes ingress controller_nginx_05

最后

到此, 本篇想介绍的 Ingress 功能介绍完了, 目前还没想好后面写的内容.

话不多说

各位国庆玩得开心 ! !