袁党生博客

  • 主页
  • linux基础
  • SHELL
  • WEB
  • 负载
  • 企业级应用
  • 数据库
  • KVM
  • Docker
  • K8S
  • 监控
  • 存储
  • 博客搭建问题
  1. 首页
  2. K8S
  3. 正文

十七、kubernetes Ingress控制器

2023年8月30日 2257点热度 0人点赞 0条评论


本章概述

  • service回顾
  • ingress介绍和部署
  • 实现单host及多host的ingress
  • 实现基于URL的ingress
  • ingress实现单域名及多域名https
  • ingress证书更新

前言
由于ingress会用到service,这里对service进行回顾

17.1 service回顾

  service类型包括四种: NodePort、clusterIP、loadBalancer、ExternalName。
  其中NodePort和clusterIP在第七章节资源对象service中已经讲过,这里不再详细说明,这里只对loadBalancer、ExternalName这两种service类型进行举例说明。
1、ClusterIP:
  kubectl explain service.spec.type
  ClusterIP:默认的类型,用于 k8s 内部之间的服务访问,即通过内部的 service ip 实现服务间的访问,service IP 仅可以在内部访问,不能从外部访问。
2、NodePort:
  NodePort:在 cluster IP 的基础之上,通过在每个 node 节点监听一个可以指定宿主机端口(nodePort)来暴露服务,从而允许外部 client 访问 k8s 集群中的服务,nodePort 把外部 client的请求转发至 service 进行处理。
3、LoadBalancer:
  LoadBalancer:主要在公有云如阿里云、AWS 上使用,LoadBalancer 构建在 nodePort 基础之上,通过公有云服务商提供的负载均衡器将 k8s 集群中的服务暴露给集群外部的 client访问。
以下为yaml文件示例:(这种类型的service主要用在公有云环境,这里只列出yaml文件,不再进行创建)
vim 0.1.loadbalancer-dashboard.yaml

kind: Service
apiVersion: v1
metadata:
  namespace: kubernetes-dashboard
  name: dashboard-lb
  labels:
    k8s-app: kubernetes-dashboard
spec:
  ports:
    - protocol: TCP
      port: 8443
      targetPort: 8443
      nodePort: 30063
  type: LoadBalancer
  selector:
     k8s-app: kubernetes-dashboard

4、ExternalName:
  ExternalName:用于将 k8s 集群外部的服务映射至 k8s 集群内部访问,从而让集群内部的pod 能够通过固定的 service name 访问集群外部的服务,有时候也用于将不同 namespace之间的 pod 通过 ExternalName 进行访问。这种使用方式不常用。
  常用的方式是将k8s内部service指向k8s集群外部某服务的域名,通过固定的servicename访问外部服务,这样的好处是:一旦外部服务ip地址发生变化,只需更改域名对应的ip地址即可,只要域名不变,就不影响k8s集群对外部服务的访问,k8s集群内部配置代码也不需要变动,降低风险。
示例:
vim 0.2.externalName.yaml

apiVersion: v1
kind: Service
metadata:
  name: my-external-test-name    #指定service name
  namespace: default
spec:
  type: ExternalName  #service类型
  externalName: www.magedu.com   #外部域名

创建并查看service
kubectl apply -f 0.2.externalName.yaml
kubectl get svc -n default

验证:
在一个容器内对新建的ExternalName类型的service name进行ping测试,查看返回地址,是否为k8s集群外部域名的ip地址
查看k8s集群外部域名www.magedu.com的公网地址:

进入测试容器对servicename进行解析,返回地址正是www.magedu.com的公网域名解析地址

5、Endpoints:
  指定service后端的pod。一般情况下,service后端的endpoint是通过pod的label标签匹配的,而endpoints则可以手动指定service后端的pod。这种使用方式不常用。
注意:yaml文件中service名称和endpoints的名称必须一致,service会将同一个namespace下同名的endpoints关联起来
  使用场景:在k8s集群内需要访问k8s集群外部的某些服务的地址(如kafka,elasticsearch等),此时可以在k8s集群内部创建一个service,将需要访问的k8s集群外部服务地址直接指向k8s集群内的service,这样就使用到了endpoints类型的资源对象。(备注:该场景下另一种方法是:将k8s集群内部service域名解析为集群外部服务地址,这种方式也可以满足,如果是用这种方式,由于要访问的服务地址不在k8s集群内,因此要在k8s集群外部的dns上配置域名解析才可以)

示例:以访问k8s集群外部的mysql为例
1、在集群外部一台机器上安装mysql(这里以mariadb为例)
注意:机器地址为:172.31.7.151
yum -y install mariadb-server mariadb mariadb-devel
启动服务
systemctl start mariadb
进入mysql进行授权(由于要访问mysql的容器在172.31.7.112上,因此要授权该节点访问mysql数据库的权限)

#mysql
#MariaDB [(none)]> grant all on *.* to root@'172.31.7.112';

2、在k8s集群内创建service和endpoints
(1)编写yaml文件
vim 0.3.Endpoints.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql-production-server-name    #servicename和endpoints name要保持一致
  namespace: default
spec:
  ports:
    - port: 3306
---
kind: Endpoints
apiVersion: v1
metadata:
  name: mysql-production-server-name   #servicename和endpoints name要保持一致
  namespace: default
subsets:    #指定后端pod地址和端口
  - addresses:
      - ip: 172.31.7.151
    ports:
      - port: 3306

(2)创建并查看service以及service后端endpoints地址
kubectl apply -f 0.3.Endpoints.yaml
kubectl get svc -n default

kubectl get ep -n default

(3)通过service name访问集群外部的mysql
进入集群内测试容器,通过telnet servicename的3306端口来进行测试,如果telnet能通,说明可以访问集群外部的mysql
进入测试容器(该容器在172.31.7.112上),执行telnet ,可以正常telnet通
kubectl exec -it net-test-centos-pod1 bash -n default
yum -y install mariadb-server mariadb mariadb-devel #如果容器内没有mysql客户端,需要安装mysql
连接数据库,可以正常连接集群外部的mysql数据库

17.2 Ingress介绍和部署

17.2.1 ingress及ingress controller介绍

1、ingress介绍
  ingress官网链接:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
  Ingress 是 kubernetes API 中的标准资源类型之一,ingress 实现的功能是在应用层对客户端请求的host 名称或请求的 URL 路径把请求转发到指定的 service 资源的规则,即用于将 kubernetes 集群外部的请求资源转发之集群内部的 service,再被 service 转发至pod处理客户端的请求。
注意:ingress是属于七层的,可以转发七层的请求,而service只能转发四层请求

请求流程:(这里使用deployment方式部署ingress controller)

ingress访问链路:负载均衡-->nodeport-->ingress-serve-->ingress-->service-->后端pod
(1)为了能够接收k8s集群外部的请求,会为ingress创建一个service,通过service对外暴露一个nodeport端口,用来接收集群外部的请求
(2)外部请求到达pod后,nodeport接收请求,然后转发给ingress前端的service
(3)service将请求转发给ingress
(4)ingress经过匹配将请求转发给后端的service
(5)service将请求转发给对应的pod

2、ingress controller介绍
  ingress controller官网链接:https://kubernetes.io/zh/docs/concepts/services-networking/ingress-controllers/
  Ingress 资源需要指定监听地址、请求的 host 和 URL 等配置,然后根据这些规则的匹配机制将客户端的请求进行转发,这种能够为 ingress 配置资源监听并转发流量的组件称为ingress 控制器(ingress controller),ingress controller 是 kubernetes 的一个附件,类似于dashboard 或者 flannel 一样,需要单独部署。ingress controller本身是一个资源对象组件,它会拉起一个pod,外部的请求的处理由pod完成。
  ingress controller目前支持和维护 AWS、 GCE 和 Nginx Ingress 控制器。除了这些控制器以外,还有其他很多第三方的控制器,这里对Nginx Ingress进行讲解。

17.2.2 部署nginx ingress controller

nginx ingress官网安装指南:https://kubernetes.github.io/ingress-nginx/deploy/
github安装指南:https://github.com/kubernetes/ingress-nginx/blob/main/docs/deploy/index.md
这里我们以github官网提供的安装方式进行部署
与k8s版本兼容性:部署时要注意支持的k8s版本

  github官网提供了部署需要的yaml文件,可以直接使用,但是由于yaml文件中的镜像指向谷歌官方镜像仓库,在国内无法下载,需要想办法获取这些镜像。
  访问以下链接可以获取部署ingress-nginx controller的 yaml文件:https://github.com/kubernetes/ingress-nginx/blob/main/deploy/static/provider/baremetal/1.23/deploy.yaml

部署方式:
  ingress-nginx controller部署可以通过两种方式进行部署:deployment方式部署和daemonset方式部署。
  这两者的区别在于:通过deployment方式部署时,默认只拉起一个ingress pod,ingress到后端service转发时,如果ingress和service不在同一个node,存在跨主机访问的情况,存在网络消耗;而通过daemonset方式部署时,ingress到后端service转发时,由于k8s集群每个主机都会部署一个ingress,ingress会将请求直接转发给本机的service,这样就降低了网络消耗,效率更高。
daemonset类型ingress架构图:

  另外, ingress service暴露的nodeport到ingress service到ingress再到后端service仍然会进行node到service再到ingress的网络转发,如果想进一步提升访问效率,ingress service可以使用hostIP模式,即ingress service使用宿主机网络,这样外部请求到达node后,直接将请求直接转发给ingress,中间不再经过ingress service转发,效率会更高,但是需要注意,由于使用宿主机网络,要防止端口冲突问题
hostNetwork类型ingress架构图:

  需要注意的是,通过daemonset方式和hostNetwork网络模式部署ingress-nginx controller降低了node到ingress之间的网络开销,但ingress后端的service到pod之间还会存在跨主机访问情况。

以下yaml文件是改好的(镜像仓库是阿里云镜像仓库),可以直接使用
1、使用deployment方式部署ingress-nginx controller:

使用以下文件进行部署:(yaml文件在以下百度网盘链接中下载)

链接:https://pan.baidu.com/s/1mY7Bmh65xAlOx8cWzyefuQ 
提取码:oewj

(1)创建ingress并查看ingress pod
kubectl apply -f 1.ingress-nginx-controller-v1.2.0_deployment.yaml

(2)查看ingress service,通过nodeport将宿主机随机端口转发至pod的80端口,将33609转发至pod的443端口(yaml文件中没有指定宿主机端口,由随机端口进行转发)

2、使用daemonset方式部署ingress-nginx controller,为了提高性能,ingress 使用hostIP类型

使用以下文件进行部署:(yaml文件在以下百度网盘链接中下载)

链接:https://pan.baidu.com/s/1LVEKsm9qQrHpac1ocRmFPw 
提取码:vh5t

创建并查看ingress
由于是daemonset容器,每个主机都会创建一个ingress(yaml文件配置了容忍,master节点也会创建ingress)
kubectl apply -f 2.ingress-nginx-controller-v1.2.0_daemonset.yaml

查看ingress service

进入ingress-nginx容器,可以看到ingress其实就是一个nginx,他的配置都是动态生成的

需要注意的是,这里的配置不能随意改动,否则就会影响访问

17.3 实现单host及多host的ingress

实现基于客户端请求的host域名进行转发
架构图:

环境准备:
创建两个tomcat模拟业务,通过ingress控制实现转发效果
注意:在进行以下演示时,ingress-nginx controller使用daemonset部署并且使用hostNetwork网络模式共享宿主机网络
1、创建tomcat1:
(1)编写yaml文件
vim tomcat-app1.yaml

kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app1-deployment-label
  name: magedu-tomcat-app1-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app1-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app1-selector
    spec:
      containers:
      - name: magedu-tomcat-app1-container
        image: tomcat:7.0.94-alpine
        #command: ["/apps/tomcat/bin/run_tomcat.sh"]
        #imagePullPolicy: IfNotPresent
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 1
            memory: "512Mi"
          requests:
            cpu: 500m
            memory: "512Mi"
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: magedu-tomcat-app1-service-label
  name: magedu-tomcat-app1-service
  namespace: magedu
spec:
  type: NodePort   #临时开启,以验证tomcat服务是否可以正常访问,验证完成后关闭即可
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    nodePort: 40003        #临时开启,以验证tomcat服务是否可以正常访问,验证完成后关闭即可
  selector:
app: magedu-tomcat-app1-selector

(2)创建tomcat容器
kubectl apply -f tomcat-app1.yaml
(3)准备web页面
进入容器

kubectl exec -it magedu-tomcat-app1-deployment-96f994cf7-v8mlk bash -n magedu
bash-4.4# pwd
/usr/local/tomcat
bash-4.4# cd webapps/
bash-4.4#
bash-4.4# mkdir app1
bash-4.4# echo "app1 web" > app1/index.jsp

(4)验证:
浏览器访问172.31.7.111:40003/app1,可以正常访问

  由于要通过ingress从外部访问集群内部服务,为了避免nodeport配置影响ingress访问验证,验证完成后关闭tomcat yaml文件中配置的nodeport。关闭nodeport配置后tomcat容器默认为clusterIP类型,无法通过外部访问,这样就可以通过ingress来访问集群内部服务
vim tomcat-app1.yaml 这里只贴出修改部分内容

spec:
  #type: NodePort   #临时开启,以验证tomcat服务是否可以正常访问,验证完成后关闭即可
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    #nodePort: 40003        #临时开启,以验证tomcat服务是否可以正常访问,验证完成后关闭即可
  selector:
app: magedu-tomcat-app1-selector

重新加载yaml文件
kubectl apply -f tomcat-app1.yaml

2、创建tomcat2容器:
(1)编写yaml文件
vim tomcat-app2.yaml

kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
  labels:
    app: magedu-tomcat-app2-deployment-label
  name: magedu-tomcat-app2-deployment
  namespace: magedu
spec:
  replicas: 1
  selector:
    matchLabels:
      app: magedu-tomcat-app2-selector
  template:
    metadata:
      labels:
        app: magedu-tomcat-app2-selector
    spec:
      containers:
      - name: magedu-tomcat-app2-container
        image: tomcat:7.0.94-alpine
        #command: ["/apps/tomcat/bin/run_tomcat.sh"]
        #imagePullPolicy: IfNotPresent
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
          protocol: TCP
          name: http
        env:
        - name: "password"
          value: "123456"
        - name: "age"
          value: "18"
        resources:
          limits:
            cpu: 1
            memory: "512Mi"
          requests:
            cpu: 500m
            memory: "512Mi"
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: magedu-tomcat-app2-service-label
  name: magedu-tomcat-app2-service
  namespace: magedu
spec:
  #type: NodePort
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    #nodePort: 40004        #临时开启,以验证tomcat服务是否可以正常访问,验证完成后关闭即可
  selector:
app: magedu-tomcat-app2-selector

(2)创建tomcat容器
kubectl apply -f tomcat-app1.yaml
(3)准备web页面
进入tomcat-app2容器

kubectl exec -it magedu-tomcat-app2-deployment-5f8c855b9f-pqnp8 bash -n magedu
bash-4.4# cd webapps/
bash-4.4# mkdir app2
bash-4.4# echo "app2 web" > app2/index.jsp

(4)验证:
浏览器访问:172.31.7.112:40004/app2,可以正常访问

  由于要通过ingress从外部访问集群内部服务,为了避免nodeport配置影响ingress访问验证,验证完成后关闭tomcat yaml文件中配置的nodeport。关闭nodeport配置后tomcat容器默认为clusterIP类型,无法通过外部访问,这样就可以通过ingress来访问集群内部服务
vim tomcat-app1.yaml 这里只贴出修改部分内容

spec:
  #type: NodePort   #临时开启,以验证tomcat服务是否可以正常访问,验证完成后关闭即可
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
    #nodePort: 40003        #临时开启,以验证tomcat服务是否可以正常访问,验证完成后关闭即可
  selector:
app: magedu-tomcat-app1-selector

重新加载yaml文件
kubectl apply -f tomcat-app1.yaml

17.3.1 实现单个虚拟主机(即单域名)

  ingress yaml文件中rules配置可参考官方文档:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/
示例:
1、编写yaml文件
vim 2.1.ingress_single-host.yaml

#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-web
  namespace: magedu    #指定namespace,要和pod以及service在同一个namespace
  annotations:
    kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
    nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-body-size: "50m" ##客户端上传文件,最大大小,默认为20m
    #nginx.ingress.kubernetes.io/rewrite-target: / ##URL重写
    nginx.ingress.kubernetes.io/app-root: /index.html    ##如果访问其他页面,会跳转到主页面

spec:
  rules:        ##配置规则
  - host: www.jiege.com    ##配置host域名
    http:         ##http配置
      paths:
      - pathType: Prefix      ##前缀匹配,
        path: "/"        ##即从”/”后进行匹配,只要是请求host域名中的任何一个url路径,都往后端转发
        backend:       ##指定后端服务器,类似nginx中的upstream
          service:      ##指定后端服务器类型为service
            name: magedu-tomcat-app1-service      ##指定servicename,该名称即tomcat-app1的service名称,匹配成功后,ingress会将请求转发给该service
            port:          ##指定service端口为80
              number: 80

2、创建并查看ingress
kubectl apply -f 2.1.ingress_single-host.yaml
kubectl get ingress -n magedu

注意:此时可以通过访问域名来访问tomcat服务,但是域名需要和ip地址进行绑定

有两种方式:
  (1)把域名和node ip进行绑定,访问域名直接转发给node,node上的ingress进行转发,但是如果node较多,需要多个配置,比较麻烦
  (2)把域名和VIP地址绑定,在负载均衡haproxy上监听VIP的请求,然后将请求转发给node ,node上的ingress进行转发。

3、推荐使用第2种方式,配置如下:
在要访问www.jiege.com域名的主机hosts文件中对域名www.jiege.com进行地址绑定
(1)修改hosts
vim /etc/hosts

172.31.7.189   www.jiege.com
注意172.31.7.189为VIP地址,通过keepalived配置的
我们还要修改haproxy的配置,把负载均衡的后端地址修改为node地址
注意:由于使用的hostNetwork网络模式,因此需要监听宿主机的80端口和443端口,而不是其他nodeport类型的端口

(2)修改haparoxy配置
vim /etc/haproxy/haproxy.cfg

listen magedu-linux66-nginx-80
    bind 172.31.7.189:80
    mode tcp
    server node1 172.31.7.111:80 check inter 3s fall 3 rise 1
    server node2 172.31.7.112:80 check inter 3s fall 3 rise 1
    server node3 172.31.7.113:80 check inter 3s fall 3 rise 1

listen magedu-linux66-nginx-443
    bind 172.31.7.189:443
    mode tcp
    server node1 172.31.7.111:443 check inter 3s fall 3 rise 1
    server node2 172.31.7.112:443 check inter 3s fall 3 rise 1
    server node3 172.31.7.113:443 check inter 3s fall 3 rise 1

(3)重启haproxy服务
systemctl restart haproxy
这样一旦访问www.jiege.com域名,就会将请求转发给node,node上的ingress收到请求根据规则进行转发
(4)验证:
浏览器访问:www.jiege.com/app1/index.jsp

访问链路:
客户端访问域名(www.jiege.com/app1/index.jsp)-->负载均衡(将请求转发给后端node)-->node(ingress使用hostNetwork,共享宿主机网络,接收请求)-->ingress(根据规则匹配域名和访问的路径,转发给对应的service)-->service(将请求转发给tomcat)-->tomcat(tomcat接收请求并响应)

17.3.2 实现多个虚拟机(即多域名)

通过不同的域名转发到不同的后端服务上
示例:配置两个域名,模拟一个转发移动端请求,一个转发pc端请求
1、编写yaml文件
vim 2.2.ingress_multi-host.yaml

#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-web
  namespace: magedu
  annotations:
    kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
    nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-body-size: "10m" ##客户端上传文件,最大大小,默认为20m
    #nginx.ingress.kubernetes.io/rewrite-target: / ##URL重写
    nginx.ingress.kubernetes.io/app-root: /index.html

spec:
  rules:
  - host: www.jiege.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app1-service
            port:
              number: 80
  - host: mobile.jiege.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app2-service
            port:
              number: 80

2、创建ingress并查看
kubectl apply -f 2.2.ingress_multi-host.yaml

3、验证:
访问http://www.jiege.com/app1/index.jsp

访问mobile.jiege.com/app2/index.jsp

17.4 实现基于 URL 的 ingress

基于客户端请求的同一个 host 不同的 URL 进行转发

示例:通过访问同一个域名的不同url实现访问不同的服务
1、编写yaml文件
vim 3.1.ingress-url.yaml

#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-web
  namespace: magedu
  annotations:
    kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
    nginx.ingress.kubernetes.io/use-regex: "true" ##指定后面rules定义的path可以使用正则表达式
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" ##连接超时时间,默认为5s
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600" ##后端服务器回转数据超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600" ##后端服务器响应超时时间,默认为60s
    nginx.ingress.kubernetes.io/proxy-body-size: "10m" ##客户端上传文件,最大大小,默认为20m
    #nginx.ingress.kubernetes.io/rewrite-target: / ##URL重写
    nginx.ingress.kubernetes.io/app-root: /index.html
spec:
  rules:
  - host: www.jiege.com
    http:
      paths:
      - pathType: Prefix
        path: "/app1"       ##指定url路径
        backend:
          service:
            name: magedu-tomcat-app1-service
            port:
              number: 80
      - pathType: Prefix
        path: "/app2"      ##指定url路径
        backend:
          service:
            name: magedu-tomcat-app2-service
            port:
              number: 80

2、创建并查看ingress
kubectl apply -f 3.1.ingress-url.yaml
kubectl get ingress -n magedu

3、验证:
浏览器访问www.jiege.com/app1

浏览器访问www.jiege.com/app2

17.5 ingress 实现单域名及多域名 https

17.5.1 实现基于htpps协议的单域名访问

1、首先要配置证书,这里我们使用自签名证书

#创建存放证书的目录
mkdir certs  && cd certs
#创建ca证书
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3560 -nodes -subj '/CN=www.jiegeca.com'
#生成csr文件,注意域名要和访问的域名对应上
openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=www.jiege.com'
#创建自签名证书
openssl x509 -req -sha256 -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
证书上传至k8s(创建k8s证书)
创建pc端证书,在当前目录创建,否则证书需要写上绝对路径
kubectl create secret tls  tls-secret-www  --cert=server.crt --key=server.key  -n magedu

查看证书

2、创建ingress
(1)编写yaml文件
vim 4.1.ingress-https-magedu_single-host.yaml

#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-web
  namespace: magedu
  annotations:
    kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
    nginx.ingress.kubernetes.io/ssl-redirect: 'true' #SSL重定向,即将http请求强制重定向至https,等于nginx中的全站https
spec:
  tls:
  - hosts:
    - www.jiege.com
    secretName: tls-secret-www    #指定证书名称
  rules:
  - host: www.jiege.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app1-service
            port:
              number: 80

(2)创建ingress
kubectl apply -f 4.1.ingress-https-magedu_single-host.yaml
(3)访问验证:
浏览器访问http://www.jiege.com/app1,内容可以正常显示
由于做了ssl重定向,即使访问http,也会被重定向到https,

查看证书:

17.5.2 实现基于htpps协议的多域名访问

模拟移动端和pc端的访问,需要再次签发一个证书
1、首先要配置证书,这里我们使用自签名证书

创建存放证书的目录
cd certs
#生成csr文件,注意域名要和访问的域名对应上
openssl req -new -newkey rsa:4096 -keyout mobile.key -out mobile.csr -nodes -subj '/CN=mobile.jiege.com'
#创建自签名证书
openssl x509 -req -sha256 -days 3650 -in mobile.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out mobile.crt
证书上传至k8s(创建k8s证书)
创建pc端证书,在当前目录创建,否则证书需要写上绝对路径
kubectl create secret tls  tls-secret-mobile  --cert=mobile.crt --key=mobile.key  -n magedu

查看证书

2、创建ingress
(1)编写yaml文件
vim 4.2.ingress-https-magedu_multi-host.yaml

#apiVersion: networking.k8s.io/v1beta1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-web-mobile
  namespace: magedu
  annotations:
    kubernetes.io/ingress.class: "nginx" ##指定Ingress Controller的类型
    nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
  tls:
  - hosts:
    - mobile.jiege.com
secretName: tls-secret-mobile    #指定mobile证书名称
  - hosts:
    - www.jiege.com
    secretName: tls-secret-www      #指定pc端证书名称
  rules:
  - host: www.jiege.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app1-service
            port:
              number: 80

  - host: mobile.jiege.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: magedu-tomcat-app2-service
            port:
              number: 80

注意:建议一个域名使用一个单独的yaml文件,这样容易区分。域名配置写在同一个yaml文件中修改时容易改错,存在风险
(2)创建ingress
kubectl apply -f 4.2.ingress-https-magedu_multi-host.yaml
(3)验证:
浏览器访问http://www.jiege.com/app1,内容可以正常显示
由于做了ssl重定向,即使访问http,也会被重定向到https

浏览器访问http://mobile.jiege.com/app1,内容可以正常显示
由于做了ssl重定向,即使访问http,也会被重定向到https

查看mobile端的ssl证书

使用命令访问域名,通过查看域名返回结果来排查域名配置是否正确
curl -lvk https://www.jiege.com/app1/index.jsp

17.6 ingress证书更新

购买的商业证书,一般情况下有效期是一年,当ingress证书到期后需要更新证书
更新方式有两种:
(1)生成新的证书,证书使用新的名称,然后修改ingress yaml文件指定的证书名称。但是如果项目较多,需要更改的yaml文件就比较多,需要改多个yaml。
(2)保留证书名称,修改证书内容,直接将生成的新证书中公钥和私钥替换到旧的证书中
以pc端证书tls-secret-www证书更新为例
为了区分新旧证书,查看当前证书的生成时间

1、备份证书
获取证书内容,将证书复制出来并保存
kubectl get secret -n magedu

kubectl get secrets tls-secret-www -n magedu -o yaml

2、生成新证书(新证书需要进行购买,这里为了演示,手动生成新的证书)

创建存放证书的目录
mkdir new-certs && cd new-certs
#创建ca证书
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3560 -nodes -subj '/CN=www.jiegeca.com'
#生成csr文件,注意域名要和访问的域名对应上
openssl req -new -newkey rsa:4096 -keyout new2022.key -out new2022.csr -nodes -subj '/CN=www.jiege.com'
#创建自签名证书
openssl x509 -req -sha256 -days 3650 -in new2022.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out new2022.crt

3、将私钥new2022.key和公钥new2022.crt内容进行base64加密
(1)对私钥进行base64加密
复制私钥内容
cat new2022.crt

将证书内容(红框内所有内容)复制出来,在互联网找到base64在线加密工具进行base64加密

将加密后内容复制到文本保存
(2)对私钥使用同样的方式进行base64加密

将加密后的私钥保存到文本中
4、动态编辑secret证书,将base64加密后的新的公钥和私钥替换原证书中的公钥和私钥
kubectl edit secrets tls-secret-www -n magedu

编辑完成后保存并退出
通过浏览器访问进行验证,查看证书的时间,已经更新为最新的证书

标签: ingress控制器 k8s
最后更新:2023年9月1日

袁党生

这个人很懒,什么都没留下

点赞
< 上一篇

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2023 linux学习. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

豫ICP备18039507号-1