K8S 发布资源方式之---- ingress详解(理论加案例)

前言

一 . ingress原理介绍

暴露service的三种方式ClusterIP、NodePort与LoadBalance,这几种方式都是在service的维度提供的,service的作用体现在两个方面,对集群内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制,对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。但是,单独用service暴露服务的方式,在实际生产环境中不太合适:
ClusterIP的方式只能在集群内部访问。
NodePort方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理是灾难。
LoadBalance方式受限于云平台,且通常在云平台部署ELB还需要额外的费用。

所幸k8s还提供了一种集群维度暴露服务的方式,也就是ingress。ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。
举个例子,现在集群有api、文件存储、前端3个service,可以通过一个ingress对象来实现图中的请求转发:
在这里插入图片描述

ingress与ingress-controller

要理解ingress,需要区分两个概念,ingress和ingress-controller:

ingress对象:
指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。
ingress-controller:
具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。

ingress-controller
ingress-controller并不是k8s自带的组件,实际上ingress-controller只是一个统称,用户可以选择不同的ingress-controller实现,目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,其他还有很多第三方维护的ingress-controller,具体可以参考官方文档。但是不管哪一种ingress-controller,实现的机制都大同小异,只是在具体配置上有差异。一般来说,ingress-controller的形式都是一个pod,里面跑着daemon程序和反向代理程序。daemon负责不断监控集群的变化,根据ingress对象生成配置并应用新配置到反向代理,比如nginx-ingress就是动态生成nginx配置,动态更新upstream,并在需要的时候reload程序应用新配置。为了方便,后面的例子都以k8s官方维护的nginx-ingress为例。

ingress
ingress是一个API对象,和其他对象一样,通过yaml文件来配置。ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS能力以及基于host的方向代理。ingress要依靠ingress-controller来具体实现以上功能。前一小节的图如果用ingress来表示,大概就是如下配置:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: abc-ingress
  annotations: 
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  tls:
  - hosts:
    - api.abc.com
    secretName: abc-tls
  rules:
  - host: api.abc.com
    http:
      paths:
      - backend:
          serviceName: apiserver
          servicePort: 80
  - host: www.abc.com
    http:
      paths:
      - path: /image/*
        backend:
          serviceName: fileserver
          servicePort: 80
  - host: www.abc.com
    http:
      paths:
      - backend:
          serviceName: feserver
          servicePort: 8080

与其他k8s对象一样,ingress配置也包含了apiVersion、kind、metadata、spec等关键字段。有几个关注的在spec字段中,tls用于定义https密钥、证书。rule用于指定请求路由规则。这里值得关注的是metadata.annotations字段。在ingress配置中,annotations很重要。前面有说ingress-controller有很多不同的实现,而不同的ingress-controller就可以根据"kubernetes.io/ingress.class:"来判断要使用哪些ingress配置,同时,不同的ingress-controller也有对应的annotations配置,用于自定义一些参数。列如上面配置的’nginx.ingress.kubernetes.io/use-regex: “true”’,最终是在生成nginx配置中,会采用location ~来表示正则匹配。

ingress的部署

ingress的部署,需要考虑两个方面:

ingress-controller是作为pod来运行的,以什么方式部署比较好
ingress解决了把如何请求路由到集群内部,那它自己怎么暴露给外部比较好
下面列举一些目前常见的部署和暴露方式,具体使用哪种方式还是得根据实际需求来考虑决定。

Deployment+LoadBalancer模式的Service
如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向该地址,就实现了集群服务的对外暴露。

Deployment+NodePort模式的Service
同样用deployment模式部署ingress-controller,并创建对应的服务,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。

DaemonSet+HostNetwork+nodeSelector
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。比较适合大并发的生产环境使用。

Service虽然解决了服务发现和负载均衡的问题,但它在使用上还是有一些限制:

只支持4层负载均衡,没有7层功能
对外访问时,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer要求kubernetes必须跑在支持的cloud provider上
一、ingress引入历程
我们已经了解到Kubernetes暴露服务的方式目前只有三种:LoadBalancer Service、ExternalName、NodePort Service;那还有没有更好的方式呢?我们先来了解一下以下几个问题:

1、Pod漂移问题

我们知道Pod是有生命周期的,Pod宕机之后,其IP必然会改变,那我们如何把这个动态的Pod IP暴露出去呢?总所周知,我们可以借助Kubernetes的Service机制,在Service中以标签的形式选定一组带有指定标签的Pod,并监控和自动负载到它们的Pod IP,那么我们向外只需要暴露Service IP就行了,这就是我们常使用的NodePort模式:即在每个节点上开启一个端口,然后转发到内部的Pod IP上。此时的访问方式为:http: //nodeip:nodeport/
在这里插入图片描述

2、端口管理问题

采用NodePort方式暴露服务面临的问题是:服务一旦多起来,NodePort在每个节点上开启的端口会极其庞大,而且难以维护。想一想,鉴于nginx的能力,我们能够使用一个nginx直接对内进行转发呢?由于Pod与Pod之间是可以互相通信的,而Pod是可以共享宿主机的网络名称空间的,此时Pod上所监听的就是Node上的端口。那这又该如何实现呢?简单的实现就是使用DaemonSet在每个Node上监听80端口,然后写好规则,因为nginx外面绑定了宿主机80端口(就像NodePort),本身又在集群内,那么向后直接转发到相应Service IP就行了
在这里插入图片描述
在这里插入图片描述

3. 域名分配及动态更新问题

用上面的方法,我们采用nginx Pod似乎已经解决了问题,但是当每次有新服务加入又该如何修改nginx配置呢?nginx可以通过虚拟主机域名区分不同的服务,而每个服务通过upstream进行定义不同的负载均衡池,再加上location进行负载均衡的反向代理,在日常使用中只需要修改nginx.conf即可实现,但是在k8s中又该如何实现这种方式调度呢?
假设后端的服务开始只有ecshop,后面增加了bbs和member服务,那么又该如何将这2个服务加入到nginx Pod进行调度呢?总不能每次手动改后者Rolling update前端nginx pod吧!所以k8s引入了ingress,ingress就是为了解决这些问题而生的,ingress包含两大组件:ingress controller和ingress。

ingress

简单理解就是你原来需要修改nginx配置,然后配置各种域名对应哪个Service,现在把这个动作抽象出来,变成一个Ingress对象,你可以用yaml创建,每次不要去修改nginx了,直接改yaml然后创建/更新就行了,那么问题又来了:nginx该如何处理呢?
ingress controller
这个东西就是解决nginx如何处理这个问题的,ingress controller通过与kubernetes API交互,动态的去感知集群中Ingress规则变化,然后读取它,按照它自己的模板生成一段nginx配置,再写到nginx Pod中,最后reload以下,工作流程如下图
在这里插入图片描述
图表说明:
首先我们有一个外部的负载均衡器externalLB把请求调度到一个nodePort类型的Service(ingress-nginx)上,然后nodePort类型的Service(ingress-nginx)又把它调度到内部的叫做ingressController的Pod上,ingressCtroller根据ingress中的定义(虚拟主机还是URL),每一组主机名或者URL都对应后端的Pod资源,并且用Service分组(图中的site1/site2只是用来做分组用的)

4、Ingress Nginx部署 步骤

使用Ingress功能步骤:

安装部署ingressCtroller Pod

部署ingress-nginx service

部署后端服务

部署ingress
从前面的描述我们知道,Ingress可以使用yaml的方式进行创建,从而得知Ingress也是标准的K8S资源,其定义的方式也可以使用kubectl explain进行查看:
[root@master ~]# kubectl explain ingress
KIND: Ingress
VERSION: extensions/v1beta1

DESCRIPTION:
Ingress is a collection of rules that allow inbound connections to reach
the endpoints defined by a backend. An Ingress can be configured to give
services externally-reachable urls, load balance traffic, terminate SSL,
offer name based virtual hosting etc. DEPRECATED - This group version of
Ingress is deprecated by networking.k8s.io/v1beta1 Ingress. See the release
notes for more information.

FIELDS:
apiVersion
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

kind
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

metadata
Standard object’s metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

spec
Spec is the desired state of the Ingress. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

status
Status is the current state of the Ingress. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

二. 实例演示,用ingress 发布 后端的tomcat资源

1 . 首先官方下载 mandatory.yaml 文件,进行稍微修改

https://github.com/kubernetes/ingress-nginx

[root@master ~]# vim mandatory.yaml


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:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    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
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:
#  replicas: 1
  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:
      # wait up to five minutes for the drain of connections
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        isIngress: "true"
      hostNetwork: true
      containers:
        - name: nginx-ingress-controller
          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 101
            runAsUser: 101
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
          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
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown

---

apiVersion: v1
kind: LimitRange
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  limits:
  - min:
      memory: 90Mi
      cpu: 100m
    type: Container

可以看到主要使用了“quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.0”这个镜像,指定了一些启动参数。同时开放了80与443两个端口,并在10254端口做了健康检查。
我们需要使用daemonset部署到特定node,需要修改部分配置:先给要部署nginx-ingress的node打上特定标签,这里测试部署在"node-1"这个节点。

kubectl  label   node  node1 isIngress="true"
node/node1 labeled

在这里插入图片描述

[root@master ~]# kubectl apply -f mandatory.yaml
namespace/ingress-nginx unchanged
configmap/nginx-configuration unchanged
configmap/tcp-services unchanged
configmap/udp-services unchanged
serviceaccount/nginx-ingress-serviceaccount unchanged
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole unchanged
role.rbac.authorization.k8s.io/nginx-ingress-role unchanged
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding unchanged
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding unchanged
daemonset.apps/nginx-ingress-controller created
limitrange/ingress-nginx configured
[root@master ~]#
[root@master ~]# kubectl get daemonset -n ingress-nginx
NAME                       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR    AGE
nginx-ingress-controller   1         1         1       1            1           isIngress=true   40s
[root@master ~]# kubectl get daemonset -n ingress-nginx - o^C
[root@master ~]# kubectl get po -n ingress-nginx -o wide
NAME                             READY   STATUS    RESTARTS   AGE     IPNODE    NOMINATED NODE   READINESS GATES
nginx-ingress-controller-6nmhl   1/1     Running   0          2m31s   192.168.100.14node1   <none>           <none>
[root@master ~]#

nginx-ingress-controller 资源已经运行在node1 上了

[root@node1 ~]# netstat -lntup | grep nginx
tcp        0      0 127.0.0.1:10247         0.0.0.0:*               LISTEN      56986/nginx: master
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      56986/nginx: master
tcp        0      0 0.0.0.0:8181            0.0.0.0:*               LISTEN      56986/nginx: master
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      56986/nginx: master
tcp        0      0 127.0.0.1:10245         0.0.0.0:*               LISTEN      56935/nginx-ingress
tcp        0      0 127.0.0.1:10246         0.0.0.0:*               LISTEN      56986/nginx: master
tcp6       0      0 :::10254                :::*                    LISTEN      56935/nginx-ingress
tcp6       0      0 :::80                   :::*                    LISTEN      56986/nginx: master
tcp6       0      0 :::8181                 :::*                    LISTEN      56986/nginx: master
tcp6       0      0 :::443                  :::*                    LISTEN      56986/nginx: master
[root@node1 ~]#

2. 部署ingress-nginx service

通过ingress-controller对外提供服务,现在还需要手动给ingress-controller建立一个servcie,接收集群外部流量。

2.1 下载ingress-controller service的yaml文件

wget --no-check-certificate https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.20.0/deploy/provider/baremetal/service-nodeport.yaml

apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: 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
[root@master ~]# kubectl apply -f service-nodeport.yaml
service/ingress-nginx created

[root@master ~]# kubectl get svc -n ingress-nginx -o wide
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
ingress-nginx   NodePort   10.96.177.250   <none>        80:31478/TCP,443:31772/TCP   78m   app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx

由于配置了hostnetwork,nginx已经在node主机本地监听80/443/8181端口。其中8181是nginx-controller默认配置的一个default backend。这样,只要访问node主机有公网IP,就可以直接映射域名来对外网暴露服务了。如果要nginx高可用的话,可以在多个node
上部署,并在前面再搭建一套LVS+keepalive做负载均衡。用hostnetwork的另一个好处是,如果lvs用DR模式的话,是不支持端口映射的,这时候如果用nodeport,暴露非标准的端口,管理起来会很麻烦。

3. 部署完ingress-controller,创建tomcat 后端资源

cat   tomcat-demo.yaml
apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
    release: stable
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  - name: ajp
    port: 8009
    targetPort: 8009
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-demo
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat
      release: stable
  template:
    metadata:
      labels:
        app: tomcat
        release: stable
    spec:
      containers:
      - name: tomcat
        image: tomcat:8.5.34-jre8-alpine
        ports:
        - name: http
          containerPort: 8080
        - name: ajp
          containerPort: 8009
[root@master ~]# kubectl get svc
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP             21d
tomcat          ClusterIP   10.96.40.123   <none>        8080/TCP,8009/TCP   11s
[root@master ~]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
tomcat             1/1     1            1           22d
tomcat-demo        3/3     3            3           86s
[root@master ~]# kubectl get pods
NAME                                READY   STATUS      RESTARTS   AGE
tomcat-demo-65867686cd-c2prr        1/1     Running     0          102s
tomcat-demo-65867686cd-sqr5n        1/1     Running     0          102s
tomcat-demo-65867686cd-zx9gd        1/1     Running     0          102s

4. 准备证书并生成secret

[root@master ~]# openssl genrsa -out tls.key 2048
Generating RSA private key, 2048 bit long modulus
............................................+++
............................................................................+++
e is 65537 (0x10001)
[root@master ~]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=tomcat.zwx.com

4.1生成secret:

[root@master ~]# kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
secret/tomcat-ingress-secret created
[root@master ~]# kubectl get secret
NAME                    TYPE                                  DATA   AGE
db-user-pass            Opaque                                2      22d
default-token-fkhds     kubernetes.io/service-account-token   3      23d
hahassl-secret          kubernetes.io/tls                     2      61m
tomcat-ingress-secret   kubernetes.io/tls                     2      28s

5. 创建ingress(用于导入规则到ingress-controller)

[root@master ~]# vim ingress-tomcat-tls.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-tomcat-tls
  namespace: default
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - tomcat.zwx.com
    secretName: tomcat-ingress-secret
  rules:
  - host: tomcat.zwx.com
    http:
      paths:
      - backend:
          serviceName: tomcat
          servicePort: 8080

6. 查看 nginx 反向代理资源的配置文件发现已自动更新

[root@master ~]# kubectl exec -n ingress-nginx nginx-ingress-controller-6nmhl  -it bash
bash-5.0$ vi nginx.conf
 location / {

                        set $namespace      "default";
                        set $ingress_name   "ingress-tomcat-tls";
                        set $service_name   "tomcat";
                        set $service_port   "8080";
                        set $location_path  "/";

                        rewrite_by_lua_block {
                                lua_ingress.rewrite({
                                        force_ssl_redirect = false,
                                        ssl_redirect = true,
                                        force_no_ssl_redirect = false,
                                        use_port_in_redirects = false,
                                })
                                balancer.rewrite()
                                plugins.run()
                        }

7. 访问测试

在宿主机添加hosts 解析域名

192.168.100.13   tomcat.zwx.com

查看ingress-nginx 服务,及暴露的端口

[root@master ~]# kubectl get svc -n ingress-nginx -o wide
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE   SELECTOR
ingress-nginx   NodePort   10.96.177.250   <none>        80:31478/TCP,443:31772/TCP   9h    app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx

访问
https://tomcat.zwx.com:31772
经过nginx 反向代理成功访问到后段服务
在这里插入图片描述

三. 其他

查看ingress 的配置清单选项

在这里插入图片描述

编写ingress 的 配置清单

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Kubernetes Ingress-Nginx是一个在Kubernetes集群中使用的开源Ingress控制器。它允许将外部流量引导到Kubernetes集群内部的服务。下面是它的一些主要特点和详解: 1. 灵活性:Ingress-Nginx支持多种配置方式,包括基于注解的配置、自定义资源定义(CRD)以及基于配置文件的方式。这使得用户可以根据自己的需求选择最适合的方式来配置Ingress规则。 2. 可扩展性:Ingress-Nginx可以通过水平扩展来处理高负载的流量。它使用Nginx作为反向代理服务器,可以根据需要进行水平扩展,并通过负载均衡来分发请求。 3. SSL/TLS支持:Ingress-Nginx支持通过TLS/SSL来保护传输的数据。它可以配置证书和私钥,从而实现安全的通信。 4. 负载均衡:Ingress-Nginx可以根据不同的负载均衡算法来分发流量。它支持轮询、IP哈希、最少连接等负载均衡算法,并且可以根据需要进行自定义配置。 5. 基于名称的虚拟主机:Ingress-Nginx支持基于名称的虚拟主机(Virtual Host)。通过配置不同的主机名和路径规则,可以将流量引导到不同的服务。 6. HTTP/HTTPS重定向:Ingress-Nginx可以配置HTTP到HTTPS的重定向,从而确保所有的流量都是通过安全的通道传输。 7. 基于URI的请求路由:Ingress-Nginx可以根据请求的URI来进行路由。这使得可以根据不同的URI将流量引导到不同的后端服务。 8. 支持WebSocket:Ingress-Nginx对WebSocket协议有良好的支持。它可以转发WebSocket请求,并在需要时进行负载均衡。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值