Kubernetes Ingress实战
2017-04-21
2018/06:经过一年多的发展Kubernetes的Ingress发生了很大的变化,这篇的很多地方都不适用了。因此决定结合我们目前的使用情况重新写几篇Kubernetes Ingress相关的分享,链接如下,内容是比较入门和初级的实操,请高手勿喷。
- Kubernetes Ingress实战(一):在Kubernetes集群中部署NGINX Ingress Controller
- Kubernetes Ingress实战(二):使用Ingress将第一个HTTP服务暴露到集群外部
- Kubernetes Ingress实战(三):使用Ingress将gRPC服务暴露到Kubernetes集群外部
- Kubernetes Ingress实战(四):Bare metal环境下Kubernetes Ingress边缘节点的高可用
- Kubernetes Ingress实战(五):Bare metal环境下Kubernetes Ingress边缘节点的高可用(基于IPVS)
Ingress和Ingress Controller #
前面写过一篇《从集群外部访问Kubernetes Service》,介绍了从Kubernetes集群外部访问Service的方式。本篇将实践一下使用Ingress将Kubernetes集群外部的流量接入到集群内。
一般来说Kubernetes集群中的节点位于互联网防火墙后边,在集群的前面有一个边界路由器(Edge router)用来实现集群的防火墙策略。边界路由器可以是云服务商提供或物理硬件管理的网关。Kubernetes集群的网络是一组物理或逻辑链接,使用Kubernetes的网络模型实现集群内的通信,我们的集群网络使用的是Overlay模型的flannel。在集群内通过虚拟IP访问服务。 对于集群外部的请求,所有到达边界路由器的流量会被丢弃或转发到其他地方。
Ingress可以授权和控制从集群外部访问集群内的Service。Ingress是授权进入集群并访问集群内Service的规则集合。 通过Ingress可以给Service配置外部可访问的URL、负载均衡、终止SSL、 按域名访问的虚拟主机等功能。
Ingress也是通过Kubernetes API创建的,但只是创建一个Ingress没有任何意义,需要先创建一个Ingress Controller。 Ingress Controller负责实现Ingress,通常是一个负载均衡器,也可以配置为边界路由器或者其他前端,这样就可以高可用的方式接入外部流量。
运行一个Ingress Controller
#
我们的Kubernetes集群是使用kubeadm初始化的,所以参考这里Deploying the Nginx Ingress controller on kubeadm clusters。
1kubectl apply -f https://rawgit.com/kubernetes/ingress/master/examples/deployment/nginx/kubeadm/nginx-ingress-controller.yaml
2
3deployment "default-http-backend" created
4service "default-http-backend" created
5deployment "nginx-ingress-controller" created
部署成功后,创建了如下两个Pod:
1kubectl get pods --namespace=kube-system -l k8s-app=default-http-backend -o wide
2NAME READY STATUS RESTARTS AGE IP NODE
3default-http-backend-2198840601-4dr3x 1/1 Running 3 6m 10.244.2.13 node3
4
5kubectl get pods --namespace=kube-system -l k8s-app=nginx-ingress-controller -o wide
6NAME READY STATUS RESTARTS AGE IP NODE
7nginx-ingress-controller-3697895370-ljhzm 1/1 Running 8 7m 192.168.61.43 node3
其中default-http-backend-2198840601-4dr3x
作为 Nginx Ingress Controller默认的后端,处理所有404请求。因为我们还没有任何ingress规则生效,此时请求http://node3
,将由此pod响应。
1curl http://node3
2default backend - 404
Nginx Ingress Controller的Pod被调度到node3上,作为负载均衡器监听80和443端口,将外部请求接入。
创建Ingress
#
集群部署两个服务nginx1-7和nginx1-8:
nginx1.7.yaml
1apiVersion: v1
2kind: Service
3metadata:
4 name: nginx1-7
5spec:
6 ports:
7 - port: 80
8 targetPort: 80
9 selector:
10 app: nginx1-7
11---
12apiVersion: apps/v1beta1
13kind: Deployment
14metadata:
15 name: nginx1-7-deployment
16spec:
17 replicas: 2
18 template:
19 metadata:
20 labels:
21 app: nginx1-7
22 spec:
23 containers:
24 - name: nginx
25 image: nginx:1.7.9
26 ports:
27 - containerPort: 80
nginx1.8.yaml
1apiVersion: v1
2kind: Service
3metadata:
4 name: nginx1-8
5spec:
6 ports:
7 - port: 80
8 targetPort: 80
9 selector:
10 app: nginx1-8
11---
12apiVersion: apps/v1beta1
13kind: Deployment
14metadata:
15 name: nginx1-8-deployment
16spec:
17 replicas: 2
18 template:
19 metadata:
20 labels:
21 app: nginx1-8
22 spec:
23 containers:
24 - name: nginx
25 image: nginx:1.8
26 ports:
27 - containerPort: 80
1kubectl create -f nginx1.7.yaml
2service "nginx1-7" created
3deployment "nginx1-7" created
4
5kubectl create -f nginx1.8.yaml
6service "nginx1-8" created
7deployment "nginx1-8" created
8
9 kubectl get pods -o wide
10NAME READY STATUS RESTARTS AGE IP NODE
11nginx1-7-deployment-2912423055-rpclr 1/1 Running 0 10s 10.244.2.29 node3
12nginx1-7-deployment-2912423055-s4chf 1/1 Running 0 10s 10.244.0.16 node1
13nginx1-8-deployment-2060323882-dj786 1/1 Running 0 5s 10.244.1.36 node2
14nginx1-8-deployment-2060323882-r2vbg 1/1 Running 0 5s 10.244.2.30 node3
15
16
17kubectl get svc -o wide
18NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
19kubernetes 10.96.0.1 <none> 443/TCP 16d <none>
20nginx1-7 10.104.163.171 <none> 80/TCP 46s app=nginx1-7
21nginx1-8 10.108.239.60 <none> 80/TCP 41s app=nginx1-8
假设这两个服务要暴露到集群外部。要创建一个ingress:
test-ingress.yaml
1apiVersion: extensions/v1beta1
2kind: Ingress
3metadata:
4 name: test
5spec:
6 rules:
7 - host: n17.my.com
8 http:
9 paths:
10 - backend:
11 serviceName: nginx1-7
12 servicePort: 80
13 - host: n18.my.com
14 http:
15 paths:
16 - backend:
17 serviceName: nginx1-8
18 servicePort: 80
1kubectl create -f test-ingress.yaml
2ingress "test" created
3
4kubectl get ing
5NAME HOSTS ADDRESS PORTS AGE
6test n17.my.com,n18.my.com 192.168.61.43 80 14s
在客户机上配置host正确解析n17.my.com和n18.my.com,分别打开这两个地址可以请求到对应的nginx服务。
注意这里ingress中的规则是基于名称的虚拟主机,如果需要添加新的虚拟主机,可以修改test-ingress.yaml,使用kubectl replace -f
更新即可。