k8s初级实战11--ingress案例
1 基础概念
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
集群中必须具有 Ingress 控制器 才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。因此,可能需要部署 Ingress 控制器,例如 ingress-nginx,traefik;本文以traefik为案例进行说明。
下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例, 客户端流量通过Ingress控制器进入到集群,控制器再根据规则将不同的域名 或者 不同的{域名+路径}转发到不同的service对应的端口,最后由service将具体的请求转发到pod中,pod处理完请求后返回相关数据。
2 常见用法
2.1 配置Ingress Controller
- 创建新角色和绑定权限
vim ingress.rbac.yaml kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: traefik-ingress-controller rules: - apiGroups: - "" resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses verbs: - get - list - watch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: traefik-ingress-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress-controller subjects: - kind: ServiceAccount name: traefik-ingress-controller namespace: kube-system # kubectl create -f ingress.rbac.yaml clusterrole.rbac.authorization.k8s.io/traefik-ingress-controller created clusterrolebinding.rbac.authorization.k8s.io/traefik-ingress-controller created 或者直接使用远程文件部署: # kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/traefik-rbac.yaml
- 创建 Traefik controller
vim traefik-ds.yaml --- apiVersion: v1 kind: ServiceAccount metadata: name: traefik-ingress-controller namespace: kube-system --- kind: DaemonSet apiVersion: apps/v1 metadata: name: traefik-ingress-controller namespace: kube-system labels: k8s-app: traefik-ingress-lb spec: selector: matchLabels: name: traefik-ingress-lb template: metadata: labels: k8s-app: traefik-ingress-lb name: traefik-ingress-lb spec: serviceAccountName: traefik-ingress-controller terminationGracePeriodSeconds: 60 hostNetwork: True containers: - image: traefik:1.7.13 name: traefik-ingress-lb ports: - name: http containerPort: 80 hostPort: 80 - name: admin containerPort: 8080 hostPort: 8080 args: - --api - --kubernetes - --logLevel=INFO --- kind: Service apiVersion: v1 metadata: name: traefik-ingress-service namespace: kube-system spec: selector: k8s-app: traefik-ingress-lb type: NodePort ports: - protocol: TCP port: 80 name: web - protocol: TCP port: 8080 name: admin # kubectl create -f traefik-ds.yaml serviceaccount/traefik-ingress-controller created daemonset.apps/traefik-ingress-controller created service/traefik-ingress-service created 或者直接使用远程文件部署,可根据需要选择deploy 或者 ds来部署 traefik: # kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/traefik-deployment.yaml # kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v1.7/examples/k8s/traefik-ds.yaml
2.2 测试Ingress规则
-
创建2个deploy
创建第一个nginx01 # vim nginx01.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx01 name: nginx01 spec: replicas: 1 selector: matchLabels: app: nginx01 template: metadata: labels: app: nginx01 spec: containers: - image: nginx:1.19.6 name: nginx01 # kubectl apply -f nginx01.yaml 创建第二个nginx02 # vim nginx02.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx02 name: nginx02 spec: replicas: 1 selector: matchLabels: app: nginx02 template: metadata: labels: app: nginx02 spec: containers: - image: nginx:1.19.6 name: nginx02 # kubectl apply -f nginx02.yaml
-
创建2个相应的service
# kubectl expose deployment nginx01 --name=nginx01-svr --type=NodePort --port=80 # kubectl expose deployment nginx02 --name=nginx02-svr --type=NodePort --port=80 # kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 45d mysql-5730 ClusterIP 10.1.56.161 <none> 3306/TCP 32d nginx01-svr NodePort 10.1.130.8 <none> 80:30218/TCP 16s nginx02-svr NodePort 10.1.1.41 <none> 80:31868/TCP 9s
-
分别修改nginx01 和 nginx02
修改nginx01 # kubectl exec -it nginx01-7d4d7f956f-mhg77 -- bash # cat << EOF > /usr/share/nginx/html/index.html <head> <title>Welcome to nginx 01!</title> </head> <body> <h1>Welcome to nginx01!</h1> </body> EOF 修改nginx02 # kubectl exec -it nginx02-85d87d44c9-hzcjz -- bash # cat << EOF > /usr/share/nginx/html/index.html <head> <title>Welcome to nginx 02!</title> </head> <body> <h1>Welcome to nginx02!</h> </body> EOF
ngixn01 效果:
ngixn02 效果:
-
创建ingress规则
# vim ingress.rule.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-nginx-test spec: rules: - host: www.nginx01.com http: paths: - backend: serviceName: nginx01-svr servicePort: 80 path: / - host: www.nginx02.com http: paths: - backend: serviceName: nginx02-svr servicePort: 80 path: / # kubectl create -f ingress.rule.yaml Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress ingress.extensions/ingress-nginx-test created # kubectl get ingress Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-nginx-test <none> www.nginx01.com,www.nginx02.com 80 67s
此时还没有ADDRESS,因此需要创建相关服务;然后通过ingress的ip访问服务即可;
-
使用不同host测试ingress
注:10.120.75.107 是k8s集群的其中之一节点,xg04不是k8s集群的节点。 xg04:~$ curl -H "Host: www.nginx01.com" http://10.120.75.107 xg04:~$ curl -H "Host: www.nginx01.com" http://10.120.75.107:30143 xg04:~$ curl -H "Host: www.nginx02.com" http://10.120.75.107:30143
通过上面3种方式访问,都可以正常访问内部服务nginx01和nginx02,很明显Host不同其访问的服务也不同,即充分验证来ingress controller的转发能功能。上面可以直接通过http://10.120.75.107来访问服务,原因为笔者将 traefik-ingress-controller 容器的hostNetwork 设置为True。
继续通过ip:8080的NodePort查看Traefik的管理界面,可见其代理了2个服务,且后端通过WRR实现负载均衡。
health界面:
3 注意事项
- 测试的时候,可以通过上述案例中 curl -H “Host: www.example.com” 来模拟不同的host访问。
- 线上服务,一般会给每个服务配置一个专有的域名,ingress 会根据不同的域名将流量转发到不同的内部服务上,从而实现流量转发。
4 说明
1 concepts/services-networking/ingress
2 概念->服务、负载均衡和联网->Ingress 控制器
3 概念->服务、负载均衡和联网->Ingress 控制器
4 traefik 官方文档
5 traefik/user-guides/crd-acme/
6 traefik/v1.7/user-guide/kubernetes/