12-K8S Basic-Ingress资源介绍及实战

PS :ingress官方文档:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/

一、什么是Ingress

  • Ingress 公开了从集群外部到集群内 services 的HTTP和HTTPS路由。 流量路由由 Ingress 资源上定义的规则控制。
     internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]
  • 可以将 Ingress 配置为提供服务外部可访问的 URL、负载均衡流量、终止 SSL / TLS 并提供基于名称的虚拟主机。Ingress 控制器通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
  • Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或者 Service.Type=LoadBalancer 类型的服务。
  • 可以将Ingress配置为提供服务外部可访问的URL,负载均衡流量,终止 SSL / TLS 并提供基于名称的虚拟主机。 Ingress 控制器通常负责通过负载平衡器来实现入口,尽管它也可以配置边缘路由器或其他前端以帮助处理流量。
  • Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开给 Internet 时,通常使用以下类型的服务 Service.Type=NodePort 或者 Service.Type=LoadBalancer.

二、Ingress资源介绍

  • Ingress资源时基于HTTP虚拟主机或URL的转发规则,需要强调的是,这是一条转发规则。它在资源配置清单中的spec字段中嵌套了rules、backend和tls等字段进行定义。如下示例中定义了一个Ingress资源,其包含了一个转发规则:将发往myapp.magedu.com的请求,代理给一个名字为myapp的Service资源。
  • 注意:ingress自身步支持使用标签选择器挑选真正提供服务的Pod对象,因此,他需要由Service对象的辅助完成此类功能。
    • (所以还是要先为后端的一组提供服务的Pod定义一个Service,然后Ingress变相借助Service的标签选择器实现对后端Pod的过滤,Service在此仅作为一个辅助的角色实现Pod根据标签选择器发现机制及挑选机制)
apiVersion : extensions/v1beta1
kind : Ingress
metadata :
  name : test-ingress
  annotations :     #资源注解
    nginx.ingress.kubernetes.io/rewrite-target : /
spec :
  rules :                     #rules是一个对象列表,每一个列表是一个虚拟代理形式
  - http : myapp.magedu.com   #指定虚拟主机名称,如果没指定代表Ingress  Controller 所在的虚拟主机的名称
      paths :
      - path : /testpath      #Server中的Url访问的路径映射到backend后端主机的upstream     (-path 指明,提供客户端访问的url路径)
      backend :               #backend相当于后端的虚拟主机,真正提供服务的upstream
		#关联到的后端Service资源,它的标签选择器匹配到的Pod对象将成为反代服务的"后端"                         
        serviceName : test
        servicePort : 80      

Ingress七层代理中的Service 作用,以为一个辅助工具:

  • Service的作用一 :标签过滤器
    • 因为Ingress并不支持标签选择器来选择代理后端哪些pod,所以只能借助Service来完成,所以此处Service的资源仅仅是帮助Ingress提供一个选择后端Pod的标签选择器,并不是我们要代理的后端。
    • 所以在定义backend是要使用serviceName资源,所以在定义之前必须实现为一组Pod来创建一个Service。切记Service并不是作为用户的访问一端,仅用于帮助七层代理提供标签选择器。
    • 如果七层代理一旦开始代理,所有的请求到达Ingress Controllers,代理后是直达pod,不会经过Service。所以Service在这里仅作为标签选择器使用。
  • Service的作用二 :变相将Pod变动让Ingress Controller捕获
    • Ingress Controller 是无法识别到被Service标签选择的Pod的数量的,所以Service的第二个作用就是通过标签过滤器检查后端Pod的数量。

  • 与所有其他 Kubernetes 资源一样,Ingress 需要使用 apiVersion、kind 和 metadata 字段。 有关使用配置文件的一般信息,请参见部署应用、 配置容器、管理资源。 Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress 控制器,例如 rewrite-target annotation。 不同的 Ingress 控制器支持不同的注解(annotations)。查看文档以供您选择 Ingress 控制器,以了解支持哪些注解(annotations)。
  • Ingress 规范 具有配置负载均衡器或者代理服务器所需的所有信息。最重要的是,它包含与所有传入请求匹配的规则列表。Ingress 资源仅支持用于定向 HTTP 流量的规则。

2.1、Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段

  • Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段:
    • rules:用于定义当前Ingress资源的转发规则列表;由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端。
    • backend:默认的后端用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端。
    • tls:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNI TLS扩展机制来支持该功能。backend对象的定义由2个必要的字段组成:serviceName和servicePort,分别用于指定流量转发的后端目标Service资源名称和端口。rules对象由一系列的配置的Ingress资源的host规则组成,这些host规则用于将一个主机上的某个URL映射到相关后端Service对象。
    • default backend : 如果rules规则中的请求转发给backend的主机都宕机,则由default backend 提供sorry Server
      • 没有规则的 Ingress 将所有流量发送到单个默认后端。默认后端通常是 Ingress 控制器的配置选项,并且未在 Ingress 资源中指定。
      • 如果没有主机或路径与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到您的默认后端。
spec:
  rules:
  - hosts: <string>
    http:
      paths:
      - path:
        backend:
          serviceName: <string>
          servicePort: <string>
  • 需要注意的是,.spec.rules.host属性值,目前暂不支持使用IP地址定义,也不支持IP:Port的格式,该字段留空,代表着通配所有主机名。
  • tls对象由2个内嵌的字段组成,仅在定义TLS主机的转发规则上使用。
    • hosts: 包含 于 使用 的 TLS 证书 之内 的 主机 名称 字符串 列表, 因此, 此处 使用 的 主机 名 必须 匹配 tlsSecret 中的 名称。
    • secretName: 用于 引用 SSL 会话 的 secret 对象 名称, 在 基于 SNI 实现 多 主机 路 由 的 场景 中, 此 字段 为 可选。

2.2、Ingress资源的类型

  • ingress的资源类型有以下四种:
    • 1、单Server资源型ingress
    • 2、基于URL路径进行流量转发
    • 3、基于主机名称的虚拟主机
    • 4、TLS类型的Ingress资源

2.2.1、单Server资源型ingress

  • 暴露单个服务的方法有多种,如NodePort、LoadBanlancer等等,当然也可以使用Ingress来进行暴露单个服务,只需要为Ingress指定default backend即可,如下示例:
#官方示例
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  backend:
    serviceName: my-svc
    servicePort: 80


#-path:  省略相当于 / ,可以不用写,Ingress控制器会为其分配一个IP地址接入请求流量,并将其转发至后端my-svc


如果使用 kubectl apply -f 创建它,则应该能够查看刚刚添加的 Ingress 的状态:
	kubectl get ingress test-ingress
		NAME           HOSTS     ADDRESS           PORTS     AGE
		test-ingress   *         107.178.254.228   80        59s

其中 107.178.254.228 是由 Ingress 控制器分配以满足该 Ingress 的 IP。
注意:Ingress 控制器和负载均衡器可能需要一两分钟才能分配 IP 地址。 在此之前,您通常会看到地址为 <pending>。
注意:入口控制器和负载平衡器可能需要一两分钟才能分配IP地址。 在此之前,您通常会看到地址字段的值被设定为 <pending>。

2.2.2、基于URL路径进行流量转发(简单分列)

  • 一个分列配置根据请求的 HTTP URI 将流量从单个 IP 地址路由到多个服务。 Ingress 允许您将负载均衡器的数量降至最低。例如,这样的设置
foo.bar.com -> 178.91.123.132 -> / foo    service1:4200
                                 / bar    service2:8080
  • 例如创建一个ingress
#官方示例
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: simple-fanout-example
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: service1
          servicePort: 4200
      - path: /bar
        backend:
          serviceName: service2
          servicePort: 8080




当您使用 kubectl apply -f 创建 Ingress 时:
	kubectl describe ingress simple-fanout-example
		Name:             simple-fanout-example
		Namespace:        default
		Address:          178.91.123.132
		Default backend:  default-http-backend:80 (10.8.2.3:8080)
		Rules:
		  Host         Path  Backends
		  ----         ----  --------
		  foo.bar.com
		               /foo   service1:4200 (10.8.0.90:4200)
		               /bar   service2:8080 (10.8.0.91:8080)
		Annotations:
		  nginx.ingress.kubernetes.io/rewrite-target:  /
		Events:
		  Type     Reason  Age                From                     Message
		  ----     ------  ----               ----                     -------
		  Normal   ADD     22s                loadbalancer-controller  default/test

	Ingress 控制器将提供实现特定的负载均衡器来满足 Ingress,只要 Service (s1,s2) 存在。 当它这样做了,你会在地址栏看到负载均衡器的地址。
注意:根据您使用的 Ingress 控制器,您可能需要创建默认 HTTP 后端 Service。

2.2.3、基于主机名称的虚拟主机(基于名称的虚拟托管)

  • 基于名称的虚拟主机支持将 HTTP 流量路由到同一 IP 地址上的多个主机名。
foo.bar.com --|                 |-> foo.bar.com service1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com service2:80
  • 以下 Ingress 让后台负载均衡器基于主机 header 路由请求
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
  - host: bar.foo.com
    http:
      paths:
      - backend:
          serviceName: service2
          servicePort: 80


如果您创建的 Ingress 资源没有规则中定义的任何主机,则可以匹配到您 Ingress 控制器 IP 地址的任何网络流量,而无需基于名称的虚拟主机。
  • 例如,以下 Ingress 资源会将 first.bar.com 请求的流量路由到 service1,将 second.foo.com 请求的流量路由到 service2,而没有在请求中定义主机名的 IP 地址的流量路由(即,不提供请求标头)到 service3
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: first.bar.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
  - host: second.foo.com
    http:
      paths:
      - backend:
          serviceName: service2
          servicePort: 80
  - http:
      paths:
      - backend:
          serviceName: service3
          servicePort: 80

2.2.4、TLS类型的Ingress资源

  • 您可以通过指定包含 TLS 私钥和证书的 secret Secret 来加密 Ingress。 目前,Ingress 只支持单个 TLS 端口 443,并假定 TLS 终止。
  • 如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过 SNI TLS 扩展指定的主机名(如果 Ingress 控制器支持 SNI)在同一端口上进行复用。 TLS Secret 必须包含名为 tls.crt 和 tls.key 的密钥,这些密钥包含用于 TLS 的证书和私钥
apiVersion: v1
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
type: kubernetes.io/tls
  • 在 Ingress 中引用此 Secret 将会告诉 Ingress 控制器使用 TLS 加密从客户端到负载均衡器的通道。您需要确保创建的 TLS secret 来自包含 sslexample.foo.com 的 CN 的证书。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
    - sslexample.foo.com
    secretName: testsecret-tls
  rules:
    - host: sslexample.foo.com
      http:
        paths:
        - path: /
          backend:
            serviceName: service1
            servicePort: 80

注意:各种 Ingress 控制器所支持的 TLS 功能之间存在差异。请参阅有关文件 nginx、 GCE 或者任何其他平台特定的 Ingress 控制器,以了解 TLS 如何在您的环境中工作

2.3、高级:Ingress → annotations 注解(annotations)来配置一些选项

三、Ingress实战部署(单Server资源型ingress /TLS类型的Ingress资源 )

3.1、ingress资源创建清单

ingress]# 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	<string>
     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	<string>
     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	<Object>
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

   spec	<Object>
     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	<Object>
     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

3.2、实战创建流程

  • ingress-controller(ingress-nginx)也是个pod(ns:ingress-nginx), → 所以需要pod控制器deployment(ns:ingress-nginx) → 也需要NodePort类型service(ns:ingress-nginx) → 创建deployment类型的控制器(ns:myns)管理/创建真实被调度访问的pod → 创建 ClusterIP 类型 Service 使用标签选择器匹配被访问的pod → 创建ingress资源(七层代理) → 访问

image

3.3、创建实战 → 单Server资源型ingress

1、实现前要手动创建ingress-controller
ingress]# cat 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: Deployment
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:
        kubernetes.io/os: linux
      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


2、所有的资源都会被创建在ingress-nginx名称空间中
    #查看名称空间
        ~]# kubectl get ns
            NAME              STATUS   AGE
            ingress-nginx     Active   3m46s
    #查看此名称空间下的Pod   其实就是nginx的 ingress controller    ( basic]# kubectl describe pods nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx查看启动步骤状态)
        ~]# kubectl get pods -n ingress-nginx
            NAME                                        READY   STATUS              RESTARTS   AGE
            nginx-ingress-controller-948ffd8cc-gdxrz   1/1     Running   0          44m                 #nginx-ingress-controller还不能接入集群外部流量
        #查看标签,此Pod标签可作为下面创建的Service使用的标签选择器的标签
        ~]# kubectl get pods -n ingress-nginx --show-labels
        NAME                                       READY   STATUS    RESTARTS   AGE   LABELS
        nginx-ingress-controller-948ffd8cc-gdxrz   1/1     Running   0          50m   app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=948ffd8cc


3、手动编辑一个对应NodePort类型的Service资源,并关联到nginx-ingress-controller
#定义NodePort类型的Service资源
~]# mkdir  mainfests/ingress
ingress]# cat ingress-nginx-svc.yaml
#service所属的标准资源api版本定义群组
apiVersion: v1
#定义资源的类型为Service
kind: Service
#定义元数据
metadata:
  #Service名称
  name: ingress
  #定义service所属的名称空间需要和nginx-ingress-controller————Pod在同一名称空间
  namespace: ingress-nginx
#定义service规格
spec:
  #定义Service的标签选择器,仅用于定义选择匹配nginx-ingress-controller的标签
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  #ports字段
  ports:
  #此端口的名称
  - name: http
    #Service地址的哪个端口于后端Pods端口映射
    port: 80
    #nodePort: 30080
  - name: https
    port: 443
    #nodePort: 30443
  #定义Server类型为NodePort类型
  type: NodePort
 
4、使用声明式接口创建此Service资源
    ingress]# kubectl apply -f ingress-nginx-svc.yaml
    service/ingress created
 
5、查看定义的Service信息
    ingress]# kubectl get svc -n ingress-nginx
        NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
        ingress   NodePort   10.2.100.124   <none>        80:48420/TCP,443:49572/TCP   51s      #30080    30443
 
6、测试访问此集群中其中一台node地址+映射提供用户访问的端口
    ingress]# curl 192.168.20.177:48420             #可以访问任何的node节点的IP + Port,可以访问到nginx-ingress-controller
        nginx 


--------------------------------------------------------以上已经再上一章定义过,这里为了回顾--------------------------------------------




1、为了方便验证创建一个单独的名称空间
	~]# kubectl create ns myns
		namespace/myns created

	~]# kubectl get ns
		NAME              STATUS   AGE
		default           Active   21d
		myns              Active   13s


2、(控制器+Service+pods)创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用) ,以及为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)
	# 1、非自主式Pod,由Deployment控制器管理的提供后端服务的Pod(创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用))
	# 2、为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)


ingress]# cat myns-deployment-pods-example.yaml 
## ----> 定义控制器
# 定义deployment群组名称以及版本
apiVersion: apps/v1
# 定义资源类型
kind: Deployment
# 元数据
metadata:
  # 控制器名称
  name: myapp
  # 控制器所属的名称空间
  namespace: myns
# 定义deployment控制器资源规格(标签选择器、pod数量、pod模板)
spec:
  # 定义pods数量
  replicas: 2
  # 匹配的pods的标签选择器
  selector:
    matchLabels:
      app: myapp
      rel: beta
  # 定义pod创建依据的模板
  template:
    # 定义后端pod的元数据
    metadata:
      # 定义pod的名称
      name: myapp-pod
      # 定义pod所属的名称空间应该和deployment控制器保持一致
      namespace: myns
      # 定义pod的标签,应该和deployment控制器匹配后端pod的标签选择器保持一致
      labels:
        app: myapp
        rel: beta
    # 定义pos的资源的规格
    spec:
      # pod内部运行的容器信息
      containers:
      # pod中容器运行名称
      - name: myapp-test-con
      # pod内部容器运行的镜像
        image: ikubernetes/myapp:v1
# 资源界定符
---
## ----> 定义Service资源
# 定义Service资源的群组名称及版本
apiVersion: v1
# 定义资源类型
kind: Service
# 定义Service资源元数据
metadata:
  # 定义service资源的名称(不同资源的名称可以一致)
  name: myapp
  # 定义所属的名称空间
  namespace: myns
# 定义service资源规格(标签选择器匹配pod标签、pod数量、pod模板)
spec:
  # 定义Service匹配的后端pod的标签的标签选择器
  selector:
    app: myapp
    rel: beta
  # 定义service类型默认为cluster
  type: ClusterIP
  # clusterIP: 10.97.97.97
  # ports字段
  ports:
  # 此端口的名称
  - name: http
    # Service地址的哪个端口于后端Pods端口映射
    port: 80
    # 后端Pods的哪个端口于Service做映射
    targetPort: 80

	# 使用apply声明式接口创建资源
	ingress]# kubectl apply -f  myns-deployment-pods-example.yaml
		deployment.apps/myapp created
		service/myapp created


3、查看创建的资源
	# deployment控制器
    ingress]# kubectl get deploy -n myns -o wide
		NAME    READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS       IMAGES                 SELECTOR
		myapp   2/2     2            2           9m44s   myapp-test-con   ikubernetes/myapp:v1   app=myapp,rel=beta
	# server
	ingress]# kubectl get svc -n myns -o wide
		NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   SELECTOR
		myapp   ClusterIP   10.104.87.25   <none>        80/TCP    10m   app=myapp,rel=beta
	# pod
	ingress]# kubectl get pods -n myns -o wide --show-labels
		NAME                   READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES   LABELS
		myapp-89484f5d-qsbx7   1/1     Running   0          10m   10.244.1.38   k8s.node1   <none>           <none>            app=myapp,pod-template-hash=89484f5d,rel=beta
		myapp-89484f5d-zqc57   1/1     Running   0          10m   10.244.1.39   k8s.node1   <none>           <none>            app=myapp,pod-template-hash=89484f5d,rel=beta
	# 显示执行的名称空间下的所有资源
	[root@k8s ingress]# kubectl get all -n myns
		NAME                       READY   STATUS    RESTARTS   AGE
		pod/myapp-89484f5d-qsbx7   1/1     Running   0          12m
		pod/myapp-89484f5d-zqc57   1/1     Running   0          12m

		NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
		service/myapp   ClusterIP   10.104.87.25   <none>        80/TCP    12m

		NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
		deployment.apps/myapp   2/2     2            2           12m

		NAME                             DESIRED   CURRENT   READY   AGE
		replicaset.apps/myapp-89484f5d   2         2         2       12m

4、资源访问测试
	# 访问pod
	[root@k8s ingress]# curl 10.244.1.38
		Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
	[root@k8s ingress]# curl 10.244.1.39
		Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>


	# service
    ingress]# curl 10.104.87.25
		Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>


5、通过ingress-controller七层代理进行调度
	# 创建ingress资源清单
ingress]# cat myns-ingress-example.yaml 
# 定义ingress资源所属群组名称以及版本
apiVersion: extensions/v1beta1
# 定义资源类型
kind: Ingress
# 元数据
metadata:
  # 定义Ingress名称
  name: myapp
  # 定义名称空间
  namespace: myns
  # 定义资源注解
  annotations:
    # url重定向--> 非主要无需关注
    nginx.ingress.kubernetes.io/rewrite-target: /
    # ingress类型为nginx
    kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
  # 定义代理规则
  rules:
  # 定义虚拟主机名称,不写默认为localhost
  - host: www.daizhe.net.cn
    http:
      paths:
      # Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
      - path: /
      # backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port) 
        backend:
          # ingress代理的server名称,之前创建的service为myapp
          serviceName: myapp
          # service和pods映射的端口(service-->sepc.ports.port)
          servicePort: 80

	# 使用声明式接口创建资源清单
		ingress]# kubectl apply -f myns-ingress-example.yaml 
			ingress.extensions/myapp created

6、查看已经创建的ingress资源
	ingress]# kubectl get ingress -n myns
		NAME    CLASS    HOSTS               ADDRESS   PORTS   AGE
		myapp   <none>   www.daizhe.net.cn             80      2m10s

	# 显示ingress yaml格式
ingress]# kubectl get ingress -n myns -o yaml
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx","nginx.ingress.kubernetes.io/rewrite-target":"/"},"name":"myapp","namespace":"myns"},"spec":{"rules":[{"host":"www.daizhe.net.cn","http":{"paths":[{"backend":{"serviceName":"myapp","servicePort":80},"path":"/"}]}}]}}
      kubernetes.io/ingress.class: nginx
      nginx.ingress.kubernetes.io/rewrite-target: /
    creationTimestamp: "2020-05-13T10:23:47Z"
    generation: 1
    managedFields:
    - apiVersion: extensions/v1beta1
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations:
            .: {}
            f:kubectl.kubernetes.io/last-applied-configuration: {}
            f:kubernetes.io/ingress.class: {}
            f:nginx.ingress.kubernetes.io/rewrite-target: {}
        f:spec:
          f:rules: {}
      manager: kubectl
      operation: Update
      time: "2020-05-13T10:23:47Z"
    name: myapp
    namespace: myns
    resourceVersion: "3868216"
    selfLink: /apis/extensions/v1beta1/namespaces/myns/ingresses/myapp
    uid: 0b39e70e-f19e-4c48-8031-e5ee6ebb2bbf
  spec:
    rules:
    - host: www.daizhe.net.cn
      http:
        paths:
        - backend:
            serviceName: myapp
            servicePort: 80
          path: /
          pathType: ImplementationSpecific
  status:
    loadBalancer: {}
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

	# 使用describe查看当前状态
ingress]# kubectl describe ingress -n myns
Name:             myapp
Namespace:        myns
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host               Path  Backends
  ----               ----  --------
  www.daizhe.net.cn                             # 可以查看到对 www.daizhe.net.cn  地址的访问都会被映射到后端myapp的service的80端口响应
												# 可以查看到service四层代理的后端 pod有10.244.1.38:80,10.244.1.39:80 
                     /   myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations:         kubernetes.io/ingress.class: nginx
                     nginx.ingress.kubernetes.io/rewrite-target: /
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  4m1s  nginx-ingress-controller  Ingress myns/myapp



7、连接ingress-controller验证
	# 手动连入ingress-controller查看配置文件
	ingress]# kubectl get pods -n ingress-nginx
		NAME                                        READY   STATUS    RESTARTS   AGE
		nginx-ingress-controller-5bb8fb4bb6-q5lpg   1/1     Running   0          4h50m
[root@k8s ingress]# kubectl exec -it nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx -- /bin/sh
/etc/nginx $ ls
fastcgi.conf            geoip                   mime.types              nginx.conf              scgi_params             uwsgi_params.default
fastcgi.conf.default    koi-utf                 mime.types.default      nginx.conf.default      scgi_params.default     win-utf
fastcgi_params          koi-win                 modsecurity             opentracing.json        template
fastcgi_params.default  lua                     modules                 owasp-modsecurity-crs   uwsgi_params
/etc/nginx $ more nginx.conf
.....
        server {             
                server_name www.daizhe.net.cn ;
                             
                listen 80  ; 
                listen 443  ssl http2 ;
                             
                set $proxy_upstream_name "-";
                             
                ssl_certificate_by_lua_block {
                        certificate.call()
                }            
                             
                location / { 
                             
                        set $namespace      "myns";   
                        set $ingress_name   "myapp";
                        set $service_name   "myapp";
                        set $service_port   "80";
                        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()
                        }    

......



8、访问验证。由于上面ingress定义的- host: www.daizhe.net.cn,需要再(本机电脑)宿主机上添加解析测试
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 daizhe.com
192.168.20.236 192.168.20.212 192.168.20.214 www.daizhe.net.cn
	# 访问: http://{ingress.host}:{ingress-controller.控制器-Port.service}
	# 查看ingress-controller.控制器-Port.service
	~]# kubectl get svc -n ingress-nginx
		NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
		ingress   NodePort   10.98.225.170   <none>        80:32145/TCP,443:31430/TCP   4h23m


# windows客户端访问 --> 轮询效果 (后端pod副本数量为2,默认调度算法为随机)
daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    21  100    21    0     0    269      0 --:--:-- --:--:-- --:--:--   269my                                                                                                                                  app-89484f5d-zqc57


daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    21  100    21    0     0    269      0 --:--:-- --:--:-- --:--:--   269my                                                                                                                                  app-89484f5d-zqc57


daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    21  100    21    0     0    223      0 --:--:-- --:--:-- --:--:--   223my                                                                                                                                  app-89484f5d-qsbx7


daizhe@DESKTOP-ABLCU8H MINGW64 ~/Desktop
$ curl www.daizhe.net.cn:32145/hostname.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100    21  100    21    0     0    269      0 --:--:-- --:--:-- --:--:--   269my      

image

  • 下面访问出错由于ingress未配置TLS

image

3.4、创建实战 → TLS类型的Ingress资源

1、生成自签名证书
	[root@k8s ingress]# mkdir ssl
	[root@k8s ingress]# cd ssl/
	# 私钥
	ssl]# openssl genrsa -out myapp.key 2048
		Generating RSA private key, 2048 bit long modulus
		.................+++
		..................................+++
		e is 65537 (0x10001)
		You have new mail in /var/spool/mail/root
	# 证书
	ssl]# openssl req -new -x509 -key myapp.key -out myapp.crt -subj /C=CN/ST/Beijing/L=Beijing/O=Ops/CN=www.toptops.top -days 3650
	ssl]# ls
		myapp.crt  myapp.key

2、创建tls 类型 secret(将自签名证书转为secret资源才能使得k8s所引用)
	ssl]# kubectl create secret -h
		Create a secret using specified subcommand.
		Available Commands: # secret 类型
  		docker-registry Create a secret for use with a Docker registry
  		generic         Create a secret from a local file, directory or literal value
  		tls             Create a TLS secret

		Usage:
  		kubectl create secret [flags] [options]
		Use "kubectl <command> --help" for more information about a given command.
		Use "kubectl options" for a list of global command-line options (applies to all commands).

	ssl]# kubectl create secret  tls -h
		Usage:
  		kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run=server|client|none] [options]
			# -n 指定名称空间,必须和ingress在同一名称空间下
			# --dry-run 干跑模式
			# toptops  创建的secret 名称
	ssl]# kubectl create secret tls toptops -n myns --cert=myapp.crt --key=myapp.key --dry-run
	ssl]# kubectl create secret tls toptops -n myns --cert=myapp.crt --key=myapp.key
		secret/toptops created

3、根据创建secret名称查看证书详细信息
ssl]# kubectl describe secret toptops -n myns
Name:         toptops
Namespace:    myns
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.crt:  1184 bytes
tls.key:  1679 bytes



4、创建TLS类型的ingress --> 继续调度前面示例的 pod
	# 官方文档 : https://kubernetes.io/zh/docs/concepts/services-networking/ingress/#ingress-%E7%B1%BB%E5%9E%8B
ssl]# cat myns-ingress-tls-example.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  # 定义ingress名称
  name: myapp-tls
  # 定义所属的名称空间
  namespace: myns
  # 定义资源注解
  annotations:
    # ingress类型为nginx
    kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
  tls:
  # 定义虚拟主机名称,这里需要和上面创建tls证书中域名保持一致,不写默认为localhost
  - hosts:
    - www.toptops.top
    # 创建tls 类型 secret名称
    secretName: toptops
  # 定义代理规则
  rules:
    # 定义虚拟主机名称,这里需要和上面创建tls证书中域名保持一致,不写默认为localhost
    - host: www.toptops.top
      http:
        paths:
        # Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
        - path: /
          # backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port)
          backend:
            # ingress代理的server名称,之前创建的service为myapp
            serviceName: myapp
            # service和pods映射的端口(service-->sepc.ports.port)
            servicePort: 80

	# 使用声明式接口创建资源

	ssl]# kubectl apply -f myns-ingress-tls-example.yaml 
		ingress.extensions/myapp-tls created

5、查看已经创建的ingress资源
	ssl]# kubectl get ingress -n myns -o wide
		NAME        CLASS    HOSTS               ADDRESS   PORTS     AGE
		myapp       <none>   www.daizhe.net.cn             80        29h
		myapp-tls   <none>   www.toptops.top               80, 443   45s

	# 使用describe查看当前状态
ssl]# kubectl describe ingress -n myns
Name:             myapp
Namespace:        myns
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host               Path  Backends
  ----               ----  --------
  www.daizhe.net.cn  
                     /   myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations:         kubernetes.io/ingress.class: nginx
                     nginx.ingress.kubernetes.io/rewrite-target: /
Events:              <none>


Name:             myapp-tls
Namespace:        myns
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  toptops terminates www.toptops.top
Rules:
  Host             Path  Backends
  ----             ----  --------
  www.toptops.top  
                   /   myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations:       kubernetes.io/ingress.class: nginx
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  93s   nginx-ingress-controller  Ingress myns/myapp-tls

ssl]# kubectl describe ingress myapp-tls  -n myns
Name:             myapp-tls
Namespace:        myns
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  toptops terminates www.toptops.top
Rules:
  Host             Path  Backends
  ----             ----  --------
  www.toptops.top  
                   /   myapp:80 (10.244.1.38:80,10.244.1.39:80)
Annotations:       kubernetes.io/ingress.class: nginx
Events:
  Type    Reason  Age    From                      Message
  ----    ------  ----   ----                      -------
  Normal  CREATE  2m22s  nginx-ingress-controller  Ingress myns/myapp-tls

6、连接ingress-controller验证
	# 手动连入ingress-controller查看配置文件
ingress]# kubectl exec -it nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx -- /bin/sh
/etc/nginx $ more nginx.conf
...


       server {             
                server_name www.toptops.top ;
                             
                listen 80  ; 
                listen 443  ssl http2 ;
                             
                set $proxy_upstream_name "-";
                             
                ssl_certificate_by_lua_block {
                        certificate.call()
                }            
                             
                location / { 
                             
                        set $namespace      "myns";
                        set $ingress_name   "myapp-tls";
                        set $service_name   "myapp";
                        set $service_port   "80";
                        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()
                        }    

...


8、访问验证。由于上面ingress定义的- host: www.toptops.top,需要再(本机电脑)宿主机上添加解析测试
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 daizhe.com
192.168.20.236 192.168.20.212 192.168.20.214 www.daizhe.net.cn
    # 访问: http://{ingress.host}:{ingress-controller.控制器-Port.service}
    # 查看ingress-controller.控制器-Port.service
    ~]# kubectl get svc -n ingress-nginx
        NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
        ingress   NodePort   10.98.225.170   <none>        80:32145/TCP,443:31430/TCP   4h23m

# # windows客户端访问 --> 轮询效果 (后端pod副本数量为2,默认调度算法为随机)

image

四、(NT)实际项目(ingress-controller(ingress-nginx)代理→ ingress → Tomcat应用

4.1、创建ingress-controller(ingress-nginx-pod)

1、实现前要手动创建ingress-controller
ingress]# cat 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: Deployment
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:
        kubernetes.io/os: linux
      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
 
 
2、所有的资源都会被创建在ingress-nginx名称空间中
    #查看名称空间
        ~]# kubectl get ns
            NAME              STATUS   AGE
            ingress-nginx     Active   3m46s
    #查看此名称空间下的Pod   其实就是nginx的 ingress controller    ( basic]# kubectl describe pods nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx查看启动步骤状态)
        ~]# kubectl get pods -n ingress-nginx
            NAME                                        READY   STATUS              RESTARTS   AGE
            nginx-ingress-controller-948ffd8cc-gdxrz   1/1     Running   0          44m                 #nginx-ingress-controller还不能接入集群外部流量
        #查看标签,此Pod标签可作为下面创建的Service使用的标签选择器的标签
        ~]# kubectl get pods -n ingress-nginx --show-labels
        NAME                                       READY   STATUS    RESTARTS   AGE   LABELS
        nginx-ingress-controller-948ffd8cc-gdxrz   1/1     Running   0          50m   app.kubernetes.io/name=ingress-nginx,app.kubernetes.io/part-of=ingress-nginx,pod-template-hash=948ffd8cc
 
 
3、手动编辑一个对应NodePort类型的Service资源,并关联到nginx-ingress-controller
#定义NodePort类型的Service资源
~]# mkdir  mainfests/ingress
ingress]# cat ingress-nginx-svc.yaml
#service所属的标准资源api版本定义群组
apiVersion: v1
#定义资源的类型为Service
kind: Service
#定义元数据
metadata:
  #Service名称
  name: ingress
  #定义service所属的名称空间需要和nginx-ingress-controller————Pod在同一名称空间
  namespace: ingress-nginx
#定义service规格
spec:
  #定义Service的标签选择器,仅用于定义选择匹配nginx-ingress-controller的标签
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  #ports字段
  ports:
  #此端口的名称
  - name: http
    #Service地址的哪个端口于后端Pods端口映射
    port: 80
    #nodePort: 30080
  - name: https
    port: 443
    #nodePort: 30443
  #定义Server类型为NodePort类型
  type: NodePort
  
4、使用声明式接口创建此Service资源
    ingress]# kubectl apply -f ingress-nginx-svc.yaml
    service/ingress created
  
5、查看定义的Service信息
    ingress]# kubectl get svc -n ingress-nginx
        NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
        ingress   NodePort   10.2.100.124   <none>        80:48420/TCP,443:49572/TCP   51s      #30080    30443
  
6、测试访问此集群中其中一台node地址+映射提供用户访问的端口
    ingress]# curl 192.168.20.177:48420             #可以访问任何的node节点的IP + Port,可以访问到nginx-ingress-controller

4.2、ns-Pod控制器+Service+Tomcat-pod

1、(控制器+Service+pods)创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用) ,以及为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)
    # 1、非自主式Pod,由Deployment控制器管理的提供后端服务的Pod(创建deployment七层代理pods资源清单(后端应用即被代理端pods,七层应用))
    # 2、为上面代理的pods创建service(通过ingress代理service是要引用,service标签选择器匹配的pods)
ingress]# cat myns-deployment-tomcatpods-example.yaml
## ---->(名称空间创建)定义tomcat-pod + service + deployment所属的名称空间
# 定义namespace群组及版本
apiVersion: v1
# 定义资源类型
kind: Namespace
# 元数据
metadata:
  # 名称空间名称
  name: eshop

---
## ----> 定义控制器
# 定义deployment群组名称以及版本
apiVersion: apps/v1
# 定义资源类型
kind: Deployment
# 元数据
metadata:
  # 控制器名称
  name: tomcat-dep
  # 控制器所属的名称空间
  namespace: eshop
# 定义deployment控制器资源规格(标签选择器、pod数量、pod模板)
spec:
  # 定义pods数量
  replicas: 2
  # 匹配的pods的标签选择器
  selector:
    matchLabels:
      app: tomcat
      rel: beta
  # 定义pod创建依据的模板
  template:
    # 定义后端pod的元数据
    metadata:
      # 定义pod的名称
      name: tomcat-pod
      # 定义pod所属的名称空间应该和deployment控制器保持一致
      namespace: eshop
      # 定义pod的标签,应该和deployment控制器匹配后端pod的标签选择器保持一致
      labels:
        app: tomcat
        rel: beta
    # 定义pos的资源的规格
    spec:
      # pod内部运行的容器信息
      containers:
      # pod中容器运行名称
      - name: tomcat-test-con
      # pod内部容器运行的镜像
        image: tomcat:alpine
# 资源界定符
---
## ----> 定义Service资源
# 定义Service资源的群组名称及版本
apiVersion: v1
# 定义资源类型
kind: Service
# 定义Service资源元数据
metadata:
  # 定义service资源的名称(不同资源的名称可以一致)
  name: tomcat-svc
  # 定义所属的名称空间
  namespace: eshop
# 定义service资源规格(标签选择器匹配pod标签、pod数量、pod模板)
spec:
  # 定义Service匹配的后端pod的标签的标签选择器
  selector:
    app: tomcat
    rel: beta
  # 定义service类型默认为cluster
  type: ClusterIP
  # clusterIP: 10.97.97.97
  # ports字段
  ports:
  # 此端口的名称
  - name: http
    # Service地址的哪个端口于后端Pods端口映射
    port: 8080
    # 后端Pods的哪个端口于Service做映射
    targetPort: 8080
  - name: ajp
    port: 8009
    targetPort: 8009

2、使用声明式接口创建资源
	ingress]# kubectl apply -f myns-deployment-tomcatpods-example.yaml 
		namespace/eshop created
		deployment.apps/tomcat-dep created
		service/tomcat-svc created

3、资源创建验证
	# 名称空间
	ingress]# kubectl get ns
		eshop             Active   40s

	# pod控制器资源
	ingress]# kubectl get deploy -n eshop -o wide
		NAME         READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS        IMAGES          SELECTOR
		tomcat-dep   2/2     2            2           2m28s   tomcat-test-con   tomcat:alpine   app=tomcat,rel=beta

	# service资源
	ingress]# kubectl get service -n eshop -o wide
		NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)           AGE     SELECTOR
		tomcat-svc   ClusterIP   10.102.124.114   <none>        8080/TCP,8009/TCP   3m14s   app=tomcat,rel=beta
	ingress]# kubectl describe service -n eshop
		Name:              tomcat-svc
		Namespace:         eshop
		Labels:            <none>
		Annotations:       Selector:  app=tomcat,rel=beta
		Type:              ClusterIP
		IP:                10.102.124.114
		Port:              http  8080/TCP
		TargetPort:        8080/TCP
		Endpoints:         10.244.1.40:8080,10.244.2.24:8080	# pod地址
		Port:              ajp  8009/TCP
		TargetPort:        8009/TCP
		Endpoints:         10.244.1.40:8009,10.244.2.24:8009
		Session Affinity:  None
		Events:            <none>

	# pods资源
	ingress]# kubectl get pods -n eshop -o wide --show-labels
		NAME                          READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES   LABELS
		tomcat-dep-5bdc54686b-9w75x   1/1     Running   0          6m55s   10.244.2.24   k8s.node2   <none>           <none>            app=tomcat,pod-template-hash=5bdc54686b,rel=beta
		tomcat-dep-5bdc54686b-cm5kq   1/1     Running   0          6m55s   10.244.1.40   k8s.node1   <none>           <none>            app=tomcat,pod-template-hash=5bdc54686b,rel=beta

4.3、ingress资源创建(通过ingress-controller七层代理进行调度)

1、创建ingress资源清单
ingress]# cat eshop-ingress-tomcat-pod.yaml 
# 定义ingress资源所属群组名称以及版本
apiVersion: extensions/v1beta1 
# 定义资源类型
kind: Ingress
# 元数据
metadata: 
  # 定义Ingress名称
  name: tomcat-ingress
  # 定义名称空间
  namespace: eshop
  # 定义资源注解
  annotations:
    # url重定向--> 非主要无需关注
    nginx.ingress.kubernetes.io/rewrite-target: /
    # ingress类型为nginx
    kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
  # 定义代理规则
  rules:
  # 定义虚拟主机名称,不写默认为localhost
  - host: www.daizhe.net.cn
    http:
      paths:
      # Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
      - path: /eshop
      # backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port) 
        backend:
          # ingress代理的server名称,之前创建的service为myapp
          serviceName: tomcat-svc
          # service和pods映射的端口(service-->sepc.ports.port)--> 虽然tomcat-svc的service与pod映射了两个端口但是nginx是不支持ajp协议所以仅暴漏一个
          servicePort: 8080



2、使用声明式接口创建资源
	ingress]# kubectl apply -f eshop-ingress-tomcat-pod.yaml 
		ingress.extensions/tomcat-ingress created

3、查看已经创建的ingress资源
[root@k8s ingress]# kubectl get ingress -n eshop
NAME             CLASS    HOSTS               ADDRESS   PORTS   AGE
tomcat-ingress   <none>   www.daizhe.net.cn             80      40s
[root@k8s ingress]# kubectl get ingress -n eshop -o wide
NAME             CLASS    HOSTS               ADDRESS   PORTS   AGE
tomcat-ingress   <none>   www.daizhe.net.cn             80      46s
[root@k8s ingress]# kubectl describe ingress tomcat-ingress 
Error from server (NotFound): ingresses.extensions "tomcat-ingress" not found
[root@k8s ingress]# kubectl describe ingress tomcat-ingress  -n eshop
Name:             tomcat-ingress
Namespace:        eshop
Address:          
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host               Path  Backends
  ----               ----  --------
  www.daizhe.net.cn  
                     /eshop   tomcat-svc:8080 (10.244.1.40:8080,10.244.2.24:8080)#可以查看到对 www.daizhe.net.cn/eshop  地址的访问都会被映射到后端tomcat-svc的service的8080端口响应
                                                								 # 可以查看到service四层代理的后端 pod有10.244.1.40:8080,10.244.2.24:8080
Annotations:         kubernetes.io/ingress.class: nginx
                     nginx.ingress.kubernetes.io/rewrite-target: /
Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  99s   nginx-ingress-controller  Ingress eshop/tomcat-ingress



4、连接ingress-controller验证
    # 手动连入ingress-controller查看配置文件
    ingress]# kubectl get pods -n ingress-nginx
        NAME                                        READY   STATUS    RESTARTS   AGE
        nginx-ingress-controller-5bb8fb4bb6-q5lpg   1/1     Running   0          4h50m
[root@k8s ingress]# kubectl exec -it nginx-ingress-controller-5bb8fb4bb6-q5lpg -n ingress-nginx -- /bin/sh
...
        ## start server www.daizhe.net.cn
        server {
                server_name www.daizhe.net.cn ;
                
                listen 80  ;
                listen 443  ssl http2 ;
                
                set $proxy_upstream_name "-";
                
                ssl_certificate_by_lua_block {
                        certificate.call()
                }
                
                location ~* "^/eshop" {
                        
                        set $namespace      "eshop";
                        set $ingress_name   "tomcat-ingress";
                        set $service_name   "tomcat-svc";
                        set $service_port   "8080";
                        set $location_path  "/eshop";
                        
                        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()
                        }    

...
5、访问验证。由于上面ingress定义的- host: www.daizhe.net.cn/eshop:32145,需要再(本机电脑)宿主机上添加解析测试
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 daizhe.com
192.168.20.236 192.168.20.212 192.168.20.214 www.daizhe.net.cn
    # 访问: http://{ingress.host}:{ingress-controller.控制器-Port.service}
    # 查看ingress-controller.控制器-Port.service
    ~]# kubectl get svc -n ingress-nginx
        NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
        ingress   NodePort   10.98.225.170   <none>        80:32145/TCP,443:31430/TCP   4h23m
  • tomcat中很多资源路径无法找到(问题是修改了location)

image

# 最好不修改location


ingress]# kubectl delete -f eshop-ingress-tomcat-pod.yaml
	ingress.extensions "tomcat-ingress" deleted




ingress]# cat eshop-ingress-tomcat-pod.yaml 
# 定义ingress资源所属群组名称以及版本
apiVersion: extensions/v1beta1 
# 定义资源类型
kind: Ingress
# 元数据
metadata: 
  # 定义Ingress名称
  name: tomcat-ingress
  # 定义名称空间
  namespace: eshop
  # 定义资源注解
  annotations:
    # url重定向--> 非主要无需关注
    nginx.ingress.kubernetes.io/rewrite-target: /
    # ingress类型为nginx
    kubernetes.io/ingress.class: "nginx"
# 定义资源规格
spec:
  # 定义代理规则
  rules:
  # 定义虚拟主机名称,不写默认为localhost
  - host: www.daizhe.com
    http:
      paths:
      # Server中的Url访问的路径映射到backend后端主机的upstream(相当于nginx的location)
      - path: /
      # backend相当于后端的虚拟主机,真正提供服务的upstream (service & service-port) 
        backend:
          # ingress代理的server名称,之前创建的service为myapp
          serviceName: tomcat-svc
          # service和pods映射的端口(service-->sepc.ports.port)--> 虽然tomcat-svc的service与pod映射了两个端口但是nginx是不支持ajp协议所以仅暴漏一个
          servicePort: 8080

image

posted @ 2021-06-13 23:28  SRE运维充电站  阅读(2)  评论(0编辑  收藏  举报