K8s-----(七)Ingress服务
一种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的Ingress 服务。Ingress由两部分组成:Ingress controller和Ingress服务。Ingress Controller 会根据你定义的 Ingress 对象,提供对应的代理能力。业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都
K8s-----(七)Ingress服务
1 使用Service访问集群内部存在的问题
Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、ExternalName、NodePort Service、Ingress
将集群内服务提供外界访问就会产生以下几个问题:
1、Pod 漂移问题
- 随着 Pod 的创建和销毁,Pod IP 肯定会动态变化;那么如何把这个动态的 Pod IP 暴露出去,可以通过NodePort
Service解决
2、端口管理问题
- 采用 NodePort 方式暴露服务面临问题是,服务一旦多起来,NodePort
在每个节点上开启的端口会及其庞大,而且难以维护。由于Pod与Pod之间是可以互相通信的,而Pod是可以共享宿主机的网络名称空间的,也就是说当在共享网络名称空间时,Pod上所监听的就是Node上的端口。简单的实现就是使用
DaemonSet 在每个 Node 上监听 80,然后写好规则,因为 Nginx 外面绑定了宿主机 80
端口,本身又在集群内,那么向后直接转发到相应 Service IP 就行了
3、域名分配及动态更新问题
- 采用 Nginx-Pod 其实有一个很大缺陷:当每次有新服务加入又该如何修改 Nginx
配置呢;使用Nginx可以通过虚拟主机域名进行区分不同的服务,而每个服务通过upstream进行定义不同的负载均衡池,再加上location进行负载均衡的反向代理,在日常使用中只需要修改nginx.conf即可实现。
目前面临的问题:
(1)在K8S中如何实现这种方式的调度;
(2)假设后端的服务初始服务只有ecshop,后面增加了bbs和member服务,那么又该如何将这2个服务加入到Nginx-Pod进行调度
2 Ingress 的介绍
官网:https://kubernetes.github.io/ingress-nginx/
Kubernetes 里的Ingress 服务一种全局的、为了代理不同后端 Service 而设置的负载均衡服务
Ingress由两部分组成:Ingress controller和Ingress服务
Ingress Controller 会根据定义的 Ingress 对象,提供对应的代理能力。业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller。
Ingress 控制器不同于Deployment 控制器
的是,Ingress控制器不直接运行为kube-controller-manager的一部分,它仅仅是Kubernetes集群的一个附件,类似于CoreDNS,需要在集群上单独部署
ngress资源时基于HTTP虚拟主机或URL的转发规则,需要强调的是,这是一条转发规则。它在资源配置清单中的spec字段中嵌套了rules、backend和tls等字段进行定义。Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段:
-
rules:用于定义当前Ingress资源的转发规则列表;由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端。
-
backend:默认的后端用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端
-
tls:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNITLS扩展机制来支持该功能。
-
backend对象的定义由2个必要的字段组成:serviceName和servicePort,分别用于指定流量转发的后端目标Service资源名称和端口
3 ngress-nginx的部署
(1)下载官方的ingress应用文件:
wget https://raw.githubusercontent.com/kubernetes/ingress nginx/controller-v0.33.0/deploy/static/provider/baremetal/deploy.yaml
(2)修改ingress controller部署文件
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/443端口就能访问服务。
- 优点是整个请求链路最简单,性能相对NodePort模式更好。
- 缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。
(3)将镜像上传至harbor仓库
(4)创建服务和pod
- 编辑清单资源文件:
demo.yml
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:v1
- 应用文件:
kubectl apply -f demo.yml
- 应用deploy文件:
kubectl apply -f deploy.yaml
- 查看namespace的信息:
kubectl get ns
- 查看ingress-nginx命名空间的pod信息:
kubectl -n ingress-nginx get pod -o wide
- 查看服务的信息:
kubectl get svc
- 查看myservice 服务的信息:
kubectl describe svc myservice
4 创建ingress服务
4.1 通过域名访问后端
(1)编辑资源清单文件:vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo
spec:
rules:
- host: www1.westos.org
http:
paths:
- path: /
backend:
serviceName: myservice
servicePort: 80
- 应用文件:
kubectl apply -f ingress.yaml
(2)查看指定命名空间的pod信息:kubectl -n ingress-nginx get pod -o wide
(3)测试
- 查看myservice 服务的详细信息:
kubectl describe svc myservice
- 编辑测试真机的dns解析文件
- 在真机上测试:
curl www1.westos.org/hostname.html
4.2 不同的域名访问不同的后端服务
(1)编辑资源清单文件:vim nginx-svc.yml
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v2
- 应用文件:
kubectl apply -f nginx-svc.yml
- 查看服务信息:
kubectl get svc
- 查看nginx-svc 服务的信息:
kubectl describe svc nginx-svc
- 过滤app标签的pod:
kubectl get pod -L app
(2)编辑ingress服务文件:vim ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo
spec:
rules:
- host: www1.westos.org
http:
paths:
- path: /
backend:
serviceName: myservice
servicePort: 80
- host: www2.westos.org
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
- 应用文件:
kubectl apply -f ingress.yaml
- 查看ingress的信息:
kubectl get ingress
(3)测试:
- 编辑测试真机的dns解析文件
- 在真机上测试
[root@westos Desktop]# curl www2.westos.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
[root@westos Desktop]# curl www1.westos.org/hostname.html
deployment-59dff4cf5d-h56kz
[root@westos Desktop]# curl www1.westos.org/hostname.html
deployment-59dff4cf5d-fnhhb
[root@westos Desktop]# curl www1.westos.org/hostname.html
deployment-59dff4cf5d-j7b7h
[root@westos Desktop]# curl www2.westos.org/hostname.html
demo-6d4f5bf58f-r49bq
[root@westos Desktop]# curl www2.westos.org/hostname.html
demo-6d4f5bf58f-ztt7j
[root@westos Desktop]# curl www2.westos.org/hostname.html
demo-6d4f5bf58f-djlnv
4.3 Ingress TLS 配置
参考官方的配置步骤:https://kubernetes.github.io/ingress-nginx/examples/PREREQUISITES/
(1)openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj “/CN=nginxsvc/O=nginxsvc”
(2)生成证书:kubectl create secret tls tls-secret --key tls.key --cert tls.crt
(3)修改并应用配置文件:kubectl apply -f ingress.yaml
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo
spec:
tls:
- hosts:
- www1.westos.org
secretName: tls-secret
rules:
- host: www1.westos.org
http:
paths:
- path: /
backend:
serviceName: myservice
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo1
spec:
rules:
- host: www2.westos.org
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
- 查看get ingress的信息:kubectl get ingress
[root@server2 ~]# kubectl describe ingress ingress-demo
Name: ingress-demo
Namespace: default
Address: 172.25.12.4
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
tls-secret terminates www1.westos.org
Rules:
Host Path Backends
---- ---- --------
www1.westos.org
/ myservice:80 (10.244.1.87:80,10.244.1.88:80,10.244.2.63:80)
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal UPDATE 46s (x5 over 64m) nginx-ingress-controller Ingress default/ingress-demo
- 查看指定的ingress-demo1信息:
kubectl describe ingress ingress-demo1
测试:
在真机访问:
- 将域名加入真机的dns解析文件
- 访问被重定向:
curl www1.westos.org -I
- 可以访问:
curl -k https://www1.westos.org/
在浏览器端访问
- 访问 www1.westos.org时提示有风险,忽略风险后可以正常访问
4.4 Ingress 认证配置
(1)生成auth认证文件
- 安装http-tools工具 yum install http-tools
htpasswd -c auth admin ## 生成认证用户,第一次创建必须用-c
htpasswd auth tom ## 添加认证用户,如果用-c会覆盖已经存在的认证的用户
(2) 创建secret:
kubectl create secret generic basic-auth --from-file=auth
## secret名称: basic-auth
## generic通过auth文件创建
- 查看 secrets 的信息:
kubectl get secrets
- 将secret的basic-auth输出为yaml格式:
kubectl get secret basic-auth -o yaml
(3) 应用文件:kubectl apply -f ingress.yaml
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo
annotations: ## 添加annotations的信息
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth ## secret的名字
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - admin' ## 能通过认证的用户名
spec:
tls:
- hosts:
- www1.westos.org
secretName: tls-secret
rules:
- host: www1.westos.org
http:
paths:
- path: /
backend:
serviceName: myservice
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-demo1
spec:
rules:
- host: www2.westos.org
http:
paths:
- path: /
backend:
serviceName: nginx-svc
servicePort: 80
- 查看 ingress-demo的信息:
kubectl describe ingress ingress-demo
,添加认证生效
(4)测试:
在本机主机上www1.westos.org没有访问的权限
在浏览器页面访问:www1.westos.org,忽略风险提示后会弹出认证页面,输入正确的认证信息后可以正常的访问服务
更多推荐
所有评论(0)