Ingress详解

Posted 我的紫霞辣辣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ingress详解相关的知识,希望对你有一定的参考价值。

Ingress介绍

K8S Ingress官方文档

在前面课程中已经提到,Service对集群之外暴露服务的主要方式有两种:NotePort 和 LoadBalancer,但是这两种方式,都有一定的缺点:

  • NodePort方式的缺点是会占用很多集群机器(物理主机)的端口,那么当集群服务变多的时候,这个缺点就愈发明显

  • LB方式的缺点是每个service需要一个LB(负载均衡),浪费、麻烦,并且需要kubernetes之外设备的支持

基于这种现状,kubernetes提供了Ingress资源对象,Ingress只需要一个NodePort或者一个LB就可以满足暴露多个Service的需求。
工作机制大致如下图表示:

实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:

  • ingress:kubernetes中的一个对象,作用是定义请求如何转发到service的规则

  • ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx,Contour,Haproxy等等

Ingress(以Nginx为例)的工作原理如下:

  1. 用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service

  2. Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置

  3. Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新

  4. 到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则

Ingress使用

环境准备

搭建ingress环境

# 创建文件夹
[root@k8s-master-01 ~]# mkdir ingress-controller
[root@k8s-master-01 ~]# cd ingress-controller/

# 获取ingress-nginx,本次案例使用的是0.30版本
[root@k8s-master-01 ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml

[root@k8s-master-01 ingress-controller]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

# 查看当前目录下载的yaml文件
[root@k8s-master-01 ingress-controller]# ls
mandatory.yaml  service-nodeport.yaml

# 创建ingress-nginx
[root@k8s-master-01 ingress-controller]# kubectl apply -f ./
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created
service/ingress-nginx created

# 查看nginx-ingress-controller控制器
[root@k8s-master-01 ingress-controller]# kubectl get pod -n ingress-nginx
NAME                                        READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-65886f4f5d-fzwrs   1/1     Running   0          6m43s

# 查看service规则
[root@k8s-master-01 ingress-controller]# kubectl get svc -n ingress-nginx
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx   NodePort   10.111.148.140   <none>        80:31949/TCP,443:32400/TCP   7m15s

准备service和pod

为了后面的实验比较方便,创建如下图所示的模型

创建tomcat-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deploymeny
  namespace: dev
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat-pod
  template:
    metadata:
      labels:
        app: tomcat-pod
    spec:
      containers:
        - name: tomcat
          image: tomcat:8.5-jre10-slim
          ports:
            - containerPort: 8080
            
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: dev
spec:
  selector:
    app: nginx-pod
  clusterIP: None
  type: ClusterIP
  ports:
    - port: 80      # service端口
      targetPort: 80    # pod端口

---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  namespace: dev
spec:
  selector:
    app: tomcat-pod
  clusterIP: None
  type: ClusterIP
  ports:
    - port: 8080    # service端口
      targetPort: 8080   # pod端口
# 创建
[root@k8s-master-01 ~]# kubectl create -f tomcat-nginx.yaml 

# 查看
[root@k8s-master-01 ~]# kubectl get svc -n dev
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
nginx-service    ClusterIP   None         <none>        80/TCP     103s
tomcat-service   ClusterIP   None         <none>        8080/TCP   103s

Http代理

创建ingress-http.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-http
  namespace: dev
spec:
  rules:
    - host: nginx.nana.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 80
    - host: tomcat.nana.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tomcat-service
                port:
                  number: 8080
# 创建
[root@k8s-master-01 ~]#  kubectl apply -f ingress-http.yaml
ingress.networking.k8s.io/ingress-http created

# 查看
[root@k8s-master-01 ~]# kubectl get ing ingress-http -n dev
NAME           CLASS    HOSTS                            ADDRESS          PORTS   AGE
ingress-http   <none>   nginx.nana.com,tomcat.nana.com   10.111.148.140   80      49s

# 查看详情
[root@k8s-master-01 ~]# kubectl describe ing ingress-http -n dev
Name:             ingress-http
Namespace:        dev
Address:          10.111.148.140
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host             Path  Backends
  ----             ----  --------
  nginx.nana.com   
                   /   nginx-service:80 (10.244.1.10:80,10.244.2.5:80,10.244.2.6:80)
  tomcat.nana.com  
                   /   tomcat-service:8080 (10.244.1.11:8080,10.244.1.9:8080,10.244.2.7:8080)
Annotations:       <none>
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  113s  nginx-ingress-controller  Ingress dev/ingress-http
  Normal  UPDATE  84s   nginx-ingress-controller  Ingress dev/ingress-http
[root@k8s-master-01 ~]# kubectl describe ing ingress-http -n dev
Name:             ingress-http
Namespace:        dev
Address:          10.111.148.140
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host             Path  Backends
  ----             ----  --------
  nginx.nana.com   
                   /   nginx-service:80 (10.244.1.10:80,10.244.2.5:80,10.244.2.6:80)
  tomcat.nana.com  
                   /   tomcat-service:8080 (10.244.1.11:8080,10.244.1.9:8080,10.244.2.7:8080)
Annotations:       <none>
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  2m1s  nginx-ingress-controller  Ingress dev/ingress-http
  Normal  UPDATE  92s   nginx-ingress-controller  Ingress dev/ingress-http

# 测试
在本机添加域名解析
C:\\Windows\\System32\\drivers\\etc
在hosts文件添加域名解析(master主机的iP地址)
192.168.15.11 		nginx.nana.com,tomcat.nana.com 	

# 在本机浏览器输入:
http://nginx.nana.com:31949/
http://tomcat.nana.com:31949/

Https代理

创建证书

# 生成证书
[root@k8s-master-01 ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=itheima.com"
Generating a 2048 bit RSA private key
................................................................................+++
..........................+++
writing new private key to 'tls.key'
-----

# 创建密钥
[root@k8s-master-01 ~]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created

创建ingress-https.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-https
  namespace: dev
spec:
  tls:
    - hosts:
        - nginx.nana.com
        - tomcat.nana.com
      secretName: tls-secret    # 指定密钥
  rules:
    - host: nginx.nana.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx-service
                port:
                  number: 80
    - host: tomcat.nana.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tomcat-service
                port:
                  number: 8080
# 创建
[root@k8s-master-01 ~]# kubectl create -f ingress-https.yaml 
ingress.networking.k8s.io/ingress-https created

# 查看
[root@k8s-master-01 ~]# kubectl get ing ingress-https -n dev
NAME            CLASS    HOSTS                            ADDRESS   PORTS     AGE
ingress-https   <none>   nginx.nana.com,tomcat.nana.com             80, 443   45s

# 查看详情
[root@k8s-master-01 ~]# kubectl describe ing ingress-https -n dev
Name:             ingress-https
Namespace:        dev
Address:          10.111.148.140
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  tls-secret terminates nginx.nana.com,tomcat.nana.com
Rules:
  Host             Path  Backends
  ----             ----  --------
  nginx.nana.com   
                   /   nginx-service:80 (10.244.1.10:80,10.244.2.5:80,10.244.2.6:80)
  tomcat.nana.com  
                   /   tomcat-service:8080 (10.244.1.11:8080,10.244.1.9:8080,10.244.2.7:8080)
Annotations:       <none>
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  65s   nginx-ingress-controller  Ingress dev/ingress-https
  Normal  UPDATE  7s    nginx-ingress-controller  Ingress dev/ingress-https

# 在本机浏览器输入:
https://nginx.nana.com:32400/
https://tomcat.nana.com:32400/

以上是关于Ingress详解的主要内容,如果未能解决你的问题,请参考以下文章

ingress详解

Kubernetes-Ingress资源详解

k8s 实践经验ingress 详解

K8S系列第十三讲:Ingress详解

Kubernetes Service与Ingress详解

详解 Rainbond Ingress 泛解析域名机制