使用 Kubernetes Ingress 对外暴露服务

标签: kubernetes ingress 服务 | 发表时间:2020-03-07 02:16 | 作者:老马
出处:http://weekly.dockone.io

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

Kubernetes 对外暴露服务的方法

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

Ingress 及 Ingress Controller 简介

Ingress 是 Kubernetes 资源对象,用于对外暴露服务,该资源对象定义了不同主机名(域名)及 URL 和对应后端 Service(Kubernetes 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 配置的 Kubernetes 资源体现),Ingress Controller 部署好后会动态检测 Ingress 的创建情况生成相应配置。Ingress Controller 的实现有很多种:有基于 Nginx 的,也有基于 HAProxy的,还有基于 OpenResty 的 Kong Ingress Controller 等,更多 Controller 见: https://kubernetes.io/docs/con ... lers/,本文使用基于 Nginx 的 Ingress Controller: ingress-nginx

Helm 裸机部署 Nginx Ingress Controller

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

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

使用 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. ... s.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: 2
template:
metadata:
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx
spec:
selector:
app: nginx
ports:
- port: 80
  targetPort: 80

kubectl create -f nginx.yml

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

ingress.yml:
apiVersion: extensions/v1beta1  
kind: Ingress
metadata:
name: ingress-nginx
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: nginx.kube.com
http:
  paths:
  - path: /
    backend:
      serviceName: nginx
      servicePort: 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 绑定到 Kubernetes 任意节点 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"  

使用生成的证书创建 Kubernetes 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-dashboard
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- dashboard.kube.com
secretName: kube-dasboard-ssl
rules:
- host: dashboard.kube.com
http:
  paths:
  - path: /
    backend:
      serviceName: kubernetes-dashboard
      servicePort: 443
kubectl create -f kube-dashboard-ingress.yml -n kube-system

说明:

1、kubernetes.io/ingress.class: "nginx":Inginx Ingress Controller 根据该注解自动发现 Ingress;

2、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/ques ... board

3、secretName: kube-dasboard-ssl:https 证书 Secret;

4、host: dashboard.kube.com:对外访问的域名;

5、serviceName: kubernetes-dashboard:集群对外暴露的 Service 名称;

6、servicePort: 443:service 监听的端口。

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

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


原文链接: https://qhh.me/2019/08/12/使用-Kubernetes-Ingress-对外暴露服务/

相关 [kubernetes ingress 服务] 推荐:

使用 Kubernetes Ingress 对外暴露服务

- - DockOne.io
本文主要介绍如何通过 Kubernetes Ingress 资源对象实现从外部对 Kubernetes 集群中服务的访问,介绍了 Kubernetes 对外暴露服务的多种方法、Ingress 及 Ingress Controller 的概念. Kubernetes 对外暴露服务的方法. 向 Kubernetes 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress.

Kubernetes的负载均衡问题(Nginx Ingress) - ericnie - 博客园

- -
Kubernetes关于服务的暴露主要是通过NodePort方式,通过绑定minion主机的某个端口,然后进行pod的请求转发和负载均衡,但这种方式下缺陷是. Service可能有很多个,如果每个都绑定一个node主机端口的话,主机需要开放外围一堆的端口进行服务调用,管理混乱. 无法应用很多公司要求的防火墙规则.

Kubernetes Nginx Ingress 教程 - 漠然的博客 | mritd Blog

- -
一、Ingress 介绍. Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、NodePort Service、Ingress;前两种估计都应该很熟悉,具体的可以参考下  这篇文章;下面详细的唠一下这个 Ingress. 1.1、Ingress 是个什么玩意.

以图形化的方式简单介绍Kubernetes Ingress

- - DockOne.io
【编者的话】原文地址: here. 本文主要介绍了 Kubernetes Ingress 的内部原理,以及一些 Ingress 的用法示例. 第一部分: 以图形化的方式简单介绍Kubernetes Service. 第二部分:以图形化的方式简单介绍Kubernetes Ingress,即这篇文章.

浅谈Kubernetes Ingress控制器的技术选型

- - DockOne.io
【编者的话】在Kubernetes的实践、部署中,为了解决 Pod 迁移、Node Pod 端口、域名动态分配等问题,需要开发人员选择合适的 Ingress 解决方案. 面对市场上众多Ingress产品,开发者该如何分辨它们的优缺点. 又该如何结合自身的技术栈选择合适的技术方案呢. 在本文中,腾讯云中间件核心研发工程师厉辉将为你介绍如何进行Kubernates Ingress 控制器的技术选型.

kubernetes dashboard向外网提供服务

- - 学习日志
目前新版本的 kubernetes dashboard ( https://github.com/kubernetes/dashboard)安装了后,为了安全起见,默认情况下已经不向外提供服务,只能通过. http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ 本机访问.

Kubernetes 服务部署最佳实践(一)

- - 腾讯云容器团队
业务容器化后,如何将其部署在 K8S 上. 如果仅仅是将它跑起来,很简单,但如果是上生产,我们有许多地方是需要结合业务场景和部署环境进行方案选型和配置调优的. 比如,如何设置容器的 Request 与 Limit、如何让部署的服务做到高可用、如何配置健康检查、如何进行弹性伸缩、如何更好的进行资源调度、如何选择持久化存储、如何对外暴露服务等.

Kubernetes中的服务发现与负载均衡

- - Feisky's Blog
Kubernetes在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了Service资源,并通过kube-proxy配合cloud provider来适应不同的应用场景. 随着kubernetes用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制. 目前,kubernetes中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:.

说说Kubernetes是怎么实现服务发现的

- - 掘金后端
我们来说说 kubernetes 的服务发现. 那么首先这个大前提是同主机通信以及跨主机通信都是 ok 的,即同一 kubernetes 集群中各个 pod 都是互通的. 这点是由更底层的方案实现,包括 docker0/CNI 网桥、flannel vxlan/host-gw 模式等,在此篇就不展开讲了.

Kubernetes在微服务中的最佳实践

- - DockOne.io
你可以在网上找到许多关于如何正确构建微服务体系架构的最佳实践. 其中之一是我以前写的一篇文章 Spring Boot在微服务中的最佳实践. 我把重点放在在生产上基于Spring Boot构建的微服务应用程序应该考虑哪些方面. 我没有使用任何用于编排或管理应用程序的平台,而只是一组独立的应用程序. 在本文中,我将基于已经介绍的最佳实践,在Kubernetes平台上部署微服务,你需要注意的一些新规则和事项.