K8s(7)——ingress服务
k8s 对外暴露服务(service)主要有两种方式:NodePort, LoadBalance, 此外externalIPs也可以使各类service对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外平台的支持;而ingress则只需要一个NodePort或者一个L
目录
什么是ingress
k8s 对外暴露服务(service)主要有两种方式:NodePort, LoadBalance, 此外externalIPs也可以使各类service对外提供服务,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外平台的支持;而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。
一种全局的、为了代理不同后端 Service 而设置的负载均衡服务,就是 Kubernetes 里的Ingress 服务。
实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环), 然后对外部提供服务。ingress包括:ingress controller和ingress resources
ingress controller:核心是一个deployment,实现方式有很多,比如nginx, Contour, Haproxy, trafik, Istio,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。
ingress resources:这个就是一个类型为Ingress的k8s api对象了,这部分则是面向开发人员。
简而言之:以前一个service一个虚拟ip,但是随着服务数量的增加,ip是不够用的,所以就产生了ingress服务,它可以代理不同后端 Service ,这样很多的service在一个ingress下,只需要一个ip即可。ingres在客户和服务之间增加一层,进而实现负载均衡服务。
ingress部署
官网:https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters
下载部署文件
[root@k8s2 ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.5.1/deploy/static/provider/baremetal/deploy.yaml
上传镜像到harbor
官网下载ingress-nginx部署所需资源清单deploy.yaml文件,修改对应镜像地址为本地harbor仓库
[root@k8s2 ingress]# vim deploy.yaml
image: ingress-nginx/controller:v1.5.1
image: ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343
应用该文件
[root@k8s2 ingress]# kubectl apply -f deploy.yaml
创建一个新的ns叫ingress-nginx
[root@k8s2 ingress]# kubectl -n ingress-nginx get pod
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-rppwr 0/1 Completed 0 55s
ingress-nginx-admission-patch-h9c4m 0/1 Completed 0 55s
ingress-nginx-controller-75754884bd-tgtj6 1/1 Running 0 55s
查看ingress-nginx的信息,可以看到产生了ingress-nginx-admission和ingress-nginx-controller
[root@k8s2 ingress]# kubectl -n ingress-nginx get svc
可通过ip+端口访问到,不过加端口麻烦,后续需要优化。
修改 ingress-nginx-controller这个服务的类型为LoadBalancer
[root@k8s2 ingress]# kubectl -n ingress-nginx edit svc ingress-nginx-controller
service/ingress-nginx-controller edited
[root@k8s2 ingress]# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.101.34.244 192.168.56.100 80:55872/TCP,443:37550/TCP 5m17s
ingress-nginx-controller-admission ClusterIP 10.102.223.239 <none> 443/TCP 5m16s
通过一个ingress控制多个service
创建两个svc,如下
[root@k8s2 ingress]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d3h
my-myapp ClusterIP 10.111.217.123 <none> 80/TCP 19m
my-nginx ClusterIP 10.111.116.141 <none> 80/TCP 3h26m
创建ingres路由规则,基于域名转发
[root@k8s2 ingress]# vim ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
ingressClassName: nginx #一定指定这个
rules:
- host: nginx.westos.org #当访问这个域名时,转发到my-nginx这个service上
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-nginx
port:
number: 80
- host: myapp.westos.org #当访问这个域名时,转发到my-myapp这个service上
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-myapp
port:
number: 80
[root@k8s2 ingress]# kubectl apply -f ingress.yaml
注意:ingress规则必须和上面创建的两个svc处于同一个namespace
访问不同域名,可定向到不同service上,如下
测试主机添加解析,ingress-nginx-controller的外部ip是192.168.56.100
[root@k8s1 ~]# vim /etc/hosts
192.168.56.100 nginx.westos.org myapp.westos.org
在集群外部访问成功
[root@k8s1 ~]# curl nginx.westos.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s1 ~]# curl myapp.westos.org
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
所以整体下来,客户通过不同域名访问ingress,根据标签对应服务再到pod,一个ingress的ip。
tls加密
使用一个自签名的证书,当然如果有在一些正规机构购买的 CA 证书是最好的,这样任何人访问你的服务的时候都是受浏览器信任的证书。
创建证书和密钥
[root@k8s2 ingress]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
[root@k8s2 ingress]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
查看
[root@k8s2 ingress]# kubectl get secrets
NAME TYPE DATA AGE
default-token-4d7s7 kubernetes.io/service-account-token 3 3d19h
tls-secret kubernetes.io/tls 2 11s
编辑ingress文件
[root@k8s2 ingress]# vim ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
tls:
- hosts:
- nginx.westos.org
- myapp.westos.org
secretName: tls-secret #使用secret中的tls-secret进行安全访问
ingressClassName: nginx
rules:
- host: nginx.westos.org
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-nginx
port:
number: 80
- host: myapp.westos.org
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-myapp
port:
number: 80
创建ingress
[root@k8s2 ingress]# kubectl apply -f ingress.yaml
访问80端口会自动重定向到443,myapp.westos.org被重定向为https://myapp.westos.org
[root@k8s1 harbor]# curl -I myapp.westos.org
HTTP/1.1 308 Permanent Redirect
Date: Fri, 13 Jan 2023 01:25:09 GMT
Content-Type: text/html
Content-Length: 164
Connection: keep-alive
Location: https://myapp.westos.org
测试:加入-k参数,成功访问,myapp.westos.org被重定向为https://myapp.westos.org
用户认证
创建认证用户和密钥,导入到k8s中的secret
[root@k8s2 ingress]# htpasswd -c auth wxh
New password:
Re-type new password:
Adding password for user wxh
查看用户和密钥
[root@k8s2 ingress]# cat auth
wxh:$apr1$pvsCrz1O$wd/itH7cjOkl3xGuZm.RG0
导入到k8s中的secret
[root@k8s2 ingress]# kubectl create secret generic basic-auth --from-file=auth
修改 ingress.yaml文件
[root@k8s2 ingress]# vim ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth #添加认证模块
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - wxh'
spec:
tls:
- hosts:
- nginx.westos.org
- myapp.westos.org
secretName: tls-secret
ingressClassName: nginx
rules:
- host: nginx.westos.org
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-nginx
port:
number: 80
- host: myapp.westos.org
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-myapp
port:
number: 80
创建ingress,添加认证。查看详细信息,认证模块已添加
[root@k8s2 ingress]# kubectl apply -f ingress.yaml
访问需输入用户信息,成功访问
[root@k8s1 harbor]# curl -k https://myapp.westos.org -u wxh:westos
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
重定向
当网站的资源路径发生变化时,尽量希望url不变,尤其大型项目里,涉及很多地址,修改麻烦,所以在路径变化不大的情况下,重定向起到一定作用。默认的发布页地址重写为一个特定的网页,如何实现呢?
[root@k8s2 ingress]# vim ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - wxh'
nginx.ingress.kubernetes.io/app-root: /hostname.html #根目录重新定向到hostname.html
spec:
tls:
- hosts:
- nginx.westos.org
- myapp.westos.org
secretName: tls-secret
ingressClassName: nginx
rules:
- host: nginx.westos.org
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-nginx
port:
number: 80
- host: myapp.westos.org
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: my-myapp
port:
number: 80
运行
[root@k8s2 ingress]# kubectl apply -f ingress.yaml
测试,访问myapp.westos.org自动地址重写为https://myapp.westos.org/hostname.html,改变了默认发布目录
[root@k8s1 harbor]# curl -k -I https://myapp.westos.org -u wxh:westos
HTTP/1.1 302 Moved Temporarily
Date: Fri, 13 Jan 2023 01:41:27 GMT
Content-Type: text/html
Content-Length: 138
Connection: keep-alive
Location: https://myapp.westos.org/hostname.html
更多推荐
所有评论(0)