六、Ingress详解


Ingress为弥补NodePort不足而生
  NodePort存在的缺点
    一个端口只能一个服务使用,端口需要提前规划
    只支持四层负载均衡
 
Pod与Ingress的关系 
  通过service相关联
  通过Ingress Controller实现Pod的负载均衡
  支持TCP/UDP 4层和HTTP 7层
 
部署Ingress-controller
kubectl apply -f Ingress-controller.yaml
可通过kubectl get pods -n ingress-nginx命令查看是否部署成功
 
部署完之后要定义Ingress.yaml规则文件用来连接service,通过kubectl apply -f ingress.yaml 部署规则文件,通过kubectl get ingress可查看,HOSTS就是用户浏览器需要输入的域名(我们自己测试可以更改windos机器的hosts),通过这个域名分配到不同的项目中
 
 
Ingress-controller高可用方案
如果有几百台机器,每一台都部署Ingress-controller的话就没必要,可以选用一些专门部署Ingress-controller的node节点,利用nodeslector(标签)+污点+deamonset的方式将Ingress-controller精确的分部到这几台node节点上,然后通过一个LB(可以是nginx)将请求转发到这几台机器上
 
 
Ingress的Ingress.yaml规则文件
ingress与service要在同一命名空间下,不支持跨命名空间
Ingress.yaml是用来定义转发规则的,Ingress-controller.yaml是根据转发规则来转发至service
实际上Ingress就是获取service连接的pod的IP,然后自动把IP填充到nginx配置文件的server段中,通过这个实现负载均衡,我们可以通过node进入Ingress-controller的容器,去查看nginx.conf这个文件
# 普通http的ingress.yaml文件
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
   # 指定主机
  - host: example.ctnrs.com
    http:
      paths:
      # 指定路径
      - path: /
        backend:
          # 通过kubectl get svc查询到的servicename 
          serviceName: web
          # 通过kubectl get svc查询到的前面的端口
          servicePort: 80

-----------------------------------------------------------------------
# 支持https的ingress.yaml文件
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  # 增加以下四行
  tls:
  - hosts:
      # 域名
    - example.ctnrs.com
    # 执行kubectl create secret命令时候的部分
    secretName: example-ctnrs-com
  rules:
    - host: sslexample.ctnrs.com
      http:
        paths:
        - path: /
          backend:
            serviceName: web
            servicePort: 80

-----------------------------------------------------------------------
# 可根据URL路由跳转不通服务的ingress.yaml文件,比如有的服务是nginx,有的是tomcat
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
  # 注解
  annotations:
    # 重定向目标到根
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
   # 域名
  - host: foobar.ctnrs.com
    http:
      paths:
      # 如果路径是/foo,则跳转到nginx1这个服务
      - path: /foo
        backend:
          serviceName: nginx1
          servicePort: 80
  - host: foobar.ctnrs.com
    http:
      paths:
      # 如果路径是/bar,则跳转到tomcat1这个服务
      - path: /bar
        backend:
          serviceName: tomcat1
          servicePort: 80

-----------------------------------------------------------------------
# 同一个ingress可以有多个域名,不同的域名都可以进行访问
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
   # 域名1
  - host: foo.ctnrs.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
    # 域名2
  - host: bar.ctnrs.com
    http:
      paths:
      - backend:
          serviceName: service2
          servicePort: 80

-----------------------------------------------------------------------


apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  # 通过注解设置超时nginx时间,很多nginx相关配置可通过注解来设置,具体要看官方文档
  annotations:
     kubernetes.io/ingress.class: "nginx“
     nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
     nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
     nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
     nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  rules:
  - host: example.ctnrs.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web
          servicePort: 80

-----------------------------------------------------------------------
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    # 如果不想跳转到https,设置成false即可
    nginx.ingress.kubernetes.io/ssl-redirect: 'false'
spec:
  tls:
  - hosts:
    - sslexample.ctnrs.com
    secretName: secret-tls
  rules:
    - host: sslexample.ctnrs.com
      http:
        paths:
        - path: /
          backend:
            serviceName: web
            servicePort: 80

 

Ingress的Ingress-controller.yaml文件内容
多个node之间不共享ingress,可以将Ingress-controller控制器更改成daemonset
# 创建命名空间
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: apps/v1
# 在每台node节点上都部署上ingress-nginx
kind: DaemonSet 
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  selector:
    matchLabels:
      # 标签
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
       # hostNetwork表示使用宿主机网络
      hostNetwork: true
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          # 国内镜像地址
          image: lizhenliang/nginx-ingress-controller:0.20.0 
          # 启动镜像的参数
          args:
            - /nginx-ingress-controller
            # 使用下面的变量设置命名空间
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            # 定义四层相关配置
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            # 暴露的service
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            # 注解前缀,当集群部署多个Ingress-controller时,通过注解前缀区分应用到哪个控制器上
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 33
            runAsUser: 33
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
             # 设置变量
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
            - name: https
              containerPort: 443
          # 健康检查
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10

---
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
spec:
  #type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP
  - name: https
    port: 443
    targetPort: 443
    protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

 

外部流量进集群POD是怎么被转发的?
画图说明,比如用到了3个边缘节点,流量从LB进来,然后被转发到其中一个ingress controller的pod里面,并根据svc规则转发到svc对应的后端endpoint上(对应app pod),其中ingress controller是运行在某个ingress controller pod里面,直接watch API SERVER里面ingress规则的变更,这里就已经不需要ingress-nginx的svc了(不过一般还需要配置下,否则集群会一直提示err services "ingress-nginx" not found)

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM