云原生Kubernetes:对外服务之 Ingress

目录

一、理论

1.Ingress

2.部署 nginx-ingress-controller(第一种方式)

3.部署 nginx-ingress-controller(第二种方式)

二、实验

1.部署 nginx-ingress-controller(第一种方式)

2.部署 nginx-ingress-controller(第二种方式)

三、问题

1.启动 nginx-ingress-controller报错

2.容器探针失败

3.生成pod报错

4.获取ingress失败

5.Ingress和Ingress Controller关系

四、总结


一、理论

1.Ingress

(1)  概念

service的作用体现在两个方面,对集群内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制;对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。

在Kubernetes中,Pod的IP地址和service的ClusterIP仅可以在集群网络内部使用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes目前提供了以下几种方案:
 

●NodePort:将service暴露在节点网络上,NodePort背后就是Kube-Proxy,Kube-Proxy是沟通service网络、Pod网络和节点网络的桥梁。
测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理就是个灾难。因为每个端口只能是一种服务,默认端口范围只能是 30000-32767。●LoadBalancer:通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置 Service 的场景。 受限于云平台,且通常在云平台部署LoadBalancer还需要额外的费用。
在service提交后,Kubernetes就会调用CloudProvider在公有云上为你创建一个负载均衡服务,并且把被代理的Pod的IP地址配置给负载均衡服务做后端。●externalIPs:service允许为其分配外部IP,如果外部IP路由到集群中一个或多个Node上,Service会被暴露给这些externalIPs。通过外部IP进入到集群的流量,将会被路由到Service的Endpoint上。 ●Ingress:只需一个或者少量的公网IP和LB,即可同时将多个HTTP服务暴露到外网,七层反向代理。
可以简单理解为service的service,它其实就是一组基于域名和URL路径,把用户的请求转发到一个或多个service的规则。

(2)组成

●ingress:
ingress是一个API对象,通过yaml文件来配置,ingress对象的作用是定义请求如何转发到service的规则,可以理解为配置模板。
ingress通过http或https暴露集群内部service,给service提供外部URL、负载均衡、SSL/TLS能力以及基于域名的反向代理。ingress要依靠 ingress-controller 来具体实现以上功能。●ingress-controller:
ingress-controller是具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
ingress-controller并不是k8s自带的组件,实际上ingress-controller只是一个统称,用户可以选择不同的ingress-controller实现,目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,其他还有很多第三方维护的ingress-controller,具体可以参考官方文档。但是不管哪一种ingress-controller,实现的机制都大同小异,只是在具体配置上有差异。

一般来说,ingress-controller的形式都是一个pod,里面跑着daemon程序和反向代理程序。daemon负责不断监控集群的变化,根据 ingress对象生成配置并应用新配置到反向代理,比如ingress-nginx就是动态生成nginx配置,动态更新upstream,并在需要的时候reload程序应用新配置。为了方便,后面的例子都以k8s官方维护的ingress-nginx为例。

(3)控制器分类

1)Kubernetes Ingress Controller
http://github.com/kubernetes/ingress-nginx
实现:Go/Lua(nginx 是用 C 写的)
许可证:Apache 2.0
Kubernetes 的“官方”控制器(之所以称为官方,是想把它区别于 NGINX 公司的控制器)。这是社区开发的控制器,它基于 nginx Web 服务器,并补充了一组用于实现额外功能的 Lua 插件。
由于 NGINX 十分流行,再加上把它用作控制器时所需的修改较少,它对于 K8s 普通工程师来说,可能是最简单和最直接的选择。2)NGINX Ingress Controller
http://github.com/nginxinc/kubernetes-ingress
实现:Go
许可证:Apache 2.0
这是 NGINX 公司开发的官方产品,它也有一个基于 NGINX Plus 的商业版。NGINX 的控制器具有很高的稳定性、持续的向后兼容性,且没有任何第三方模块。
由于消除了 Lua 代码,和官方控制器相比,它保证了较高的速度,但也因此受到较大限制。相较之下,它的付费版本有更广泛的附加功能,如实时指标、JWT 验证、主动健康检查等。
NGINX Ingress 重要的优势是对 TCP/UDP 流量的全面支持,最主要缺点是缺乏流量分配功能。3)Kong Ingress
http://github.com/Kong/kubernetes-ingress-controller
实现:Go
许可证:Apache 2.0
Kong Ingress 由 Kong Inc 开发,有两个版本:商业版和免费版。它基于 NGINX 构建,并增加了扩展其功能的 Lua 模块。
最初,Kong Ingress 主要用作 API 网关,用于 API 请求的处理和路由。现在,它已经成为成熟的 Ingress 控制器,主要优点是拥有大量易于安装和配置的附加模块、插件(包括第三方插件)。它开启了控制器具备大量附加功能的先河,其内置函数也提供了许多可能性。Kong Ingress 配置是用 CRD 执行的。
Kong Ingress 的一个重要特性是它只能在一个环境中运行(而不支持跨命名空间)。这是一个颇有争议的话题:有些人认为这是一个缺点,因为必须为每个环境生成实例;而另一些人认为这是一个特殊特性,因为它是更高级别的隔离,控制器故障的影响仅限于其所在的环境。4)Traefik
http://github.com/containous/traefik
实现:Go
许可证:MIT
最初,这个代理是为微服务请求及其动态环境的路由而创建的,因此具有许多有用的功能:连续更新配置(不重新启动)、支持多种负载均衡算法、Web UI、指标导出、对各种服务的支持协议、REST API、Canary 版本等。
支持开箱即用的 Let’s Encrypt 是它的另一个不错的功能,但它的主要缺点也很明显,就是为了控制器的高可用性,你必须安装并连接其 Key-value store。
在 2019 年 9 月发布的 Traefik v2.0 中,虽然它增加许多不错的新功能,如带有 SNI 的 TCP/SSL、金丝雀部署、流量镜像/shadowing 和经过改进的 Web UI,但一些功能(如 WAF 支持)还在策划讨论中。
与新版本同期推出的还有一个名叫 Maesh 的服务网格,它建在 Traefik 之上。5)HAProxy Ingress
http://github.com/jcmoraisjr/haproxy-ingress
实现:Go(HAProxy 是用 C 写的)
许可证:Apache 2.0
HAProxy 是众所周知的代理服务器和负载均衡器。作为 Kubernetes 集群的一部分,它提供了“软”配置更新(无流量损失)、基于 DNS 的服务发现和通过 API 进行动态配置。 HAProxy 还支持完全自定义配置文件模板(通过替换 ConfigMap)以及在其中使用 Spring Boot 函数。
通常,工程师会把重点放在已消耗资源的高速、优化和效率上。而 HAProxy 的优点之一正是支持大量负载均衡算法。值得一提的是,在今年 6 月发布的 v2.0 中,HAProxy 增加了许多新功能,其即将推出的 v2.1 有望带来更多新功能(包括 OpenTracing 支持)。6)Voyager
http://github.com/appscode/voyager
实现:Go
许可证:Apache 2.0
Voyager 基于 HAProxy,并作为一个通用的解决方案提供给大量供应商。它最具代表性的功能包括 L7 和 L4 上的流量负载均衡,其中,TCP L4 流量负载均衡称得上是该解决方案最关键的功能之一。
在今年早些时候,尽管 Voyager 在 v9.0.0 中推出了对 HTTP/2 和 gRPC 协议的全面支持,但总的来看,对证书管理(Let’s Encrypt 证书)的支持仍是 Voyager 集成的最突出的新功能。7)Contour
http://github.com/heptio/contour
实现:Go
许可证:Apache 2.0
Contour 和 Envoy 由同一个作者开发,它基于 Envoy。它最特别的功能是可以通过 CRD(IngressRoute)管理 Ingress 资源,对于多团队需要同时使用一个集群的组织来说,这有助于保护相邻环境中的流量,使它们免受 Ingress 资源更改的影响。
它还提供了一组扩展的负载均衡算法(镜像、自动重复、限制请求率等),以及详细的流量和故障监控。对某些工程师而言,它不支持粘滞会话可能是一个严重缺陷。8)Istio Ingress
http://istio.io/docs/tasks/traffic-management/ingress
实现:Go
许可证:Apache 2.0
Istio 是 IBM、Google 和 Lyft 的联合开发项目,它是一个全面的服务网格解决方案——不仅可以管理所有传入的外部流量(作为 Ingress 控制器),还可以控制集群内部的所有流量。
Istio 将 Envoy 用作每种服务的辅助代理。从本质上讲,它是一个可以执行几乎所有操作的大型处理器,其中心思想是最大程度的控制、可扩展性、安全性和透明性。
通过 Istio Ingress,你可以对流量路由、服务之间的访问授权、均衡、监控、金丝雀发布等进行优化。9)Ambassador
http://github.com/datawire/ambassador
实现:Python
许可证:Apache 2.0
Ambassador 也是一个基于 Envoy 的解决方案,它有免费版和商业版两个版本。
Ambassador 被称为“Kubernetes 原生 API 微服务网关”,它与 K8s 原语紧密集成,拥有你所期望的从 Ingress controller 获得的功能包,它还可以与各种服务网格解决方案,如 Linkerd、Istio 等一起使用。
顺便提一下,Ambassador 博客日前发布了一份基准测试结果,比较了 Envoy、HAProxy 和 NGINX 的基础性能。10)Gloo
http://github.com/solo-io/gloo
实现:Go
许可证:Apache 2.0
Gloo 是在 Envoy 之上构建的新软件(于 2018 年 3 月发布),由于它的作者坚持认为“网关应该从功能而不是服务中构建 API”,它也被称为“功能网关”。其“功能级路由”的意思是它可以为后端实现是微服务、无服务器功能和遗留应用的混合应用路由流量。
由于拥有可插拔的体系结构,Gloo 提供了工程师期望的大部分功能,但是其中一些功能仅在其商业版本(Gloo Enterprise)中可用。11)Skipper
http://github.com/zalando/skipper
实现:Go
许可证:Apache 2.0
Skipper 是 HTTP 路由器和反向代理,因此不支持各种协议。从技术上讲,它使用 Endpoints API(而不是 Kubernetes Services)将流量路由到 Pod。它的优点在于其丰富的过滤器集所提供的高级 HTTP 路由功能,工程师可以借此创建、更新和删除所有 HTTP 数据。
Skipper 的路由规则可以在不停机的情况下更新。正如它的作者所述,Skipper 可以很好地与其他解决方案一起使用,比如 AWS ELB。

(4)工作原理

1)ingress-controller通过和 kubernetes APIServer 交互,动态的去感知集群中ingress规则变化,2)然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置,3)再写到nginx-ingress-controller的pod里,这个ingress-controller的pod里运行着一个Nginx服务,控制器会把生成的 nginx配置写入 /etc/nginx.conf文件中,4)然后reload一下使配置生效。以此达到域名区分配置和动态更新的作用。

(5)暴露服务的方式

​​​​​​​

方式一:Deployment+LoadBalancer 模式的 Service
如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个 type为 LoadBalancer 的 service 关联这组 pod。大部分公有云,都会为 LoadBalancer 的 service 自动创建一个负载均衡器,通常还绑定了公网地址。 只要把域名解析指向该地址,就实现了集群服务的对外暴露方式二:DaemonSet+HostNetwork+nodeSelector
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。 比较适合大并发的生产环境使用。方式三:Deployment+NodePort模式的Service
同样用deployment模式部署ingress-controller,并创建对应的service,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。

(6)ingressClassName

ingressClassName 指定 IngressClass,用来指定选择的 Ingress Controller

host 主机名可以是精确匹配,或者使用通配符来匹配,但通配符仅覆盖一个 DNS 标签(例如 *.foo.com 不匹配 baz.bar.foo.com)。pathType 支持的路径类型有三种:

●Exact:精确匹配 URL 路径,且区分大小写。●Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写。如果路径的最后一个元素是请求路径中最后一个元素的子字符串,则不会匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。●ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。具体实现可以将其作为单独的 pathType 处理或者与 Prefix 或 Exact 类型作相同处理。

(7)排错思路

2.部署 nginx-ingress-controller(第一种方式)

(1)部署ingress-controller pod及相关资源

mkdir /opt/ingress
cd /opt/ingress官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.25.0/deploy/static/mandatory.yaml上面可能无法下载,可用国内的 gitee
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.25.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml#mandatory.yaml文件中包含了很多资源的创建,包括namespace、ConfigMap、role,ServiceAccount等等所有部署ingress-controller需要的资源。

(2)修改 ClusterRole 资源配置

vim mandatory.yaml
......
apiVersion: rbac.authorization.k8s.io/v1beta1
#RBAC相关资源从1.17版本开始改用rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1在1.22版本即将弃用
kind: ClusterRole
metadata:name: nginx-ingress-clusterrolelabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
rules:- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ""resources:- nodesverbs:- get- apiGroups:- ""resources:- servicesverbs:- get- list- watch- apiGroups:- "extensions"- "networking.k8s.io"# (0.25版本)增加 networking.k8s.io Ingress 资源的 api resources:- ingressesverbs:- get- list- watch- apiGroups:- ""resources:- eventsverbs:- create- patch- apiGroups:- "extensions"- "networking.k8s.io"# (0.25版本)增加 networking.k8s.io/v1 Ingress 资源的 api resources:- ingresses/statusverbs:- update

(3)指定 nginx-ingress-controller 运行在 node02 节点

采用方式:DaemonSet+HostNetwork+nodeSelector

kubectl label node node02 ingress=truekubectl get nodes --show-labels

(4)修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络

vim mandatory.yaml...
apiVersion: apps/v1
# 修改 kind# kind: Deployment
kind: DaemonSet
metadata:name: nginx-ingress-controllernamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
spec:
# 删除Replicas# replicas: 1selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxannotations:prometheus.io/port: "10254"prometheus.io/scrape: "true"spec:# 使用主机网络hostNetwork: true# 选择节点运行nodeSelector:ingress: "true"serviceAccountName: nginx-ingress-serviceaccount
......

(5)在所有 node 节点上传 nginx-ingress-controller 镜像压缩包 ingree.contro.tar.gz 到/opt/ingress 目录,并解压和加载镜像

cd /opt/ingress
tar zxvf ingree.contro.tar.gz
docker load -i ingree.contro.tar

(6)启动 nginx-ingress-controller

kubectl apply -f mandatory.yaml#nginx-ingress-controller 已经运行 node02 节点
kubectl get pod -n ingress-nginx -o widekubectl get cm,daemonset -n ingress-nginx -o wide

到 node02 节点查看

netstat -lntp | grep nginx

由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了。如果要 nginx 高可用的话,可以在多个 node上部署,并在前面再搭建一套 LVS+keepalived 做负载均衡。
 

(7)创建 ingress 规则

创建一个 deploy 和 svc

vim service-nginx.yamlapiVersion: apps/v1
kind: Deployment
metadata:name: nginx-app
spec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-app-svc
spec:type: ClusterIPports:- protocol: TCPport: 80targetPort: 80selector:app: nginx

创建 ingress

用的是方法二

#方法一:(extensions/v1beta1 Ingress 在1.22版本即将弃用)
vim ingress-app.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: nginx-app-ingress
spec:rules:- host: www.david.comhttp:paths:- path: /backend:serviceName: nginx-app-svcservicePort: 80#方法二:(1.14-1.18版本)
​vim ingress-app.yaml	
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-app-ingress
# namespace: ingress-nginx
spec:rules:- host: www.david.comhttp:paths:- path: /backend:serviceName: nginx-app-svcservicePort: 80​#方法三:(1.19版本以上)
vim ingress-app.yaml	  
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-app-ingress
spec:rules:- host: www.david.comhttp:paths:- path: /pathType: Prefixbackend:service:name: nginx-app-svcport:number: 80

生成pod并查看信息

kubectl apply -f service-nginx.yamlkubectl apply -f ingress-app.yamlkubectl get podskubectl get ingress

(8)测试访问

地 host 添加域名解析

vim /etc/hosts
192.168.204.171 master
192.168.204.173 node01
192.168.204.175 node02
192.168.204.176 hub.david.com
192.168.204.177 stor01
192.168.204.175 www.david.com     #新增

回到master测试网页

curl www.david.com

(9) 查看 nginx-ingress-controller

kubectl get pod -n ingress-nginx -o widekubectl exec -it nginx-ingress-controller-wrs7f  -n ingress-nginx /bin/bash
kubectl get pod -n ingress-nginx -o widekubectl exec -it nginx-ingress-controller-p7tdq -n ingress-nginx /bin/bash

可以看到从 start server www.david.com 到 end server www.david.com 之间包含了此域名用于反向代理的配置

more /etc/nginx/nginx.conf
……## start server www.david.comserver {server_name www.david.com ;listen 80  ;listen 443  ssl http2 ;set $proxy_upstream_name "-";ssl_certificate_by_lua_block {certificate.call()}location / {set $namespace      "ingress-nginx";set $ingress_name   "nginx-app-ingress";set $service_name   "nginx-app-svc";set $service_port   "80";set $location_path  "/";rewrite_by_lua_block {lua_ingress.rewrite({force_ssl_redirect = false,ssl_redirect = true,force_no_ssl_redirect = false,use_port_in_redirects = false,})balancer.rewrite()plugins.run()}# be careful with `access_by_lua_block` and `satisfy any` directives as satisfy any# will always succeed when there's `access_by_lua_block` that does not have any lua code doing `ngx.exit(ngx.DECLINED)`# other authentication method such as basic auth or external auth useless - all requests will be allowed.#access_by_lua_block {#}header_filter_by_lua_block {lua_ingress.header()plugins.run()}body_filter_by_lua_block {}log_by_lua_block {balancer.log()monitor.call()plugins.run()}port_in_redirect off;set $balancer_ewma_score -1;set $proxy_upstream_name "ingress-nginx-nginx-app-svc-80";set $proxy_host          $proxy_upstream_name;set $pass_access_scheme  $scheme;set $pass_server_port    $server_port;set $best_http_host      $http_host;set $pass_port           $pass_server_port;set $proxy_alternative_upstream_name "";client_max_body_size                    1m;proxy_set_header Host                   $best_http_host;# Pass the extracted client certificate to the backend# Allow websocket connectionsproxy_set_header                        Upgrade           $http_upgrade;proxy_set_header                        Connection        $connection_upgrade;proxy_set_header X-Request-ID           $req_id;proxy_set_header X-Real-IP              $remote_addr;proxy_set_header X-Forwarded-For        $remote_addr;proxy_set_header X-Forwarded-Host       $best_http_host;proxy_set_header X-Forwarded-Port       $pass_port;proxy_set_header X-Forwarded-Proto      $pass_access_scheme;proxy_set_header X-Scheme               $pass_access_scheme;# Pass the original X-Forwarded-Forproxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;# mitigate HTTPoxy Vulnerability# https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/proxy_set_header Proxy                  "";# Custom headers to proxied serverproxy_connect_timeout                   5s;proxy_send_timeout                      60s;proxy_read_timeout                      60s;proxy_buffering                         off;proxy_buffer_size                       4k;proxy_buffers                           4 4k;proxy_max_temp_file_size                1024m;proxy_request_buffering                 on;proxy_http_version                      1.1;proxy_cookie_domain                     off;proxy_cookie_path                       off;# In case of errors try the next upstream server before returning an errorproxy_next_upstream                     error timeout;proxy_next_upstream_timeout             0;proxy_next_upstream_tries               3;proxy_pass http://upstream_balancer;proxy_redirect                          off;}}## end server www.david.com
……

3.部署 nginx-ingress-controller(第二种方式)

采用方式:Deployment+NodePort模式的Service

(1)下载 nginx-ingress-controller 和 ingress-nginx 暴露端口配置文件

mkdir /opt/ingress-nodeport
cd /opt/ingress-nodeport官方下载地址:
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml国内 gitee 资源地址:
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml

(2)在所有 node 节点上传镜像包 ingress-controller-0.30.0.tar 到 /opt/ingress-nodeport 目录,并加载镜像

mkdir -p /opt/ingress-nodeport
cd /opt/ingress-nodeporttar zxvf ingree.contro-0.30.0.tar.gz
docker load -i ingree.contro-0.30.0.tar

(3)启动 nginx-ingress-controller

kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml

(4)Ingress HTTP 代理访问

创建 deployment、Service、Ingress Yaml 资源

k8s v1.14-1.18版本

vim ingress-nginx.yaml apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-myapp
spec:replicas: 2selector:matchLabels:name: nginxtemplate:metadata:labels:name: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:ports:- port: 80targetPort: 80protocol: TCP selector:name: nginx
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-test
spec:rules:- host: www.long.comhttp:paths:- path: /backend:serviceName: nginx-svcservicePort: 80

k8s v1.19版本以上:

vim ingress-nginx.yaml apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-myapp
spec:replicas: 2selector:matchLabels:name: nginxtemplate:metadata:labels:name: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-test
spec:rules:- host: www.long.comhttp:paths:- path: /pathType: Prefixbackend:service: name: nginx-svcport:number: 80
kubectl get pods,svc -o wide
#进入容器1
[root@master ingress-nodeport]# kubectl exec -it pod/nginx-myapp-65d7b99f6b-jpv5p bash
root@nginx-myapp-65d7b99f6b-jpv5p:/# cd /usr/share/nginx/html/
root@nginx-myapp-65d7b99f6b-jpv5p:/usr/share/nginx/html# echo 'this is mao' >> index.html
root@nginx-myapp-65d7b99f6b-jpv5p:/usr/share/nginx/html# cat index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
this is mao
root@nginx-myapp-65d7b99f6b-jpv5p:/usr/share/nginx/html# exit
exit
#进入容器2
[root@master ingress-nodeport]# kubectl exec -it pod/nginx-myapp-65d7b99f6b-pwv2h  bash
root@nginx-myapp-65d7b99f6b-pwv2h:/# cd /usr/share/nginx/html/
root@nginx-myapp-65d7b99f6b-pwv2h:/usr/share/nginx/html# echo 'this is long' >> index.html
root@nginx-myapp-65d7b99f6b-pwv2h:/usr/share/nginx/html# cat index.html 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
this is long
root@nginx-myapp-65d7b99f6b-pwv2h:/usr/share/nginx/html# exit
exit
[root@master ingress-nodeport]# 

(5)测试访问

curl 10.1.73.104kubectl get svc -n ingress-nginx
vim /etc/hosts
192.168.204.171 master
192.168.204.173 node01
192.168.204.175 node02
192.168.204.176 hub.david.com
192.168.204.177 stor01
#添加域名解析
192.168.204.173 www.long.com
192.168.204.175 www.long.com#外部访问
curl http://www.long.com:30778

(6)  Ingress HTTP 代理访问虚拟主机

mkdir /opt/ingress-nodeport/vhost
cd /opt/ingress-nodeport/vhost#创建虚拟主机1资源
vim deployment1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: deployment1
spec:replicas: 2selector:matchLabels:name: nginx1template:metadata:labels:name: nginx1spec:containers:- name: nginx1image: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: svc-1
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx1kubectl apply -f deployment1.yaml
#创建虚拟主机2资源
vim deployment2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: deployment2
spec:replicas: 2selector:matchLabels:name: nginx2template:metadata:labels:name: nginx2spec:containers:- name: nginx2image: soscscs/myapp:v2imagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: svc-2
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx2kubectl apply -f deployment2.yaml

k8s v1.14-1.18版本:

#创建ingress资源
vim ingress-nginx.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: ingress1
spec:rules:- host: www1.mao.comhttp:paths:- path: /backend:serviceName: svc-1servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: ingress2
spec:rules:- host: www2.mao.comhttp:paths:- path: /backend:serviceName: svc-2servicePort: 80kubectl apply -f ingress-nginx.yaml

k8s v1.19版本以上:

#创建ingress资源
vim ingress-nginx.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress1
spec:rules:- host: www1.mao.comhttp:paths:- path: /pathType: Prefixbackend:service: name: svc-1port:number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress2
spec:rules:- host: www2.mao.comhttp:paths:- path: /pathType: Prefixbackend:service: name: svc-2port:number: 80kubectl apply -f ingress-nginx.yaml

(7)  测试访问

kubectl get svc -n ingress-nginx#做主机映射
vim /etc/hostscurl www1.david.com:31751curl www2.david.com:31751

(8)  Ingress HTTPS 代理访问

mkdir /opt/ingress-nodeport/https
cd /opt/ingress-nodeport/https

 创建ssl证书

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

创建 secret 资源进行存储

kubectl create secret tls tls-secret --key tls.key --cert tls.crt
kubectl get secret
kubectl describe secret tls-secret

创建 deployment、Service、Ingress Yaml 资源

k8s v1.14-1.18版本

vim ingress-https.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-app
spec:replicas: 2selector:matchLabels:name: nginxtemplate:metadata:labels:name: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-https
spec:tls:- hosts:- www3.long.comsecretName: tls-secretrules:- host: www3.long.comhttp:paths:- path: /backend:serviceName: nginx-svcservicePort:80kubectl apply -f ingress-https.yaml

k8s v1.19版本以上:

vim ingress-https.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-app
spec:replicas: 2selector:matchLabels:name: nginxtemplate:metadata:labels:name: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: nginx-svc
spec:ports:- port: 80targetPort: 80protocol: TCPselector:name: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-https
spec:tls:- hosts:- www3.long.comsecretName: tls-secretrules:- host: www3.long.comhttp:paths:- path: /pathType: Prefixbackend:service: name: nginx-svcport:number: 80kubectl apply -f ingress-https.yaml

master添加域名

vim /etc/hosts192.168.204.171 master
192.168.204.173 node01
192.168.204.175 node02
192.168.204.176 hub.david.com
192.168.204.177 stor01
192.168.204.173 www.long.com
192.168.204.175 www.long.com
192.168.204.173 www1.mao.com
192.168.204.175 www2.mao.com
#新增下面域名
192.168.204.173 www3.long.com
192.168.204.175 www3.long.com

浏览器测试:

https://www3.long.com:32640/

(9) Nginx 进行 BasicAuth

mkdir /opt/ingress-nodeport/basic-auth
cd /opt/ingress-nodeport/basic-auth

生成用户密码认证文件,创建 secret 资源进行存储

yum -y install httpd
htpasswd -c auth mao			#认证文件名必须为 auth
kubectl create secret generic basic-auth --from-file=auth
kubectl get secrets
kubectl describe secrets basic-auth

创建 ingress 资源

k8s v1.14-1.18版本

vim ingress-auth.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: ingress-authannotations:#设置认证类型basicnginx.ingress.kubernetes.io/auth-type: basic#设置secret资源名称basic-authnginx.ingress.kubernetes.io/auth-secret: basic-auth#设置认证窗口提示信息nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - mao'
spec:rules:- host: auth.mao.comhttp:paths:- path: /backend:serviceName: nginx-svcservicePort: 80//具体详细设置方法可参考官网https://kubernetes.github.io/ingress-nginx/examples/auth/basic/

k8s v1.19版本以上:

vim ingress-auth.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-authannotations:#设置认证类型basicnginx.ingress.kubernetes.io/auth-type: basic#设置secret资源名称basic-authnginx.ingress.kubernetes.io/auth-secret: basic-auth#设置认证窗口提示信息nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - mao'
spec:rules:- host: auth.mao.comhttp:paths:- path: /pathType: Prefixbackend:service: name: nginx-svcport:number: 80//具体详细设置方法可参考官网https://kubernetes.github.io/ingress-nginx/examples/auth/basic/

访问测试

kubectl apply -f ingress-auth.yaml
kubectl get svc -n ingress-nginx
echo'192.168.204.173 auth.mao.com' >> /etc/hosts
echo'192.168.204.175 auth.mao.com' >> /etc/hosts浏览器访问:http://auth.mao.com:30778
输入账户mao和密码

(10) Nginx 进行重写

metadata.annotations 配置说明

nginx.ingress.kubernetes.io/rewrite-target: <字符串> #必须重定向流量的目标URI
nginx.ingress.kubernetes.io/ssl-redirect: <布尔值> #指示位置部分是否仅可访问SSL(当Ingress包含证书时,默认为true)
nginx.ingress.kubernetes.io/force-ssl-redirect: <布尔值> #即使Ingress未启用TLS,也强制重定向到HTTPS
nginx.ingress.kubernetes.io/app-root: <字符串> #定义Controller必须重定向的应用程序根,如果它在'/'上下文中
nginx.ingress.kubernetes.io/use-regex: <布尔值> #指示Ingress上定义的路径是否使用正则表达式

编写ingress-rewrite.yaml

k8s v1.14-1.18版本

vim ingress-rewrite.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: nginx-rewriteannotations:nginx.ingress.kubernetes.io/rewrite-target: http://www1.mao.com:30778
spec:rules:- host: re.mao.comhttp:paths:- path: /backend:#由于re.mao.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义serviceName: nginx-svcservicePort: 80

k8s v1.19版本以上:

vim ingress-rewrite.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: nginx-rewriteannotations:nginx.ingress.kubernetes.io/rewrite-target: http://www1.mao.com:30778
spec:rules:- host: re.mao.comhttp:paths:- path: /pathType: Prefixbackend:#由于re.mao.com只是用于跳转不需要真实站点存在,因此svc资源名称可随意定义service: name: nginx-svcport:number: 80

访问测试

kubectl apply -f ingress-rewrite.yaml
echo'192.168.204.173 re.mao.com' >> /etc/hosts
echo'192.168.204.175 re.mao.com' >> /etc/hosts浏览器访问:http://re.mao.com:30778

二、实验

1.部署 nginx-ingress-controller(第一种方式)

(1)部署ingress-controller pod及相关资源

(2)修改 ClusterRole 资源配置

(3)指定 nginx-ingress-controller 运行在 node02 节点

采用方式二:DaemonSet+HostNetwork+nodeSelector

(4)修改 Deployment 为 DaemonSet ,指定节点运行,并开启 hostNetwork 网络

再次修改配置文件

修改 kind为DaemonSet

注释 replicas: 1

使用主机网络hostNetwork: true

选择节点运行ingress: "true"

(5)在所有 node 节点上传 nginx-ingress-controller 镜像压缩包 ingree.contro.tar.gz 到/opt/ingress 目录,并解压和加载镜像

(6)启动 nginx-ingress-controller

nginx-ingress-controller 已经运行 node02 节点

到 node02 节点查看

由于配置了 hostnetwork,nginx 已经在 node 主机本地监听 80/443/8181 端口。其中 8181 是 nginx-controller 默认配置的一个 default backend(Ingress 资源没有匹配的 rule 对象时,流量就会被导向这个 default backend)。这样,只要访问 node 主机有公网 IP,就可以直接映射域名来对外网暴露服务了。如果要 nginx 高可用的话,可以在多个 node上部署,并在前面再搭建一套 LVS+keepalived 做负载均衡。
 

(7)创建 ingress 规则

创建一个 deploy 和 svc

创建 ingress

用的是方法二

k8s v1.14-1.18版本

k8s v1.19版本以上:

生成pod并查看信息

(8)测试访问

给node2节点的host 添加域名解析

回到master测试网页

(9) 查看 nginx-ingress-controller

可以看到从 start server www.david.com 到 end server www.david.com 之间包含了此域名用于反向代理的配置

2.部署 nginx-ingress-controller(第二种方式)

采用方式三:Deployment+NodePort模式的Service

(1)下载 nginx-ingress-controller 和 ingress-nginx 暴露端口配置文件

(2)在所有 node 节点上传镜像包 ingress-controller-0.30.0.tar 到 /opt/ingress-nodeport 目录,并加载镜像

node01

node02

(3)启动 nginx-ingress-controller

service-nodeport.yaml

(4)Ingress HTTP 代理访问

创建 deployment、Service、Ingress Yaml 资源

k8s v1.14-1.18版本

k8s v1.19版本以上:

生成资源

进入容器1

进入容器2

(5)测试访问

添加域名地址

测试网页,会轮巡显示

(6)  Ingress HTTP 代理访问虚拟主机

创建虚拟主机1资源

创建虚拟主机2资源

创建ingress资源

k8s v1.14-1.18版本

k8s v1.19版本以上:

生成资源

(7)  测试访问

做主机映射

测试网页

(8)  Ingress HTTPS 代理访问

 创建ssl证书

创建 secret 资源进行存储

创建 deployment、Service、Ingress Yaml 资源

k8s v1.14-1.18版本:

k8s v1.19版本以上:

生成资源

浏览器测试

(9) Nginx 进行 BasicAuth

生成用户密码认证文件,创建 secret 资源进行存储

创建 ingress 资源

k8s v1.14-1.18版本:

k8s v1.19版本以上:

访问测试

添加域名

 

输入账号密码

访问

(10) Nginx 进行重写

编写ingress-rewrite.yaml

k8s v1.14-1.18版本:

k8s v1.19版本以上:

新增域名

访问测试

显示已重定向

三、问题

1.启动 nginx-ingress-controller报错

  (1)  报错

(2)原因分析

配置文件错误

(3)解决方法

修改配置文件

修改前:

修改后:

成功:

2.容器探针失败

(1)报错

(2)原因分析

配置文件错误

(3)解决方法

修改配置文件

修改前:

修改后:

成功:

3.生成pod报错

(1)报错

(2)原因分析

查看 kubernetes 官方文档:https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/、https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/ 和 ingress-nginx 官方文档: https://kubernetes.github.io/ingress-nginx/,其中有下面这两段话

kubernetes官网:

The v1.22 release will stop serving the following deprecated API versions in favor of newer and more stable API versions:Ingress in the extensions/v1beta1 API version will no longer be served
Migrate to use the networking.k8s.io/v1beta1 API version, available since v1.14. Existing persisted data can be retrieved/updated via the new version.

自从 Kubernetes v1.14 版本开始 Ingress 资源才被加入到 networking.k8s.io/v1beta1 这个v1beta1 版本中来,至于什么时候开始这个 networking.k8s.io/v1beta1 这个beta版本变成了稳定版本,可以看这里,也就是说到了 kubernetes v1.19 版本,Ingress 资源才被加入到 networking.k8s.io/v1 这个版本中来。
 Ingress 在 k8s 各个版本中所处的 apiVersion 做一个归纳:

(3)解决方法

修改前:

修改后:

把yaml 文件中的 networking.k8s.io/v1 修改为 networking.k8s.io/v1beta1 ,又发生了如下的错误:

也就是说在这个 networking.k8s.io/v1beta1 这个 apiVersion 版本下, 我们ingress 的yaml 里,有些 field 字段是不存在的,比如: service等

成功:

4.获取ingress失败

(1)报错

(2)原因分析

创建ingess指定了namespace

(3)解决方法

修改配置文件,删除namespace

修改前:

修改后:

成功:

5.Ingress和Ingress Controller关系

(1)Ingress

Ingress 就是定义路由规则:从集群外部-->集群内部的HTTP和HTTPS的路由规则。

(2)Ingress Controller

一方面:ingress controller正如其名一样是控制管理(control)ingress资源的一个应用,当在集群中(任意namespce下)部署了一个ingress,ingress controller会捕获到该ingress资源,然后根据一定规则配置到对应的内部组件上。其常用的内部组件是nginx。

另一方面,从nginx角度看,ingress controller也是一种反向代理,外部请求,通过ingress controller,获取集群中的ingress资源(通过kind:ingress配置),根据其url规则,转发到不同的service上(类比nginx和nginx.conf配置文件)。

四、总结

ingress是k8s集群的请求入口,可以理解为对多个service的再次抽象;

通常说的ingress一般包括ingress资源对象及ingress-controller两部分组成;

ingress-controller有多种实现,社区原生的是ingress-nginx,根据具体需求选择;

ingress自身的暴露有多种方式,需要根据基础环境及业务类型选择合适的方式。
 

ingress controller可以为外网用户访问K8S集群内部pod提供代理服务。

1)提供全局访问代理2)访问流程:用户–>ingress controller–>service–>pod

ingress-controller作用

ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到 ingress-controller, 而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名、哪些URL要转发到哪些service等等。Ingress Controller 的重大作用是将前端负载均衡器和 Kubernetes 完美地结合了起来,一方面在云、容器平台下方便配置的管理,另一方面实现了集群统一的流量入口,而不是像 nodePort 那样给集群打多个孔。

 ingress部署

要使用 Ingress,得先部署 Ingress Controller 实体(相当于前端 Nginx),然后再创建 Ingress (相当于 Nginx 配置的 k8s 资源体现),Ingress Controller 部署好后会动态检测 Ingress 的创建情况生成相应配置。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Selenium Web自动化测试 —— 高级控件交互方法!

一、使用场景 使用场景对应事件复制粘贴键盘事件拖动元素到某个位置鼠标事件鼠标悬停鼠标事件滚动到某个元素滚动事件使用触控笔点击触控笔事件&#xff08;了解即可&#xff09; https://www.selenium.dev/documentation/webdriver/actions_api 二、ActionChains解析 实例…

iOS自动化测试方案(一):MacOS虚拟机保姆级安装Xcode教程

文章目录 一、环境准备二、基础软件三、扩展&#xff1a;usb拓展插件 一、环境准备 1、下载VMware虚拟机的壳子&#xff0c;安装并注册软件(可以百度注册码)&#xff0c;最新版本&#xff1a;v17 2、下MacOS系统iOS镜像文件&#xff0c;用于vmware虚拟机安装&#xff0c;当前镜…

油猴(篡改猴)学习记录

第一个Hello World 注意点:默认只匹配了http网站,如果需要https网站,需要自己添加match https://*/*代码如下 这样子访问任意网站就可以输出Hello World // UserScript // name 第一个脚本 // namespace http://tampermonkey.net/ // version 0.1 // descri…

ElasticSearch(二)

1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数据&#xff0c;…

钢轨长度及允许偏差

声明 本文是学习GB-T 2585-2021 铁路用热轧钢轨. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了铁路用钢轨的订货内容、分类、尺寸、外形、质量及允许偏差、技术要求、试验方法、检 验规则、标志及质量证明书。 本标准适用于3…

MySQL ——多表连接查询

一、&#xff08;左、右和全&#xff09;连接概念 内连接&#xff1a; 假设A和B表进行连接&#xff0c;使用内连接的话&#xff0c;凡是A表和B表能够匹配上的记录查询出来。A和B两张表没有主付之分&#xff0c;两张表是平等的。 关键字&#xff1a;inner join on 语句&#xf…

css实现Chrome标签栏

如图这是一个特殊的带有圆角的导航栏&#xff0c;实现这种效果并不难 这是我实现的效果&#xff1a; 淡一点的就是鼠标悬停的样式 以下是代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><m…

分类预测 | MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结合支持向量机分类预测

分类预测 | MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结合支持向量机分类预测 目录 分类预测 | MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结合支持向量机分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结…

使用 PyTorch 的计算机视觉简介 (3/6)

一、说明 在本单元中&#xff0c;我们将了解卷积神经网络&#xff08;CNN&#xff09;&#xff0c;它是专门为计算机视觉设计的。 卷积层允许我们从图像中提取某些图像模式&#xff0c;以便最终分类器基于这些特征。 二、卷积神经网络 计算机视觉不同于通用分类&#xff0c;因…

echarts 地图 visualMap 图例点击事件监听

一、切换位置 二、切换监听 // 切换事件监听 this.myChart.off(datarangeselected); // 为了不触发两次 this.myChart.on(datarangeselected,(e) > {// visualMap change });// 配置如下 visualMap: {type: piecewise,showLabel: true,inverse: true,pieces: [{value: 1,…

为什么大力推行国密算法SSL证书

国密算法SSL证书是一种采用我国自主研发的SM2公钥算法体系&#xff0c;支持SM2、SM3、SM4等国产密码算法及国密SSL安全协议的数字证书。相比于普通SSL证书&#xff0c;国密SSL证书具有以下特点&#xff1a; 自主可控&#xff1a;国密SSL证书采用我国自主研发的SM2公钥算法体系&…

STM32实现PMBus从机程序

最近在野火的STM32F103VET6开发板上实现PMBus从机程序&#xff0c;这个程序参考了以下这篇博客的关于使用中断法实现I2C从机程序&#xff1a;STM32设置为I2C从机模式_iic从机_柒壹漆的博客-CSDN博客 &#xff0c;实测这个程序是可以正常运行的&#xff0c;感谢博主的分享&#…

对标8155体验,降本20%以上!这家企业用“量产”证明

智能座舱逐渐成为智能汽车标配。 根据高工智能汽车研究院监测的数据显示&#xff0c;2022年中国市场&#xff08;不含进出口&#xff09;乘用车搭载智能数字座舱&#xff08;大屏语音车联网OTA&#xff09;前装标配交付795.05万辆&#xff0c;同比增长40.59%&#xff0c;前装搭…

[python 刷题] 84 Largest Rectangle in Histogram

[python 刷题] 84 Largest Rectangle in Histogram 题目&#xff1a; Given an array of integers heights representing the histogram’s bar height where the width of each bar is 1, return the area of the largest rectangle in the histogram. 这题也是一个典型的 mo…

微调大型语言模型(一):为什么要微调(Why finetune)?

今天我们来学习Deeplearning.ai的在线课程 微调大型语言模型(一)的第一课&#xff1a;为什么要微调(Why finetune)。 我们知道像GPT-3.5这样的大型语言模型(LLM)它所学到的知识截止到2021年9月&#xff0c;那么如果我们向ChatGPT询问2022年以后发生的事情&#xff0c;它可能会…

diff算法面试题

面试题&#xff1a;请阐述vue的diff算法 参考回答&#xff1a; 当组件创建和更新时&#xff0c;vue均会执行内部的update函数&#xff0c;该函数使用render函数生成的虚拟dom树&#xff0c;将新旧两树进行对比&#xff0c;找到差异点&#xff0c;最终更新到真实dom 对比差异的过…

轻松上手Docker:学习如何创建和运行自己的Docker容器

文章目录 轻松上手Docker&#xff1a;学习如何创建和运行自己的Docker容器容器的介绍Docker的技术架构容器的工作机制&#xff08;Docker&#xff09;容器的关键技术 - NamespaceNamespace隔离说明 容器的关键技术 - CgroupDocker环境搭建1&#xff09;安装基础软件包2&#xf…

python安全工具开发笔记(四)——python网络编程

一、C/S架构 什么是C/S架构 C : Client S : Server。客户机和服务器结构。 Server 唯一的目的就是等待Client 的请求&#xff0c;Client 连上 Server 发送必要的数据&#xff0c;然后等待Server端完成请求的反馈。 C/S网络编程 Server端进行设置&#xff0c;首先创建一个通信…

【unity2023打包安卓工程】踩坑记录

这里写自定义目录标题 踩坑记录使用环境Unity的准备工作Windows10 SDKAndroidstudio第一个需要注意的地方第二个需要注意的地方第三个需要注意的地方第四个需要注意的地方第五个需要注意的地方第六个需要注意的 其他unity启动缓慢 更新更新一 2023.9.27 踩坑记录 踩了快一个星期…

codesys【虚轴】

1概述&#xff1a;codesys里有3个轴&#xff1a; 自由编码器&#xff0c;虚轴&#xff0c;实轴。 流程&#xff1a;【高速输入&#xff1a;采集AB脉冲】带》【自由编码器】带》【虚轴】带》【实轴】 1虚轴&#xff1a; 用法和实轴一样。 一般用于&#xff0c;一拖多。 2编…