一、什么是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作用
-
基于http-header的路由
-
基于path的路由
-
单个ingress的timeout
-
请求速率limit
-
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-nginx
app.kubernetes.io/name: ingress-nginx
name: ingress-nginx
---
apiVersion: v1
automountServiceAccountToken: true
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx
namespace: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resourceNames:
- ingress-controller-leader
resources:
- configmaps
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission
namespace: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
- namespaces
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io
resources:
- ingressclasses
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission
rules:
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
verbs:
- get
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
apiVersion: v1
data:
allow-snippet-annotations: "true"
kind: ConfigMap
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-controller
namespace: ingress-nginx
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
ports:
- appProtocol: http
name: http
port: 80
protocol: TCP
targetPort: http
- appProtocol: https
name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-controller-admission
namespace: ingress-nginx
spec:
ports:
- appProtocol: https
name: https-webhook
port: 443
targetPort: webhook
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
minReadySeconds: 0
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
spec:
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/key
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.1.1
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: controller
ports:
- containerPort: 80
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
- containerPort: 8443
name: webhook
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
resources:
requests:
cpu: 100m
memory: 90Mi
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
runAsUser: 101
volumeMounts:
- mountPath: /usr/local/certificates/
name: webhook-cert
readOnly: true
dnsPolicy: ClusterFirst
nodeSelector:
kubernetes.io/os: linux
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission-create
namespace: ingress-nginx
spec:
template:
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission-create
spec:
containers:
- args:
- create
- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
- --namespace=$(POD_NAMESPACE)
- --secret-name=ingress-nginx-admission
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
name: create
securityContext:
allowPrivilegeEscalation: false
nodeSelector:
kubernetes.io/os: linux
restartPolicy: OnFailure
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
serviceAccountName: ingress-nginx-admission
---
apiVersion: batch/v1
kind: Job
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission-patch
namespace: ingress-nginx
spec:
template:
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission-patch
spec:
containers:
- args:
- patch
- --webhook-name=ingress-nginx-admission
- --namespace=$(POD_NAMESPACE)
- --patch-mutating=false
- --secret-name=ingress-nginx-admission
- --patch-failure-policy=Fail
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
imagePullPolicy: IfNotPresent
name: patch
securityContext:
allowPrivilegeEscalation: false
nodeSelector:
kubernetes.io/os: linux
restartPolicy: OnFailure
securityContext:
fsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
serviceAccountName: ingress-nginx-admission
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: nginx
spec:
controller: k8s.io/ingress-nginx
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
app.kubernetes.io/component: admission-webhook
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.2.0
name: ingress-nginx-admission
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
name: ingress-nginx-controller-admission
namespace: ingress-nginx
path: /networking/v1/ingresses
failurePolicy: Fail
matchPolicy: Equivalent
name: validate.nginx.ingress.kubernetes.io
rules:
- apiGroups:
- networking.k8s.io
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- ingresses
sideEffects: 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-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
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-backend
namespace: kube-system
spec:
selector:
app: ingress-nginx-controller
ports:
- protocol: TCP
port: 80
targetPort: 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.com
kind: StorageBucket
name: static-assets
rules:
- http:
paths:
- path: /icons
pathType: ImplementationSpecific
backend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: 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: <none>
Events: <none>
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: service1
port:
number: 80
- host: "*.foo.com" # 主机名通配符
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
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.com
kind: IngressParameters
name: 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: test
port:
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.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /bar
pathType: Prefix
backend:
service:
name: service2
port:
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.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
- host: bar.foo.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service2
port:
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.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
- host: second.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service2
port:
number: 80
- http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service3
port:
number: 80
五、TLS
可以通过指定包含 TLS 私钥和证书的
Secret来保护 Ingress。
Ingress 资源仅支持单个 TLS 端口 443,并假定 TLS 在i
ngress 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-tls
namespace: 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.com
secretName: testsecret-tls
rules:
- host: https-example.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
六、通过Ingress暴露的域名访问
6.1、部署好nginx服务
nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
type: NodePort
NodePort方式访问外网:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: "nginx" # Nginx Ingress Controller 根据该注解自动发现 Ingress
spec:
rules:
- host: www.baidu2.com # 对外访问的域名
http:
paths:
- path: /
pathType: Prefix
backend:
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-ingress
annotations:
kubernetes.io/ingress.class: "nginx" # Nginx Ingress Controller 根据该注解自动发现 Ingress
spec:
rules:
- host: www.baidu2.com # 对外访问的域名
http:
paths:
- path: /
pathType: Prefix
backend:
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-tls
namespace: 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-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: www.baidu2.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
tls:
- hosts:
- www.baidu2.com
secretName: 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-tomcat
labels:
app: k8s
spec:
containers:
- name: k8s-tomcat
image: tomcat
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: k8s-tomcat-svc
spec:
selector:
app: k8s
type: NodePort
ports:
- protocol: TCP
port: 8080
targetPort: 8080
执行命令kubectl apply -f k8s_tomcat.yaml部署tomacat。
修改ingress文件:test-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: www.baidu2.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
- host: tomact.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: k8s-tomcat-svc
port:
number: 8080
tls:
- hosts:
- www.baidu2.com
- tomact.com
secretName: 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 - 博客园