前言
ingress 能够了解为 Service 的 Service,即在现有 Service 的后面再搭建一层 Service,作为内部流量的对立入口,进行申请路由的转发。
说白了就是在前端搭建一个 nginx 或者 haproxy,将不同 host 或 url 转发到对应的后端 Service,再由 Service 转给 Pod。只不过 ingress 对 nginx/haproxy 进行了一些解耦和形象。
更新历史
- 20200628 – 初稿 – 左程立
- 原文地址 – https://blog.zuolinux.com/2020/06/28/about-ingress-controller.html
Ingress 的意义
ingress 补救了默认 Service 裸露外网拜访时候的一些缺点,如不能进行对立入口处的 7 层 URL 规定,如一个默认 Service 只能对应一种后端服务。
通常说的 ingress 蕴含 ingress-controller 和 ingress 对象两局部。
ingress-controller 对应 nginx/haproxy 程序,以 Pod 模式运行。
ingress 对象 对应 nginx/haproxy 配置文件。
ingress-controller 应用 ingress 对象中形容的信息批改本身 Pod 中 nginx/haproxy 的规定。
部署 ingress
筹备测试资源
部署 2 个服务,拜访服务 1,返回 Version 1
拜访服务 2,返回 Version 2
两个服务的程序配置
# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-v1.0
spec:
selector:
matchLabels:
app: v1.0
replicas: 3
template:
metadata:
labels:
app: v1.0
spec:
containers:
- name: hello-v1
image: anjia0532/google-samples.hello-app:1.0
ports:
- containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-v2.0
spec:
selector:
matchLabels:
app: v2.0
replicas: 3
template:
metadata:
labels:
app: v2.0
spec:
containers:
- name: hello-v2
image: anjia0532/google-samples.hello-app:2.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: service-v1
spec:
selector:
app: v1.0
ports:
- port: 8081
targetPort: 8080
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: service-v2
spec:
selector:
app: v2.0
ports:
- port: 8081
targetPort: 8080
protocol: TCP
让容器运行在 8080 上,service 运行在 8081 上。
启动两个服务和对应的 Pod
# kubectl apply -f deployment.yaml
deployment.apps/hello-v1.0 created
deployment.apps/hello-v2.0 created
service/service-v1 created
service/service-v2 created
查看启动状况,每个服务对应 3 个 Pod
# kubectl get pod,service -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/hello-v1.0-6594bd8499-lt6nn 1/1 Running 0 37s 192.10.205.234 work01 <none> <none>
pod/hello-v1.0-6594bd8499-q58cw 1/1 Running 0 37s 192.10.137.190 work03 <none> <none>
pod/hello-v1.0-6594bd8499-zcmf4 1/1 Running 0 37s 192.10.137.189 work03 <none> <none>
pod/hello-v2.0-6bd99fb9cd-9wr65 1/1 Running 0 37s 192.10.75.89 work02 <none> <none>
pod/hello-v2.0-6bd99fb9cd-pnhr8 1/1 Running 0 37s 192.10.75.91 work02 <none> <none>
pod/hello-v2.0-6bd99fb9cd-sx949 1/1 Running 0 37s 192.10.205.236 work01 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/service-v1 ClusterIP 192.20.92.221 <none> 8081/TCP 37s app=v1.0
service/service-v2 ClusterIP 192.20.255.0 <none> 8081/TCP 36s app=v2.0
查看 Service 后端 Pod 挂载状况
[root@master01 ~]# kubectl get ep service-v1
NAME ENDPOINTS AGE
service-v1 192.10.137.189:8080,192.10.137.190:8080,192.10.205.234:8080 113s
[root@master01 ~]# kubectl get ep service-v2
NAME ENDPOINTS AGE
service-v2 192.10.205.236:8080,192.10.75.89:8080,192.10.75.91:8080 113s
能够看到两个服务均胜利挂载了对应的 Pod。
上面部署前端 ingress-controller。
首先指定 work01/work02 两台服务器运行 ingress-controller
kubectl label nodes work01 ingress-ready=true
kubectl label nodes work02 ingress-ready=true
ingress-controller 应用官网 nginx 版本
wget -O ingress-controller.yaml https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
批改为启动 2 个 ingress-controller
# vim ingress-controller.yaml
apiVersion: apps/v1
kind: Deployment。。。。。。。。。。。。revisionHistoryLimit: 10
replicas: 2 # 新增该行
批改为国内镜像
# vim ingress-controller.yaml
spec:
dnsPolicy: ClusterFirst
containers:
- name: controller
#image: us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.34.1@sha256:0e072dddd1f7f8fc8909a2ca6f65e76c5f0d2fcfb8be47935ae3457e8bbceb20
image: registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:0.32.0
imagePullPolicy: IfNotPresent
部署 ingress-controller
kubectl apply -f ingress-controller.yaml
查看运行状况
# kubectl get pod,service -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/ingress-nginx-admission-create-ld4nt 0/1 Completed 0 15m 192.10.137.188 work03 <none> <none>
pod/ingress-nginx-admission-patch-p5jmd 0/1 Completed 1 15m 192.10.75.85 work02 <none> <none>
pod/ingress-nginx-controller-75f89c4965-vxt4d 1/1 Running 0 15m 192.10.205.233 work01 <none> <none>
pod/ingress-nginx-controller-75f89c4965-zmjg2 1/1 Running 0 15m 192.10.75.87 work02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/ingress-nginx-controller NodePort 192.20.105.10 192.168.10.17,192.168.10.17 80:30698/TCP,443:31303/TCP 15m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
service/ingress-nginx-controller-admission ClusterIP 192.20.80.208 <none> 443/TCP 15m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
能够看到 work01/02 上运行了 ingress-nginx-controller Pod。
编写拜访申请转发规定
# cat ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: test-v1.com
http:
paths:
- path: /
backend:
serviceName: service-v1
servicePort: 8081
- host: test-v2.com
http:
paths:
- path: /
backend:
serviceName: service-v2
servicePort: 8081
启用规定
# kubectl apply -f ingress.yaml
ingress.networking.k8s.io/nginx-ingress created
能够看到 ingress-controller Pod 外面 nginx 配置曾经失效了
# kubectl exec ingress-nginx-controller-75f89c4965-vxt4d -n ingress-nginx -- cat /etc/nginx/nginx.conf | grep -A 30 test-v1.com
server {
server_name test-v1.com ;
listen 80 ;
listen 443 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {certificate.call()
}
location / {
set $namespace "default";
set $ingress_name "nginx-ingress";
set $service_name "service-v1";
set $service_port "8081";
set $location_path "/";
咱们在集群内部拜访测试。
首先解析域名到 work01
# cat /etc/hosts
192.168.10.15 test-v1.com
192.168.10.15 test-v2.com
拜访测试
# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-svjnf
# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-zqjtm
# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-www76
# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-h8862
# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-sn84j
能够看到不同域名的申请去到了正确的 Service 上面的不同 Pod 中。
再申请 work02
# cat /etc/hosts
192.168.10.16 test-v1.com
192.168.10.16 test-v2.com
# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-www76
# curl test-v1.com
Hello, world!
Version: 1.0.0
Hostname: hello-v1.0-6594bd8499-zqjtm
# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-sn84j
# curl test-v2.com
Hello, world!
Version: 2.0.0
Hostname: hello-v2.0-6bd99fb9cd-h8862
也没问题。
如何高可用
在 work01 / work02 后面再挂 2 台 LVS+keepalived 就能够实现对 work01/02 的高可用拜访了。也能够在 work01 / work02 上间接应用 keepalived 漂一个 VIP,不须要额定机器,这样节约老本。
结束语
本文应用了 Deployment + NodePort Service 的形式部署 Ingress。
用 Deployment 治理 ingress-controller 的 Pod,应用 NodePort 形式裸露 ingress Service。
查看 ingress service
# kubectl get service -o wide -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
ingress-nginx-controller NodePort 192.20.105.10 192.168.10.17,192.168.10.17 80:30698/TCP,443:31303/TCP 22m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
能够看到对外裸露了 30698 端口,拜访任何节点的 30698 端口即可拜访到 v1/v2 版本的 Pod。
但该端口是随机的,并且重建后会变动,咱们能够间接拜访运行 ingress-controller Pod 的 work01/02 的 80 端口。
work01/02 后面再弄一套 LVS+keepalived 进行高可用负载。
work01/02 上应用 iptables -t nat -L -n -v 能够看到 80 端口是通过 NAT 模式凋谢的,高流量会有瓶颈。
能够应用 DaemonSet + HostNetwork 的形式来部署 ingress-controller。
这样 work01/02 上裸露的 80 端口间接应用宿主机的网络,不走 NAT 映射,能够防止性能问题。
分割我
微信公众号:zuolinux_com