18-1、k8s 对外服务之ingress
创始人
2024-02-24 05:16:51

一、什么是ingress

原来的项目是部署在一台电脑上的,这样爬取速度虽然很快,但是我们还能提升,联想到分布式的思想,我们是否可以通过多台电脑进行配合爬取,这样我们的爬取速度就能大幅度提升。                               k8s对外暴露服务service的主要方式是NodePort与LoadBalance,但是随着集群中微服务的增多,NodePort方式缺点是会占用很多集群机器的端口, LoadBalance方式最大的缺点是每个service一个LB,有点浪费和麻烦,而且需要k8s的支持。 而ingress则只需要一个NodePort或者一个LoadBalance就可以满足所有service对外服务的需求,所以通常情况下 我们会设计一个Ingress来做路由的转发,方便统一管理。效果如图:      

 实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的抽象,工作原理类似于nginx,可以理解为在Ingress里建立一个映射规则,ingress controller通过监听Ingress这个api对象里的配置规则并转化成nginx的配置,然后对外部提供服务。

1.1、Ingress组成

主要分为两部分:     Ingresscontroller:是流量的入口,核心是一个deployment,封装了一个web前端负载均衡器,同时在其基础上实现动态感知Ingress并根据Ingress的定义动态生成前端web负载均衡器的配置文件,比如 Nginx Ingress Controller 本质上就是一个 Nginx,只不过它能根据 Ingress 资源的定义动态生成 Nginx 的配置文件,然后动态 Reload。   实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。   ingress resources:Ingress描述具体的路由规则,一个类型为Ingress的k8s api对象,这部分则是面向开发人员。该资源对象定义了不同主机名(域名)及URL和对应后端Service的绑定,根据不同的路径路由http和https流量。  Ingress Controller是将Ingress这种变化生成一段Nginx的配置,然后将这个配置通过Kubernetes API写到Nginx的Pod中,然后reload。 (注意:写入 nginx.conf 的不是service的地址,而是service backend 的 pod 的地址,避免在 service 再增加一层负载均衡转发)

    从上图看出,实际上请求进来还是被负载均衡器拦截了,比如nginx,然后ingress controller通过跟ingress交互得知某个域名对应哪个service,再通过跟kubernetes API交互得知service地址等信息,综合以后生成配置文件实时写入负载均衡器(nginx),然后负载均衡器reload该规则便可实现服务发现,即动态映射。

1.2、Ingress作用

  1. 基于http-header的路由
  2. 基于path的路由
  3. 单个ingress的timeout
  4. 请求速率limit
  5. rewrite规则
Ingress 可以提供负载平衡、SSL终止 和 基于名称的虚拟主机。 当然在实际应用中,最新版本 Kubernetes 已经将 Nginx 与 Ingress Controller 合并为一个组件,所以 Nginx 无需单独部署,只需要部署 Ingress Controller 即可。

二、helm 裸机部署 Nginx Ingress Controller   

基于 Nginx 的 Ingress Controller 有两种,一种是 k8s 社区提供的 ingress-nginx,另一种是 Nginx 社区提供的 kubernetes-igress,关于两者的区别见 这里。 yaml文件中的镜像不能下载可以换其他的image: nginx-ingress.yaml:
apiVersion: v1
kind: Namespace
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxname: ingress-nginx
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginxnamespace: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginxnamespace: ingress-nginx
rules:
- apiGroups:- ""resources:- namespacesverbs:- get
- apiGroups:- ""resources:- configmaps- pods- secrets- endpointsverbs:- get- list- watch
- apiGroups:- ""resources:- servicesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingressesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingresses/statusverbs:- update
- apiGroups:- networking.k8s.ioresources:- ingressclassesverbs:- get- list- watch
- apiGroups:- ""resourceNames:- ingress-controller-leaderresources:- configmapsverbs:- get- update
- apiGroups:- ""resources:- configmapsverbs:- create
- apiGroups:- ""resources:- eventsverbs:- create- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admissionnamespace: ingress-nginx
rules:
- apiGroups:- ""resources:- secretsverbs:- get- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx
rules:
- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secrets- namespacesverbs:- list- watch
- apiGroups:- ""resources:- nodesverbs:- get
- apiGroups:- ""resources:- servicesverbs:- get- list- watch
- apiGroups:- networking.k8s.ioresources:- ingressesverbs:- get- list- watch
- apiGroups:- ""resources:- eventsverbs:- create- patch
- apiGroups:- networking.k8s.ioresources:- ingresses/statusverbs:- update
- apiGroups:- networking.k8s.ioresources:- ingressclassesverbs:- get- list- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admission
rules:
- apiGroups:- admissionregistration.k8s.ioresources:- validatingwebhookconfigurationsverbs:- get- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginxnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx
subjects:
- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admissionnamespace: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: ingress-nginx-admission
subjects:
- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:app.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx
subjects:
- kind: ServiceAccountname: ingress-nginxnamespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admission
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: ingress-nginx-admission
subjects:
- kind: ServiceAccountname: ingress-nginx-admissionnamespace: ingress-nginx
---
apiVersion: v1
data:allow-snippet-annotations: "true"
kind: ConfigMap
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-controllernamespace: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-controllernamespace: ingress-nginx
spec:ports:- appProtocol: httpname: httpport: 80protocol: TCPtargetPort: http- appProtocol: httpsname: httpsport: 443protocol: TCPtargetPort: httpsselector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: NodePort
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-controller-admissionnamespace: ingress-nginx
spec:ports:- appProtocol: httpsname: https-webhookport: 443targetPort: webhookselector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtype: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-controllernamespace: ingress-nginx
spec:minReadySeconds: 0revisionHistoryLimit: 10selector:matchLabels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxspec:containers:- args:- /nginx-ingress-controller- --election-id=ingress-controller-leader- --controller-class=k8s.io/ingress-nginx- --ingress-class=nginx- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller- --validating-webhook=:8443- --validating-webhook-certificate=/usr/local/certificates/cert- --validating-webhook-key=/usr/local/certificates/keyenv:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: LD_PRELOADvalue: /usr/local/lib/libmimalloc.soimage: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1imagePullPolicy: IfNotPresentlifecycle:preStop:exec:command:- /wait-shutdownlivenessProbe:failureThreshold: 5httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1name: controllerports:- containerPort: 80name: httpprotocol: TCP- containerPort: 443name: httpsprotocol: TCP- containerPort: 8443name: webhookprotocol: TCPreadinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 1resources:requests:cpu: 100mmemory: 90MisecurityContext:allowPrivilegeEscalation: truecapabilities:add:- NET_BIND_SERVICEdrop:- ALLrunAsUser: 101volumeMounts:- mountPath: /usr/local/certificates/name: webhook-certreadOnly: truednsPolicy: ClusterFirstnodeSelector:kubernetes.io/os: linuxserviceAccountName: ingress-nginxterminationGracePeriodSeconds: 300volumes:- name: webhook-certsecret:secretName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admission-createnamespace: ingress-nginx
spec:template:metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admission-createspec:containers:- args:- create- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc- --namespace=$(POD_NAMESPACE)- --secret-name=ingress-nginx-admissionenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceimage: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1imagePullPolicy: IfNotPresentname: createsecurityContext:allowPrivilegeEscalation: falsenodeSelector:kubernetes.io/os: linuxrestartPolicy: OnFailuresecurityContext:fsGroup: 2000runAsNonRoot: truerunAsUser: 2000serviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admission-patchnamespace: ingress-nginx
spec:template:metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admission-patchspec:containers:- args:- patch- --webhook-name=ingress-nginx-admission- --namespace=$(POD_NAMESPACE)- --patch-mutating=false- --secret-name=ingress-nginx-admission- --patch-failure-policy=Failenv:- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceimage: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1imagePullPolicy: IfNotPresentname: patchsecurityContext:allowPrivilegeEscalation: falsenodeSelector:kubernetes.io/os: linuxrestartPolicy: OnFailuresecurityContext:fsGroup: 2000runAsNonRoot: truerunAsUser: 2000serviceAccountName: ingress-nginx-admission
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: nginx
spec:controller: k8s.io/ingress-nginx
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:labels:app.kubernetes.io/component: admission-webhookapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.2.0name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:- v1clientConfig:service:name: ingress-nginx-controller-admissionnamespace: ingress-nginxpath: /networking/v1/ingressesfailurePolicy: FailmatchPolicy: Equivalentname: validate.nginx.ingress.kubernetes.iorules:- apiGroups:- networking.k8s.ioapiVersions:- v1operations:- CREATE- UPDATEresources:- ingressessideEffects: None
执行命令kubectl apply -f nginx-ingress.yaml

查看:kubectl get pods -n ingress-nginx -o wide:

三、Ingress resource

一个最小的Ingress资源示例:service/networking/minimal-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: minimal-ingressannotations:nginx.ingress.kubernetes.io/rewrite-target: /
spec:ingressClassName: nginx-examplerules:- http:paths:- path: /testpathpathType: Prefixbackend:service:name: testport:number: 80
1、Ingress需要apiVersion、kind、metadata字段; 2、Ingress对象的名称必须是有效的 DNS subdomain name.。 3、Ingress spec包含配置负载均衡器 或 代理服务器所需的所有信息,最重要的是它包含与所有传入请求匹配的规则列表。Ingress resource仅支持引导HTTP(S)流量的规则。 4、Ingress rules: 每个HTTP规则都包含以下信息:
  • host:可选主机,在此示例中,未指定主机,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 流量。 如果提供了主机(例如 foo.bar.com),则规则适用于该主机。
  • paths列表(例如 /testpath),每个路径都有一个关联的 backend,该后端使用 service.name 和 service.port.name 或 service.port.number 定义。 在负载均衡器将流量定向到引用的服务之前,host和path都必须匹配传入请求的内容。
  • backend是Service文档中描述的服务和端口名称的组合,或者是通过 CRD 的自定义资源后端。 对与规则的主机和路径匹配的 Ingress 的 HTTP(和 HTTPS)请求将发送到列出的后端。
defaultBackend通常在 Ingress controller中配置,以服务与规范中的路径不匹配的任何请求。

3.1、DefaultBackend

没有rules的 Ingress 将所有流量发送到单个默认后端。 defaultBackend 通常是  Ingress controller 的配置选项,并且未在 Ingress resource中指定。 如果没有任何主机或路径与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到您的默认后端。 使用kubectl get service -n kube-system查看在命名空间 kube-system 是否有 default-back-end 服务。 若没有,使用下面的 yaml 文件创建 default-back-end 服务: backend.yaml:
apiVersion: v1
kind: Service
metadata:name: default-http-backendnamespace: kube-system
spec:selector:app: ingress-nginx-controllerports:- protocol: TCPport: 80targetPort: 80

3.2、Resource backends

资源后端是与 Ingress 对象位于同一命名空间中的另一个 Kubernetes 资源的 ObjectRef。service/networking/ingress-resource-backend.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-resource-backend
spec:defaultBackend:resource:apiGroup: k8s.example.comkind: StorageBucketname: static-assetsrules:- http:paths:- path: /iconspathType: ImplementationSpecificbackend:resource:apiGroup: k8s.example.comkind: StorageBucketname: icon-assets
创建好Ingress后,使用kubectl describe ingress ingress-resource-backend查看:
​
Name: ingress-resource-backend
Namespace: default
Address:
Default backend: APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assets
Rules:
Host Path Backends
---- ---- --------
*
/icons APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assets
Annotations: 
Events: 

3.3、Path types

Ingress中的每条path都需要相应的pathType,不包含显示pathType的路径将无法通过验证。 支持三种路径类型:
  • ImplementationSpecific: 使用这种路径类型,匹配取决于 IngressClass。 实现可以将其视为单独的 pathType 或将其视为 Prefix 或 Exact 路径类型。
  • Exact: 精确匹配 URL 路径并区分大小写。
  • Prefix: 基于由 / 分隔的 URL 路径前缀进行匹配。 匹配区分大小写,并在逐个元素的路径元素基础上完成。 路径元素是指由 / 分隔符分割的路径中的标签列表。 如果每个 p 都是请求路径的 p 的元素前缀,则请求是路径 p 的匹配项。
在某些情况下,一个 Ingress 中的多个路径paths将匹配一个请求。 在这些情况下,将优先考虑最长的匹配路径。 如果两条路径仍然相等匹配,则具有精确路径类型的路径将优先于前缀路径类型。

3.4、Hostname wildcards(主机名通配符)

Host可以是精确匹配(例如“foo.bar.com”)或通配符(例如“*.foo.com”)。 精确匹配要求 HTTP 主机标头与主机字段匹配。 通配符匹配要求 HTTP 主机标头等于通配符规则的后缀。 service/networking/ingress-wildcard-host.yaml:
​
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-wildcard-host
spec:rules:- host: "foo.bar.com"http:paths:- pathType: Prefix # 前缀匹配path: "/bar"backend:service:name: service1port:number: 80- host: "*.foo.com" # 主机名通配符http:paths:- pathType: Prefixpath: "/foo"backend:service:name: service2port:number: 80

3.5、Ingress class

Ingresses可由不同的controllers实现通常具有不同的配置。每个 Ingress 都应该指定一个类,一个对 IngressClass 资源的引用,该资源包含额外的配置,包括应该实现该类的控制器的名称。 service/networking/external-lb.yaml:
​
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:name: external-lb
spec:controller: example.com/ingress-controller # 要使用的具体参数类型取决于您在 IngressClass 的 .spec.controller 字段中指定的入口控制器parameters:apiGroup: k8s.example.comkind: IngressParametersname: external-lb

四、Type of Ingress

4.1、Ingress backed by a single Service

现有的 Kubernetes 概念允许您公开单个服务(请参阅替代方案 alternatives)。 您也可以通过指定没有规则的默认后端来使用 Ingress 执行此操作。 service/networking/test-ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: test-ingress
spec:defaultBackend:service:name: testport:number: 80
kubectl apply -f后查看Ingress的状态 kubectl get ingress test-ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress external-lb * 203.0.113.123 80 59s
其中 203.0.113.123 是 Ingress controller为满足这个 Ingress 而分配的 IP。

4.2、Simple fanout

根据请求的HTTP URI将流量从单个IP地址路由到多个服务。Ingress允许你将负载均衡器的数量降至最低。 上图中的设置将需要如下的Ingress: service/networking/simple-fanout-example.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: simple-fanout-example
spec:rules:- host: foo.bar.comhttp:paths:- path: /foopathType: Prefixbackend:service:name: service1port:number: 4200- path: /barpathType: Prefixbackend:service:name: service2port:number: 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)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test

4.3、Name based virtual hosting(基于名称的虚拟主机)

基于名称的虚拟主机支持将 HTTP 流量路由到同一 IP 地址的多个主机名。 以下 Ingress 告诉后端负载均衡器根据 Host 标头路由请求: service/networking/name-virtual-host-ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: name-virtual-host-ingress
spec:rules:- host: foo.bar.comhttp:paths:- pathType: Prefixpath: "/"backend:service:name: service1port:number: 80- host: bar.foo.comhttp:paths:- pathType: Prefixpath: "/"backend:service:name: service2port:number: 80
如果您创建了一个没有在规则中定义任何主机的 Ingress 资源,则可以匹配到您的 Ingress 控制器 IP 地址的任何 Web 流量,而无需基于名称的虚拟主机 例如,以下 Ingress 将对 first.bar.com 请求的流量路由到 service1,将 second.bar.com 请求到 service2,并将请求主机标头与 first.bar.com 和 second.bar.com 不匹配的任何流量路由到 service3 . service/networking/name-virtual-host-ingress-no-third-host.yaml:
​apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: name-virtual-host-ingress-no-third-host
spec:rules:- host: first.bar.comhttp:paths:- pathType: Prefixpath: "/"backend:service:name: service1port:number: 80- host: second.bar.comhttp:paths:- pathType: Prefixpath: "/"backend:service:name: service2port:number: 80- http:paths:- pathType: Prefixpath: "/"backend:service:name: service3port:number: 80

五、TLS

可以通过指定包含 TLS 私钥和证书的 Secret来保护 Ingress。 Ingress 资源仅支持单个 TLS 端口 443,并假定 TLS 在ingress point终止(到 Service 及其 Pod 的流量是明文形式)。 如果 Ingress 中的 TLS 配置部分指定了不同的主机,则它们根据通过 SNI TLS 扩展指定的主机名在同一端口上多路复用(前提是 Ingress 控制器支持 SNI)。 TLS的secret 必须包含名为 tls.crt 和 tls.key 的密钥,其中包含用于 TLS 的证书和私钥。 例如:

执行命令生成ssl证书:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=CHINA/O=EDU"

生成secret:

kubectl create secret tls testsecret-tls --key tls.key --cert tls.crt

或者yaml生成:testsecret-tls.yaml:

apiVersion: v1
kind: Secret
metadata:name: testsecret-tlsnamespace: default
data:tls.crt: base64 encoded cert # 私钥文件crt值tls.key: base64 encoded key # ssl证书文件key值
type: kubernetes.io/tls
在 Ingress 中引用这个 secret 会告诉 Ingress controller使用 TLS 保护从客户端到负载均衡器的通道。 您需要确保您创建的 TLS 机密来自包含通用名称 (CN) 的证书,也称为 https-example.foo.com 的完全限定域名 (FQDN)。 Note: 请记住,TLS 不适用于默认规则,因为必须为所有可能的子域颁发证书。 因此,tls 部分中的主机需要显式匹配规则部分中的主机。 service/networking/tls-example-ingress.yaml:
​apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: tls-example-ingress
spec:tls:- hosts:- https-example.foo.comsecretName: testsecret-tlsrules:- host: https-example.foo.comhttp:paths:- path: /pathType: Prefixbackend:service:name: service1port:number: 80

六、通过Ingress暴露的域名访问

6.1、部署好nginx服务

nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:selector:           matchLabels:app: nginxreplicas: 1template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:name: nginx-svc
spec:selector:app: nginxports:- port: 80targetPort: 80nodePort: 30080type: NodePort
NodePort方式访问外网:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: test-ingressannotations:kubernetes.io/ingress.class: "nginx" # Nginx Ingress Controller 根据该注解自动发现 Ingress
spec:rules:- host: www.baidu2.com # 对外访问的域名http:paths:- path: /pathType: Prefixbackend:service:name: nginx-svc # 对外暴露的 Service 名称port:number: 80 # nginx service 监听的端口
​

6.2、通过helm部署 Nginx Ingress Controller

见章节二

6.3、创建ingress

test-ingress.yaml: 创建的 Ingress 必须要和对外暴露的 Service 在同一命名空间下!
​apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: test-ingressannotations:kubernetes.io/ingress.class: "nginx" # Nginx Ingress Controller 根据该注解自动发现 Ingress
spec:rules:- host: www.baidu2.com # 对外访问的域名http:paths:- path: /pathType: Prefixbackend:service:name: nginx-svc # 对外暴露的 Service 名称port:number: 80 # nginx service 监听的端口
​
执行kubectl apply -f test-ingress.yaml创建ingress。 kubectl get ingress查看ingress:

6.4、通过ingress暴露域名访问

因为没有域名,简单模拟,在master节点机器的/etc/hosts添加 10.244.2.113 www.baidu2.com。注意10.244.2.113是Nginx Ingress Controller的IP。这种只能在集群内部访问(访问端口是80),其他人电脑无法访问。 若要其他人电脑也能访问,则添加192.168.11.45 www.baidu2.com, 192.168.11.45是ingress-nginx所在的主机,也是master节点。此时的访问地址:http://www.baidu2.com:31046/ master节点上直接用域名访问:curl www.baidu2.com master节点虚拟机网页访问:http://www.baidu2.com

6.5、https配置访问

见章节五
apiVersion: v1
kind: Secret
metadata:name: testsecret-tlsnamespace: default
data:tls.crt: base64 encoded cert # 私钥文件crt值tls.key: base64 encoded key # ssl证书文件key值
type: kubernetes.io/tls
修改ingress文件:
​apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: test-ingressannotations:kubernetes.io/ingress.class: "nginx"
spec:rules:- host: www.baidu2.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svcport:number: 80tls:- hosts:- www.baidu2.comsecretName: testsecret-tls
验证https方式访问: 看看ingress-controller的实现方式,进入ingress-controller的pod: kubectl -n ingress-nginx exec -it ingress-nginx-controller-59f89cb466-q8xmw bash 查看nginx.conf文件,cat /etc/nginx/nginx.conf:

6.6、集群外访问(外网访问)

在/etc/hosts文件添加10.244.2.113 www.baidu2.com,这种只能在集群内部访问(端口是80或者443),其他人电脑无法访问。 若要其他人电脑也能访问,则添加192.168.11.45 www.baidu2.com, 192.168.11.45是ingress-nginx所在的主机,也是master节点。此时访问端口是31046(http访问)或32393(https访问) 在其他电脑上修改hosts文件,添加  192.168.11.45 www.baidu2.com。 其他电脑访问: 配置https前: http://www.baidu2.com:31046/ 配置https后: https://www.baidu2.com:32393/

6.7、再部署一个服务tomcat

k8s_tomcat.yaml:
apiVersion: v1
kind: Pod
metadata:name: k8s-tomcatlabels:app: k8s
spec:containers:- name: k8s-tomcatimage: tomcatports:- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:name: k8s-tomcat-svc
spec:selector:app: k8stype: NodePortports:- protocol: TCPport: 8080targetPort: 8080

执行命令kubectl apply -f k8s_tomcat.yaml部署tomacat。

修改ingress文件:test-ingress.yaml
​apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: test-ingressannotations:kubernetes.io/ingress.class: "nginx"
spec:rules:- host: www.baidu2.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-svcport:number: 80- host: tomact.comhttp:paths:- path: /pathType: Prefixbackend:service:name: k8s-tomcat-svcport:number: 8080tls:- hosts:- www.baidu2.com- tomact.comsecretName: testsecret-tls
在其他电脑上修改hosts文件,添加  192.168.11.45 tomact.com, 网页访问:https://tomact.com:32393

七、参考

Ingress | Kubernetes   Installation Guide - NGINX Ingress Controller 【k8s】kubernetes之ingress error: endpoints “default-http-backend“ not found_云川之下的博客-CSDN博客 k8s之Ingress 实现 http 代理访问 - wangzy-Zj - 博客园

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...