ingress是k8s中的标准API资源,作用是定义外部流量如何进入集群,并根据核心路由规则将流量转发到集群内的服务。
ingress和Istio工作栈中的virtual service都是基于service之上,更细致准确的一种流量规则。每一个pod对应的service是四层代理,也就是说处于通信网络结构的第四层(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层)。service只根据tcp或udp协议,确定主机的位置,而不能确定到底传送到哪一个服务,这是http\https等七层的协议来处理的,这就是ingress 和 virtual service工作的场景。总的来说,ingress 是工作在service aip资源之上的。
ingress
Ingress 简单的理解就是你原来需要改 Nginx 配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yaml 创建,每次不要去改 Nginx 了,直接改 yaml 然后创建/更新就行了。
ingress controller
使用ingress controller代理k8s内部应用的流程
部署ingress controller
通过部署ingress-controller的pod和default-backend的pod,成功部署了ingress服务。其中default-backend作为一个默认的ingress controller的后端。
默认后端 是一个提供基础响应的服务,当没有任何 Ingress 规则与传入的请求匹配时,Ingress Controller 会将请求路由到这个默认后端。它通常用于处理以下情况:
- 404 响应:当用户请求的路径或主机名没有被任何定义的 Ingress 规则匹配时,默认后端会返回一个标准的 404 - Not Found 响应。
- 健康检查:默认后端通常也会提供一个健康检查接口(如
/healthz
),供 Ingress Controller 或其他服务检查其健康状态。
这里的ingress controller通过args变量里的--default-backend-serivce参数,在没有ingress的情况下将流量转发给backend服务。
ingress controller代码
可以看到ingress controller使用了两个探针,分别是就绪探针和存活探针。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
labels:
k8s-app: nginx-ingress-controller
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
k8s-app: nginx-ingress-controller
template:
metadata:
labels:
k8s-app: nginx-ingress-controller
spec:
# hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
# however, it is not a hard dependency of the nginx-ingress-controller itself and it may cause issues if port 10254 already is taken on the host
# that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
# like with kubeadm
# hostNetwork: true #注释表示不使用宿主机的80口,
terminationGracePeriodSeconds: 60
hostNetwork: true #表示容器使用和宿主机一样的网络
serviceAccountName: nginx-ingress-serviceaccount #引用前面创建的serviceacount
containers:
- image: registry.cn-hangzhou.aliyuncs.com/peter1009/nginx-ingress-controller:0.20.0 #容器使用的镜像
name: nginx-ingress-controller #容器名
readinessProbe: #启动这个服务时要验证/healthz 端口10254会在运行的node上监听。
httpGet:
path: /healthz
port: 10254
scheme: HTTP
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10 #每隔10做健康检查
timeoutSeconds: 1
ports:
- containerPort: 80
hostPort: 80 #80映射到80
# - containerPort: 443
# hostPort: 443
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
args:
- /nginx-ingress-controller
- --default-backend-service=$(POD_NAMESPACE)/default-http-backend
# - --default-ssl-certificate=$(POD_NAMESPACE)/ingress-secret #这是启用Https时用的
# nodeSelector: #指明运行在哪,此IP要和default backend是同一个IP
# kubernetes.io/hostname: 10.3.1.17 #上面映射到了hostport80,确保此IP80,443没有占用.
#
nodeName: node1
这里的环境变量抓取了ingress controller运行的pod的名称和namespace的值。并且写明了是一个针对nginx的ingress controller。
default backend代码
这里定义了一个deployment和一个service。这里和上面ingress controller都将pod部署在node1
节点,这两个pod需要被部署在相同的节点。
apiVersion: apps/v1
kind: Deployment
metadata:
name: default-http-backend
labels:
k8s-app: default-http-backend
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
k8s-app: default-http-backend
template:
metadata:
labels:
k8s-app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
# Any image is permissable as long as:
# 1. It serves a 404 page at /
# 2. It serves 200 on a /healthz endpoint
image: registry.cn-hangzhou.aliyuncs.com/hachikou/defaultbackend:1.0
livenessProbe:
httpGet:
path: /healthz #这个URI是 nginx-ingress-controller中nginx里配置好的localtion
port: 8080
scheme: HTTP
initialDelaySeconds: 30 #30s检测一次/healthz
timeoutSeconds: 5
ports:
- containerPort: 8080
# resources:
# limits:
# cpu: 10m
# memory: 20Mi
# requests:
# cpu: 10m
# memory: 20Mi
nodeName: node1
---
apiVersion: v1
kind: Service #为default backend 创建一个service
metadata:
name: default-http-backend
namespace: kube-system
labels:
k8s-app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
k8s-app: default-http-backend
还需要配合rbac代码,这里不再列举。
不同的ingress controller
一个 Ingress Controller
实例通常对应一种特定的反向代理。例如,nginx-ingress-controller
仅支持 NGINX 作为反向代理,而 traefik-ingress-controller
只支持 Traefik。但你可以在同一个 Kubernetes 集群中运行多个不同类型的 Ingress Controller
,每个控制器处理不同的 Ingress
资源或不同的域名。
nginx ingress controller 是k8s中最常使用的ingress controller。
traefik ingress controller是专门针对http/https的反向代理和负载均衡器,更适合微服务。
HAProxy Ingress Controller是基于 HAProxy 的ingress controller,Envoy Ingress Controller使用 Envoy 作为反向代理,通常在基于服务网格的架构中使用。