51、K8S-流量调度-Ingress、Ingress-nginx、Dashboard

Kubernetes学习目录

1、Ingress基础

1.1、简介

在实际的应用中,kubenetes接受的不仅仅有内部的流量,还有外部流量,我们可以通过两种方式实现将集群外部的流量引入到集群的内部中来,从而实现外部客户的正常访问。
service方式:
   nodePort、externalIP 等service对象方式,借助于 namespace、iptables、ipvs 等代理模式实现流量的转发。
Host方式:
   通过node节点的 hostNetwork 与 hostPort 及配套的port映射,以间接的方式实现service的效果

1.2、k8s网络流程图

 

1.3、关于网络流向的问题

1、在实际的应用中,虽然我们可以基于service或host等多种方式实现集群内外的网络通信,但是这些
内容都是基于四层协议来进行调度的,而且服务级别的健康检查功能很难实现。

2、而对于外部流量的接入,一般都是http(s)协议的数据,四层协议是无法实现的。尤其是涉及到各种 ssl会话的管理,由于其位于osi七层模型的会话层,要高于传输层的四层,service和host是无法正常实现的。
3、虽然service能够实现将外部流量引入到集群内部,但是其本质上,是通过网络规则方式来进行转发 的,形象的说法就是在墙上打洞,将集群内部的服务暴露到外部。甚至这些洞和洞之间根本没有关联关系。

1.4、解决方案

 为了解决上述的问题,就引入了一种新的解决方法ingress,简单来说,它可以解决上面提出的三个问题:
 1、可以基于https的方式,将集群外部的流量统一的引入到集群内部
 2、通过一个统一的流量入口,避免将集群内部大量的""暴露给外部。
 Ingress这种利用应用层协议来进行流量的负载均衡效果,它可以实现让用户通过域名来访问相应的service就可以了,无需关心Node IP及Port是什么,避免了信息的泄露。

 

1.5、什么是Ingress

Ingress 是k8s上的一种标准化资源格式,它为了剥离与特定负载均衡功能实现软件的相关性,而抽象
出来的一种公共的统一的声明式配置格式。然后借助于特定的ingress controller功能负责将其加载并转换成k8s集群内部的配置信息。
Ingress的特点符合我们之前对于CRD的学习
- ingress + controller,所以,其具备了动态更新 并加载新配置的特性。而且ingress本身是不具备实现集群内外流量通信的功能的,这个功能是通过controller来实现的。

1.6、为什么需要Ingress

Service是基于四层TCP和UDP协议转发的,而Ingress可以基于七层的HTTP和HTTPS协议转发,可以通过域名和路径做到更细粒度的划分

1.7、ingress框架图

2、Ingress原理解析

2.1、Ingress组成

Ingress由任何具有反向代理功能的程序实现,如Nginx、Traefik、Envoy、HAProxy、Vulcand等,Ingress本身是运行于集群中的Pod资源对象。
ingress 主要包含两个组件Ingress Controller和Ingress。

2.2、Ingress组件

2.2.1、Ingress

将Nginx的配置抽象成一个Ingress对象,每个服务对应一个ingress的yaml配置文件

2.2.2、Ingress Controller

将新加入的Ingress转化成Nginx的配置文件并使之生效

2.3、问题梳理

如果我们将ingress以pod的方式部署到k8s集群内部,那么就会遇到多个问题:
 1、ingress的pod如何引入外部流量
   - 通过一个专用的service就可以实现了
2、ingress的pod如何把流量负载均衡到其他pod - 关于pod负载均衡的流量,直接通过controller转发给后端pod即可。
3、后端应用的pod很多,如何知道谁是我们要转发的目标? - 通过k8s的server对所有的pod进行分组管理,借助于controller内部的负载均衡配置,找到对应的目标。

2.4、Ingress原理解析

2.4.1、Ingress流程说明

Ingress是授权入站连接到达集群服务的规则集合。
从外部流量调度到nodeport上的service
从service调度到ingress-controller
ingress-controller根据ingress[Pod]中的定义(虚拟主机或者后端的url)
根据虚拟主机名直接调度到后端的一组应用pod中

2.4.2、Ingress流程图

 

外部请求首先到达Ingress Controller,Ingress Controller根据Ingress的路由规则,查找到对应的Service,
进而通过Endpoint查询到Pod的IP地址,然后将请求转发给Pod。 

2.5、Ingress-常见的解决方案

对于ingress controller的软件实现,其实没有特殊的要求,只要能够实现七层的负载均衡功能效果即可,各种组织对于ingress的controller虽然实现方式不同,
但是功能基本上一样,常见的实现方式有:
Ingress-Nginx: Kong
HAProxy:性能相对于nginx来说,较稳定。
Envoy: 基于C++语言开发,本身就为动态环境设计的,支持配置动态加载的XDS API不能像ingress-nginx一样,直接加载配置文件并动态加载转换成对应的应用配置,所以需要借助于其他控制平面工具来实现。
常见解决方案:Contour, Gloo、Traefik

注意:ingress 自从 1.6版本引入后,在1.19 正式进入了一个稳定版本状态。

3、Ingress-Nginx

3.1、Ingress-属性解析

apiVersion: networking.k8s.io/v1   # 资源所属的API群组和版本
kind: Ingress                      # 资源类型标识符
metadata:                          # 元数据
  name <string>                    # 资源名称
  annotations:                     # 资源注解,v1beta1使用下面的注解来指定要解析该资源的控制器类型
    kubernetes.io/ingress.class: <string> # 适配的Ingress控制器类别,便于多ingress组件场景下,挑选针对的类型
  namespace <string>       # 名称空间
spec:
  rules <[]Object>         # Ingress规则列表,也就是http转发时候用到的url关键字
  - host <string>          # 虚拟主机的FQDN,支持“*”前缀通配,不支持IP,不支持指定端口
    http <Object>
      paths <[]Object>     # 虚拟主机PATH定义的列表,由path和backend组成
      - path <string>      # 流量匹配的HTTP PATH,必须以/开头
      pathType <string>    # 支持Exact、Prefix和ImplementationSpecific,必选
      backend <Object>     # 匹配到的流量转发到的目标后端
        resource <Object>     # 引用的同一名称空间下的资源,与下面两个字段互斥
        service <object>      # 关联的后端Service对象
          name <string>       # 后端Service的名称
          port <object>       # 后端Service上的端口对象
            name <string>     # 端口名称
            number <integer>  # 端口号
  tls <[]Object>              # TLS配置,用于指定上rules中定义的哪些host需要工作HTTPS模式
  - hosts <[]string>          # 使用同一组证书的主机名称列表
   secretName <string>        # 保存于数字证书和私钥信息的secret资源名称,用于主机认证
  backend <Object>            # 默认backend的定义,可嵌套字段及使用格式跟rules字段中的相同
  ingressClassName <string>   # ingress类名称,用于指定适配的控制器,类似于注解的功能

3.2、Ingress-nginx布署

3.2.1、官方参考文档

参考资料:https://github.com/kubernetes/ingress-nginx
安装文档:https://kubernetes.github.io/ingress-nginx/deploy/

3.2.2、下载软件

当前版本:ingress-nginx-controller-v1.7.0.tar.gz

地址:https://github.com/kubernetes/ingress-nginx/releases/tag/controller-v1.7.0

3.2.3、获取安装的yaml

# 获取安装的yaml文件
压缩文件位置:ingress-nginx-controller-v1.7.0.tar.gz\ingress-nginx-controller-v1.7.0\deploy\static\provider\baremetal\deploy.yaml

3.2.4、提前准备镜像

# 准备离线镜像,加快安装速度
master1 ingress-nginx]# grep 'image' deploy.yaml | grep -iv 'pull' | uniq
        image: registry.k8s.io/ingress-nginx/controller:v1.7.0@sha256:7612338342a1e7b8090bef78f2a04fffcadd548ccaabe8a47bf7758ff549a5f7
        image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f

# 如果有外网代理的话,可以使用docker代理下载
参考文章:https://www.cnblogs.com/ygbh/p/17295746.html

# 下载好的镜像上传至私有仓库
docker tag 0d4c0564c465 192.168.10.33:80/k8s/ingress-nginx/controller:v1.7.0
docker push 192.168.10.33:80/k8s/ingress-nginx/controller:v1.7.0

docker tag 5a86b03a88d2 192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0
docker push 192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0

3.2.5、修改deploy.yaml【修改下载镜像的地址】

sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f#192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0#'g deploy.yaml
sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230312-helm-chart-4.5.2-28-g66a760794@sha256:01d181618f270f2a96c04006f33b2699ad3ccb02da48d0f89b22abce084b292f#192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0#'g deploy.yaml

master1 ~]# grep 'image' ingress-nginx/deploy.yaml | grep -iv 'pull' | uniq
        image: 192.168.10.33:80/k8s/ingress-nginx/controller:v1.7.0
        image: 192.168.10.33:80/k8s/ingress-nginx/kube-webhook-certgen:v1.7.0

3.2.6、修改deploy.yaml【增加一个外网访问的入口ip】

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
    app.kubernetes.io/version: 1.7.0
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/component: controller
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/name: ingress-nginx
  type: NodePort
  externalIPs: ['192.168.10.222']  # 增加此行,这个IP地址不是一个物理IP地址,虚拟IP来的

注意:如果需要被宿主机访问到的话,就要在主机上增加多一个虚拟网口,并且IP地址与externalIPs保持一致。创建方法如下:
ifconfig ens33:1 192.168.10.222 netmask 255.255.255.0

3.2.7、应用资源配置清单

master1 ~]# kubectl apply -f ingress-nginx/deploy.yaml 
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

3.2.8、查看运行状态

# Pod
master1 ~]# kubectl -n ingress-nginx get pods
NAME                                       READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create-zcm9b       0/1     Completed   0          7m39s
ingress-nginx-admission-patch-jtlj5        0/1     Completed   1          7m39s
ingress-nginx-controller-89c678f9f-j59ll   1/1     Running     0          7m39s

# SVC
master1 ~]# kubectl -n ingress-nginx get svc
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP      PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.111.40.152   192.168.10.222   80:30565/TCP,443:30073/TCP   8m47s
ingress-nginx-controller-admission   ClusterIP   10.97.213.211   <none>           443/TCP                      8m47s

# Job
master1 ~]# kubectl -n ingress-nginx get job
NAME                             COMPLETIONS   DURATION   AGE
ingress-nginx-admission-create   1/1           4s         8m51s
ingress-nginx-admission-patch    1/1           6s         8m51s

 3.2.9、测试访问svc

master1 ~]# curl 192.168.10.222
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

master1 ~]# curl -I -o /dev/null -s -w %{http_code}"\n" 192.168.10.222
404

3.2.10、安装成功

目前为止已经安装成功

4、Ingress-nginx-入门实践

4.1、创建deployment、svc资源

4.1.1、定义资源配置清单且应用

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-test
spec:
  replicas: 4
  selector:
    matchLabels:
      app: pod-test
  template:
    metadata:
      labels:
        app: pod-test
    spec:
      containers:
      - name: pod-test
        image: 192.168.10.33:80/k8s/pod_test:v0.1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: http
---
apiVersion: v1
kind: Service
metadata:
  name: deployment-service
spec:
  selector:
    app: pod-test
  ports:
    - name: http
      port: 80
      targetPort: 80
EOF

4.1.2、查询资源运行状态

master1 ~]# kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
deployment-test-d6756dd79-7njmq   1/1     Running   0          61s
deployment-test-d6756dd79-ds84h   1/1     Running   0          61s
deployment-test-d6756dd79-f5k6j   1/1     Running   0          61s
deployment-test-d6756dd79-kmqv8   1/1     Running   0          61s

master1 ~]# kubectl get svc
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
deployment-service   ClusterIP   10.99.121.115   <none>        80/TCP    63s
kubernetes           ClusterIP   10.96.0.1       <none>        443/TCP   4d14h

master1 ~]# kubectl get deployments.apps 
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
deployment-test   4/4     4            4           114s

4.2、创建ingress-nginx资源

4.2.1、定义资源配置清单且应用

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: cyc.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: deployment-service
            port: 
              number: 80
EOF

属性解析:
1、annotations注释,ingress实现类为nginx
2、对于ingress来说,最终要的就是rules了,hosts是一个自定义的域名,backend指向svc name

4.2.2、查询资源运行状态

master1 ~]# kubectl get ingress
NAME           CLASS    HOSTS             ADDRESS         PORTS   AGE
ingress-test   <none>   cyc.example.com   192.168.10.29   80      63s

master1 ~]# kubectl describe ingress ingress-test 
Name:             ingress-test
Labels:           <none>
Namespace:        default
Address:          192.168.10.29
Ingress Class:    <none>
Default backend:  <default>
Rules:
  Host             Path  Backends
  ----             ----  --------
  cyc.example.com  
                   /   deployment-service:80 (10.244.3.81:80,10.244.3.82:80,10.244.4.114:80 + 1 more...)
Annotations:       kubernetes.io/ingress.class: nginx
Events:
  Type    Reason  Age                From                      Message
  ----    ------  ----               ----                      -------
  Normal  Sync    54s (x2 over 95s)  nginx-ingress-controller  Scheduled for sync
  

ingress将后端的deployment-service:80 的样式自动与 ingress 的 url(/) 关联在一起了

4.3、访问测试

4.3.1、配置hosts

echo '192.168.10.222 cyc.example.com' >> /etc/hosts

4.3.2、访问配置的域名

master1 ~]# curl cyc.example.com
kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-f5k6j, ServerIP: 10.244.3.82!

master1 ~]# curl cyc.example.com
kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-7njmq, ServerIP: 10.244.3.81!

master1 ~]# curl cyc.example.com
kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-ds84h, ServerIP: 10.244.4.115!

master1 ~]# curl cyc.example.com
kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-kmqv8, ServerIP: 10.244.4.114!

# 通过自定义携带域名的方式可以正常访问。

4.4.、原理解析

master1 ~]# kubectl -n ingress-nginx exec -it ingress-nginx-controller-89c678f9f-xlstd -- /bin/bash -c 'grep cyc nginx.conf'
        ## start server cyc.example.com
                server_name cyc.example.com ;
        ## end server cyc.example.com
        
nginx配置文件,定义好域名信息作为信息的入口。

5、Ingress-nginx-多域名、多URL访问-实践

5.1、需求

nginx controller的功能远不止我们所说的主机域名的管理,在实际的工作需求中,肯定会遇到,不同的功能服务以子路径的方式来进行访问,以及与https相关的访问。

5.2、准备pod和svc资源

5.2.1、创建nginx pod和svc资源

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx-test
  template:
    metadata:
      labels:
        app: nginx-test
    spec:
      containers:
      - name: nginx-test
        image: 192.168.10.33:80/k8s/my_nginx:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          name: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx-test
  ports:
    - name: nginx
      port: 80
      targetPort: 80
EOF

注意:这里面有两个主机访问的地址是同一个后端端口,如果还用number的话,就无法正常的识别导致同一个地址访问不同的后端效果。

5.2.2、创建flask pod和svc资源

上一小节已经创建过的,可以忽略。
如果没有创建请看小节:4.1.1、定义资源配置清单且应用

5.2.3、查询资源创建情况

master1 ~]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
deployment-nginx-5c4b6689f6-6dfkn   1/1     Running   0          105s
deployment-nginx-5c4b6689f6-74k2w   1/1     Running   0          105s
deployment-nginx-5c4b6689f6-jmzjw   1/1     Running   0          105s
deployment-nginx-5c4b6689f6-rprfp   1/1     Running   0          105s
deployment-test-d6756dd79-7njmq     1/1     Running   0          40m
deployment-test-d6756dd79-ds84h     1/1     Running   0          40m
deployment-test-d6756dd79-f5k6j     1/1     Running   0          40m
deployment-test-d6756dd79-kmqv8     1/1     Running   0          40m

5.2、不同主机域名访问-实践

5.2.1、需求

访问 flask.example.com/的时候,返回flask的结果
访问 nginx.example.com/的时候,返回nginx的结果

5.2.2、创建ingress-nginx资源

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-mul-url
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: flask.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: deployment-service
            port:
              name: http
              #number: 80
  - host: nginx.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              name: nginx
EOF

配置解析:
 这里面有两个主机访问的地址是同一个后端端口,如果还用number的话,就无法正常的识别导致同一个
 地址访问不同的后端效果

5.2.3、查询资源运行状态

master1 ~]# kubectl get ingress
NAME              CLASS    HOSTS                                 ADDRESS         PORTS   AGE
ingress-mul-url   <none>   flask.example.com,nginx.example.com                   80      4s
ingress-test      <none>   cyc.example.com                       192.168.10.29   80      35m

master1 ~]# kubectl describe ingress ingress-mul-url 
Name:             ingress-mul-url
Labels:           <none>
Namespace:        default
Address:          192.168.10.29
Ingress Class:    <none>
Default backend:  <default>
Rules:
  Host               Path  Backends
  ----               ----  --------
  flask.example.com  
                     /   deployment-service:http (10.244.3.81:80,10.244.3.82:80,10.244.4.114:80 + 1 more...)
  nginx.example.com  
                     /   nginx-service:nginx (10.244.3.83:80,10.244.3.84:80,10.244.4.116:80 + 1 more...)
Annotations:         kubernetes.io/ingress.class: nginx
Events:
  Type    Reason  Age                   From                      Message
  ----    ------  ----                  ----                      -------
  Normal  Sync    117s (x2 over 2m37s)  nginx-ingress-controller  Scheduled for sync

5.2.4、配置hosts

echo '192.168.10.222 flask.example.com nginx.example.com' >> /etc/hosts

5.2.5、访问测试

master1 ~]# curl nginx.example.com
nginx v1版本
master1
~]# curl flask.example.com kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-f5k6j, ServerIP: 10.244.3.82!

5.3、单域名多URL访问-实践

5.3.1、需求

访问 www.example.com/flask的时候,返回flask的结果
访问 www.example.com/nginx的时候,返回nginx的结果
注意事项:
 由于这里涉及到了域名的url转发,而后端服务有可能不存在,我们需要在后端url转发的时候,取消转发关键字。
 解决方法:在annotation中添加一个重写的规则nginx.ingress.kubernetes.io/rewrite-target: /(即所有的请求,把ingress匹配到的url关键字清除掉)

5.3.2、创建ingress-nginx资源

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-mul-url
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /flask
        pathType: Prefix
        backend:
          service:
            name: deployment-service
            port:
              name: http
              #number: 80
      - path: /nginx
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              name: nginx
              #number: 80
EOF

5.3.3、查询资源运行状态

master1 ~]# kubectl get ingress
NAME              CLASS    HOSTS             ADDRESS         PORTS   AGE
ingress-mul-url   <none>   www.example.com   192.168.10.29   80      9m27s
ingress-test      <none>   cyc.example.com   192.168.10.29   80      44m

master1 ~]# kubectl describe ingress ingress-mul-url 
Name:             ingress-mul-url
Labels:           <none>
Namespace:        default
Address:          192.168.10.29
Ingress Class:    <none>
Default backend:  <default>
Rules:
  Host             Path  Backends
  ----             ----  --------
  www.example.com  
                   /flask   deployment-service:http (10.244.3.81:80,10.244.3.82:80,10.244.4.114:80 + 1 more...)
                   /nginx   nginx-service:nginx (10.244.3.83:80,10.244.3.84:80,10.244.4.116:80 + 1 more...)
Annotations:       kubernetes.io/ingress.class: nginx
                   nginx.ingress.kubernetes.io/rewrite-target: /
Events:
  Type    Reason  Age                  From                      Message
  ----    ------  ----                 ----                      -------
  Normal  Sync    20s (x3 over 9m44s)  nginx-ingress-controller  Scheduled for sync
  

5.3.4、配置hosts

echo "192.168.10.222 www.example.com" >>/etc/hosts

5.3.5、访问测试

master1 ~]# curl www.example.com/nginx
nginx v1版本
master1
~]# curl www.example.com/flask kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-f5k6j, ServerIP: 10.244.3.82!

6、Ingress-nginx-https-实践

6.1、需求

我们准备对基础的flask应用进行https方式来进行访问。
方法:Ingress的tls规则就可以帮助我们实现对http应用进行https升级

6.2、准备CA证书

6.2.1、创建CA证书

mkdir tls && cd tls
(umask 077;openssl genrsa -out tls.key 2048)
openssl req -new -x509 -key tls.key -out tls.crt -subj '/CN=www.example.com' -days 10000

6.2.2、将证书导入secret配置资源

kubectl create secret tls ingress-tls --cert=./tls.crt  --key=./tls.key 

[root@master1 tls]# kubectl get secrets 
NAME          TYPE                DATA   AGE
ingress-tls   kubernetes.io/tls   2      11s

6.3、创建ingress-nginx资源

6.3.1、定义资源配置清单并且应用

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-test
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: deployment-service
            port:
              number: 80
  tls:
  - hosts:
    - www.example.com
    secretName: ingress-tls
EOF

6.3.2、查询资源运行状态

master1 ~]# kubectl get ingress
NAME           CLASS    HOSTS             ADDRESS         PORTS     AGE
ingress-test   <none>   www.example.com   192.168.10.29   80, 443   60m

6.3.3、配置hosts

echo "192.168.10.222 www.example.com" >>/etc/hosts

# 如果配置过,就忽略

6.3.4、访问测试

master1 ~]# curl -k https://www.example.com
kubernetes pod-test v0.1!! ClientIP: 10.244.3.80, ServerName: deployment-test-d6756dd79-kmqv8, ServerIP: 10.244.4.114!

master1 ~]# curl www.example.com
<html>
<head><title>308 Permanent Redirect</title></head>
<body>
<center><h1>308 Permanent Redirect</h1></center>
<hr><center>nginx</center>
</body>
</html>

7、Dashboard、Ingress-nginx-实践

7.1、需求

7.1.1、问题点

我们知道,对于k8s的dashboard来说,它所实现的功能还是比较多的,而且原则上要求必须是https方式来
进行访问。我们之前是通过service的方式实现正常的请求访问。有了ingress,我们也可以自由的访问
dashboard了。比如我们访问k8s的dashboard的首页地址是
https://10.0.0.12:30443/#/login

7.1.2、解决dashboard的方法

除了我们之前所说的动态url的方式之外,就需要tls认证了。关于对集群内部的ingress的tls访问方式,可以借助于ingress controller的annotation的方式向nginx中传递一些属性,从而上nginx支持相应的功能。

这与我们上一节的方式有所不同通过两个annotation中的规则
ingress.kubernetes.io/ssl-passthrough: "true"
- 以为后面的dashboard本身就做了tls功能,所以这里进行tls代理即可

nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
- 对后端直接启动https协议访问即可。

参考资料:https://kubernetes.github.io/ingress-nginx/user-guide/nginxconfiguration/annotations/

7.2、创建Ingress资源

7.2.1、定义资源配置清单且应用

echo '
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-dashboard
  namespace: kubernetes-dashboard
  annotations:
    ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - host: dashboard.example.com
    http:
      paths:
      - path: /dashboard(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port: 
              number: 443
' | kubectl apply -f - 

7.2.2、查询资源运行状态

master1 ~]# kubectl get  ingress -n kubernetes-dashboard
NAME                CLASS   HOSTS                   ADDRESS         PORTS   AGE
ingress-dashboard   nginx   dashboard.example.com   192.168.10.29   80      41m

master1 ~]# kubectl get ingress -n kubernetes-dashboard 
[root@master1 ~]# kubectl describe ingress -n kubernetes-dashboard ingress-dashboard 
Name:             ingress-dashboard
Labels:           <none>
Namespace:        kubernetes-dashboard
Address:          192.168.10.29
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  dashboard.example.com  
                         /dashboard(/|$)(.*)   kubernetes-dashboard:443 (10.244.4.118:8443)
Annotations:             ingress.kubernetes.io/ssl-passthrough: true
                         nginx.ingress.kubernetes.io/backend-protocol: HTTPS
                         nginx.ingress.kubernetes.io/rewrite-target: /$2
                         nginx.ingress.kubernetes.io/use-regex: true
Events:
  Type    Reason  Age                 From                      Message
  ----    ------  ----                ----                      -------
  Normal  Sync    43s (x17 over 41m)  nginx-ingress-controller  Scheduled for sync

7.2.3、配置hosts

192.168.10.222 dashboard.example.com
# 这里的IP地址,是我们配置externalIP地址

7.2.4、访问测试

https://dashboard.example.com/dashboard/#/login

8、Ingress-nginx之hostNetwork-实践

8.1、什么时候用到?【不建议生产使用这种模式】

hostNetwork  <boolean>
  Host networking requested for this pod. Use the host's network namespace.

# 大概的意思:使用主机的网络访问Pod

1、只有一个node节点的时候,就可以使用这种模式。【不建议生产使用这种模式】
2、如果生产需要使用这种模式,需要单独部署nginx做反向代理至每台主的pod开放的端口,
但是如果pod挂掉,单独部署nginx就无法自动踢除故障服务了。

8.2、配置hostNetwork

8.2.1、配置hostNetwork: true

~]# vi ingress-nginx/deploy.yaml
spec:
  minReadySeconds: 0
  revisionHistoryLimit: 10
  selector:
    matchLabels:
...
  template:
    metadata:
...
    spec:
      hostNetwork: true
      containers:
      - args:
        - /nginx-ingress-controller
        - --election-id=ingress-nginx-leader
        - --controller-class=k8s.io/ingress-nginx
        - --ingress-class=nginx
        - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        - --validating-webhook=:8443
        - --validating-webhook-certificate=/usr/local/certificates/cert
        - --validating-webhook-key=/usr/local/certificates/key

8.2.2、配置svc【主要修改为NodePort和externalIPS】

 ~]# vi ingress-nginx/deploy.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
...
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - appProtocol: http
    name: http
    port: 80
    protocol: TCP
    targetPort: http
  - appProtocol: https
    name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
...
  type: NodePort
  externalIPs: ['192.168.10.222']

8.3、应用资源配置清单

~]# kubectl apply -f ingress-nginx/deploy.yaml 

8.4、查询相关的运行状态

8.4.1、查询svc

~]# kubectl -n ingress-nginx get svc
NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP      PORT(S)                      AGE
ingress-nginx-controller             NodePort    10.101.51.125   192.168.10.222   80:32690/TCP,443:32170/TCP   18m
ingress-nginx-controller-admission   ClusterIP   10.103.241.48   <none>           443/TCP                      18m

8.4.2、查询node节点信息

~]# kubectl get node -o wide
NAME      STATUS   ROLES           AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION           CONTAINER-RUNTIME
master1   Ready    control-plane   19h   v1.25.7   192.168.10.26   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   containerd://1.6.18
node1     Ready    <none>          19h   v1.25.7   192.168.10.29   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   containerd://1.6.18
node2     Ready    <none>          19h   v1.25.7   192.168.10.30   <none>        CentOS Linux 7 (Core)   3.10.0-1160.el7.x86_64   containerd://1.6.18

8.4.3、查询pod运行状态

~]# kubectl get pods -n ingress-nginx -o wide
NAME                                        READY   STATUS      RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
ingress-nginx-admission-create-75txr        0/1     Completed   0          23m   10.244.1.22     node1   <none>           <none>
ingress-nginx-admission-patch-4v47j         0/1     Completed   1          23m   10.244.1.23     node1   <none>           <none>
ingress-nginx-controller-67958f98cd-58dk4   1/1     Running     0          23m   192.168.10.30   node2   <none>           <none>

8.4、测试访问

8.4.1、增加externalIP

# 主要作用是nginx-controller布署在哪个节点,哪个节点才会开放出NodePort端口出来,所以增加多一个外部IP方便访问
ifconfig
ens33:1 192.168.10.222/24

8.4.2、访问externalIP地址

~]# curl -I -o /dev/null -s -w %{http_code}"\n" 192.168.10.222
404

8.4.3、访问node1节点

~]# curl -I -o /dev/null -s -w %{http_code}"\n" 192.168.10.30
404

8.4.4、小结

说明已经部署成功了

 

posted @ 2023-04-07 20:37  小粉优化大师  阅读(932)  评论(0编辑  收藏  举报