k8s容器编排技术实践——K8s中服务发现ingress、ingress controller 应用实践
k8s容器编排技术实践——k8s应用中机密信息的配置与存储https://blog.csdn.net/xiaochenXIHUA/article/details/161706954?spm1001.2014.3001.5501k8s容器编排技术实践——k8s的介绍及其整体运行架构-CSDN博客https://coffeemilk.blog.csdn.net/article/details/161011629一、ingress-nginx简介1.1、Service机制的局限性⚠️Service机制的局限性只提供 4 层负载均衡不支持7层负载均衡功能。使用 NodePort 类型的 Service需要在集群外部部署一个外部的负载均衡器。使用 LoadBalancer类型的ServiceKubernetes 必须运行在特定的云服务上。每创建一个Service NodePort类型就会在每个节点开启一个端口当项目多时端口会难以维护。当项目很多时Service的Iptables规则也随着数倍增多如此多的iptables条目让增大维护和故障定位。如何理解上面的局限性呢如下是NodePort模式运行原理图1.2、ingress-nginx如何实现服务发现针对上述问题k8s官方提供了一种折中的方案Ingress与Service不同Ingress实际上不是一种服务。相反它位于多个服务之前充当集群中的智能路由器或入口点。ingress-nginx实现架构如下图所示Ingress是在Kubernetes 1.1 版本后引入的资源类型。Ingress 支持将 Service 暴露到 Kubernetes 集群外同时可以自定义 Service 的访问策略。Ingress 能够把 Service 配置成外网能够访问的 URL也支持提供按域名访问的虚拟主机功能如通过负载均衡器实现不同的二级域名到不同 Service 的访问。实际上 Ingress 只是一个统称主要有【Ingress】、【Ingress Controller】和【Ingress-Controller-service】三部分组成。Ingress构成说明Ingress将原来需要手动配置的规则抽象成一个Ingress对象使用YAML格式的文件来创建和管理。将请求转发给Ingress Controller。Ingress Controller核心组件用作通过与Kubernetes API交互动态感知集群中Ingress规则变化并应用新配置实现七层转发。Ingress-Controller-servicekuberntes中四层的负载均衡调度机制Ingress借助service的服务发现机制实现集群中Pod资源的动态感知用于接入外部流量Ingress Controller目前有多种软件负载均衡实现如Nginx、HAProxy等而本文要讲解的是基于Nginx的Ingress Controller。在使用 Ingress前必须要先部署 Ingress ControllerIngress Controller是以一种插件的形式提供。Ingress Controller通常是部署在每个Node上是一个pod服务由Kubernetes管理而不是我们单独部署。以Ingress Nginx为例Ingress Controller镜像包含一个Nginx service和一个Ingress Controller。Ingress Controller会从apiserver获取到Ingress配置然后动态生成nginx.conf配置文件并重载-s reload配置。1.3、ingress-nginx工作流程解析ingress-nginx工作流程说明ingress简单理解就是你原来需要修改nginx配置然后配置各种域名对应哪个Service现在把这个动作抽象出来变成一个Ingress对象你可以用yaml创建每次不用去修改nginx了直接改yaml然后创建/更新就行了那么问题又来了nginx该如何处理呢ingress controlleringress controller就是解决nginx如何处理这个问题的ingress controller通过与kubernetes API交互动态的去感知集群中Ingress规则变化然后读取它按照它自己的模板生成一段nginx配置再写到nginx Pod中最后reload以下工作流程如下图首先有一个外部的负载均衡器externalLB把请求调度到一个nodePort类型的Service(ingress-nginx)上然后nodePort类型的Service(ingress-nginx)又把它调度到内部的叫做ingressController的Pod上ingress Ctroller根据ingress中的定义(虚拟主机还是URL)每一组主机名或者URL都对应后端的Pod资源并且用Service分组。二、部署ingress-nginx服务2.1、部署ingress-nginx服务的三种方法2.1.1、DeploymentLoadBalancer模式的Service如果要把ingress部署在【公有云】那用这种方式比较合适。用Deployment部署ingress-controller创建一个type为LoadBalancer的service关联这组pod。大部分公有云都会为LoadBalancer的service自动创建一个负载均衡器通常还绑定了公网地址。只要把域名解析指向该地址就实现了集群服务的对外暴露。2.1.2、DeploymentNodePort模式的Service同样用deployment模式部署ingress-controller并创建对应的服务但是type为NodePort。这样ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境并且IP地址不变的场景。注意NodePort方式暴露ingress虽然简单方便但是NodePort多了一层NAT在请求量级很大时可能对性能会有一定影响。2.1.3、DaemonSetHostNetworknodeSelector用DaemonSet结合nodeselector来部署ingress-controller到特定的node上然后使用HostNetwork直接把该pod与宿主机node的网络打通直接使用宿主机的80/433端口就能访问服务。这时ingress-controller所在的node机器就很类似传统架构的边缘节点如机房入口的nginx服务器。该方式整个请求链路最简单性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口一个node只能部署一个ingress-controller pod。此方案比较适合大并发的生产环境使用。2.2、DeploymentNodePort模式使用ingress-nginx2.2.1、下载并部署ingress资源首先需要下载ingress相关yaml文件在nginx controller 0.30.0以及版本之前需要下载多个yml文件如mandatory.yaml、service-nodeport.yaml等。但在最新nginx controller版本中这些部署文件合并到一个文件中了从ingress-nginx/deploy/static/provider/baremetal at main · kubernetes/ingress-nginx · GitHub 下载deploy.yaml文件这里使用的是最新版本nginx controller版本为1.15.1下载后需要做几个简单修改【即将registry.k8s.io修改为国内可用的k8s.m.daocloud.io】。#使用DaoCloud代理替换推荐 sed -i s|registry.k8s.io|k8s.m.daocloud.io|g deploy.yaml # 或者使用阿里云镜像替换【备选】 sed -i s|registry.k8s.io/ingress-nginx/controller|registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller|g deploy.yaml sed -i s|registry.k8s.io/ingress-nginx/kube-webhook-certgen|registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen|g deploy.yaml #ingress-nginx资源部署 kubectl apply -f deploy.yaml #查看指定的ingress-nginx的pod资源状态必须是running;且READY必须是1/1才表示成功 kubectl -n ingress-nginx get pod #查看指定的ingress-nginx的pod日志信息 kubectl -n ingress-nginx logs ingress-nginx-controller-5d98f55d49-xtgw4 #查看指定ingress-nginx的所有service kubectl -n ingress-nginx get svc #查看指定ingress-nginx的service的详细信息 kubectl -n ingress-nginx describe svc ingress-nginx-controller2.2.2、配置部署业务服务资源即需要配置部署业务所需的deployment及其对应的service资源。k8s容器编排技术实践——k8s对象job应用详解https://blog.csdn.net/xiaochenXIHUA/article/details/161572905k8s容器编排技术实践——K8s对象deployment应用详解https://coffeemilk.blog.csdn.net/article/details/161427275k8s容器编排技术实践——k8s对象service应用详解https://coffeemilk.blog.csdn.net/article/details/161593299#创建httpd的pod及其service #一、创建httpd的deployment资源 #1.1-创建资源文件httpd-deployment.yml cat httpd-deployment.yml EOF apiVersion: apps/v1 kind: Deployment metadata: name: httpd-deployment spec: replicas: 3 selector: matchLabels: app: httpd_server template: metadata: labels: app: httpd_server spec: containers: - name: httpd-web image: library/httpd:2.4.67 ports: - containerPort: 80 EOF #1.2-创建指定资源 kubectl apply -f httpd-deployment.yml #1.3查看当前所有pod状态 kubectl get pod #二、创建对应如上httpd-deployment.yml资源的service #2.1-创建指定deployment的service资源文件httpd-service.yml cat httpd-service.ymlEOF apiVersion: v1 kind: Service metadata: name: httpd-service spec: type: NodePort selector: app: httpd_server ports: - protocol: TCP port: 80 nodePort: 30060 targetPort: 80 EOF #2.2-创建指定的资源文件 kubectl apply -f httpd-service.yml #2.3-查看当前所有的service kubectl get svc#创建nginx的pod及其service #一、创建nginx的deployment资源 #1.1-创建资源文件nginx-deployment.yml cat nginx-deployment.yml EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx_server template: metadata: labels: app: nginx_server spec: containers: - name: nginx-web image: library/nginx:1.28.3 ports: - containerPort: 80 EOF #1.2-创建指定资源 kubectl apply -f nginx-deployment.yml #1.3查看当前所有pod状态 kubectl get pod -o wide #二、创建对应如上nginx-deployment.yml资源的service #2.1-创建指定nginx的service资源文件nginx-service.yml cat nginx-service.ymlEOF apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx_server ports: - protocol: TCP port: 80 targetPort: 80 EOF #2.2-创建指定的资源文件 kubectl apply -f nginx-service.yml #2.3-查看当前所有的service kubectl get svc #2.4-使用curl连接httpd-service与nginx-service curl 10.97.0.199 curl 10.104.53.1482.2.3、创建ingress服务#创建一个ingress服务让外部可以通过域名来访问pod catingress-demo.ymlEOF apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-demo spec: ingressClassName: nginx rules: - host: www.ck.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-service port: number: 80 - host: www.ck1.com http: paths: - path: / pathType: Prefix backend: service: name: httpd-service port: number: 80 EOF #创建指定的资源 kubectl apply -f ingress-demo.yml #查看ingress-nginx命名空间下的所有Service kubectl get svc -n ingress-nginx #配置本地域名解析即在本地域名解析文件中添加k8s集群中的任意节点IP 配置的pod域名 #windows系统的本地域名解析文件是【C:\Windows\System32\drivers\etc\hosts】 #linux系统的本地域名解析文件是【/etc/hosts】 192.168.1.142 www.ck.com 192.168.1.142 www.ck1.com #或者 192.168.1.140 www.ck.com 192.168.1.140 www.ck1.com #或者 192.168.1.141 www.ck.com 192.168.1.141 www.ck1.com #或者 192.168.1.143 www.ck.com 192.168.1.143 www.ck1.com #浏览器直接访问【域名:ingress-nginx-controller端口】 http://www.ck.com:31992/ http://www.ck1.com:31992/如上图正确显示不同pod组的service内容则表示ingress-nginx配置成功注意由于在配置本地域名解析时可以使用k8s集群中的任意节点IP因此建议在ingress外层再添加一个nginx做负载均衡这会造成一定的性能损耗。Nginx中的内置变量、指令、URL重写功能及其虚拟主机配置、负载均衡配置https://blog.csdn.net/xiaochenxihua/article/details/151138716#最终测试完成通过后删除命令如下 kubectl delete -f ingress-demo.yml kubectl delete -f deploy.yaml #查看是否删除完成显示“No resources found in ingress-nginx namespace.”则表示删除完成 kubectl -n ingress-nginx get pod kubectl -n ingress-nginx get svc2.3、DaemonSetHostNetworknodeSelector模式使用ingress-nginx2.3.1、下载并部署ingress资源首先需要下载ingress相关yaml文件在nginx controller 0.30.0以及版本之前需要下载多个yml文件如mandatory.yaml、service-nodeport.yaml等。但在最新nginx controller版本中这些部署文件合并到一个文件中了从ingress-nginx/deploy/static/provider/baremetal at main · kubernetes/ingress-nginx · GitHub 下载deploy.yaml文件这里使用的是最新版本nginx controller版本为1.15.1下载后需要做几个简单修改【即将registry.k8s.io修改为国内可用的k8s.m.daocloud.io】。#需要对deploy.yaml文件修改 #1-使用DaoCloud代理替换推荐 sed -i s|registry.k8s.io|k8s.m.daocloud.io|g deploy.yaml # 或者使用阿里云镜像替换【备选】 sed -i s|registry.k8s.io/ingress-nginx/controller|registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller|g deploy.yaml sed -i s|registry.k8s.io/ingress-nginx/kube-webhook-certgen|registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen|g deploy.yaml #2-在deployment资源部分修改名为ingress-nginx-controller的Deployment类型为DaemonSet kind: DaemonSet #3-接着在此DaemonSet中的template下的spec中添加如下内容 #3.1-修改spec下的strategy为updateStrategy #3.2-这一步配置的操作是【添加网络模式和nodeselector标签这样ingress-nginx-controller的pod就会部署到特定的node上并且与宿主机的node网络也打通了直接使用宿主机的80/433端口就能访问服务】且需要将最后的nodeSelector:kubernetes.io/os: linux注释或者直接修改为ingress: nginx-server。 hostNetwork: true nodeSelector: ingress: nginx-server #4-给k8s集群中的任意节点如k8s-node1设置ingress标签 kubectl label nodes k8s-node1 ingressnginx-server #5-查看当前所有的节点的标签状态 kubectl get node --show-labels #创建资源 #ingress-nginx资源部署 kubectl apply -f deploy.yaml #查看指定的ingress-nginx的daemonset资源状态NODE状态必须是ingressnginx-server kubectl -n ingress-nginx get daemonsets -o wide #查看指定的ingress-nginx的pod资源状态必须是running;READY必须是1/1;且IP必须是该节点所在的主机IP如192.168.1.142而不是k8s的内部IP才表示成功 kubectl -n ingress-nginx get pod -o wide #查看指定的ingress-nginx的pod日志信息 kubectl -n ingress-nginx logs ingress-nginx-controller-5jzqh #查看指定ingress-nginx的所有service kubectl -n ingress-nginx get svc #查看指定ingress-nginx的service的详细信息 kubectl -n ingress-nginx describe svc ingress-nginx-controller2.3.2、配置部署业务服务资源即需要配置部署业务所需的deployment及其对应的service资源。#创建httpd的pod及其service #一、创建httpd的deployment资源 #1.1-创建资源文件httpd-deployment.yml cat httpd-deployment.yml EOF apiVersion: apps/v1 kind: Deployment metadata: name: httpd-deployment spec: replicas: 3 selector: matchLabels: app: httpd_server template: metadata: labels: app: httpd_server spec: containers: - name: httpd-web image: library/httpd:2.4.67 ports: - containerPort: 80 EOF #1.2-创建指定资源 kubectl apply -f httpd-deployment.yml #1.3查看当前所有pod状态 kubectl get pod #二、创建对应如上httpd-deployment.yml资源的service #2.1-创建指定deployment的service资源文件httpd-service.yml cat httpd-service.ymlEOF apiVersion: v1 kind: Service metadata: name: httpd-service spec: type: NodePort selector: app: httpd_server ports: - protocol: TCP port: 80 nodePort: 30060 targetPort: 80 EOF #2.2-创建指定的资源文件 kubectl apply -f httpd-service.yml #2.3-查看当前所有的service kubectl get svc#创建nginx的pod及其service #一、创建nginx的deployment资源 #1.1-创建资源文件nginx-deployment.yml cat nginx-deployment.yml EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx_server template: metadata: labels: app: nginx_server spec: containers: - name: nginx-web image: library/nginx:1.28.3 ports: - containerPort: 80 EOF #1.2-创建指定资源 kubectl apply -f nginx-deployment.yml #1.3查看当前所有pod状态 kubectl get pod -o wide #二、创建对应如上nginx-deployment.yml资源的service #2.1-创建指定nginx的service资源文件nginx-service.yml cat nginx-service.ymlEOF apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx_server ports: - protocol: TCP port: 80 targetPort: 80 EOF #2.2-创建指定的资源文件 kubectl apply -f nginx-service.yml #2.3-查看当前所有的service kubectl get svc #2.4-使用curl连接httpd-service与nginx-service curl 10.97.0.199 curl 10.104.53.1482.3.3、创建ingress服务#创建一个ingress服务让外部可以通过域名来访问pod catingress-demo.ymlEOF apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-demo spec: ingressClassName: nginx rules: - host: www.ck.com http: paths: - path: / pathType: Prefix backend: service: name: nginx-service port: number: 80 - host: www.ck1.com http: paths: - path: / pathType: Prefix backend: service: name: httpd-service port: number: 80 EOF #创建指定的资源 kubectl apply -f ingress-demo.yml #查看ingress的状态信息 kubectl get ingress #查看指定ingress-nginx命名空间下的所有pod状态详情 kubectl -n ingress-nginx get pod -o wide #查看ingress-nginx命名空间下的所有Service状态 kubectl -n ingress-nginx get svc #配置本地域名解析即在本地域名解析文件中添加指定了标签名称的podIP与域名 #windows系统的本地域名解析文件是【C:\Windows\System32\drivers\etc\hosts】 #linux系统的本地域名解析文件是【/etc/hosts】 192.168.1.142 www.ck.com 192.168.1.142 www.ck1.com #浏览器直接访问【域名】 http://www.ck.com http://www.ck1.com #剖析《ingress-controller会动态加载ingress服务资源而不用手动配置》 #1-查看指定ingress-nginx命名空间下的所有pod状态详情 kubectl -n ingress-nginx get pod -o wide #2-进入ingress-nginx的pod容器中默认就在/etc/nginx目录下直接查看nginx.conf文件是否包含ingress服务的网站域名配置有则表示是动态配置上的 kubectl exec -it -n ingress-nginx ingress-nginx-controller-5jzqh sh #也就是说需要配置网站域名内容只需要修改ingress服务资源文件后重新创建即可如上图通过不同的域名可以正确显示不同pod组的service内容则表示ingress-nginx配置成功