Ingress出现的原因
由于每个Service都要有一个负载均衡服务,这种做法实际上既浪费成本又高。作为用户,我们其实更希望看到Kubernetes内置一个全局的负载均衡器。然后通过我访问的URL,把请求转发到不同的后端Service。
这种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的 Ingress 服务。
所以,Ingress 的功能其实很容易理解:所谓 Ingress,就是 Service 的“Service”。
实例:把tomcat service通过ingress发布出去
- 部署Nginx Ingress Controller
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml
kubectl get pod -n ingress-nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-ingress-controller-775d945fdd-xjc7b 1/1 Running 1 30d 10.244.0.248 10.10.13.127
- 部署service-nodeport
service-nodeport服务,实现把集群外部流量接入到集群中来。
kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.100.44.0 <none> 80:31454/TCP,443:31077/TCP 1y
3. 部署tomcat-svc
[[email protected] ingress]# cat tomcat-demo.yaml
apiVersion: v1
kind: Service
#必须设置为无头service
metadata:
name: tomcat
namespace: default
spec:
selector:
app: tomcat
release: canary
ports:
- name: http
targetPort: 8080 #这是容器port
port: 8080 #这是service port
- name: ajp
targetPort: 8009
port: 8009
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deploy
namespace: default
spec:
replicas: 2
selector: #标签选择器
matchLabels: #匹配的标签为
app: tomcat
release: canary
template:
metadata:
labels:
app: tomcat #和上面的myapp要匹配
release: canary
spec:
containers:
- name: tomcat
image: tomcat:8.5.34-jre8-alpine #在https://hub.docker.com/r/library/tomcat/tags/上面找
ports:
- name: http
containerPort: 8080
- name: ajp
containerPort: 8009
kubectl apply -f tomcat-demo.yaml
[[email protected]]$kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tomcat ClusterIP 10.103.174.6 <none> 8080/TCP,8009/TCP 6h
[[email protected]]$kubectl get pods
NAME READY STATUS RESTARTS AGE
tomcat-deploy-85799c8666-4l2hd 1/1 Running 0 6h
tomcat-deploy-85799c8666-6x6f7 1/1 Running 0 6h
4.部署ingress
[[email protected] ingress]# cat ingress-tomcat.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-tomcat
namespace: default #要和deployment和要发布的service处于同一个名称空间
annotations: #这个注解说明我们要用到的ingress-controller是nginx,而不是traefic,enjoy
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: tomcat.zhixin.com #表示访问这个域名,就会转发到后端myapp管理的pod上的服务:
http:
paths:
- path:
backend:
serviceName: tomcat
servicePort: 8080
kubectl apply -f ingress-tomcat.yaml
[[email protected]]$kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
ingress-tomcat tomcat.zhixin.com 80 6h
[[email protected]]$kubectl describe ingress ingress-tomcat
Name: ingress-tomcat
Namespace: testing-wmh
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
tomcat.zhixin.com
tomcat:8080 (<none>)
Annotations:
Events: <none>
5.本机hosts里增加域名-ip映射
10.10.13.127 tomcat.zhixin.com
原理解释:
创建service,能够从外网访问Ingress controller。这个 Pod 本身,就是一个监听 Ingress 对象以及它所代理的后端 Service 变化的控制器。当一个新的 Ingress 对象由用户创建后,nginx-ingress-controller 就会根据 Ingress 对象里定义的内容,生成一份对应的 Nginx 配置文件(/etc/nginx/nginx.conf),并使用这个配置文件启动一个 Nginx 服务。
nginx server_name对应请求header中的host
参考资料:
https://kubernetes.io/docs/concepts/services-networking/ingress/
https://time.geekbang.org/column/article/69214