理解k8s 的 Ingress

暴露一个http服务的方式

service 是 k8s 暴露http服务的默认方式, 其中 NodePort 类型可以将http 服务暴露在宿主机的端口上,以便外部可以访问。 service模式的结构如下.


 

service -> label selector -> pods 
31217 -> app1 selector -> app1 1234
31218 -> app2 selector -> app2 3456
31218 -> app2 selector -> app2 4567

模式的优点

结构简单, 容易理解。

模式缺点

  1. 一个app 需要占用一个主机端口
  2. 端口缺乏管理
  3. L4转发, 无法根据http header 和 path 进行路由转发

Ingress 模式

在service 之前加了一层ingress,结构如下

            ingress -> service -> label selector -> pods
            www.app1.com -> app1-service -> app1 selector -> app1 1234
80   ->     www.app2.com -> app2-service -> app2 selector -> app2 3456
            www.app3.com -> app3-service -> app3 selector ->app3 4567

模式的优点

  1. 增加了7层的识别能力,可以根据 http header, path 进行路由转发

Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。

下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:

 
 

可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。

Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的服务。

 

理解Ingress 实现

Ingress 的实现分为两个部分 Ingress Controller 和 Ingress .

  1. Ingress Controller 是流量的入口,是一个实体软件, 一般是Nginx 和 Haproxy 。
  2. Ingress 描述具体的路由规则。

Ingress Controller 会监听 api server上的 /ingresses 资源 并实时生效。
Ingerss 描述了一个或者多个 域名的路由规则,以 ingress 资源的形式存在。

简单说: Ingress 描述路由规则, Ingress Controller 实时实现规则。

设计理念

k8s 有一个贯穿始终的设计理念,即需求和供给的分离。 Ingress Controller和 Ingress 的实现也很好的实践了这一点。 要理解k8s ,时刻记住 需求供给分离的设计理念。

在负载平衡器上处理多个应用

 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web2
  namespace: default
spec:
  selector:
    matchLabels:
      run: web2
  template:
    metadata:
      labels:
        run: web2
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: web2
        ports:
        - containerPort: 8087
          protocol: TCP
 
root@ubuntu:~# kubectl apply -f web-deployment-v2.yaml
deployment.apps/web2 created

root@ubuntu:~# kubectl get pods
NAME                             READY   STATUS             RESTARTS   AGE
kata-busybox                     1/1     Running            0          223d
kata-nginx                       1/1     Running            0          221d
my-deployment-68bdbbb5cc-bbszv   0/1     ImagePullBackOff   0          16d
my-deployment-68bdbbb5cc-nrst9   0/1     ImagePullBackOff   0          16d
my-deployment-68bdbbb5cc-rlgzt   0/1     ImagePullBackOff   0          16d
my-nginx-5dc4865748-jqx54        1/1     Running            2          16d
my-nginx-5dc4865748-pcrbg        1/1     Running            2          16d
nginx                            0/1     ImagePullBackOff   0          16d
web2-6d784f67bf-4gqq2            1/1     Running            0          33s
root@ubuntu:~# 

 NodePort Service 上的集群

 
apiVersion: v1
kind: Service
metadata:
  name: web2
  namespace: default
spec:
  ports:
  - port: 8097
    protocol: TCP
    targetPort: 8087
  selector:
    run: web2
  type: NodePort

 
root@ubuntu:~# kubectl apply -f web-service-v2.yaml
service/web2 created
root@ubuntu:~# kubectl get service -A
NAMESPACE     NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP                  223d
default       my-nginx      ClusterIP   10.110.79.116    <none>        8280/TCP                 16d
default       my-nginx-np   NodePort    10.99.1.231      <none>        8081:31199/TCP           15d
default       web2          NodePort    10.110.171.213   <none>        8097:31866/TCP           10s
kube-system   antrea        ClusterIP   10.108.137.187   <none>        443/TCP                  86m
kube-system   kube-dns      ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   223d
root@ubuntu:~# 

下面的清单描述了具备以下特点的 Ingress 资源:

  • 使用以 /v2/ 开头的路径将请求路由到 web2 Service
  • 将其他所有请求路由到 web Service
 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: fanout-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-nginx-np
          servicePort: 8081
      - path: /v2/*
        backend:
          serviceName: web2
          servicePort: 8097
root@ubuntu:~# kubectl create -f fanout-ingress.yaml
ingress.networking.k8s.io/fanout-ingress created
root@ubuntu:~# kubectl get service -A
NAMESPACE     NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP                  223d
default       my-nginx      ClusterIP   10.110.79.116    <none>        8280/TCP                 16d
default       my-nginx-np   NodePort    10.99.1.231      <none>        8081:31199/TCP           15d
default       web2          NodePort    10.110.171.213   <none>        8097:31866/TCP           2m54s
kube-system   antrea        ClusterIP   10.108.137.187   <none>        443/TCP                  89m
kube-system   kube-dns      ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP,9153/TCP   223d
root@ubuntu:~# iptables -t nat -nvL | grep 8097
    3   180 KUBE-MARK-MASQ  tcp  --  *      *      !10.244.0.0/16        10.110.171.213       /* default/web2: cluster IP */ tcp dpt:8097
    3   180 KUBE-SVC-7UGYW7HVUL5B72AK  tcp  --  *      *       0.0.0.0/0            10.110.171.213       /* default/web2: cluster IP */ tcp dpt:8097
root@ubuntu:~# 

 

 从47节点

root@cloud:~# curl  http://10.110.171.213:8097/ 
curl: (7) Failed to connect to 10.110.171.213 port 8097: Connection refused
root@cloud:~# curl  http://10.110.171.213:8097/v2 
curl: (7) Failed to connect to 10.110.171.213 port 8097: Connection refused
root@cloud:~# ip r | grep  10.110.171.213
10.110.171.213 via 10.10.16.82 dev enahisic2i0 
root@cloud:~# 

访问 

default       my-nginx-np   NodePort    10.99.1.231      <none>        8081:31199/TCP           15d
10.110.171.213 via 10.10.16.82 dev enahisic2i0 
root@cloud:~# telnet 10.99.1.231  8081
Trying 10.99.1.231...
Connected to 10.99.1.231.
Escape character is '^]'.
^CConnection closed by foreign host.
root@cloud:~# curl  http://telnet 10.99.1.231:8081/v2 
curl: (6) Could not resolve host: telnet
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.19.10</center>
</body>
</html>
root@cloud:~# curl  http://telnet 10.99.1.231:8081/
curl: (6) Could not resolve host: telnet
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
         35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@cloud:~# 

排查
root@ubuntu:~# kubectl get ingress fanout-ingress
NAME             CLASS    HOSTS   ADDRESS   PORTS   AGE
fanout-ingress   <none>   *                 80      8m11s
 
root@ubuntu:~# kubectl describe ingress  fanout-ingress
Name:             fanout-ingress
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host        Path  Backends
  ----        ----  --------
  *           
              /*      my-nginx-np:8081 (10.244.0.19:80,10.244.0.20:80)
              /v2/*   web2:8097 (10.244.0.2:8087)
Annotations:  <none>
Events:       <none>
root@ubuntu:~# 
 
 
 

 
原文地址:https://www.cnblogs.com/dream397/p/14822509.html