Kubernetes学习笔记(2):k8s的服务发现

3种服务访问情况

1. 内部 -> 内部

1.1 DNS + ClusterIP

1.2 Headless Service

2. 内部 -> 外部

2.1 IP + Port

2.2 Out Service

3. 外部 -> 内部

3.1 Node Port

3.2 Host Port

3.3 Ingress

部署Ingress

什么是Ingress

利用 Nginx、Haproxy 之类的负载均衡器暴露k8s集群内服务的工具。

k8s 服务暴露的3种方式

  • LoadBlancer Service: LoadBlancer Service 是 kubernetes 深度结合云平台的一个组件;当使用 LoadBlancer Service 暴露服务时,实际上是通过向底层云平台申请创建一个负载均衡器来向外暴露服务;目前 LoadBlancer Service 支持的云平台已经相对完善,比如国外的 GCE、DigitalOcean,国内的 阿里云,私有云 Openstack 等等,由于 LoadBlancer Service 深度结合了云平台,所以只能在一些云平台上来使用
  • NodePort Service: 顾名思义,实质上就是通过在集群的每个 node 上暴露一个端口,然后将这个端口映射到某个具体的 service 来实现的,虽然每个 node 的端口有很多(0~65535),但是由于安全性和易用性(服务多了就乱了,还有端口冲突问题)实际使用可能并不多。
  • Ingress: Ingress 这个东西是 1.2 后才出现的,通过 Ingress 用户可以实现使用 nginx 等开源的反向代理负载均衡器实现对外暴露服务。

    Ingress 三个组件

  • 反向代理负载均衡器: 说白了就是 nginx、apache 这类反向代理应用;在集群中反向代理负载均衡器可以自由部署,可以使用 Replication ControllerDeploymentDaemonSet 等等,不过个人喜欢以 DaemonSet 的方式部署,感觉比较方便。
  • Ingress Controller: 实质上可以理解为是个监视器,Ingress Controller 通过不断地跟 kubernetes API 打交道,实时的感知后端 service、pod 等变化,比如新增和减少 pod,service 增加与减少等;当得到这些变化信息后,Ingress Controller 再结合下文的 Ingress 生成配置,然后更新反向代理负载均衡器,并刷新其配置,达到服务发现的作用。
  • Ingress: 简单理解就是个规则定义;比如说某个域名对应某个 service,即当某个域名的请求进来时转发给某个 service;这个规则将与 Ingress Controller 结合,然后 Ingress Controller 将其动态写入到负载均衡器配置中,从而实现整体的服务发现和负载均衡。

从上图中可以很清晰的看到,实际上请求进来还是被负载均衡器拦截,比如 nginx,然后 Ingress Controller 通过跟 Ingress 交互得知某个域名对应哪个 service,再通过跟 kubernetes API 交互得知 service 地址等信息;综合以后生成配置文件实时写入负载均衡器,然后负载均衡器 reload 该规则便可实现服务发现,即动态映射。

了解了以上内容以后,这也就很好的说明了我为什么喜欢把负载均衡器部署为 Daemon Set;因为无论如何请求首先是被负载均衡器拦截的,所以在每个 node 上都部署一下,同时 hostport 方式监听 80 端口,就解决了其他方式部署不确定负载均衡器在哪的问题,同时访问每个 node 的 80 都能正确解析请求;如果前端再放个 nginx 就又实现了一层负载均衡。

Ingress-Nignx

Ingress Nignx 介绍:https://github.com/kubernetes/ingress-nginx

Installation Guide: https://kubernetes.github.io/ingress-nginx/deploy/#provider-specific-steps

为指定节点打标签

查看当前节点信息:

1
kubectl get nodes

假设这里我们要给节点w1.mooc.com打标签,执行以下命令:

1
kubectl label node w1.mooc.com app=ingress

查看标签是否打成功了。

1
kubectl describe node w1.mooc.com

下载并修改配置文件

1
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

为了指定Ingress部署节点,修改mandatory.yaml,配置hostNetworknodeSelector选项。这里特别指定在含有app=nginx标签的节点上部署Ingress-Nginx。

部署 Ingress-Nginx

1
kubectl create -f mandatory.yaml

切换到w1那台机器上,可以看到已经在监听80443端口了。

检验 Ingress 服务

编写一个测试文件,如:ingress-demo.yaml,启动一个tomcat服务,并配置服务映射,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-demo
spec:
selector:
matchLabels:
app: tomcat-demo
replicas: 1
template:
metadata:
labels:
app: tomcat-demo
spec:
containers:
- name: tomcat-demo
image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
ports:
- containerPort: 8080
---
#service
apiVersion: v1
kind: Service
metadata:
name: tomcat-demo
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: tomcat-demo

---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat-demo
spec:
rules:
- host: tomcat.mooc.com
http:
paths:
- path: /
backend:
serviceName: tomcat-demo
servicePort: 80

注意这个配置文件,除了正常的deployment和service节点,还多了一个#ingress节点,并且在这个节点下相应地配置了跳转规则。当访问tomcat.mooc.com时,ingress-nginx会将流量导流到tomcat-demo且端口是80这个服务上。

执行部署命令:

1
kubectl create -f ingress-demo.yaml

  • 在本机(测试机)配置一下/etc/hosts,将tomcat.mooc.com指向ingress-nginx所在的节点w1.mooc.com的IP地址,以便测试。
  • 同时,在配置一个api.mooc.com,也指向同一个IP地址,用来验证没有配置规则时,ingress-nginx返回的效果。

在浏览器中访问http://tomcat.mooc.com,如果一切正常,应该跳转到tomcat首页。

访问http://api.mooc.com,因为并没有在ingress-nignx配置这个的跳转规则,所以返回默认错误页面。

说明我们的ingress-nginx服务正常工作了。

王方钢 / Kenny Wang wechat
0%