ingress对外服务
目录
ingress概念
安装ingress
ingress-nginx暴露服务的方式
1. Deployment+LoadBalncer
2. DaemonSet+HostNetwork+nodeSelector
编辑
3.deployment+nodePort
编辑
ingress-nginx的deployment+nodePort+https部署
1.创建ssl的证书
2.ingress+nginx
ingress-nginx的权限控制
实验:ingress提示信息
实验:页面重定向
ingress-traefik插件
ingress-traefik部署
总结
ingress概念
service:在k8s集群当中相当于网关。用标签来匹配pod,还能通过endpoint更新pod的变化,也可以用四层代理实现负载均衡,service暴露的端口只能用于内网访问(局域网内)。
ingress:在k8s当中,它是一个独立的配置。ingress只能通过yaml文件配置。
它的作用是定义请求如何转发到service的规则。
ingress提供对外访问的流程:通过http或者https协议来暴露内部的service,它是给service提供外部的url、负载均衡、 SSL/TLS。它可以实现基于域名的反向代理。
ingress通过ingress-controller来实现上述的i功能。ingress-controller不是k8s自带的组件,这是一种插件的统称。
k8s维护的插件类型: 1. 谷歌云的GCE
2. ingress-nginx:最常用的模式
3. traefik:有可视化界面
ingress对外提供访问数据流向图
ingress对外提供访问的数据流向:ingress指定service的名称,把流量转发到指定的service,然后service再根据pod的标签来匹配pod把流量转发到pod。
安装ingress
三台主机都操作
先把ingree.contro-0.30.0.tar拖入到三台虚拟机中
tar -xf ingree.contro-0.30.0.tar.gz
docker load -i ingree.contro-0.30.0.tar
mkdir ingress
cd ingress/
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
ingress-nginx暴露服务的方式
1. Deployment+LoadBalncer
需要公有云提供负载均衡的ip地址(公网地址)
2. DaemonSet+HostNetwork+nodeSelector
在这个模式下ingress-controller会在每个节点都部署一个pod。ingress-controller直接使用每个节点的80和443端口,不需要做映射,可以直接实现流量的转发和访问。
hostwork就是宿主机之间和service做映射
数据流向图
如果是k8s pod部署的访问域名后面不加端口的,就是用的这个模式。它更适合于外网。
在master主机上部署
cd ingress/
vim mandatory.yaml
kubectl apply -f mandatory.yaml
kubectl get pod -o wide -n ingress-nginx
netstat -antp | grep nginx
注:8081端口是nginx-controller的默认配置端口,当ingress没有资源可以匹配时,会自动转发到这个端口。
vim ingress-nginx1.yaml
#创建pvc请求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
---
#创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22
ports:
- containerPort: 80
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: nfs-pvc
---
#创建service
apiVersion: v1
kind: Service
metadata:
name: nginx-daemon-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
#协议
port: 80
#service端口
targetPort: 80
#容器端口
selector:
app: nginx
---
#创建ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-daemon-ingress
spec:
rules:
- host: www.xy102.com
http:
paths:
- path: /
pathType: Prefix
#prefix:前缀匹配,可以匹配/、/test1、/test1/xy102
backend:
#匹配的svc的名称
service:
name: nginx-daemon-svc
port:
number: 80
#这里的80是service的cluserIP的端口
此时的状态:
然后做主机域名映射 vim /etc/hosts
然后到客户机 进入cd /opt/k8s/
此时再回到master主机上访问 curl www.xy102.com
如果要做nodeSelector选择标签
vim mandatory.yaml
kubectl label node node01 ingress-true 打标签
此时就只能匹配这个标签的node节点
3.deployment+nodePort
ingress根据副本数和调度在节点上部署多个pod,再根据nodeport在每个节点打开一个指定的端口 30000-32767。
nodeport就是nodeport和service做映射
数据流向图
如果是k8s pod部署的访问域名后面加端口号的,就是用的这个模式。它更适合于内网。
在master主机上部署
cd ingress/
vim mandatory.yaml
kubectl apply -f mandatory.yaml
下载nodeport的yaml文件:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
这个是service的nodeport
kubectl apply -f service-nodeport.yaml
kubectl apply -f mandatory.yaml 查看部署位置
vim ingress-nginx2.yaml
#创建pvc请求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
---
#创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22
ports:
- containerPort: 80
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: nfs-pvc
---
#创建service
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
#协议
port: 80
#service端口
targetPort: 80
#容器端口
selector:
app: nginx
---
#创建ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-deployment-ingress
spec:
rules:
- host: www.xy102.com
http:
paths:
- path: /
pathType: Prefix
#prefix:前缀匹配,可以匹配/、/test1、/test1/xy102
backend:
#匹配的svc的名称
service:
name: nginx-deployment-svc
port:
number: 80
#这里的80是service的cluserIP的端口
kubectl get svc -o wide -n ingress-nginx
然后访问域名和这个暴露nodeport的端口 www.xy102.com:31835
ingress-nginx的deployment+nodePort+https部署
1.创建ssl的证书
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=CHINA/O=NJ"
解释:
req:表示执行证书请求和生成相关文件
-x509:生成自签名的x.509证书
-sha256:表示sha256的散列算法
-nodes:表示生成的私钥不加密
-days 365:表示证书的有效期为365天
-newkey rsa:2048:表示使用RSA的密钥对,长度是2048个单位
-keyout:把私钥保存到tls.key文件
-out:把证书保存到tls.crt文件
-subj:添加证书的主题
执行命令:kubectl create secret tls tls-secret --key tls.key --cert tls.crt
2.ingress+nginx
vim ingress-https.yaml
#创建pvc请求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
---
#创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22
ports:
- containerPort: 80
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: nfs-pvc
---
#创建service
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
#协议
port: 80
#service端口
targetPort: 80
#容器端口
selector:
app: nginx
---
#创建ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-deployment-ingress
spec:
tls:
- hosts:
- www.xy102.com
secretName: tls-secret
#指定加密通信的域名,上下文要一致,指定secret加密的名称,获取私钥和证书。
rules:
- host: www.xy102.com
http:
paths:
- path: /
pathType: Prefix
#prefix:前缀匹配,可以匹配/、/test1、/test1/xy102
backend:
#匹配的svc的名称
service:
name: nginx-deployment-svc
port:
number: 80
#这里的80是service的cluserIP的端口
上面都一样,就是ingress不一样
如果上面只有执行过这个yaml文件不需要kubectl apply -f
kubectl get svc -n ingress-nginx
然后在虚拟机访问https://www.xy102.com:30222
在xshell里面访问https
curl -k
总结:为什么deployment必须要用nodeport?
因为deployment不能保证每个节点上只分配一个pod,如果是deployment+hostnetwork,pod会出现pending
ingress-nginx的权限控制
权限控制:当访问页面的时候,提醒用户要输入账号密码才可以访问页面。
实现这个实验的过程叫basicAuth
实验:ingress提示信息
cd /opt/ingress
yum -y install httpd
htpasswd -c auth gfw
kubectl create secret generic basic-auth --from-file=auth
vim ingress-nginx3.yaml
#创建pvc请求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
---
#创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-app
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.22
ports:
- containerPort: 80
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: nfs-pvc
---
#创建service
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
#协议
port: 80
#service端口
targetPort: 80
#容器端口
selector:
app: nginx
---
#创建ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-deployment-ingress
annotations:
#设置认证的类型:
nginx.ingress.kubernetes.io/auth-type: basic
#设置认证的secret的名称:
nginx.ingress.kubernetes.io/auth-secret: basic-auth
#设置认证窗口的提示信息:
nginx.ingress.kubernetes.io/auth-realm: 'hao hao xue xi'
spec:
tls:
- hosts:
- www.xy102.com
secretName: tls-secret
#指定加密通信的域名,上下文要一致,指定secret加密的名称,获取私钥和证书。
rules:
- host: www.xy102.com
http:
paths:
- path: /
pathType: Prefix
#prefix:前缀匹配,可以匹配/、/test1、/test1/xy102
backend:
#匹配的svc的名称
service:
name: nginx-deployment-svc
port:
number: 80
#这里的80是service的cluserIP的端口
kubectl get svc -n ingress-nginx 查看ingress对外开放的端口
然后回到浏览器访问https://www.xy102.com:30628
此时就会出现提示信息,然后你填上面设置的信息就可以了
实验:页面重定向
在上面的实验修改一下ingress即可
vim /etc/hosts 做域名映射把www.test1.com添加进去
此时访问https://www.xy102.com:30628就会跳转到https://www.test1.com:30628
ingress-traefik插件
它叫traefik ingress controller。它是专门为了部署k8s微服务开发的http反向代理和负载均衡工具。
它可以自动发现匹配的后端pod的变化,同时有可视化的页面。它能够自动感知变化,实现服务的自动发现。
traefik部署方式:
daemonset+hostnetwork 适用于大集群
deployment+nodeport 适用于内部访问,性能较低
面试题:
ingress-traefik和ingress-nginx之间的区别:
ingress-nginx使用nginx作为前端的负载均衡,它通过ingress-controller和k8s的api交互的方式来实现后端服务器的发现、pod ip地址的变化、动态实现nginx的配置修改。
ingress-traefik本身就能够和k8s的api交互,感知后端service以及pod的变化。traefik更简单,更方便。它本身是go语言写的,和k8s的兼容性更好,并发能力只有ingress-nginx的60%。
ingress-traefik部署
cd /opt/ingress/
mkdir traefik
cd traefik/
wget https://gitee.com/mirrors/traefik/raw/v1.7/examples/k8s/traefik-deployment.yaml
wget https://gitee.com/mirrors/traefik/raw/v1.7/examples/k8s/traefik-rbac.yaml
wget https://gitee.com/mirrors/traefik/raw/v1.7/examples/k8s/traefik-ds.yaml
wget https://gitee.com/mirrors/traefik/raw/v1.7/examples/k8s/ui.yaml
此时就会生成以下四个文件:
kubectl apply -f traefik-rbac.yaml
kubectl apply -f traefik-deployment.yaml
kubectl apply -f ui.yaml
cd /opt/ingress/
kubectl delete -f mandatory.yaml
cd -
vim nginx-traefik.yaml
#创建pvc请求
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-client-storageclass
resources:
requests:
storage: 2Gi
---
#创建pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-traefik
labels:
app: nginx1
spec:
replicas: 1
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
ports:
- containerPort: 80
volumeMounts:
- name: nfs-pvc
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: nfs-pvc
---
#创建service
apiVersion: v1
kind: Service
metadata:
name: nginx-traefik-svc
spec:
type: ClusterIP
ports:
- protocol: TCP
#协议
port: 80
#service端口
targetPort: 80
#容器端口
selector:
app: nginx1
---
#创建ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-traefik-ingress
annotations:
#设置认证的类型:
#nginx.ingress.kubernetes.io/auth-type: basic
#设置认证的secret的名称:
#nginx.ingress.kubernetes.io/auth-secret: basic-auth
#设置认证窗口的提示信息:
#nginx.ingress.kubernetes.io/auth-realm: 'hao hao xue xi'
#设定重定向流量的目标连接:
#nginx.ingress.kubernetes.io/rewrite-target: https://www.test1.com:30628
spec:
# tls:
# - hosts:
# - www.xy102.com
# secretName: tls-secret
#指定加密通信的域名,上下文要一致,指定secret加密的名称,获取私钥和证书。
rules:
- host: www.xy102.com
http:
paths:
- path: /
pathType: Prefix
#prefix:前缀匹配,可以匹配/、/test1、/test1/xy102
backend:
#匹配的svc的名称
service:
name: nginx-traefik-svc
port:
number: 80
#这里的80是service的cluserIP的端口
然后回到浏览器访问192.168.233.31:30437 就会进入traefik可视化界面
总结
ingress是对外提供访问,它可以支持http、https
访问流程:请求——ingress根据service的名称来匹配service——service把请求根据匹配的标签转发到pod
部署方式:deployment+nodeport、daemonset+hostnetwork
类型:ingress+nginx、ingress+traefik