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。
kubectl apply -f https://rawgit.com/kubernetes/ingress/master/examples/deployment/nginx/kubeadm/nginx-ingress-controller.yaml
deployment "default-http-backend" created
service "default-http-backend" created
deployment "nginx-ingress-controller" created部署成功后,创建了如下两个Pod:
kubectl get pods --namespace=kube-system -l k8s-app=default-http-backend -o wide
NAME READY STATUS RESTARTS AGE IP NODE
default-http-backend-2198840601-4dr3x 1/1 Running 3 6m 10.244.2.13 node3
kubectl get pods --namespace=kube-system -l k8s-app=nginx-ingress-controller -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-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响应。
curl http://node3
default backend - 404Nginx Ingress Controller的Pod被调度到node3上,作为负载均衡器监听80和443端口,将外部请求接入。
创建Ingress
集群部署两个服务nginx1-7和nginx1-8:
nginx1.7.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx1-7
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx1-7
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx1-7-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx1-7
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80nginx1.8.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx1-8
spec:
ports:
- port: 80
targetPort: 80
selector:
app: nginx1-8
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx1-8-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx1-8
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80kubectl create -f nginx1.7.yaml
service "nginx1-7" created
deployment "nginx1-7" created
kubectl create -f nginx1.8.yaml
service "nginx1-8" created
deployment "nginx1-8" created
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx1-7-deployment-2912423055-rpclr 1/1 Running 0 10s 10.244.2.29 node3
nginx1-7-deployment-2912423055-s4chf 1/1 Running 0 10s 10.244.0.16 node1
nginx1-8-deployment-2060323882-dj786 1/1 Running 0 5s 10.244.1.36 node2
nginx1-8-deployment-2060323882-r2vbg 1/1 Running 0 5s 10.244.2.30 node3
kubectl get svc -o wide
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes 10.96.0.1 <none> 443/TCP 16d <none>
nginx1-7 10.104.163.171 <none> 80/TCP 46s app=nginx1-7
nginx1-8 10.108.239.60 <none> 80/TCP 41s app=nginx1-8假设这两个服务要暴露到集群外部。要创建一个ingress:
test-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: n17.my.com
http:
paths:
- backend:
serviceName: nginx1-7
servicePort: 80
- host: n18.my.com
http:
paths:
- backend:
serviceName: nginx1-8
servicePort: 80kubectl create -f test-ingress.yaml
ingress "test" created
kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
test 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更新即可。