Kubernetes核心组件Ingress详解

1.1 Ingress介绍

  • Kubernetes 集群中,服务(Service)是一种抽象,它定义了一种访问 Pod 的方式,无论这些 Pod 如何变化,服务都保持不变。服务可以被映射到一个静态的 IP 地址(ClusterIP)、一个 NodePort(在集群的每个节点上的特定端口)、一个 LoadBalancer(通过云服务提供商的负载均衡器)或一个外部 IP。

  • Service的两种服务暴露方式,NodePort 和 LoadBalancer,确存在一些局限性:

    • NodePort:当一个服务被配置为 NodePort 类型时,它会在集群的所有节点上的一个静态端口上暴露服务。这种方式的缺点是,如果集群中有大量的服务,那么就需要占用大量的端口,而这些端口资源是有限的。

    • LoadBalancer:这种方式通过云服务提供商的负载均衡器来暴露服务。虽然它解决了 NodePort 方式中端口资源有限的问题,但是每个服务都需要一个单独的负载均衡器,这不仅增加了成本,而且管理起来也相对复杂。

  • 为了解决这些问题,Kubernetes 引入了 Ingress 资源对象:

    • Ingress 是一种 API 对象,它管理外部访问到集群内服务的 HTTP 和 HTTPS 路由。它提供了一种规则,允许你将外部 HTTP/HTTPS 路由到集群内的多个服务。

    • Ingress 可以提供单一的 IP 地址,通过不同的 URL 路径或不同的端口来路由到不同的服务。

    • 它只需要一个 NodePort 或者一个 LoadBalancer,就可以将多个服务暴露给外部网络,这样做既节省了资源,又简化了配置。

    • Ingress 还支持 SSL/TLS 终止,可以为不同的服务配置 SSL 证书。

    • 它允许更复杂的路由规则,比如基于路径、主机名或 HTTP 头部的路由。

image-20240516160949154

  • 实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:

    • ingress:kubernetes中的一个对象,作用是定义请求如何转发到service的规则

    • ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx, Contour, Haproxy等等

  • Ingress(以Nginx为例)的工作原理:

    • 定义路由规则:用户通过 Kubernetes API 创建 Ingress 规则,指定域名与集群内服务的映射关系。

    • 感知规则变化:Ingress 控制器(如基于 Nginx)实时监控 Kubernetes API,以便发现 Ingress 规则的更新。

    • 生成配置:一旦检测到变化,Ingress 控制器自动生成相应的 Nginx 配置,以实现定义的路由规则。

    • 更新 Nginx 配置:新生成的 Nginx 配置被应用到运行中的 Nginx 实例,无需重启服务即可动态更新路由规则。

    • 流量转发:Nginx 作为反向代理,根据更新的配置,将外部请求转发到集群内正确的服务。

    • SSL/TLS 终止(可选):如果配置了 SSL/TLS,Nginx 还可以在转发前终止加密连接,提高安全性和效率。

image-20240516161950526

1.2 Ingress安装部署

  • GitHub地址:GitHub - kubernetes/ingress-nginx: Ingress-NGINX Controller for Kubernetes

SupportedIngress-NGINX versionk8s supported versionAlpine VersionNginx VersionHelm Chart Version
🔄v1.10.11.29, 1.28, 1.27, 1.263.19.11.25.34.10.1*
🔄v1.10.01.29, 1.28, 1.27, 1.263.19.11.25.34.10.0*
🔄v1.1.61.29, 1.28, 1.27, 1.26, 1.253.19.01.21.64.1.1*
🔄v1.1.51.28, 1.27, 1.26, 1.253.18.41.21.64.1.0*
🔄v1.1.41.28, 1.27, 1.26, 1.253.18.41.21.64.8.3
🔄v1.1.31.28, 1.27, 1.26, 1.253.18.41.21.64.8.*
🔄v1.1.11.28, 1.27, 1.26, 1.253.18.41.21.64.8.*
🔄v1.1.01.28, 1.27, 1.26, 1.253.18.21.21.64.8.*
v1.8.41.27, 1.26, 1.25, 1.243.18.21.21.64.7.*
v1.7.11.27, 1.26, 1.25, 1.243.17.21.21.64.6.*
v1.6.41.26, 1.25, 1.24, 1.233.17.01.21.64.5.*
v1.5.11.25, 1.24, 1.233.16.21.21.64.4.*
v1.4.01.25, 1.24, 1.23, 1.223.16.21.19.10†4.3.0
v1.3.11.24, 1.23, 1.22, 1.21, 1.203.16.21.19.10†4.2.5
[root@K8s-master-01 ~]# wget -c https://gitee.com/kong-xiangyuxcz/svn/releases/download/ingress-nginx-controller-v1.10.1/deploy.yaml
​
[root@k8s-master-01 ~]# sed -i 's#registry.k8s.io/ingress-nginx/controller:v1.10.1.*#registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.10.1#' deploy.yaml 
​
[root@k8s-master-01 ~]# sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.1.*#registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.4.1#g' deploy.yaml
​
[root@k8s-master-01 ~]# sed -i '345 a \
  annotations: \
    lb.kubesphere.io/v1alpha1: openelb \
    protocol.openelb.kubesphere.io/v1alpha1: layer2 \
    eip.openelb.kubesphere.io/v1alpha2: eip-pool' deploy.yaml
​
[root@k8s-master-01 ~]# vim deploy.yaml
372 apiVersion: v1   #匹配到第二个Service,添加HTTP
373 kind: Service
374 metadata:
375   labels:
376     app.kubernetes.io/component: controller
377     app.kubernetes.io/instance: ingress-nginx
378     app.kubernetes.io/name: ingress-nginx
379     app.kubernetes.io/part-of: ingress-nginx
380     app.kubernetes.io/version: 1.10.1
381   name: ingress-nginx-controller-admission
382   namespace: ingress-nginx
383 spec:
384   ports:
      - appProtocol: http 
        name: http 
        port: 80 
        protocol: TCP 
        targetPort: http
390   - appProtocol: https
391     name: https-webhook
392     port: 443
​
[root@k8s-master-01 ~]# sed -i 's/ClusterIP/NodePort/' deploy.yaml    # 设置暴露端口
  • 部署

# 手动把镜像拉下来,自己拉可能会失败
$ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.10.1
$ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v1.4.1
​
[root@K8s-master-01 ~]# kubectl apply -f deploy.yaml 
[root@k8s-master-01 ~]# kubectl get svc,pod -n ingress-nginx
NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.109.90.36    192.168.110.200   80:30397/TCP,443:32205/TCP   86s
service/ingress-nginx-controller-admission   NodePort       10.111.97.151   <none>            80:31410/TCP,443:32380/TCP   86s
​
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-2bvsj        0/1     Completed   0          86s
pod/ingress-nginx-admission-patch-66khb         0/1     Completed   0          86s
pod/ingress-nginx-controller-676c7b59c4-wsvfc   1/1     Running     0          86s
​
# 注意eip-pool必须提前配好,OpenELB提前要有,具体配置见8.4.6.2

1.3 Ingress暴露服务的方式

1.3.1 Deployment + LoadBalancer 模式的 Service

  • 适用场景:适用于公有云环境,尤其是那些支持自动创建负载均衡器并绑定公网地址的云平台。

  • 工作原理:使用 Deployment 部署 Ingress Controller,并创建一个类型为 LoadBalancer 的 Service 关联这些 Pods。大部分公有云平台会自动为 LoadBalancer 类型的 Service 创建一个负载均衡器,并绑定公网地址。

  • 优势:简单易用,只需配置 DNS 讲解析指向负载均衡器的地址即可实现服务的对外暴露。

  • 参考资料:OpenELB 配置示例。见service详解

1.3.1.1 配置Deployment + LoadBalancer 模式的 Service
  • 环境

[root@k8s-master-01 ~]# kubectl get svc -n test   # 准备好一个LoadBalancer类型的service
NAME     TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)        AGE
svc-lb   LoadBalancer   10.101.43.178   192.168.110.201   80:31545/TCP   27m
  • 创建Ingress

[root@k8s-master-01 ~]# vim ingress-dep_lb.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: test
spec:
  ingressClassName: nginx
  rules:
  - host: www.kxyctl.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc-lb
            port:
              number: 80
​
[root@k8s-master-01 ~]# kubectl apply -f ingress-dep_lb.yaml 
ingress.networking.k8s.io/nginx-ingress created
[root@k8s-master-01 ~]# kubectl get ingress -n test
NAME            CLASS   HOSTS            ADDRESS           PORTS   AGE
nginx-ingress   nginx   www.kxyctl.com   192.168.110.200   80      86s
  • 测试

[root@k8s-master-01 ~]# echo '192.168.110.200 www.kxyctl.com' >> /etc/hosts
[root@k8s-master-01 ~]# for ((i=0;i<=6;i++)) do curl www.kxyctl.com; done
10.244.44.197  web-03
10.244.154.198  web-01
10.244.44.197  web-03
10.244.44.197  web-03
10.244.154.197  web-02
10.244.154.197  web-02
10.244.154.198  web-01

image-20240526162853795

1.3.2 DaemonSet + HostNetwork + NodeSelector

  • 适用场景:适用于需要高性能和低延迟的场景,例如大并发生产环境。

  • 工作原理:使用 DaemonSet 和 NodeSelector 将 Ingress Controller 部署到特定的节点上,然后使用 HostNetwork 功能直接将 Pod 与宿主机的网络打通,直接使用宿主机的 80/443 端口访问服务。

  • 优势:整个请求链路最简单,性能相对 NodePort 模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个节点只能部署一个 Ingress Controller Pod。

  • 适用场景:比较适合大并发的生产环境使用。

  • 使用 DaemonSet 结合 nodeselector 来部署 ingress-controller 到特定的 node 上,然后使用 HostNetwork 直接把该 pod 与宿主机 node 的网络打通,直接使用宿主机的 80/443 端口就能访问服务,这种方式确实有其独特的优点和缺点。

特性描述
请求链路简单直接使用宿主机的网络和端口,请求链路直观且简单,无额外跳板。
性能优越相比 NodePort 模式,减少网络跳转次数和处理开销,性能更佳。
单一节点限制一个 node 只能部署一个 ingress-controller pod,扩展服务需要增加节点。
灵活性降低难以实现跨多个节点的负载均衡和故障转移策略。
适用场景高性能和低延迟需求的大并发生产环境,希望最大限度利用宿主机资源减少网络开销。
  • 这种部署方式通过直接利用宿主机的网络和端口,将 ingress-controller 的部署变得更加简单和高效,同时也带来了性能上的提升。然而,由于这种方式的单一节点限制和灵活性降低,可能并不适合所有场景,特别是那些需要高度可扩展性和弹性的场景。

1、指定nginx-ingress-controller运行在node2节点
[root@k8s-master-01 ~]# kubectl label node k8s-node-01 ingress=true
node/k8s-node-01 labeled
​
2、修改Deployment为DaemonSet,指定节点运行,并开启 hostNetwork
[root@k8s-master-01 ~]# kubectl delete -f deploy.yaml
[root@k8s-master-01 ~]# cp deploy.yaml deploy_daemonset.yaml
[root@k8s-master-01 ~]# sed -i 's/Deployment/DaemonSet/' deploy_daemonset.yaml  # Deployment改为DaemonSet
[root@k8s-master-01 ~]# vim deploy.yaml   # Daemonset下修改
419 #  strategy:
420 #    rollingUpdate:
421 #      maxUnavailable: 1
422 #    type: RollingUpdate
​
473         ports:
474         - containerPort: 80
475           name: http
476           protocol: TCP
477           hostPort: 80
478         - containerPort: 443
479           name: https
480           protocol: TCP
481           hostPort: 443
​
516       nodeSelector:
517         #kubernetes.io/os: linux
518         ingress: "true"
519       hostNetwork: true
​
3、部署
[root@k8s-master-01 ~]# kubectl apply -f deploy.yaml 
[root@k8s-master-01 ~]# kubectl get pod -n ingress-nginx -o wide
NAME                                   READY   STATUS      RESTARTS   AGE   IP               NODE          NOMINATED NODE   READINESS GATES
ingress-nginx-admission-create-wb4s7   0/1     Completed   0          29s   10.244.154.195   k8s-node-01   <none>           <none>
ingress-nginx-admission-patch-55282    0/1     Completed   0          29s   10.244.154.196   k8s-node-01   <none>           <none>
ingress-nginx-controller-lsnz9         1/1     Running     0          29s   10.244.154.197   k8s-node-01   <none>           <none>
​
# 这里如果是pending那就是443端口被占用了,换个节点试就行
  • Ingress配置

[root@k8s-master-01 ~]# vim ingress-dep_ds.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: test
spec:
  ingressClassName: nginx
  rules:
  - host: www.kxyctl.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc-lb
            port:
              number: 80
              
[root@k8s-master-01 ~]# kubectl get svc,ing,pod -n test
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)        AGE
service/svc-lb         LoadBalancer   10.104.99.81   192.168.110.201   80:31468/TCP   43m
service/svc-nodeport   NodePort       10.96.103.97   <none>            80:32522/TCP   42m
​
NAME            CLASS   HOSTS            ADDRESS           PORTS   AGE
nginx-ingress   nginx   www.kxyctl.com   192.168.110.200   80      86s
​
NAME                                 READY   STATUS    RESTARTS   AGE
pod/pc-deployment-5cb65f68db-kj4qf   1/1     Running   0          40m
pod/pc-deployment-5cb65f68db-ph7rz   1/1     Running   0          40m
pod/pc-deployment-5cb65f68db-thwb6   1/1     Running   0          40m              
  • 测试

[root@k8s-master-01 ~]# for ((i=0;i<=6;i++)) do curl www.kxyctl.com; done
10.244.44.199  DaemonSet + HostNetwork + NodeSelector-03
10.244.44.198  DaemonSet + HostNetwork + NodeSelector-02
10.244.44.199  DaemonSet + HostNetwork + NodeSelector-01
10.244.44.198  DaemonSet + HostNetwork + NodeSelector-01
10.244.154.199  DaemonSet + HostNetwork + NodeSelector-02
10.244.154.199  DaemonSet + HostNetwork + NodeSelector-03
10.244.44.199  DaemonSet + HostNetwork + NodeSelector-01

1.3.3 Deployment + NodePort 模式的 Service

  • 适用场景:适用于宿主机 IP 地址相对固定,不太可能频繁变动的环境。

  • 工作原理:使用 Deployment 部署 Ingress Controller,并创建一个类型为 NodePort 的 Service。这样,Ingress 就会暴露在集群节点 IP 的特定端口上。

  • 优势:简单方便,NodePort 暴露的端口是随机的,但可以通过负载均衡器转发请求。

  • 缺点:NodePort 多了一层 NAT,在请求量级很大的时候可能对性能会有一定影响。

1.3.3.1 Deployment + NodePort 模式的 Service配置
  • 环境

[root@k8s-master-01 ~]# kubectl get svc -n test | grep NodePort  # 准备好一个nodeport类型的Service
svc-nodeport   NodePort       10.97.216.108   <none>            80:32522/TCP   17s
  • Ingress配置

[root@k8s-master-01 ~]# vim ingress-dep_np.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: test
spec:
  ingressClassName: nginx
  rules:
  - host: www.kxyctl.cn
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc-nodeport
            port:
              number: 80
​
[root@k8s-master-01 ~]# sed -i 's/www.kxyctl.com/www.kxyctl.cn/' /etc/hosts
[root@k8s-master-01 ~]# kubectl apply -f ingress-dep_np.yaml 
ingress.networking.k8s.io/nginx-ingress created
​
[root@k8s-master-01 ~]# kubectl get ingress -n test
NAME            CLASS   HOSTS           ADDRESS           PORTS   AGE
nginx-ingress   nginx   www.kxyctl.cn   192.168.110.200   80      38s
  • 测试

[root@k8s-master-01 ~]# for ((i=0;i<=6;i++)) do curl www.kxyctl.cn; done
10.244.44.199  Deployment + NodePort-03
10.244.44.198  Deployment + NodePort-02
10.244.44.199  Deployment + NodePort-03
10.244.44.198  Deployment + NodePort-02
10.244.154.199  Deployment + NodePort-01
10.244.154.199  Deployment + NodePort-01
10.244.44.199  Deployment + NodePort-03

image-20240526170135642

1.4 Ingress应用

1.4.1 Ingress的HTTP代理

  • 准备service和pod为了后面的实验比较方便,创建如下图所示的模型

image-20240526173910088

  • 创建tomcat-nginx.yaml

[root@k8s-master-01 ~]# vim tomcat-nginx.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  namespace: test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat-pod
  template:
    metadata:
      labels:
        app: tomcat-pod
    spec:
      containers:
      - name: tomcat
        image: tomcat:8.5-jre10-slim
        ports:
        - containerPort: 8080
​
---
apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
  namespace: test
  annotations:
    lb.kubesphere.io/v1alpha1: openelb
    protocol.openelb.kubesphere.io/v1alpha1: layer2
    eip.openelb.kubesphere.io/v1alpha2: eip-pool
spec:
  selector:
    app: tomcat-pod
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080
      
[root@k8s-master-01 ~]# kubectl apply -f tomcat-nginx.yaml 
deployment.apps/tomcat-deployment unchanged
service/tomcat-service created
​
[root@k8s-master-01 ~]# kubectl get service -n test
NAME             TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)          AGE
svc-lb           LoadBalancer   10.104.99.81   192.168.110.201   80:31468/TCP     57m
svc-nodeport     NodePort       10.96.103.97   <none>            80:32522/TCP     56m
tomcat-service   LoadBalancer   10.103.51.78   192.168.110.202   8080:31609/TCP   54s
​
[root@k8s-master-01 ~]# kubectl get pod -n test
NAME                                 READY   STATUS    RESTARTS   AGE
pc-deployment-5cb65f68db-kj4qf       1/1     Running   0          65m
pc-deployment-5cb65f68db-ph7rz       1/1     Running   0          65m
pc-deployment-5cb65f68db-thwb6       1/1     Running   0          65m
tomcat-deployment-7ff7bd5bcd-9q8gk   1/1     Running   0          15m
tomcat-deployment-7ff7bd5bcd-ghvzm   1/1     Running   0          15m
tomcat-deployment-7ff7bd5bcd-s6hrb   1/1     Running   0          15m
  • Ingress配置

[root@k8s-master-01 ~]# vim ingress-dep_lb.yaml 
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: test
spec:
  ingressClassName: nginx
  rules:
  - host: www.kxyctl.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc-lb
            port:
              number: 80
  - host: tomcat.kxyctl.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port:
              number: 80
​
[root@k8s-master-01 ~]# kubectl apply -f ingress-dep_lb.yaml 
ingress.networking.k8s.io/nginx-ingress created
[root@k8s-master-01 ~]# kubectl get service,ingress -n test
NAME                     TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)          AGE
service/svc-lb           LoadBalancer   10.104.99.81   192.168.110.201   80:31468/TCP     63m
service/svc-nodeport     NodePort       10.96.103.97   <none>            80:32522/TCP     62m
service/tomcat-service   LoadBalancer   10.103.51.78   192.168.110.202   8080:31609/TCP   6m45s
​
NAME                                      CLASS   HOSTS                              ADDRESS           PORTS   AGE
ingress.networking.k8s.io/nginx-ingress   nginx   www.kxyctl.com,tomcat.kxyctl.com   192.168.110.200   80      62s
​
# Windows添加Hosts解析,192.168.110.202 tomcat.kxyctl.com   访问:http://tomcat.kxyctl.com/

image-20240526180219430

1.4.2 Ingress的HTTPS代理

  • 创建证书和密钥

[root@k8s-master-01 ~]# openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=itopenlab.com"
Generating a 2048 bit RSA private key
..+++
......................................+++
writing new private key to 'tls.key'
-----
[root@k8s-master-01 ~]# kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created
  • 创建ingress-https.yaml

[root@k8s-master-01 ~]# vim ingress-https.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-https
  namespace: test
spec:
  tls:
  - hosts:
    - nginx.kxyctl.com
    - tomcat.kxyctl.com
    secretName: tls-secret # 指定秘钥
  rules:
  - host: nginx.kxyctl.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
  - host: tomcat.kxyctl.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port:
              number: 8080
​
[root@k8s-master-01 ~]# kubectl apply -f ingress-https.yaml 
ingress.networking.k8s.io/ingress-https created
​
[root@k8s-master-01 ~]# kubectl get ing ingress-https -n test
NAME            CLASS    HOSTS                                      ADDRESS   PORTS     AGE
ingress-https   <none>   nginx.itopenlab.com,tomcat.itopenlab.com             80, 443   9s
​
[root@k8s-master-01 ~]# kubectl describe ing ingress-https -n test
Name:             ingress-https
Labels:           <none>
Namespace:        test
Address:          
Ingress Class:    <none>
Default backend:  <default>
TLS:
  tls-secret terminates nginx.kxyctl.com,tomcat.kxyctl.com
Rules:
  Host               Path  Backends
  ----               ----  --------
  nginx.kxyctl.com   
                     /   nginx-service:80 (<error: endpoints "nginx-service" not found>)
  tomcat.kxyctl.com  
                     /   tomcat-service:8080 (10.244.154.206:8080,10.244.44.215:8080,10.244.44.216:8080)
Annotations:         <none>
Events:              <none>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/649613.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

element ui 的el-input输入一个字后失去焦点,需重新点击输入框才能再次输入!

解决方案&#xff1a; 我是form表单嵌套表格&#xff0c;里面的el-input输入框&#xff0c;输入第一个值的时候会突然失去焦点&#xff0c;需要再次点击输入框才能正常输入&#xff0c;原因是table的key值&#xff0c;需要改成正常的index即可&#xff0c;如果你是循环的&…

精益生产培训公司:为企业量身定制的精益解决方案——张驰咨询

在当今竞争激烈的市场环境下&#xff0c;企业要想持续发展&#xff0c;就必须不断寻求转型升级的途径。精益生产作为一种高效的生产管理方式&#xff0c;已经成为众多企业追求的目标。而精益生产培训公司&#xff0c;正是帮助企业实现这一目标的重要力量。 一、精益生产培训的…

Kubernetes可视化界面之DashBoard

1.1 DashBoard Kubernetes Dashboard 是 Kubernetes 集群的一个开箱即用的 Web UI&#xff0c;提供了一种图形化的方式来管理和监视 Kubernetes 集群中的资源。它允许用户直接在浏览器中执行许多常见的 Kubernetes 管理任务&#xff0c;如部署应用、监控应用状态、执行故障排查…

WPF中CommandParameter用法

1. 界面样式 2. XAML中代码部分 <ButtonGrid.Row"0"Grid.Column"1"Command"{Binding BtnClick_Number}"CommandParameter"7"Content"7"Style"{StaticResource BtnStyle_Num}" /> <ButtonGrid.Row"…

产品经理-需求收集(二)

1. 什么是需求 指在一定的时期中&#xff0c;一定场景中&#xff0c;无论是心理上还是生理上的&#xff0c;用户有着某种“需要”&#xff0c;这种“需要”用户自己不一定知道的&#xff0c;有了这种“需要”后用户就有做某件事情的动机并促使达到其某种目的&#xff0c;这也就…

最新dofm飞行棋高阶版,分享情侣版飞行棋高级版和终极版

阿星今天要给大家带来一款甜蜜蜜的小游戏——情侣飞行棋。这不是普通的飞行棋&#xff0c;而是专为情侣设计的&#xff0c;让你们的感情在游戏中升温&#xff0c;擦出更多爱的火花。 准备好了吗&#xff1f;跟着阿星一起&#xff0c;咱们来看看这款软件的魅力所在&#xff01;…

设置虚拟机为静态IP

为什么需要设置静态IP&#xff1a;有时候我们在练习项目的时候&#xff0c;明明已经连接好了虚拟机的ip&#xff0c;某一天突然连接不上了&#xff0c;通过ifconfig命令查看发现虚拟机的ip发生了变化&#xff0c;导致之前做的内容都需要重新布置&#xff0c; 一、设置静态IP …

Python 全栈体系【四阶】(五十三)

第五章 深度学习 十二、光学字符识别&#xff08;OCR&#xff09; 2. 文字检测技术 2.3 DB&#xff08;2020&#xff09; DB全称是Differentiable Binarization&#xff08;可微分二值化&#xff09;&#xff0c;是近年提出的利用图像分割方法进行文字检测的模型。前文所提…

分布式理论--BASE

目录 是什么BASE 与 CAP&#xff0c;ACID 的区别BASE 和 Paxos 类共识算法的区别相关问题 是什么 BASE 理论是对 CAP 理论的进一步扩展主要强调在分布式系统中&#xff0c;为了获得更高的可用性和性能&#xff0c;可以放宽对一致性的要求&#xff0c;是对 CAP 中 AP 方案的一个…

QT 掩码 InputMask

字符规则 如IP输入框可以简单设置为 IP->setInputMask("000.000.000.000");就会有80%的相似度 另外设置掩码用 ui.edtIP->setInputMask(“这里面是字符格式”); ★消除已有的掩码用 ui.edtIP->setInputMask(""); 双引号之间没有空…

数据挖掘实战-基于余弦相似度的印度美食推荐系统

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

Three.js——二维平面、二维圆、自定义二维图形、立方体、球体、圆柱体、圆环、扭结、多面体、文字

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

外汇天眼:野村证券和Laser Digital与GMO互联网集团合作发行日元和美元稳定币

野村控股和Laser Digital将与GMO互联网集团合作&#xff0c;在日本探索发行日元和美元稳定币。GMO互联网集团的美国子公司GMO-Z.com Trust Company, Inc. 在纽约州金融服务部的监管框架下&#xff0c;在以太坊、恒星币和Solana等主要区块链上发行稳定币。GMO-Z.com Trust Compa…

三坐标测量机在汽车零部件质量控制中的应用

高质量的零部件能够确保汽车的性能达到设计标准&#xff0c;包括动力性能、燃油效率、操控稳定性等&#xff0c;从而提供更好的驾驶体验&#xff0c;建立消费者对汽车品牌的信任&#xff1b;也推动了汽车行业的技术创新&#xff0c;制造商不断研发新材料、新工艺&#xff0c;以…

驾考学法减分拍照搜题模拟考试小程序开发

驾考学法减分拍照搜题模拟考试小程序开发 项目介绍 驾考搜题&#xff0c;一款专为驾考学员设计的智能搜题助手&#xff0c;集合了海量题库与实战模拟&#xff0c;助力学员快速掌握驾考知识&#xff0c;轻松应对各类考试。 主要功能特点 智能搜题 通过关键词、拍照搜索&#xf…

Python爬虫实战(实战篇)—16获取【百度热搜】数据—写入Ecel(附完整代码)

文章目录 专栏导读背景结果预览1、爬取页面分析2、通过返回数据发现适合利用lxmlxpath3、继续分析【小说榜、电影榜、电视剧榜、汽车榜、游戏榜】4、完整代码总结 专栏导读 &#x1f525;&#x1f525;本文已收录于《Python基础篇爬虫》 &#x1f251;&#x1f251;本专栏专门…

【数据结构】图解红黑树以及代码实现

目录 一、相关概念 性质 二、图解 1、插入操作 2、parent在左边情况1&#xff1a;cur为红色节点parent也是红色节点、uncle也为红色节点 3、parent在左边情况2&#xff1a;cur为红色节点parent也是红色节点、uncle为黑色或者是空&#xff0c;cur是parent的left 4、parent…

【清灰教程】联想拯救者Y7000p(2018款)拆机清灰教程+更换硅脂

清灰教程 本人电脑&#xff1a;联想拯救者Y7000p&#xff08;2018款&#xff09;第一步&#xff1a;购买清灰道具&#xff08;提前买好&#xff09;螺丝刀1.硅脂 这里随便买的 2.刮刀&#xff08;买硅脂送&#xff09;4.刷子&#xff08;清风扇灰&#xff09;5.撬后盖用&#x…

wordpress主题给网站增加一个版权声明区块代码分享

在数字化时代&#xff0c;网络上的信息传播变得越来越便捷&#xff0c;给人们生活和工作带来了极大的便利。然而&#xff0c;在这个过程中也产生了很多版权问题。为了更好地保护自己的版权&#xff0c;许多网站开始在其网页上添加版权声明。本文将探讨在网站上添加版权声明的重…

sklearn线性回归--岭回归

sklearn线性回归--岭回归 岭回归也是一种用于回归的线性模型&#xff0c;因此它的预测公式与普通最小二乘法相同。但在岭回归中&#xff0c;对系数&#xff08;w&#xff09;的选择不仅要在训练数据上得到好的预测结果&#xff0c;而且还要拟合附加约束&#xff0c;使系数尽量小…