Ingress 是什么
Ingress 可以通过HTTP或HTTPS公开集群内部的Service,而不需要再通过NodePort的方式暴露服务。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
1
客户端--->Ingress---路由规则--->Service--->Pod
Ingress-Controller 并不是K8S自带的组件,它只是一个统称,我们可以选择不同的Ingress-Controller的实现。官方提供了ingress-nginx, 也可以选择 其它的ingress实现, 比如有:
- APISIX ingress
- Nginx ingress
- Kong ingress
- Traefik ingress
- Haproxy ingress
- Istio ingress
- Ambassador ingress
它们的实现机制都大同小异,Ingress-Controller一般都会有一个Pod,里面跑着反向代理,并不断的监听着集群的变化,动态生成路由配置。
你可以将 ingress-nginx 看作一个nginx外加一些 golang 和 lua 代码。
部署 ingress-nginx
可以想将yaml文件下载过来,根据自己的需要稍作修改修改:
1
2
3
wget -e "https_proxy=http://172.16.10.11:8118" https://github.com/kubernetes/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
kubectl apply -f mandatory.yaml
我这里作了两处改动:
- 将 nginx-ingress-controller 的 Deployment 改为DaemonSet,这样就可以在每个node节点上部署一个ingress-nginx了。
- Deployment 下增加配置 hostNetwork 并设置为 true,这样可以每个节点上将80端口和443端口暴露出来, 还可以增加一个SLB前置负载到每个节点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spec:
hostNetwork: true # 增加的配置
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
你可能也会看到这样的警告:
1
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
有的api版本已经过期,根据提示将yaml文件中的v1beta1改为v1, 再重新执行 kubectl apply就可以了。看下ingress-nginx的pod部署情况:
1
2
3
4
5
# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-54b86f8f7b-fq899 1/1 Running 0 11h
nginx-ingress-controller-sv7z8 1/1 Running 0 20m
nginx-ingress-controller-znq5r 1/1 Running 0 20m
另外需要注意的是执行 kubectl apply -f mandatory.yaml 会自动下载需要的镜像,可能需要翻墙,如果没有成功,可以检查下是不是没有下载到镜像。
通过ingress-nginx暴露服务
现在可以通过ingress-nginx暴露后端的服务了, 增加ingress-nginx.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: "foo.bar.com" # 指定host
http:
paths:
- pathType: Prefix
path: "/" # 可以定义路由规则
backend:
service:
name: nginx # 要通过ingres暴露的服务
port:
number: 80
执行一下:
1
kubectl apply -f ingress-nginx.yaml
查看ingress:
1
2
3
# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress <none> foo.bar.com 80 3m
通过curl测试一下, 这个IP是宿主机的IP:
1
2
3
4
5
6
7
8
9
10
11
# curl -I http://foo.bar.com -x 172.16.10.13:80
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Thu, 26 Nov 2020 13:47:11 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Thu, 26 Oct 2020 15:09:20 GMT
ETag: "5f983820-264"
Accept-Ranges: bytes
通过ingress-nginx暴露tcp服务
通过 ingress-nginx 不仅可以暴露基于http的内部服务,还可以通过L4负载暴露内部的tcp,upd服务。
通过查看以上mandatory.yaml文件,可以看到 tcp-services-configmap, udp-services-configmap 这些都是通过 configmap 动态配置的。可以修改名称为 tcp-services 和 udp-services的 ConfigMap 暴露服务。
示例:
1
2
3
4
5
6
7
8
9
10
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
data:
16379: "default/redis-svc:6379" # 增加的配置
这里是将default命名空间下的redis-svc的6379端口负载到ingress-nginx的16379端口,udp-service也是一样的。