一、引言
在 Kubernetes 中,Ingress 是一种 API 对象,用于管理外部访问集群服务的方式,通常是 HTTP 和 HTTPS 流量。可以将 Ingress 理解为一个智能的路由器,它根据请求的 URL 路径或主机名将流量路由到不同的服务。
主要功能:
路由
:Ingress 可以根据请求的 URL 路径或主机名将流量路由到不同的服务。例如,你可以将 example.com/api 的请求路由到一个服务,而将 example.com/app 的请求路由到另一个服务。负载均衡
:Ingress 可以在多个后端服务之间分配流量,从而实现负载均衡。SSL/TLS 终止
:Ingress 可以处理 SSL/TLS 加密,允许你在 Ingress 控制器中配置证书,而不是在每个服务中配置。基于主机和路径的路由
:Ingress 支持基于主机名和路径的路由规则,使得多个服务可以通过同一个 IP 地址和端口进行访问。
1、把端口号对外暴露,通过 IP+端口号 进行访问。
1)使用 Service 里面的 NodePort 实现。
2、NodePort 缺陷
1)在每个节点上都会启动端口,在访问时候通过任何节点,通过节点 IP+暴露端口号 实现访问。
2)意味着每个端口只能使用一次,一个端口对应一个应用。
3)实际访问中都是用域名,根据不同域名跳转到不同端口服务中。
二、Ingress概述
通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 将其转发给相关的 Pod。
Ingress 为 Kubernetes 集群中的服务提供了入口,可以提供负载均衡、SSL 终止和基于名称的虚拟主机,在生产环境中常用的 Ingress
有 Treafik、Nginx、HAProxy、Istio
等。在 Kubernetes v1.1 版中添加的 Ingress 用于从集群外部到集群内部 Service 的 HTTP 和 HTTPS 路由,流量从 Internet 到 Ingress 再到 Services 最后到 Pod 上,通常情况下,Ingress 部署在所有的 Node 节点上。Ingress 可以配置提供服务外部访问的 URL、负载均衡、终止SSL,并提供基于域名的虚拟主机。但 Ingress 不会暴露任意端口或协议。
三、Ingress 工作流程
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort
或 Service.Type=LoadBalancer
类型的服务。
四、Ingress 控制器(官方维护)
4.1、官方维护 Ingress 控制器
为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。
与作为 kube-controller-manager 可执行文件的一部分运行的其他类型的控制器不同, Ingress 控制器不是随集群自动启动的。 基于此页面,你可选择最适合你的集群的 ingress 控制器实现。
Kubernetes 作为一个项目,目前支持和维护 AWS
, GCE
和 nginx Ingress
控制器。
4.2、其他 Ingress 控制器
AKS
应用程序网关 Ingress 控制器 是一个配置 Azure 应用程序网关 的 Ingress 控制器。Ambassador API
网关是一个基于 Envoy 的 Ingress 控制器。Apache APISIX Ingress
控制器 是一个基于 Apache APISIX 网关 的 Ingress 控制器。Avi Kubernetes Operator
使用 VMware NSX Advanced Load Balancer 提供第 4 到第 7 层的负载均衡。BFE Ingress
控制器 是一个基于 BFE 的 Ingress 控制器。Citrix Ingress
控制器 可以用来与 Citrix Application Delivery Controller 一起使用。Contour
是一个基于 Envoy 的 Ingress 控制器。EnRoute
是一个基于 Envoy API 网关, 可以作为 Ingress 控制器来执行。Easegress IngressController
是一个基于 Easegress API 网关,可以作为 Ingress 控制器来执行。F5 BIG-IP
的用于 Kubernetes 的容器 Ingress 服务 让你能够使用 Ingress 来配置 F5 BIG-IP 虚拟服务器。Gloo
是一个开源的、基于 Envoy 的 Ingress 控制器,能够提供 API 网关功能,HAProxy Ingress
针对 HAProxy 的 Ingress 控制器。- 用于 Kubernetes 的
HAProxy Ingress
控制器 也是一个针对 HAProxy 的 Ingress 控制器。 Istio Ingress
是一个基于 Istio 的 Ingress 控制器。- 用于 Kubernetes 的
Kong Ingress
控制器 是一个用来驱动 Kong Gateway 的 Ingress 控制器。 - 用于 Kubernetes 的
NGINX Ingress
控制器 能够与 NGINX Web 服务器(作为代理) 一起使用。 Skipper HTTP
路由器和反向代理可用于服务组装,支持包括 Kubernetes Ingress 这类使用场景, 设计用来作为构造你自己的定制代理的库。Traefik Kubernetes Ingress
提供程序 是一个用于 Traefik 代理的 Ingress 控制器。Tyk Operator
使用自定义资源扩展 Ingress,为之带来 API 管理能力。Tyk Operator 使用开源的 Tyk Gateway & Tyk Cloud 控制面。Voyager
是一个针对 HAProxy 的 Ingress 控制器。
五、安装Nginx-Ingress
访问架构图:
5.1、helm 安装 Ingress
#1.新建ingress存放目录
[root@kubernetes-master-001 ~]# mkdir ingress && cd ingress
#2.添加官方ingress-nginx的helm仓库
[root@kubernetes-master-001 ~/ingress]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
"ingress-nginx" has been added to your repositories
#3.搜索仓库中已有的ingress-nginx版本信息(建议安装0.40.2以上的版本)
[root@kubernetes-master-001 ~/ingress]# helm search repo ingress-nginx
NAME CHART VERSION APP VERSION DESCRIPTION
ingress-nginx/ingress-nginx 4.0.9 1.0.5 Ingress controller for Kubernetes using NGINX a...
#4.拉取ingress-nginx的包
helm pull [repo名称/chart名称]
[root@kubernetes-master-001 ~/ingress]# helm pull ingress-nginx/ingress-nginx
#5.解压包,修改values.yaml配置文件
[root@kubernetes-master-001 ~/ingress]# tar -xf ingress-nginx-4.0.9.tgz && cd ingress-nginx
#6.修改values.yaml
# 修改镜像
# 注释掉registry,image,digest,并打开repository
repository: willdockerhub/ingress-nginx-controller
tag: "v1.0.5"
repository: jettech/kube-webhook-certgen
tag: v1.5.2
repository: mirrorgooglecontainers/defaultbackend-amd64
tag: "1.5"
#修改dns策略
dnsPolicy: ClusterFirstWithHostNet
# 使用hostNetwork,即使用宿主机上的端口80 443
hostNetwork: false
# 使用DaemonSet,将ingress部署在指定节点上
kind: DaemonSet
# 节点选择,将需要部署的节点打上ingress=true的label
nodeSelector:
kubernetes.io/os: linux
ingress: "true"
# 选择节点打label
kubectl label node node01 ingress=true
# 创建一个ingress的namespace
kubectl create ns ingress-nginx
# 创建ingress
# 如果提示cannot re-use a name that is still in use
# 则先helm uninstall ingress-nginx --namespace ingress-nginx
# 如果安装完成后无法访问其他节点日志,则需要配置hosts,将所有节点配置到hosts中即可
helm install ingress-nginx ingress-nginx -n ingress-nginx
5.2、直接部署安装
#1.部署ingress-nginx 比较简单,直接下载github上的 deploy.yaml 部署即可,由于网络问题镜像如果拉取失败,我们可以直接去GitHub复制这个yaml文件
[root@kubernetes-master-001 ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml
#2.修改镜像地址
[root@kubernetes-master-001 ~]# sed -i 's@k8s.gcr.io/ingress-nginx/controller:v1.0.0\(.*\)@willdockerhub/ingress-nginx-controller:v1.0.0@' deploy.yaml
[root@kubernetes-master-001 ~]# sed -i 's@k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0\(.*\)$@hzde0128/kube-webhook-certgen:v1.0@' deploy.yaml
#3.安装ingress-nginx
[root@kubernetes-master-001 ~]# kubectl apply -f ingress-1.0.0.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx configured
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx configured
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
ingressclass.networking.k8s.io/nginx configured
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission configured
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission configured
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission configured
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
#4.查看ingress-nginx状态
[root@kubernetes-master-001 ~]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-fgcrk 0/1 Completed 0 20m
ingress-nginx-admission-patch-b6d96 0/1 Completed 0 20m
ingress-nginx-controller-6b64bc6f47-4sd7g 1/1 Running 0 20m
[root@kubernetes-master-001 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.107.105.141 <none> 80:31386/TCP,443:31083/TCP 20m
ingress-nginx-controller-admission ClusterIP 10.103.7.53 <none> 443/TCP 20m
六、部署示例验证
6.1、创建 Pod
[root@kubernetes-master-001 ~]# kubectl create deployment web --image=nginx
deployment.apps/web created
[root@kubernetes-master-001 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-96d5df5c8-prps4 1/1 Running 0 44s
6.2、对外暴露应用
[root@kubernetes-master-001 ~]# kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
service/web exposed
[root@kubernetes-master-001 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d23h
web NodePort 10.106.214.3 <none> 80:30645/TCP 4d23h
6.3、创建Ingress规则
[root@kubernetes-master-001 ~]# vi ingress-http.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: example.ingredemo.com
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: web
port:
number: 80
[root@kubernetes-master-001 ~]# kubectl apply -f ingress-http.yaml
ingress.networking.k8s.io/example-ingress created
[root@kubernetes-master-001 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.107.105.141 <none> 80:31386/TCP,443:31083/TCP 3h55m
ingress-nginx-controller-admission ClusterIP 10.103.7.53 <none> 443/TCP 3h55m
[root@kubernetes-master-001 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress <none> example.ingredemo.com 80 5s
七、Ingress-Nginx优化
上面每次部署 ingres-nginx 都随机一个nodePort ,而使用ingres-nginx访问的时候也要以 域名:端口 的形式去访问如何直接使用域名去访问呢?下面介绍hostNetwork 的方式部署Ingress-Nginx。
7.1、下载Ingress-Nginx
[root@kubernetes-master-001 ~]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml
[root@kubernetes-master-001 ~]# sed -i 's@k8s.gcr.io/ingress-nginx/controller:v1.0.0\(.*\)@willdockerhub/ingress-nginx-controller:v1.0.0@' deploy.yaml
[root@kubernetes-master-001 ~]# sed -i 's@k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0\(.*\)$@hzde0128/kube-webhook-certgen:v1.0@' deploy.yaml
7.2、使用hostNetwork
默认 ingress-nginx 随机提供 nodeport 端口,开启 hostNetwork 启用80、443端口。
修改 Deployment 下面的 spec
参数如下:
spec:
hostNetwork: true # 新增
dnsPolicy: ClusterFirst
containers:
- name: controller
image: willdockerhub/ingress-nginx-controller:v1.0.0 # 更换镜像地址
imagePullPolicy: IfNotPresent
lifecycle:
7.3、修改负载均衡问题
把 kind: Deployment 改为 kind: DaemonSet 模式,这样每台 node 上都有 ingress-nginx-controller pod 副本。
参数如下:
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
#kind: Deployment # 注释
kind: DaemonSet # 新增
metadata:
labels:
helm.sh/chart: ingress-nginx-4.0.1
7.4、修改 ingressClass 问题
如果不关心 ingressClass 或者很多没有 ingressClass 配置的 ingress 对象,
添加参数 ingress-controller --watch-ingress-without-class=true 。
args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller
- --election-id=ingress-controller-leader
- --controller-class=k8s.io/ingress-nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --watch-ingress-without-class=true # 新增
6.部署检查ingress
#1.部署ingress
[root@kubernetes-master-001 ~]# kubectl apply -f deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx unchanged
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx unchanged
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
daemonset.apps/ingress-nginx-controller created
ingressclass.networking.k8s.io/nginx unchanged
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission configured
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission unchanged
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
#2.部署pod
[root@kubernetes-master-001 ~]# kubectl get pod -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-cm5h4 0/1 Completed 0 4m4s 10.244.1.97 kubernetes-node-002 <none> <none>
ingress-nginx-admission-patch-49wc7 0/1 Completed 1 4m4s 10.244.1.98 kubernetes-node-002 <none> <none>
ingress-nginx-controller-cks5x 1/1 Running 0 4m5s 192.168.13.102 kubernetes-node-002 <none> <none>
ingress-nginx-controller-cqgfb 1/1 Running 0 4m4s 192.168.13.101 kubernetes-node-001 <none> <none>
#3.node节点检查端口
[root@kubernetes-node-002 ~]# netstat -lntp |grep 443
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 70037/nginx: master
tcp6 0 0 :::8443 :::* LISTEN 70016/nginx-ingress
tcp6 0 0 :::443 :::* LISTEN 70037/nginx: master
[root@kubernetes-node-002 ~]# netstat -lntp |grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 70037/nginx: master
tcp6 0 0 :::80 :::* LISTEN 70037/nginx: master
[root@kubernetes-node-001 ~]# netstat -lntp |grep 443
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 93825/nginx: master
tcp6 0 0 :::8443 :::* LISTEN 93765/nginx-ingress
tcp6 0 0 :::443 :::* LISTEN 93825/nginx: master
[root@kubernetes-node-001 ~]# netstat -lntp |grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 93825/nginx: master
tcp6 0 0 :::80 :::* LISTEN 93825/nginx: master
评论