本文主要介绍如何通过 Kubernetes Ingress 资源对象实现从外部对 k8s 集群中服务的访问,介绍了 k8s 对外暴露服务的多种方法、Ingress 及 Ingress Controller 的概念。涉及到的话题有:

  • k8s 对外暴露服务的方法;
  • Ingress 及 Ingress Controller 简介;
  • helm 裸机部署 Nginx Ingress Controller;
  • 使用 Ingress 对外暴露服务;
  • 通过 Ingress 访问 kubernetes dashboard(支持 HTTPS 访问);

k8s 对外暴露服务的方法

向 k8s 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress。每种方式都有各自的优缺点,nodePort 方式在服务变多的情况下会导致节点要开的端口越来越多,不好管理。而 LoadBalancer 更适合结合云提供商的 LB 来使用,但是在 LB 越来越多的情况下对成本的花费也是不可小觑。Ingress 是 k8s 官方提供的用于对外暴露服务的方式,也是在生产环境用的比较多的方式,一般在云环境下是 LB + Ingress Ctroller 方式对外提供服务,这样就可以在一个 LB 的情况下根据域名路由到对应后端的 Service,有点类似于 Nginx 反向代理,只不过在 k8s 集群中,这个反向代理是集群外部流量的统一入口。

Ingress 及 Ingress Controller 简介

Ingress 是 k8s 资源对象,用于对外暴露服务,该资源对象定义了不同主机名(域名)及 URL 和对应后端 Service(k8s Service)的绑定,根据不同的路径路由 http 和 https 流量。而 Ingress Contoller 是一个 pod 服务,封装了一个 web 前端负载均衡器,同时在其基础上实现了动态感知 Ingress 并根据 Ingress 的定义动态生成 前端 web 负载均衡器的配置文件,比如 Nginx Ingress Controller 本质上就是一个 Nginx,只不过它能根据 Ingress 资源的定义动态生成 Nginx 的配置文件,然后动态 Reload。个人觉得 Ingress Controller 的重大作用是将前端负载均衡器和 Kubernetes 完美地结合了起来,一方面在云、容器平台下方便配置的管理,另一方面实现了集群统一的流量入口,而不是像 nodePort 那样给集群打多个孔。

所以,总的来说要使用 Ingress,得先部署 Ingress Controller 实体(相当于前端 Nginx),然后再创建 Ingress (相当于 Nginx 配置的 k8s 资源体现),Ingress Controller 部署好后会动态检测 Ingress 的创建情况生成相应配置。Ingress Controller 的实现有很多种:有基于 Nginx 的,也有基于 HAProxy的,还有基于 OpenResty 的 Kong Ingress Controller 等,更多 Controller 见:https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/,本文使用基于 Nginx 的 Ingress Controller:ingress-nginx。

helm 裸机部署 Nginx Ingress Controller

基于 Nginx 的 Ingress Controller 有两种,一种是 k8s 社区提供的 ingress-nginx,另一种是 Nginx 社区提供的 kubernetes-igress,关于两者的区别见 这里。

在这里我们部署 k8s 社区提供的 ingress-nginx,Ingress Controller 对外暴露方式采用 hostNetwork,在裸机环境下更多其他暴露方式见:https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

使用 Helm 官方提供的 Chart stable/nginx-ingress,修改 values 文件:

  • 使用 DaemonSet 控制器,默认是 Deployment:controller.kind 设为 DaemonSet;
  • pod 使用主机网络:controller.hostNetwork 设为 true;
  • 在hostNetwork 下 pod 使用集群提供 dns 服务:controller.dnsPolicy 设为 ClusterFirstWithHostNet;
  • Service 类型设为 ClusterIP,默认是 LoadBalancer:controller.service.type 设为 ClusterIP;
  • 默认后端镜像使用 docker hub 提供的镜像,Google 国内无法访问;

修改后的 values 文件:https://raw.githubusercontent.com/qhh0205/helm-charts/master/nginx-ingress-values.yml
helm 部署

helm install stable/nginx-ingress --name nginx-ingress -f https://raw.githubusercontent.com/qhh0205/helm-charts/master/nginx-ingress-values.yml

验证部署是否成功

[root@master ~]# kubectl get pod
NAME                                             READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-mg8df                   1/1     Running   2          2m14s
nginx-ingress-default-backend-577857cd9c-gfsnd   1/1     Running   0          2m14s

浏览器访问节点 ip 出现:default backend - 404 页面,部署成功。

至此 Nginx Ingress Controller 已部署完成,接下来讲解如何通过 Ingress 结合 Ingress Controller 实现集群服务对外访问。

使用 Ingress 对外暴露服务

为了快速体验 Ingress,下面部署一个 nginx 服务,然后通过 Ingress 对外暴露 nginx service 进行访问。
首先部署 nginx 服务:
Deployment + Service:nginx.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 2template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:name: nginx
spec:selector:app: nginxports:- port: 80targetPort: 80

kubectl create -f nginx.yml

接下来创建 Ingress 对外暴露 nginx service 80 端口:
ingress.yml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: ingress-nginxannotations:# use the shared ingress-nginxkubernetes.io/ingress.class: "nginx"
spec:rules:- host: nginx.kube.comhttp:paths:- path: /backend:serviceName: nginxservicePort: 80

说明:

  • kubernetes.io/ingress.class: "nginx":Nginx Ingress Controller 根据该注解自动发现 Ingress;
  • host: nginx.kube.com:对外访问的域名;
  • serviceName: nginx:对外暴露的 Service 名称;
  • servicePort: 80:nginx service 监听的端口;

注意:创建的 Ingress 必须要和对外暴露的 Service 在同一命名空间下!

将域名 nginx.kube.com 绑定到 k8s 任意节点 ip 即可访问:http://nginx.kube.com

上面的示例不支持 https 访问,下面举一个支持 https 的 Ingress 例子:通过 Ingress 访问 kubernetes dashboard 服务。

通过 Ingress 访问 kubernetes dashboard(支持 HTTPS 访问)

之前我们使用 helm 以 nodePort 的方式部署了 kubernetes dashboard:「helm 部署 kubernetes-dashboard」,从集群外部只能通过 nodeIP:nodePort 端口号 访问,接下来基于之前部署的 kubernetes-dashboard 配置如何通过 Ingress 访问,并且支持 HTTPS 访问,HTTP 自动跳转到 HTTPS。 :
首先,练习使用,先用自签名证书来代替吧:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout kube-dashboard.key -out kube-dashboard.crt -subj "/CN=dashboard.kube.com/O=dashboard.kube.com"

使用生成的证书创建 k8s Secret 资源,下一步创建的 Ingress 会引用这个 Secret:

kubectl create secret tls kube-dasboard-ssl --key kube-dashboard.key --cert kube-dashboard.crt -n kube-system

创建 Ingress 资源对象(支持 HTTPS 访问):
kube-dashboard-ingress.yml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: ingress-kube-dashboardannotations:# use the shared ingress-nginxkubernetes.io/ingress.class: "nginx"nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:tls:- hosts:- dashboard.kube.comsecretName: kube-dasboard-sslrules:- host: dashboard.kube.comhttp:paths:- path: /backend:serviceName: kubernetes-dashboardservicePort: 443

kubectl create -f kube-dashboard-ingress.yml -n kube-system
说明:

  • kubernetes.io/ingress.class: "nginx":Inginx Ingress Controller 根据该注解自动发现 Ingress;
  • nginx.ingress.kubernetes.io/backend-protocol: Controller 向后端 Service 转发时使用 HTTPS 协议,这个注解必须添加,否则访问会报错,可以看到 Ingress Controller 报错日志:kubectl logs -f nginx-ingress-controller-mg8df

2019/08/12 06:40:00 [error] 557#557: *56049 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: 192.168.26.10, server: dashboard.kube.com, request: “GET / HTTP/1.1”, upstream: “http://10.244.1.8:8443/”, host: “dashboard.kube.com”

报错原因主要是 dashboard 服务后端只支持 https,但是 Ingress Controller 接到客户端的请求时往后端 dashboard 服务转发时使用的是 http 协议,解决办法就是给 创建的 Ingress 设置:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" 注解。解决方法参考自 StackOverflow:https://stackoverflow.com/questions/48324760/ingress-configuration-for-dashboard

  • secretName: kube-dasboard-ssl:https 证书 Secret;
  • host: dashboard.kube.com:对外访问的域名;
  • serviceName: kubernetes-dashboard:集群对外暴露的 Service 名称;
  • servicePort: 443:service 监听的端口;

注意:创建的 Ingress 必须要和对外暴露的 Service 在同一命名空间下!

将域名 dashboard.kube.com 绑定到 k8s 任意节点 ip 即可访问:https://dashboard.kube.com

相关文档

https://kubernetes.io/docs/concepts/services-networking/ingress/ | 官方文档
https://mritd.me/2017/03/04/how-to-use-nginx-ingress/ | Kubernetes Nginx Ingress 教程
https://github.com/nginxinc/kubernetes-ingress | Inginx Ingress Controller:nginx 社区提供
https://github.com/kubernetes/ingress-nginx | Inginx Ingress Controller:k8s 社区提供
https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/nginx-ingress-controllers.md | 两种基于 nginx 的 Ingress Controller 区别
https://kubernetes.github.io/ingress-nginx/deploy/ | Inginx Ingress Controller k8s 社区版安装文档
https://kubernetes.github.io/ingress-nginx/deploy/baremetal/ | 在 裸机环境下 Inginx Ingress Controller 对外暴露方案

使用 Kubernetes Ingress 对外暴露服务相关推荐

  1. k8s核心技术-Ingress(对外暴露应用实施)---K8S_Google工作笔记0042

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们来实现一下这个ingress. 首先我们创建一个nginx应用 kubectl creat ...

  2. Kubernetes 系列(三):Kubernetes使用Traefik Ingress暴露服务

    一.Kubernetes 服务暴露介绍 从 kubernetes 1.2 版本开始,kubernetes提供了 Ingress 对象来实现对外暴露服务:到目前为止 kubernetes 总共有三种暴露 ...

  3. 理解对方暴露服务的对象 Ingress 和 Service

    Kubernetes 中的服务(Service)可以理解为对外暴露服务的最小单元对象,这个和 Pod 对象还是有不同的.例如用户通过发布服务对象 Deployment 发布应用,当在容器集群中启动后, ...

  4. Kubernetes - Ingress暴露应用(四)

    阅读本文前可先参考 Kubernetes - Kubernetes详解:安装部署_MinggeQingchun的博客-CSDN博客 https://blog.csdn.net/MinggeQingch ...

  5. Kubernetes Ingress 日志分析与监控的最佳实践

    2019独角兽企业重金招聘Python工程师标准>>> 前言 目前Kubernetes(K8s)已经真正地占领了容器编排市场,是默认的云无关计算抽象,越来越多的企业开始将服务构建在K ...

  6. 使用Golang自定义Kubernetes Ingress Controller

    在Kubernetes中通过Ingress来暴露服务到集群外部,这个已经是很普遍的方式了,而真正扮演请求转发的角色是背后的Ingress Controller,比如我们经常使用的traefik.ing ...

  7. 带着问题学 Kubernetes 抽象对象 Service 服务间调用

    带着问题学 Kubernetes 抽象对象 Service https://github.com/jasonGeng88/blog/blob/master/201707/k8s-service.md ...

  8. 如何在Kubernetes中暴露服务访问

    Kubernetes概述 最近的一年,kubernetes的发展如此闪耀,正被越来越多的公司采纳用于生产环境的实践.同时,我们可以在最著名的开发者问答社区StackOverflow上看到k8s的问题数 ...

  9. Kubernetes系列之五:使用yaml文件创建service向外暴露服务

    系列链接 Kubernetes系列之一:在Ubuntu上快速搭建一个集群Demo Kubernetes系列之二:将Slave节点加入集群 Kubernetes系列之三:部署你的第一个应用程序到k8s集 ...

  10. kubernetes系列之一:Kubernetes如何利用iptables对外暴露service

    一.前言 Kubernetes利用iptables达成以下两个目的: 对外暴露POD和服务(通过host port.cluster service.node external IP.external ...

最新文章

  1. [国家集训队]航班安排
  2. 【中文】Joomla1.7扩展介绍之Kunena(强大的论坛)
  3. hadoop学习--K-Means(聚类算法)
  4. Android Google Play app signing 最终完美解决方式
  5. 20145231 《信息安全系统设计基础》期中总结
  6. 团队项目第二次冲刺(4)
  7. 博士可能是所有学生群体里被黑最猛烈的
  8. 企业微信H5_身份验证,PC网站企业微信扫码授权登录
  9. Tesseract Ocr文字识别
  10. 【学习笔记】慕课网—Java设计模式精讲 第3章 软件设计七大原则-3-6 迪米特原则(最少知道原则)...
  11. CSDN 创始人蒋涛:拥抱中国开源技术生态发展黄金十年
  12. BroadcastReceiver的学习和使用实例
  13. 树莓派4 PWM控制风扇转速
  14. 微信小程序 自定义底部导航栏
  15. EmmyLua的安装与使用
  16. 上海市高等学校信息技术水平二三级python 模拟题 编程
  17. 计算机网络与安全课程设计,计算机网络课程设计-网络安全..doc
  18. 京东轮播图片的静态页面CSS3
  19. 高等代数 :2 行列式
  20. ae破碎效果在哪_AE教程 | 五分钟制作文字破碎效果

热门文章

  1. SpringMVC-狂神笔记
  2. CE 开启 DBVM
  3. 简历中的工作经历怎么写?
  4. SystemVerilog学习笔记7——覆盖率
  5. VUE打包图片,icon图标不显示解决方案
  6. dropbox连接不上解决方法
  7. 国民岳父的“屁民理论”
  8. 各大搜索引擎Ping服务 php实现方法
  9. 2. 文件如何进行md5校验和sha1校验
  10. 人工智能在法律中的应用丨“AI+传统行业”全盘点