为什么需要 Ingress

一个重要的原因是每个 LoadBalancer 服务都需要自己的带有公有 IP 地址的负载均衡器, 而 Ingress 只需要一个公网 IP 就能为许多服务提供访问。 当客户端向 Ingress 发送 HTTP 请求时, Ingress 会根据请求的host和path决定请求转发到的服务, 如图5.9所示。
image.png

Ingress 在网络栈的应用层 (HTTP) 操作, 并且可以提供一些服务不能实现的功能, 诸如基于cookie 的会话亲和性 (session affinity) 等功能。

Ingress 控制器是必不可少的

只有Ingress控制器(比如Nginx)在集群中运行,Ingress 资源才能正常工作。 不同的 Kubernetes 环境使用不同的控制器实现, 但有些并不提供默认控制器。

5.4.1 创建 Ingress 资源

image.png

定义了一个单一规则(rule)的 Ingress ,确保 Ingress 控制器收到的所有对主机kubia.example.com的HTTP请求,将被发送到kubia-nodeport服务的端口80上。

注意:云供应商的 Ingress 控制器(例如 GKE )要求 Ingress 指向一个 NodePort服务。 但Kuberetes 并没有这样的要求。

  1. cd /root/k8s/
  2. kubectl create -f kubia-rc.yaml
  3. kubectl create -f kubia-svc-nodeport.yaml
  4. cat >kubia-ingress.yaml <<'EOF'
  5. apiVersion: networking.k8s.io/v1 #K8S 1.21版本
  6. kind: Ingress
  7. metadata:
  8. name: kubia
  9. spec:
  10. rules:
  11. - host: kubia.example.com
  12. http:
  13. paths:
  14. - path: /
  15. pathType: Prefix
  16. backend:
  17. service:
  18. name: kubia-nodeport
  19. port:
  20. number: 80
  21. EOF
  22. kubectl create -f kubia-ingress.yaml

image.png

5.4.2 通过 Ingress 访问服务

获取 Ingress(控制器) 的 IP 地址

image.png

注意:在云提供商的环境上运行时,地址可能需要一段时间才能显示,因为Ingress控制器在幕后调配负载均衡器。

确保在 Ingress 中配置的 Host 指向 Ingress 的 IP 地址

echo ‘192.168.99.100 kubia.example.com’ >>/etc/hosts

通过 Ingress 访问 pod

image.png

了解 Ingress 的工作原理

图5.1显示了客户端如何通过Ingress控制器连接到其中一个pod:
客户端首先对kubia.example.com执行DNS查询,DNS服务器(或本地操作系统)返回Ingress控制器的IP地址。客户端然后向Ingress控制器发送HTTP请求,并在Host首部字段中指定kubia.example.com。控制器从该首部字段确定客户端尝试访问哪个service,通过与该服务关联的Endpoints对象查看pod IP,并将客户端的请求转发给其中一个pod。

如你所见,Ingress控制器不会将请求转发给服务,只用它来选择pod。大多数(即使不是全部)控制器都是这样工作的。
image.png

5.4.3 通过相同的 Ingress 暴露多个服务

不同的服务映射到相同host的不同path

image.png

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. name: kubia
  5. spec:
  6. rules:
  7. - host: kubia.example.com
  8. http:
  9. paths:
  10. - path: /kubia
  11. pathType: Prefix
  12. backend:
  13. service:
  14. name: kubia
  15. port:
  16. number: 80
  17. - path: /foo
  18. pathType: Prefix
  19. backend:
  20. service:
  21. name: bar
  22. port:
  23. number: 80

根据请求的URL中的path,请求将发送到两个不同的服务。

不同的服务映射到不同的host

image.png

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia
spec:
  rules:
  - host: foo.example.com
    http:
      paths:     
      - path: /
        pathType: Prefix
        backend:
          service:
            name: foo
            port: 
              number: 80
  - host: bar.example.com
    http:
      paths: 
      - path: /
        pathType: Prefix
        backend:
          service: 
            name: bar
            port: 
              number: 80

根据请求中的 Host 头(虚拟主机在网络服务器中处理的方式),控制器收到的请求将被转发到 foo 服务或 bar 服务,DNS 需要将 foo.example.com 和 bar.example.com 域名都指向 Ingress 控制器的 IP 地址。

5.4.4 配置 Ingress 处理 TLS 传输

为Ingress 创建 TLS 认证

客户端和控制器之间的通信是加密的,而控制器和后端 pod 之间的通信不加密 。运行在 pod 上的应用程序不需要支持 TLS。
客户端 --(加密)--> Ingress控制器 --(不加密)--> pod
例如,如果 pod 运行 web服务器,则它只能接收HTTP 通信,并让 Ingress 控制器负责处理与 TLS 关的所有内容。
要使控制器能够这样做,需要将证书和私钥附加到 Ingress。这两个必需资源存储在称为Secret的Kubernetes资源中,然后在Ingress manifest中引用它。

#首先,需要创建私钥和证书:
openssl genrsa -out tls.key 2048
openssl req -new -x509 -key tls.key -out tls.cert -days 360 -subj /CN=kubia.example.com

#创建一个TLS Secret资源,名称为tls-secret,存储这两个文件
kubectl create secret tls tls-secret --cert=tls.cert --key=tls.key
kubectl get secret

cat >kubia-ingress-tls.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubia
spec:
  tls:
  - hosts: 
    - kubia.example.com
    secretName: tls-secret
  rules:
  - host: kubia.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubia-nodeport
            port: 
              number: 80
EOF

#使用kubectl apply更新Ingress资源kubia,不需要删除并重新创建
kubectl apply -f kubia-ingress-tls.yaml

image.png
image.png
image.png

通过 CertificateSigningRequest 资源签署证书

可以不通过自己签署证书,而是通过创建 CertificateSigningRequest(CSR)资源来签署。用户或他们的应用程序可以创建一个常规证书请求,将其放入 CSR 中,然后由人工操作员或自动化程序批准请求,像这样: $ kubectl certificate approve <name of the CSR> 然后可以从 CSR 的 status.certificate 字段中检索签名的证书。 请注意,证书签署者组件必须在集群中运行,否则创建 CertificateSigningRequest 以及批准或拒绝将不起作用。

使用 HTTPS 通过 Ingress 访问服务

image.png
image.png
注意:虽然ingress开放了80端口,但是无法正常访问后端pod上的应用。

虽然目前(2018年)仅支持 L7 (网络第7层) ( HTTP I HTTPS )负载平衡,但也计划支持 L4 (网络第4层)负载平衡。