Ingress
NodePort缺点:
- 一个端口只能对应一个服务使用,端口需要提前规划
- 只支持4层负载均衡
Ingress与Pod的关系
-
通过Service相关联
-
通过Ingress Controller实现Pod的负载均衡
-支持TCP/UDP4层和HTTP 7层
ingress Controller部署
Ingress Controller 有很多种实现方法,这里采用官网维护的Nginx控制器
部署文档: https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md
其他主流控制器:
Traefik: HTTP反向代理, 负载均衡工具
istio: 服务治理, 控制入口流量
部署nginx-ingress-controller
YAML文件地址:
https://github.com/kubernetes/ingress-nginx/blob/nginx-0.30.0/deploy/static/mandatory.yaml
下载YAML文件到本地ingress-nginx.yaml,修改配置:
-
修改ingress-nginx镜像地址
suisrc/ingress-nginx:0.30.0
-
如果使用Deployment控制器建议配置replicas为2
-
加入default-http-backend(在Deployment.nginx-ingress-controller之前),YAML配置如下
还需要再ingress-nginx.yaml中加入参数–default-backend-service=$(POD_NAMESPACE)/default-http-backend,如下
containers: - name: nginx-ingress-controller image: suisrc/ingress-nginx:0.30.0 args: - /nginx-ingress-controller - --default-backend-service=$(POD_NAMESPACE)/default-http-backend - --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
default-http-backend的yaml配置
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: default-http-backend
labels:
app: default-http-backend
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app: default-http-backend
template:
metadata:
labels:
app: default-http-backend
spec:
terminationGracePeriodSeconds: 60
containers:
- name: default-http-backend
image: registry.cn-qingdao.aliyuncs.com/kubernetes_xingej/defaultbackend-amd64:1.5
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
timeoutSeconds: 5
ports:
- containerPort: 8080
resources:
limits:
cpu: 100m
memory: 100Mi
requests:
cpu: 100m
memory: 100Mi
---
apiVersion: v1
kind: Service
metadata:
name: default-http-backend
# namespace: ingress-nginx
namespace: ingress-nginx
labels:
app: default-http-backend
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: default-http-backend
---
hostNetwork模式
-
hostNetwork
将域名解析到部署ingress Controller的node节点IP,端口为ingress Controller暴露端口(80,443),进行访问
通过Ingress访问的逻辑为:Client Request -> Ingress-Controller节点 -> Ingress -> Service -> Deployment
注意:
- 需要在Ingress Controller的yaml配置文件中指定使用主机网络hostNetwork: true位置位于spec.tmplate.spec下
- 不需要配置Service,通过kubectl get ingress获取ingress信息时候,ADDRESS地址会为空
- 可以将控制器设置为DaemonSet,就可以将域名解析到任意节点进行访问了
- 部署ingress Controller节点端口(80,443)不能被占用
NodePort模式
-
nodePort
通过Service暴露部署的Ingress Controller,将域名解析到任意节点,然后通过域名:nodePort端口进行访问
通过Ingress访问的逻辑为:Client Request -> Ingress-service(通过NodePort暴露端口) -> Ingress -> Service -> Deployment
注意:
- 需要配置Service暴露端口,通过kubectl get ingress获取ingress信息时候,ADDRESS地址为Service的ClusterIP
- 域名可以解析到任意节点,访问时候需要带端口,端口为service的nodePort
配置ingress-service.yaml
---
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
# HTTP
nodePort: 32080
- name: https
port: 443
targetPort: 443
protocol: TCP
# HTTPS
nodePort: 32443
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
配置ingress
配置ingress.yaml,为已存在的deploy/nginx添加域名(namespace为default,service为nginx-service)
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx-domain
namespace: default
spec:
rules:
- host: www.abc.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
---
ingress其余样例
---
# http
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
---
# https
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.ctnrs.com
secretName: secret-tls
rules:
- host: sslexample.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
---
# url route
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foobar.ctnrs.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 80
- host: foobar.ctnrs.com
http:
paths:
- path: /bar
backend:
serviceName: service2
servicePort: 80
---
# server
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.ctnrs.com
http:
paths:
- backend:
serviceName: service1
servicePort: 80
- host: bar.ctnrs.com
http:
paths:
- backend:
serviceName: service2
servicePort: 80
---
# annotations
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
kubernetes.io/ingress.class: "nginx“
nginx.ingress.kubernetes.io/proxy-connect-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
rules:
- host: example.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
annotations:
kubernetes.io/ingress.class: "nginx“
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
tls:
- hosts:
- sslexample.ctnrs.com
secretName: secret-tls
rules:
- host: sslexample.ctnrs.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
应用配置 && 验证
应用部署
kubectl apply -f ingress-nginx.yaml
kubectl apply -f ingress-service.yaml
kubectl apply -f ingress.yaml
验证
配置相关信息
查看nginx-ingress-controller所有部署信息
kubectl get all -n ingress-nginx
查看default下ingress信息
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-domain <none> www.abc.com 10.0.0.160 80 122m
如果ADDRESS为空,可能是没有配置或者没有配置好ingress-service
查看ingress详细信息
kubectl describe ingress
Name: nginx-domain
Namespace: default
Address: 10.0.0.160
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
www.abc.com
/ nginx-service:80 (10.244.0.7:80,10.244.1.12:80,10.244.2.7:80 + 1 more...)
Annotations: Events: <none>
<error: endpoints “default-http-backend” not found>这个报错可能跟namespace有关,但是不影响效果,通过ip:port方式访问结果为如下即说明default-http-backend工作正常
default backend - 404
域名验证
确定设置本机hosts
192.169.2.201 www.abc.com
访问http://www.abc.com,出现正常页面即为解析成功
固定节点部署ingress
- Deployment模式下使用,DaemonSet下忽略
在节点上打标签
kubectl label nodes k8s-node1 node-role.kubernetes.io/ingress="true"
kubectl label nodes k8s-node2 node-role.kubernetes.io/ingress="true"
配置nodeSelector
配置deployment下的nodeSelector,加入node-role.kubernetes.io/ingress: “true”
spec:
hostNetwork: true
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
node-role.kubernetes.io/ingress: "true"
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.30.0