本文将介绍如何使用Ingress实现七层代理。在这个教程中,我们将使用Nginx作为Ingress控制器。
Ingress介绍
在开始之前,我们首先了解一下Ingress是什么?
Ingress是Kubernetes中负责将外部请求引导到集群内部服务的机制,通过将服务映射到集群外的URL,实现服务的外部可访问性。Ingress支持配置集群内的Service,使其可以通过外部URL访问,同时提供流量负载均衡和基于域名的虚拟主机等功能。
简单理解Ingress就是将原本需要手动修改Nginx配置、配置域名与服务映射的繁琐步骤,抽象成一个Ingress对象
。通过使用YAML文件创建和更新Ingress对象,我们不再需要手动操作Nginx配置文件,而是通过更方便的方式管理域名与服务的关系。
然而,这引发了一个问题:“Nginx应该如何处理这些变化?”这时候,Ingress Controller登场,专门解决Nginx处理方式的问题。Ingress Controller与Kubernetes API进行交互,实时感知集群中Ingress规则的变化。一旦有变化,Ingress Controller会读取这些规则,并根据自己的模板生成相应的Nginx配置。随后,它将这段配置写入Nginx Pod,最后触发Nginx的重载操作,确保配置的生效。
通过Ingress和Ingress Controller的配合,我们在管理外部访问时变得更加灵活和便捷,摆脱了手动修改Nginx配置的烦恼,让我们能够更专注于服务与域名的映射关系,提升了Kubernetes集群的可维护性。
Ingress Controller介绍
Ingress Controller
是一种七层负载均衡调度器,它作为客户端请求的第一站,接收并处理所有外部请求。在这个七层负载均衡调度器的作用下,请求会经过反向代理,最终被路由到后端的Pod。常见的七层负载均衡器包括nginx、traefik等。以我们熟悉的nginx为例,当请求到达nginx时,nginx会通过upstream配置反向代理到后端Pod应用。
然而,后端Pod的IP地址是动态变化的,为了解决这个问题,我们引入了Service。这个Service并非实际的服务,而是起到了对后端Pod的分组作用。因此,在配置upstream时,我们只需要填写Service的地址即可,而不需要关心后端Pod的具体IP地址。
通过这样的设计,Ingress Controller能够灵活处理后端Pod的变化,保证请求能够正确地路由到集群中的服务。这种模式使得我们能够更方便地管理后端服务的变化,而不必担心Pod的IP地址的不断变化所带来的问题。
准备工作
在了解完Ingress和Ingress Controller之后,要想使用Ingress确保您已经安装了Kubernetes集群,并安装了Nginx Ingress
控制器。如果您还没有安装Nginx Ingress控制器,可以参考以下的安装步骤。
部署Ingress-Nginx
这里同样使用killercoda平台进行测试,该平台部署的是最新版V1.29.0的K8S环境。
由于该环境没有部署Ingress。以下通过部署ingress-nginx为例。通过查阅ingress-nginx官方,了解V1.29.0
对应的是Ingress-NGINX 的V1.10.0或v1.9.6。如下:
通过执行如下命令部署Ingress-NGINX 的V1.10.0。
kubectl apply -f \
https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml
执行完上述命令,输出如下结果
通过如下命令查看部署情况
controlplane $ kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-d69wp 0/1 Completed 0 102s
ingress-nginx-admission-patch-hkv66 0/1 Completed 0 102s
ingress-nginx-controller-7dcdbcff84-gfqcs 1/1 Running 0 102s
controlplane $ kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.98.23.38 <pending> 80:30770/TCP,443:31444/TCP 3m57s
ingress-nginx-controller-admission ClusterIP 10.102.219.183 <none> 443/TCP 3m57s
通过以上步骤就完成了Ingress-nginx的部署了。
创建七层代理服务
首先,我们需要创建一个七层代理服务。在这个例子中,我们将创建一个简单的HTTP服务,它将接收来自客户端的请求,并将其转发到后端服务。
- 创建一个名为
proxy-service.yaml
的文件,内容如下:
apiVersion: v1
kind: Service
metadata:
name: proxy-service
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
selector:
app: proxy-app
sessionAffinity: ClientIP
type: ClusterIP
这个文件定义了一个名为proxy-service
的服务,它将流量从端口80转发到端口8080。sessionAffinity
设置为ClientIP
,以确保客户端请求始终路由到同一个后端Pod。
- 应用配置文件:
kubectl apply -f proxy-service.yaml
- 创建一个名为
proxy-app
的Deployment,用于运行HTTP服务。创建一个名为proxy-app.yaml
的文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: proxy-app
spec:
replicas: 2
selector:
matchLabels:
app: proxy-app
template:
metadata:
labels:
app: proxy-app
spec:
containers:
- name: proxy-app
image: nginx:latest
ports:
- containerPort: 8080
这个文件定义了一个名为proxy-app
的Deployment,它将运行两个Nginx容器实例。
- 应用配置文件:
kubectl apply -f proxy-app.yaml
配置Ingress规则
现在我们已经创建了七层代理服务,接下来我们需要配置Ingress规则以将流量路由到该服务。
- 创建一个名为
proxy-ingress.yaml
的文件,内容如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: proxy-ingress
spec:
rules:
- host: proxy.example.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: proxy-service
port:
number: 80
这个文件定义了一个名为proxy-ingress
的Ingress规则,它将将所有发往proxy.example.com
的流量路由到proxy-service
服务。
- 应用配置文件:
kubectl apply -f proxy-ingress.yaml
测试七层代理服务
现在我们已经配置了Ingress规则,我们可以测试七层代理服务是否正常工作。
- 获取Ingress控制器的外部IP地址:
kubectl get ingress controller-instance -n <ingress-controller-namespace> -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
- 使用浏览器或curl访问
http://<ingress-controller-ip>/
,您应该能够看到Nginx的默认欢迎页面。
至此,您已经成功配置了Ingress七层代理服务。您可以根据需要修改Ingress规则和七层代理服务,以满足您的实际需求。
CKA真题
真题截图
中文解析
切换 k8s 集群环境:kubectl config use-context k8s
Task:
如下创建一个新的 nginx lngress资源:
名称:pong
Namespace:ing-internal
使用服务端口 5678 在路径 /hi 上公开服务hi
可以使用以下命令检查服务 hi 的可用性,该命令应返回 hi, curl -kL<INTERNAL_IP>/hi
官方参考文档
Ingress
解题作答
- 切换 k8s 集群环境
kubectl config use-context k8s
- 创建一个名为pong.yaml。资源内容如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: pong
namespace: ing-internal
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /hi
pathType: Prefix
backend:
service:
name: hi
port:
number: 5678
- ingressClassName的值,建议在考试的时候通过
kubectl get ingressclasses
- service.name的值,题目中没有告诉,建议在考试时候可以通过
kubectl get svc
查看 - 提交资源清单
kubectl apply -f pong.yaml
- 通过
curl -kL<INTERNAL_IP>/hi
验证,看是否返回hi