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 资源示例:
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
Ingress 需要指定 apiVersion、kind、 metadata和 spec 字段。 Ingress 对象的命名必须是合法的 DNS 子域名名称。
使用Ingress Controller代理k8s内部应用的流程
- 部署Ingress controller,我们ingress controller使用的是nginx
- 创建Pod应用,可以通过控制器创建pod
- 创建Service,用来分组pod
- 创建Ingress http,测试通过http访问应用
- 创建Ingress https,测试通过https访问应用
必须具有 ingress 控制器,才能满足 Ingress 的要求。仅创建 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
部署后端tomcat服务
通过部署tomcat服务测试Ingress HTTP代理k8s内部站点,编写如下资源清单
apiVersion: v1 kind: Service metadata: name: tomcat namespace: default spec: selector: app: tomcat release: canary ports: - name: scport targetPort: 8080 port: 8009 --- apiVersion: apps/v1 kind: Deployment metadata: name: tomcat-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: tomcat release: canary template: metadata: labels: app: tomcat release: canary spec: containers: - name: tomcat image: tomcat:8.5.34-jre8-alpine imagePullPolicy: IfNotPresent ports: - name: containerport containerPort: 8080 name: ajp containerPort: 8009
- 查看pod是否部署成功
controlplane $ kubectl apply -f ingress-demo.yaml service/tomcat created deployment.apps/tomcat-deploy created controlplane $ kubectl get pod NAME READY STATUS RESTARTS AGE tomcat-deploy-7c67c4d459-5s859 1/1 Running 0 11m tomcat-deploy-7c67c4d459-bvp2k 1/1 Running 0 11m
编写Ingress规则
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-myapp namespace: default annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx rules: # 定义后端的转发规则 - host: tomcat.test.com # 通过域名进行转发 http: paths: - path: / #配置访问路径,如果通过url进行转发。需要修改,空的默认访问路径是"/" pathType: Prefix backend: # 配置后端服务 service: name: tomcat # 配置关联的serverce port: number: 8080 # service暴露的端口
ingressClassName:这个值可以通过kubectl get ingressclasses
查看ingress-myapp的详细信息
controlplane $ kubectl apply -f ingress-myapp.yaml ingress.networking.k8s.io/ingress-myapp created controlplane $ kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-myapp nginx tomcat.test.com 80 8s controlplane $ kubectl describe ingress ingress-myapp Name: ingress-myapp Labels: <none> Namespace: default Address: Ingress Class: nginx Default backend: <default> Rules: Host Path Backends ---- ---- -------- tomcat.test.com / tomcat:8080 () Annotations: nginx.ingress.kubernetes.io/rewrite-target: / Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 62s nginx-ingress-controller Scheduled for sync
查看ingress-nginx
部署到那个节点上,如下图:
通上图可知ingress-nginx部署到node1上,并且SVC方式是通过LoadBalancer方式部署。如果,要访问到这个后端tomcat服务,需要做域名的解析。如下:
...省略.. 172.30.2.2 tomcat.test.com
正常访问如下;
CKA真题
- 真题截图
- 中文解析
切换 k8s 集群环境:kubectl config use-context k8s
Task:
如下创建一个新的 nginx lngress资源:
名称:pong
Namespace:ing-internal
使用服务端口 5678 在路径 /hi 上公开服务hi
可以使用以下命令检查服务 hi 的可用性,该命令应返回 hi, curl -kL<INTERNAL_IP>/hi
- 官方参考文档
- 解题作答
- 切换 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