1.Ingress介绍

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

  • NodePort方式的缺点是会占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就愈发明显
  • LB方式的缺点是每个service需要一个LB,浪费、麻烦,并且需要kubernetes之外设备的支持

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

img

实际上,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了,内部配置了用户定义的请求转发规则

img

1.1环境准备 搭建Ingress环境

#下载yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

#编辑Yaml
mv deploy.yaml  ingress-deploy.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-3.10.1
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.41.2
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: NodePort
  externalIPs: [192.168.10.105]
  ports:
  
  #修改镜像的地址为
registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller
[root@master1 ingress]# kubectl apply -f ingress-deployment.yaml

[root@master ingress]# kubectl get pods -n ingress-nginx 
NAME                                       READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-9tmlz       0/1     Completed   0          2m9s
ingress-nginx-admission-patch-x2zp5        0/1     Completed   0          2m9s
ingress-nginx-controller-f57c5b4d9-f7kpv   1/1     Running     0          2m9s

[root@master ingress]# kubectl get svc -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.107.219.36    192.168.10.105   80:30474/TCP,443:31446/TCP   3m13s
ingress-nginx-controller-admission   ClusterIP      10.104.236.117   <none>           443/TCP                      3m13s

1.2准备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-deployment
  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
  type: ClusterIP
  ports:
  - port: 80
    targetPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  namespace: dev
spec:
  selector:
    app: tomcat-pod
  type: ClusterIP
  ports:
  - port: 8080
    targetPort: 8080

[root@master ingress]# kubectl apply -f tomcat-nginx.yaml 
deployment.apps/nginx-deployment created
deployment.apps/tomcat-deployment created
service/nginx-service created
service/tomcat-service created

[root@master ingress]# kubectl get svc -n dev
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
nginx-service    ClusterIP   10.106.139.23    <none>        80/TCP     30m
tomcat-service   ClusterIP   10.102.242.180   <none>        8080/TCP   30m

1.3创建ingress

ingress资源规范

apiVersion: networking.k8s.io/v1 #资源所属的API群组和版本
kind: Ingress	#资源类型标识符
metadata:
  name: myingress #资源名称
  labels:
    name: myingress
  annotations: #资源注解  v1beta1 使用下面的注解来指定要解析该资源的控制器类型
  	kubernetes.io/ingress.class: <string> #适配的Ingress控制器类别
  namespace: #名称空间	
spec:
  rules: <[]Object> #Ingress规则表
  - host: <String> #虚拟主机的FQDN,支持"*"前缀匹配,不支持IP,不支持指定端口
    http:
      paths: <[]Object> #虚拟主机path定义的列表,由path和backend组成
      - pathType: <string> #匹配机制,支持Exact、Prefix和ImplementationSpecific
        path: "/" #流量匹配的http PATH,必须以/开头,相当于nginx
        backend: #匹配到的流量转发到的目标后端
          service:
            name: #引用的service的资源名称
            port: 
              number: #service用于提供服务的端口
    tls:
    - hosts: <[]string> #使用同一组证书和私钥信息的主机名称列表
      secretName: <String> #用于保存证书和私钥的secret资源名称
    backend:  <Object> #默认backend的定义,可嵌套字段以及使用格式跟rules字段中的相同
    ingressClassName: <String> #Ingress类名称,用于指定适配的控制器         

创建ingress-http.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: dev
  name: ingress-demo
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: www.nginx.it
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: nginx-service
            port: 
              number: 80
  - host: www.tomcat.it
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: tomcat-service
            port:
              number: 8080
[root@master ingress]# kubectl apply -f ingress-http.yaml 
ingress.networking.k8s.io/ingress-demo configured

[root@master ingress]# kubectl get ingress -n dev
NAME           CLASS    HOSTS                        ADDRESS          PORTS   AGE
ingress-demo   <none>   www.nginx.it,www.tomcat.it   192.168.10.105   80      2m29s

#访问测试:
[root@master ingress]# curl -H "Host: www.nginx.it" 192.168.10.105
[root@master ingress]# curl -H "Host: www.tomcat.it" 192.168.10.105

1.4路径匹配规则

#修改path路径为/test

spec:
  rules:
  - host: www.nginx.it
    http:
      paths:
      - pathType: Prefix
        path: "/test"
        backend:
          service:
            name: nginx-service
            port: 
              number: 80
#访问测试
[root@master ingress]# curl www.nginx.it/test

#查看日志
[root@master ingress]# kubectl logs nginx-deployment-5cb65f68db-7kqqs -f -n dev
10.244.2.70 - - [12/Jan/2024:08:51:33 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "10.244.0.0"
10.244.2.70 - - [12/Jan/2024:08:58:11 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "10.244.0.0"
2024/01/12 09:12:44 [error] 7#7: *3 open() "/usr/share/nginx/html/test" failed (2: No such file or directory), client: 10.244.2.70, server: localhost, request: "GET /test HTTP/1.1", host: "www.nginx.it"

#会带上匹配的路径,但是我们不需要他加上这个路径。在yaml文件中配置
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: / #重写为/


#此时可以正常访问
[root@master ingress]# curl www.nginx.it/test
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐