CKA认证 | Day6 K8s网络
第六章 Kubernetes网络
1、Service 控制器
在 Kubernetes (K8S) 中,Service 控制器 是一个关键组件,负责管理 Kubernetes 服务的生命周期和实现其功能。Service 控制器确保服务能够正确地将流量路由到后端 Pod,并处理服务的负载均衡和 DNS 解析。
1.1 Service存在的意义
Service 引入主要是解决Pod的动态变化,提供统一访问入口:
- 定义一组Pod的访问策略(负载均衡)
- Pod的生存周期是短暂的动态的,在重建或增加的情况下,Service为了防止Pod失联,动态感知Pod的变化获取最新的IP,找到提供同一个服务的Pod(服务发现)
Service 控制器的主要职责包括:
- 负载均衡: 将流量分发到后端 Pod
- DNS 解析: 提供 DNS 名称解析,使得服务可以通过名称被其他服务或应用访问
- IP 管理: 确保 Service 拥有一个稳定的 IP 地址
- 健康检查: 监控后端 Pod 的健康状态,确保流量只被发送到健康的 Pod
1.2 Pod与Service的关系
Service 通过标签选择器(Label Selector)来选择一组 Pod。标签选择器定义了一组键值对,Service 会根据这些键值对来匹配具有相应标签的 Pod。
- Service 通过 标签 关联一组Pod(selector)
- Service 为一组Pod提供负载均衡能力
1.3 Service定义与创建
前提:之前创建Service是基于Deployment控制器,如:kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
- Kubectl expose 基于已有的Deployment创建service
- kubectl create service 可以直接创建service,不需要基于Deployment
1)创建service:
- 命令:kubectl create service --tcp=port:port
kubectl create service clusterip web --tcp=80:80
2)生成YAML:
kubectl create service clusterip web --tcp=80:80 --dry-run=client -o yaml > clusterip-web.yaml
3)定义 service:
apiVersion: v1
kind: Service
metadata:name: web
spec:type: ClusterIP # 服务类型ports:- name: 80-80port: 80 # Service端口,统一的内部访问端口protocol: TCP # 协议targetPort: 80 # 容器端口(应用程序监听端口)selector: app: web # 指定关联Pod的标签
4)查看 service:
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEweb ClusterIP 10.110.27.138 <none> 80/TCP 6s
测试:Cluster IP类型 Service 内部集群访问
# 由于是直接创建的Service,没有相关的Pod进行关联
[root@k8s-master-1-71 ~]# kubectl get ep
NAME ENDPOINTS AGEweb <none> 10s //相关endpoints为空# 需创建标签相同的Pod与Service进行关联
[root@k8s-master-1-71 ~]# kubectl run web --image=nginx
[root@k8s-master-1-71 ~]# kubectl label pods web app=web --overwrite //定义标签(--overwrite覆盖)
[root@k8s-master-1-71 ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELSweb 1/1 Running 0 13m app=web,run=web
[root@k8s-master-1-71 ~]# kubectl get ep
NAME ENDPOINTS AGEweb 10.244.114.31:80 5m59s //相关endpoints已关联Pod# 将web作为后端,再创建一个bs作为前端进行测试
[root@k8s-master-1-71 ~]# kubectl run bs --image=busybox -- sleep 24h
[root@k8s-master-1-71 ~]# kubectl exec -it bs -- sh
/ # wget 10.110.27.138:80 //访问并下载web svc的默认首页
/ # cat index.html<title>Welcome to nginx!</title>
注意:由于镜像是周期性方式存在的,没有相关执行进程将会一直不断拉取镜像重启,而在创建busybox类似镜像时,需要通过加 sleep进行Hold住。
多端口Service定义:
对于某些服务,需要公开多个端口, Service也需要配置多个端口定义,通过端口名称区分。例如https服务:
apiVersion: v1
kind: Service
metadata:name: web
spec:type: ClusterIPports:- name: httpport: 80 protocol: TCPtargetPort: 80 //需转发80端口- name: httpsport: 443 protocol: TCP targetPort: 443 //需转发443端口selector: app: web
示例:
# 创建多镜像Pod,注意标签
[root@k8s-master-1-71 ~]# kubectl apply -f pod-mutil.yaml
apiVersion: v1
kind: Pod
metadata:labels:run: pod-mutilname: pod-mutil
spec:containers:- image: nginxname: web- image: tomcat:6name: api
[root@k8s-master-1-71 ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-mutil 2/2 Running 0 14m 10.244.114.33 k8s-node2-1-73 <none> <none># 创建多端口Service,注意标签
[root@k8s-master-1-71 ~]# kubectl apply -f clusterip-mutil.yaml
apiVersion: v1
kind: Service
metadata:name: clusterip-mutil
spec:ports:- name: 80-80port: 80protocol: TCPtargetPort: 80- name: 88-8080port: 88protocol: TCPtargetPort: 8080selector:run: pod-mutil //指定Pod的Labels标签type: ClusterIP[root@k8s-master-1-71 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
clusterip-mutil ClusterIP 10.111.231.50 <none> 80/TCP,88/TCP 4m34s
[root@k8s-master-1-71 ~]# kubectl get ep
NAME ENDPOINTS AGE
clusterip-mutil 10.244.114.33:8080,10.244.114.33:80 23m# 通过bs作为前端进行测试
[root@k8s-master-1-71 ~]# kubectl exec -it bs -- sh
/ # wget 10.111.231.50:80 -O web-index.html
/ # cat web-index.html
<title>Welcome to nginx!</title>
/ # wget 10.111.231.50:88 -O tomcat-index.html
/ # cat tomcat-index.html<a href="http://tomcat.apache.org/">
1.4 Service 三种类型
类型 | 描述 | 备注 |
Clusterlp | 集群内部使用 (Pod) | 仅集群内部访问,适用于内部服务发现和通信 |
NodePort | 对外暴露应用 (浏览器) | 通过节点端口从集群外部访问,适用于简单的外部访问需求 |
LoadBalancer | 对外暴露应用,适用公有云 | 通过云提供商的负载均衡器从集群外部访问,适用于生产环境和高可用性需求 |
注意:选择哪种 Service 类型取决于您的具体需求和部署环境。
1.4.1 ClusterIP
ClusterIP 是 Kubernetes 中默认的 Service 类型。它为 Service 分配一个仅在集群内部可访问的虚拟 IP 地址。这意味着只有集群内部的 Pod 和组件可以通过这个 IP 地址访问 Service。
特点:
- 仅集群内部访问:Service 只能在集群内部访问,不会暴露在集群外部。
- 负载均衡:Kubernetes 会自动在后端 Pod 之间进行负载均衡。
- 简单的内部通信:适用于集群内部的服务发现和通信。
使用场景:
- 当您只需要在集群内部访问服务时。
- 用于内部微服务之间的通信。
默认创建,会分配一个稳定的IP地址,即VIP(VirtualIP),只能在k8s集群内部进行访问,用于内部维护使用。示例配置:
apiVersion: v1
kind: Service
metadata:name: my-clusterip-service
spec:selector:app: my-appports:- protocol: TCPport: 80targetPort: 8080type: ClusterIP
1.4.2 NodePort
NodePort 通过在每个节点上打开一个特定的端口(称为 NodePort),将外部流量转发到 Service。NodePort 允许外部流量通过节点的 IP 地址和 NodePort 访问 Service。
特点:
- 外部访问:通过节点的 IP 地址和 NodePort 可以从集群外部访问 Service。
- 固定端口:NodePort 的范围通常是 30000-32767,但可以通过配置修改。
- 简单配置:适用于需要简单外部访问的场景。
- 访问地址:<任意NodeIP>:<NodePort>
- 默认端口范围:30000 - 32767
使用场景:
- 当您需要从集群外部访问服务,但没有负载均衡器时。
- 适用于简单的开发和测试环境。
在每个节点上启用一个端口来暴露服务,可以在集群 外部访问。也会分配一个稳定内部集群IP地址。示例配置:
apiVersion: v1
kind: Service
metadata:name: my-nodeport-service
spec:selector:app: my-appports:- protocol: TCPport: 80targetPort: 8080nodePort: 30007type: NodePort
结论:NodePort可字面理解为节点Port,用于外部访问集群内部使用。
负载均衡器:
NodePort 会在每台Node上监听端口接收用户流量,在实际情 况下,对用户暴露的只会有一个IP和端口,那这么多台Node该使 用哪台让用户访问呢? 这时就需要前面加一个公网负载均衡器为项目提供统一访问入口了。
1.4.3 LoadBalancer
LoadBalancer 类型的 Service 会自动在支持的云提供商(如 AWS、GCP、Azure 等)上创建一个外部负载均衡器。负载均衡器会将外部流量转发到 Service 的 Pod。
特点:
- 外部访问:通过负载均衡器的外部 IP 地址可以访问 Service。
- 自动配置:在支持的云提供商上自动创建和配置负载均衡器。
- 高可用性:通常提供高可用性和负载均衡功能。
使用场景:
- 当您需要从集群外部访问服务,并且希望利用云提供商的负载均衡功能时。
- 适用于生产环境,需要高可用性和负载均衡的场景。
与NodePort类似,在每个节点上启用一个端口来暴 露服务。除此之外,Kubernetes会请求底层云平台(例如阿里云、腾 讯云、AWS等)上的负载均衡器,将每个Node ([NodeIP]:[NodePort])作为后端添加进去。示例配置:
apiVersion: v1
kind: Service
metadata:name: my-loadbalancer-service
spec:selector:app: my-appports:- protocol: TCPport: 80targetPort: 8080type: LoadBalancer
1.5 Service 代理模式
Kubernetes 使用多种代理模式来实现 Service 的负载均衡和流量路由。以下是 Kubernetes 中常见的几种 Service 代理模式:
Service的底层实现主要有iptables和ipvs二种网络模式,决定了如何转发流量;而负责维护转发流量工作的组件则是Kube-proxy。
1.5.1 iptables
iptables 模式 是 Kubernetes 最早使用的 Service 代理模式。它通过修改节点上的 iptables 规则来实现负载均衡和流量路由。
工作原理:
- 当创建一个 Service 时,Kubernetes 会为该 Service 分配一个 ClusterIP。
- Kubernetes 会在每个节点上配置 iptables 规则,将流量从 Service 的 ClusterIP 和端口转发到后端 Pod 的 IP 和端口。
- 当客户端向 Service 的 ClusterIP 发送请求时,iptables 规则会根据负载均衡算法(如轮询)将请求转发到一个后端 Pod。
特点:
- 性能较好:iptables 规则在内核空间中处理,性能较高。
- 配置复杂:需要维护大量的 iptables 规则,配置相对复杂。
- 不支持某些高级功能:不支持基于 HTTP 的路由和负载均衡。
使用场景:
- 适用于需要高性能的场景。
- 适用于不需要基于 HTTP 的路由和负载均衡的场景。
# Pod和svc准备
[root@k8s-node1-1-72 ~]# kubectl create deployment web --image=nginx --replicas=3
[root@k8s-node1-1-72 ~]# kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
[root@k8s-node1-1-72 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEweb NodePort 10.101.124.44 <none> 80:31895/TCP 82s
# 第一步 流程处理入口
[root@k8s-node1-1-72 ~]# iptables-save | grep web
...
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/web" -m tcp --dport 31895 -j KUBE-EXT-LOLE4ISW44XBNF3G# 解释:处理来自TCP协议,且访问目标端口为 31895,都转发到 KUBE-EXT-LOLE4ISW44XBNF3G 链
-A KUBE-SERVICES -d 10.101.124.44/32 -p tcp -m comment --comment "default/web cluster IP" -m tcp --dport 80 -j KUBE-SVC-LOLE4ISW44XBNF3G# 解释:与上面意思相同,处理来自NodePort:Port的数据,都转发到 KUBE-SVC-LOLE4ISW44XBNF3G 链
# 第二步 负载均衡
...
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment "default/web -> 10.244.114.34:80" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-GCCHNO42UKXGR227
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment "default/web -> 10.244.114.35:80" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-7ZMRYMMRUHATZVYE
-A KUBE-SVC-LOLE4ISW44XBNF3G -m comment --comment "default/web -> 10.244.117.26:80" -j KUBE-SEP-4ICTCH44VJXESGBS
# 解释:--mode random为概率计算,按照权重概率进行负载均衡转发
# 第三步 具体的转发
[root@k8s-node1-1-72 ~]# iptables-save | grep KUBE-SEP-GCCHNO42UKXGR227
-A KUBE-SEP-GCCHNO42UKXGR227 -p tcp -m comment --comment "default/web" -m tcp -j DNAT --to-destination 10.244.114.34:80
[root@k8s-node1-1-72 ~]# iptables-save | grep KUBE-SEP-7ZMRYMMRUHATZVYE
-A KUBE-SEP-7ZMRYMMRUHATZVYE -p tcp -m comment --comment "default/web" -m tcp -j DNAT --to-destination 10.244.114.35:80
[root@k8s-node1-1-72 ~]# iptables-save | grep KUBE-SEP-4ICTCH44VJXESGBS
-A KUBE-SEP-4ICTCH44VJXESGBS -p tcp -m comment --comment "default/web" -m tcp -j DNAT --to-destination 10.244.117.26:80# 解释:每条从负载均衡转发的规则,最终都能对应转发到Service后端的Pod容器中处理
[root@k8s-node1-1-72 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESweb-5cc97bc7d5-8v8gc 1/1 Running 0 16m 10.244.114.34 k8s-node2-1-73 <none> <none>
web-5cc97bc7d5-pflrp 1/1 Running 0 16m 10.244.117.26 k8s-node1-1-72 <none> <none>
web-5cc97bc7d5-t5ftc 1/1 Running 0 16m 10.244.114.35 k8s-node2-1-73 <none> <none>
1.5.2 ipvs
IPVS(IP Virtual Server)模式 是 Kubernetes 中另一种 Service 代理模式。它使用 Linux 内核的 IPVS 模块来实现负载均衡和流量路由。
工作原理:
- 当创建一个 Service 时,Kubernetes 会为该 Service 分配一个 ClusterIP。
- Kubernetes 会在每个节点上配置 IPVS 规则,将流量从 Service 的 ClusterIP 和端口转发到后端 Pod 的 IP 和端口。
- IPVS 提供多种负载均衡算法(如轮询、最少连接、源哈希等),可以根据需要选择合适的算法。
特点:
- 性能更优:IPVS 在内核空间中处理流量,性能优于 iptables。
- 支持多种算法:提供多种负载均衡算法,可以根据需求选择。
- 配置相对简单:相对于 iptables,IPVS 的配置相对简单。
使用场景:
- 适用于需要高性能和多种负载均衡算法的场景。
- 适用于大型集群和高流量场景。
IPVS 支持多种负载均衡算法,以下是一些常见的算法:
- 轮询(Round Robin, RR):按顺序将请求分发到后端 Pod。
- 最少连接(Least Connections, LC):将请求分发到当前连接数最少的 Pod。
- 源哈希(Source Hashing, SH):根据客户端 IP 地址的哈希值将请求分发到后端 Pod,保证同一客户端的请求总是被发送到同一个 Pod。
- 本地最少连接(Local Least Connections, LCC):将请求分发到本地节点上连接数最少的 Pod。
- 源掩码哈希(Source Hashing with Mask, SMC):根据客户端 IP 地址的掩码哈希值将请求分发到后端 Pod。
两种不同的底层网络代理模式,都是由Kube-proxy进行维护,所以如果需要修改代理模式,则需修改Kube-proxy的配置文件,而Kube-proxy的配置文件由 configmap 进行存储。
- kube-proxy配置文件以configmap方式存储
- 如果让所有节点生效,需要重建所有节点 kube-proxy pod
查看configmap命令:kubectl get configmap -n kube-system
[root@k8s-master-1-71 ~]# kubectl get configmap -n kube-system | grep kube-proxy
NAME DATA AGEkube-proxy 2 16d
[root@k8s-master-1-71 ~]# kubectl get pods -n kube-system -o wide | grep kube-proxy
kube-proxy-2np4n 1/1 Running 2 (31h ago) 16d 192.168.1.72 k8s-node1-1-72 <none> <none>
kube-proxy-ch5qf 1/1 Running 2 (31h ago) 16d 192.168.1.73 k8s-node2-1-73 <none> <none>
kube-proxy-sw9qt 1/1 Running 2 (31h ago) 16d 192.168.1.71 k8s-master-1-71 <none> <none>
# 注意:kube-proxy是用dameon-set控制器进行创建,3个Pod即有3个kube-proxy进行维护
— edit方式修改ipvs模式:
- 命令:kubectl edit configmap kube-proxy -n kube-system
# kubectl edit configmap kube-proxy -n kube-system
...
mode: "ipvs" //不填写默认为iptables
...
测试:需要通过删除Pod进行重建才能生效,尝试删除Node2节点的Pod
[root@k8s-node1-1-71 ~]# kubectl delete pod kube-proxy-2np4n -n kube-system
[root@k8s-node1-1-72 ~]# ipvsadm -L -n
TCP 192.168.1.72:31895 rr-> 10.244.114.34:80 Masq 1 0 0-> 10.244.114.35:80 Masq 1 0 0-> 10.244.117.26:80 Masq 1 0 0
— 二进制方式修改ipvs模式:
# vi kube-proxy-config.yml
mode: ipvs
ipvs:scheduler: "rr“
# systemctl restart kube-proxy
注:配置文件路径根据实际安装目录为准
总结:
- 流程包流程:客户端 -> NodePort/ClusterIP(iptables/Ipvs负载均衡规则) -> 分布在各节点Pod
- 查看负载均衡规则:
- iptables模式 iptables-save | grep
- ipvs模式 ipvsadm -L -n
- Iptables VS IPVS
- Iptables: 灵活,功能强大 ;规则遍历匹配和更新,呈线性时延
- IPVS: 工作在内核态,有更好的性能; 调度算法丰富:rr,wrr,lc,wlc,ip hash..
1.6 Service DNS服务
CoreDNS:是 Kubernetes 集群中默认使用的 DNS 服务,负责提供域名解析服务。它是一个灵活、可扩展且高性能的 DNS 服务器,专为 Kubernetes 环境设计,主要作用包括:
- 域名解析:为集群内部的 Pod 提供 DNS 解析服务,使得 Pod 可以通过服务名称(Service Name)访问其他服务。
- 服务发现:通过 DNS 解析,实现服务之间的自动发现和通信。
- 配置管理:提供灵活的配置选项,可以根据需要进行自定义。
工作原理:
- CoreDNS 监听 DNS 请求,通常是 UDP 和 TCP 端口 53。
- 根据配置的插件顺序处理请求。常见的插件包括 forward、kubernetes、cache 等。
- 根据处理结果生成 DNS 响应并返回给客户端。
CoreDNS 使用插件来处理不同的 DNS 请求。以下是一些核心插件:
- forward:将 DNS 请求转发到其他 DNS 服务器(如外部 DNS 服务器)。
- kubernetes:提供 Kubernetes 服务和 Pod 的 DNS 解析。
- cache:缓存 DNS 响应以提高性能。
- errors:处理和记录 DNS 错误。
- log:记录 DNS 请求和响应日志。
- health:提供健康检查端点。
- ready:提供就绪检查端点。
1.6.1 CoreDNS 的配置
CoreDNS 的配置文件通常位于 /etc/coredns/Corefile。以下是一个典型的 Corefile 示例:
.:53 {errorshealthreadykubernetes cluster.local in-addr.arpa ip6.arpa {pods insecureupstreamfallthrough in-addr.arpa ip6.arpa}prometheus :9153forward . /etc/resolv.confcache 30loopreloadloadbalance
}
配置说明:
.:53:监听所有接口的 53 端口。
errors:处理和记录 DNS 错误。
health:提供健康检查端点。
ready:提供就绪检查端点。
kubernetes:提供 Kubernetes 服务和 Pod 的 DNS 解析。
cluster.local:集群的默认域名。
in-addr.arpa 和 ip6.arpa:用于反向 DNS 解析。
pods insecure:允许不安全的 Pod 访问。
upstream:使用上游 DNS 服务器。
fallthrough:如果当前插件无法解析请求,则传递给下一个插件。
prometheus:提供 Prometheus 监控端点。
forward:将无法解析的请求转发到 /etc/resolv.conf 中配置的 DNS 服务器。
cache:缓存 DNS 响应 30 秒。
loop:防止 DNS 查询循环。
reload:允许动态重新加载配置。
loadbalance:在多个后端之间进行负载均衡。
1.6.2 CoreDNS 的部署和管理
CoreDNS 通常作为 Kubernetes 集群的一部分自动部署。以下是一些常见的管理任务:
- 查看 CoreDNS Pod:kubectl get pods -n kube-system -l k8s-app=kube-dns
- 查看 CoreDNS 配置:kubectl get configmap coredns -n kube-system -o yaml
- 更新 CoreDNS 配置:kubectl edit configmap coredns -n kube-system
- 查看 CoreDNS 日志:kubectl logs -n kube-system -l k8s-app=kube-dns
CoreDNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析。
ClusterIP A记录格式:<service-name>.<namespace-name>.svc.cluster.local
例如my-svc.my-namespace.svc.cluster.local,在解析过程中填写完整DNS A记录格式可加快解析速度
测试:
[root@k8s-master-1-71 ~]# kubectl run dns-client --image=busybox -- sleep 24h
[root@k8s-master-1-71 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d
web NodePort 10.101.124.44 <none> 80:31895/TCP 52m
[root@k8s-master-1-71 ~]# kubectl exec -it dns-client -- sh
/ # nslookup kubernetes //解析ClusterIP Service服务
Server: 10.96.0.10
Address: 10.96.0.10:53Name: kubernetes.default.svc.cluster.local
Address: 10.96.0.1/ # nslookup web //解析默认的NodePort Service服务
Server: 10.96.0.10
Address: 10.96.0.10:53Name: web.default.svc.cluster.local
Address: 10.101.124.44
注意:不同的命名空间需要指定命名空间才可以解析
[root@k8s-master-1-71 ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 16d
metrics-server ClusterIP 10.110.104.55 <none> 443/TCP 27h
/ # nslookup kube-dns.kube-system.svc.cluster.local
/ # nslookup metrics-server.kube-system.svc.cluster.local
2、Ingress 对象(对外暴露应用)
2.1 Ingress 介绍
Ingress 是 Kubernetes 中用于管理外部对集群内服务的访问的一种 API 对象。它提供了一种方式来将集群内部的服务暴露给外部网络,通常通过 HTTP 和 HTTPS 协议。Ingress 可以简化服务的暴露和负载均衡配置。
Ingress为弥补NodePort不足而生,NodePort 存在的不足:
- 暴露的一个端口只能一个服务使用,端口需提前规划(增加维护成本)
- 只能支持4层负载均衡(工作机制限制:iptables、ipvs)
了解OSI七层:
- 四层:基于IP和端口转发、例如LVS、Nginx、Haproxy
- 七层:基于应用层协议(HTTP)转发,例如Nginx、Haproxy
主要作用:
- 外部访问:允许外部用户通过域名访问集群内的服务。
- 负载均衡:将外部请求分发到多个后端服务实例。
- 路由规则:根据 URL 路径或主机名将请求路由到不同的服务。
- SSL/TLS 终止:处理 SSL/TLS 加密,确保数据传输的安全性。
- 日志记录和监控:提供日志记录和监控功能,便于排查问题和优化性能。
工作原理:
Ingress 通过定义一组规则来管理外部对集群内服务的访问。以下是 Ingress 的基本工作流程:
- 定义 Ingress 资源:用户定义 Ingress 资源,指定路由规则和后端服务。
- Ingress Controller:Ingress Controller 监听 Kubernetes API,根据 Ingress 资源的定义动态配置反向代理服务器(如 NGINX、Traefik 等)。
- 反向代理服务器:反向代理服务器根据 Ingress 规则将外部请求转发到相应的后端服务。
典型的 Ingress 资源示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: example-ingressnamespace: defaultannotations:nginx.ingress.kubernetes.io/rewrite-target: /
spec:rules:- host: example.comhttp:paths:- path: /app1pathType: Prefixbackend:service:name: app1-serviceport:number: 80- path: /app2pathType: Prefixbackend:service:name: app2-serviceport:number: 80tls:- hosts:- example.comsecretName: example-tls-secret
2.2 Ingress Controller
Ingress Controller 是一个反向代理服务器,负责实现 Ingress 资源定义的规则。常见的 Ingress Controller 包括:
- NGINX Ingress Controller:使用 NGINX 作为反向代理服务器。
- Traefik:使用 Traefik 作为反向代理服务器。
- HAProxy Ingress:使用 HAProxy 作为反向代理服务器。
- AWS ALB Ingress Controller:使用 AWS Application Load Balancer (ALB)。
- GCE Ingress Controller:使用 Google Cloud Load Balancer。
- Contour:使用 Envoy 作为反向代理服务器。
Ingress 与 Ingress Controller 的关系:
- Ingress:K8s中的一个抽象资源,给管理员 提供一个暴露应用的入口定义方法
- Ingress Controller:负责流量路由,根据 Ingress生成具体的路由规则,并对Pod负载 均衡(类似ipvs、iptables)
2.3 Ingress Controller 部署
Ingress Controller :Ingress管理的负载均衡器,为集群提供全局的负载均衡能力。
使用流程:
- 部署Ingress Controller
- 创建Ingress规则
Ingress Controller有很多实现,我们这里采用官方维护的Nginx控制器。
- 其他控制器:Ingress Controllers | Kubernetes
- Git项目地址:GitHub - kubernetes/ingress-nginx: Ingress NGINX Controller for Kubernetes
进入Get started: Installation Guide - Ingress-Nginx Controller
找到 Bare metal clusters 云原生环境,下载官方YAML:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.6.4/deploy/static/provider/baremetal/deploy.yaml
修改YAML里镜像地址为国内的: lizhenliang/ingress-nginx-controller:v1.1.0
补充:Ingress Controller是以Deployment Pod方式在集群节点进行部署的,如需要外部进行访问,则需要利用NodePort Service进行暴露,所以在部署Ingress Controller时会默认创建Pod和Svc。(Svc默认监听80、443)
- 查看Ingress Controller的Pod命令:kubectl get pods -n ingress-nginx
- 查看Ingress Controller的Svc命令:kubectl get svc -n ingress-nginx
[root@k8s-master-1-71 ~]# kubectl apply -f ingress-controller-1.1.yaml
[root@k8s-master-1-71 ~]# kubectl get pods -n ingress-nginx //会启动3个容器,其中admission为临时容器,状态为completed(类似初始化容器)
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-jp2xl 0/1 Completed 0 71s
ingress-nginx-admission-patch-ctjj5 0/1 Completed 0 71s
ingress-nginx-controller-c4db458f5-qp5ff 1/1 Running 0 71s[root@k8s-master-1-71 ~]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.108.162.206 <none> 80:30513/TCP,443:32099/TCP 3h8m
ingress-nginx-controller-admission ClusterIP 10.103.217.175 <none> 443/TCP 3h8m
2.4 Ingress 的规则配置
了解:客户端可通过基于域名、IP、端口的方式,访问负载均衡进行分流,比如:Nginx配置文件中的vhost虚拟主机,生成环境大部分是基于域名(创建Ingress的逻辑就是类似vhost)
【rule】中的host,对应【vhost】中的 server_name 域名;
【rule】中的path,对应【vhost】中的 location 访问首页路径;
【rule】中的service.name,对应【vhost】中的 proxy_pass 后端主机(upstream);
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-nginx
spec:ingressClassName: nginx //指定Ingress控制器(kubectl get ingressclass)rules:- host: web.aliangedu.cn //host域名http:paths:- path: / //访问首页路径pathType: Prefixbackend:service:name: web //需要关联的svc(一组Pod)port:number: 80
备注:ingressClassName指定Ingress控制器是为了防止一个集群中有2套Ingress Controller
查看ingress Controller标识(用来标识控制器):kubectl get ingressclass
[root@k8s-master-1-71 ~]# kubectl get ingressclass
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 26m
2.5 Ingress Controller 的两种访问方式
2.5.1 Service NodePort暴露Ingress Controller
访问流程:用户(通过域名:端口)— 所有宿主机 SVC NodePort — ingress controller pod(Nginx,基于域名)— 分布在各个节点的Pod
测试:
# Pod和Svc准备
kubectl create deployment nginx-web --image=nginx --replicas=3kubectl create deployment httpd-web --image=httpd --replicas=3kubectl expose deployment nginx-web --port=80 --target-port=80
kubectl expose deployment httpd-web --port=80 --target-port=80
# 注意:因为需要进行测试,未指定NodePort,可通过Cluster IP进行访问
[root@k8s-master-1-71 ~]# curl 10.96.113.140
<html><body><h1>It works!</h1></body></html>
[root@k8s-master-1-71 ~]# curl 10.99.20.23<title>Welcome to nginx!</title>
示例1:创建Nginx的Ingress YAML文件(性质与vhost类似)
[root@k8s-master-1-71 ~]# vi ingress-nginx.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-nginx
spec:ingressClassName: nginx # 标识控制器(下载的控制器即Nginx)rules:- host: nginx.hostname.cn # 域名http:paths:- path: / # 默认首页pathType: Prefixbackend:service:name: nginx-web # 后端SVCport:number: 80 # 端口
查看ingress命令:kubectl get ingress
[root@k8s-master-1-71 ~]# kubectl apply -f ingress-nginx.yaml[root@k8s-master-1-71 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-nginx nginx nginx.hostname.cn 80 9s
由于ingress中的host是定义域名,需要在C:\Windows\System32\drivers\etc\hosts进行解析
补充:因为ingress Controller暴露是NodePort Service方式,解析的节点地址任意
[root@k8s-master-1-71 ~]# kubectl get svc -n ingress-nginx //先前创建Ingress controller的NodePort Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.108.162.206 <none> 80:30513/TCP,443:32099/TCP 3h42m
ingress-nginx-controller-admission ClusterIP 10.103.217.175 <none> 443/TCP 3h42m
测试外部访问ingress定义的Nginx域名:nginx.hostname.cn:30513
示例2:创建httpd的Ingress YAML文件
[root@k8s-master-1-71 ~]# kubectl apply -f ingress-httpd.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-httpd
spec:ingressClassName: nginx # 标识控制器(下载的控制器即Nginx)rules:- host: httpd.hostname.cn # 域名http:paths:- path: / # 默认首页pathType: Prefixbackend:service:name: httpd-web # 后端SVCport:number: 80 # 端口
# 查看ingress
[root@k8s-master-1-71 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-nginx nginx nginx.hostname.cn 192.168.1.73 80 33m
ingress-web nginx httpd.hostname.cn 192.168.1.73 80 12m
测试外部访问ingress定义的httpd域名:httpd.hostname.cn:30513
2.5.2 共享宿主机网络
访问流程:用户(通过域名)— 指定宿主机 ingress controller pod(Nginx,基于域名)— 分布在各个节点的Pod
注意:域名必须得解析到 ingress controller pod 所在的节点IP(即该节点要有该ingress controller pod,否则无法监听80、443端口)
# 在ingress-controller.yaml添加HostNetwork:True设置,支持共享宿主机网络
[root@k8s-master-1-71 ~]# vi ingress-controller-1.1.yaml
[root@k8s-master-1-71 ~]# kubectl apply -f ingress-controller-1.1.yaml
# 查看Ingress Controller Pod所在Node IP
[root@k8s-master-1-71 ~]# kubectl get pods -n ingress-nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ingress-nginx-admission-create-jp2xl 0/1 Completed 0 4h42m 10.244.114.43 k8s-node2-1-73 <none> <none>
ingress-nginx-admission-patch-ctjj5 0/1 Completed 1 4h42m 10.244.117.29 k8s-node1-1-72 <none> <none>
ingress-nginx-controller-85cdb79d-htwwh 1/1 Running 0 2m57s 192.168.1.73 k8s-node2-1-73 <none> <none>
# 查看是否监听80端口
[root@k8s-node2-1-73 ~]# ss -nlptu | grep 80
修改地址解析:Ingress Controller Pod所在Node IP web.hostname.cn
测试:
补充:公网负载均衡器的作用
① 将内网K8S集群的Service、Ingress暴露到互联网
② 提高内网K8S集群的安全性
2.6 Ingress 规则配置HTTPS步骤:
步骤1:准备域名证书文件
- 通过 openssl/cfssl 工具自签或者权威机构颁发
- 准备 certs.sh 脚本,主要生成以下:
- ca-config.json 根证书的配置文件
- ca-csr.json 根证书的请求颁发文件
- web.hostname.cn-csr.json 域名颁发客户端证书文件
[root@k8s-master-1-71 ~]# tar -zxvf cfssl.tar.gz -C /usr/bin/[root@k8s-master-1-71 ~]# vi certs.sh
cat > ca-config.json <<EOF # 根证书的配置文件
{"signing": {"default": {"expiry": "87600h"},"profiles": {"kubernetes": {"expiry": "87600h","usages": ["signing","key encipherment","server auth","client auth"]}}}
}
EOFcat > ca-csr.json <<EOF # 根证书的请求颁发文件
{"CN": "kubernetes","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","ST": "Beijing"}]
}
EOF# 通过以上相关根证书信息,为指定域名颁发客户端证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -cat > web.hostname.cn-csr.json <<EOF
{"CN": "web.hostname.cn", # 一定要与访问的实际域名保持一致"hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}]
}
EOFcfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes web.hostname.cn-csr.json | cfssljson -bare web.hostname.cn[root@k8s-master-1-71 ~]# mkdir ssl[root@k8s-master-1-71 ~]# mv certs.sh ssl/
[root@k8s-master-1-71 ~]# cd ssl/
[root@k8s-master-1-71 ssl]# bash certs.sh
[root@k8s-master-1-71 ssl]# ls
ca-config.json ca-csr.json ca.pem web.hostname.cn.csr web.hostname.cn-key.pem
ca.csr ca-key.pem certs.sh web.hostname.cn-csr.json web.hostname.cn.pem
步骤2:将证书文件保存到Secret(不能在YAML文件中直接引用)
- 创建Secret命令:kubectl create secret tls --cert=web.hostname.cn.pem --key=web.hostname.cn-key.pem
- 查看Secret命令:kubectl get secret
[root@k8s-master-1-71 ssl]# kubectl create secret tls web-hostname-cn \
--cert=web.hostname.cn.pem --key=web.hostname.cn-key.pem
[root@k8s-master-1-71 ssl]# kubectl get secret
NAME TYPE DATA AGE
web-hostname-cn kubernetes.io/tls 2 40s
步骤3:Ingress规则配置tls
[root@k8s-master-1-71 ~]# kubectl apply -f ingress-https.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: ingress-https //ingress名字
spec:ingressClassName: nginx## 添加 tls 配置tls:- hosts:- httpd.hostname.cn //https 解析域名secretName: web-hostname-cn //secret证书名rules:- host: httpd.hostname.cn //http 解析域名http:paths:- path: /pathType: Prefixbackend:service:name: httpd-webport:number: 80
[root@k8s-master-1-71 ~]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-https nginx httpd.hostname.cn 192.168.1.73 80, 443 2m8s
思考:Ingress Controller怎么工作的?
Ingress Controller通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取它, 按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段 Nginx 配置,应用到管理的 Nginx服务,然后热加载生效。 以此来达到Nginx负载均衡器配置及动态更新的问题。
流程包流程:客户端 ->Ingress Controller(nginx) -> 分布在各节点Pod
[root@k8s-master-1-71 ~]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-jp2xl 0/1 Completed 0 5h8m
ingress-nginx-admission-patch-ctjj5 0/1 Completed 1 5h8m
ingress-nginx-controller-85cdb79d-htwwh 1/1 Running 0 28m
[root@k8s-master-1-71 ~]# kubectl exec -it ingress-nginx-controller-85cdb79d-htwwh bash -n ingress-nginx
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-5.1$ ps -ef
PID USER TIME COMMAND1 www-data 0:00 /usr/bin/dumb-init -- /nginx-ingress-controller --election-id=ingress-controller-leader --controller-class=k87 www-data 0:01 /nginx-ingress-controller --election-id=ingress-controller-leader --controller-class=k8s.io/ingress-nginx --c28 www-data 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf32 www-data 0:00 nginx: worker process33 www-data 0:00 nginx: worker process34 www-data 0:00 nginx: worker process35 www-data 0:00 nginx: worker process36 www-data 0:00 nginx: cache manager process167 www-data 0:00 bash173 www-data 0:00 ps -ef
进入ingress-nginx-controller容器查看守护进程,主要以下2个进程:
- nginx-ingress-controller 主要用于访问k8s api 获取创建的ingress原则,生成Nginx Vhost配置并生效;
- nginx 即Nginx本尊,做了一些优化和功能加强
补充:通过命令创建并导出ingress YAML
- 创建ingress:kubectl create ingress --rule=域名/=:80
- 导出ingress:kubectl create ingress --rule=域名/=:80 --dry-run=client -o yaml
# kubectl create ingress ingress-web --rule=nginx.hostname.cn/=nginx:80 --dry-run=client -o yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:creationTimestamp: nullname: ingress-web
spec:rules:- host: nginx.hostname.cnhttp:paths:- backend:service:name: nginxport:number: 80path: /pathType: Exact
status:loadBalancer: {}
课后作业
1、给一个pod创建service,并可以通过ClusterIP / NodePort访问
- 名称:web-service
- pod名称:web
- 容器端口:80
2、 任意名称创建deployment和service,使用busybox容器nslookup解析service
3、列出命名空间下某个service关联的所有pod,并将pod名称写到/opt/pod.txt文件中(使用标签筛选)
- 命名空间:default
- service名称:web
4、使用Ingress将美女示例应用暴露到外部访问
- 镜像:lizhenliang/java-demo(通过进入容器查看得知为tomcat应用)
小结:
本篇为 【Kubernetes CKA认证 Day6】的学习笔记,希望这篇笔记可以让您初步了解到 K8S中Service控制器以及它的三种类型,了解Service代理模式、Ingress等;课后还有扩展实践,不妨跟着我的笔记步伐亲自实践一下吧!
Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。
相关文章:
CKA认证 | Day6 K8s网络
第六章 Kubernetes网络 1、Service 控制器 在 Kubernetes (K8S) 中,Service 控制器 是一个关键组件,负责管理 Kubernetes 服务的生命周期和实现其功能。Service 控制器确保服务能够正确地将流量路由到后端 Pod,并处理服务的负载均衡和 DNS …...
基于Llamaindex的网页内容爬取实战
目的 本文不关注如何解析网页 html 元素和各种 python 爬虫技术,仅作为一种网页数据的预处理手段进行研究。Llamaindex 也并不是爬虫技术的集大成者,使用它是为了后续的存查一体化。 安装依赖 pip install llama-index-readers-web # pip install llam…...
springboot429校运会管理系统(论文+源码)_kaic
摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装校运会管理系统软件来发挥其高效地信息处理的作用ÿ…...
tcpdump编译
https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz tar -zxvf flex-2.6.4.tar.gz ./configure CFLAGS-D_GNU_SOURCE make sudo make installwget http://ftp.gnu.org/gnu/bison/bison-3.2.1.tar.gz ./configure make sudo make install以上两个库是…...
Vite快速构建Vue教程
步骤 1: 初始化项目目录 创建一个名为 projects 的文件夹,作为存放所有 Vite 项目的根目录。这个文件夹将容纳多个独立的 Vite 项目。 步骤 2: 创建 Vite 项目 右键点击 projects 文件夹并选择“在此处打开终端”或使用您偏好的代码编辑器(如 VSCode&…...
四、个人项目系统搭建
文章目录 一、python写的后端代码二、html代码三、index.css四、js代码 效果图: 一、python写的后端代码 后端代码使用Flask编写,如下所示: # app.py from flask import Flask, render_template, request, jsonify, g import sqlite3 import…...
长沙理工大学《2024年825自动控制原理真题》 (完整版)
本文内容,全部选自自动化考研联盟的:《长沙理工大学825自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2024年真题 Part1:2024年完整版真题 2024年真题...
Linux上安装Anaconda
查看版本 lsb_release -a uname -m x86_64:表示系统是64位。i686、i386:表示系统是32位。 到连接安装对应版本 连接到ldhttps://repo.anaconda.com/archive/ 配置对应的conda环境,export PATH/对应目录/anaconda3/bin:$PATH *注意为bi…...
HTTP常见的请求头有哪些?都有什么作用?在 Web 应用中使用这些请求头?
HTTP 请求头(Request Headers)用于在 HTTP 请求中携带额外的信息,帮助服务器更好地处理请求。以下是一些常见的 HTTP 请求头及其作用: 常见请求头及其作用 1. Accept 作用:告知服务器客户端可以接受的内容类型。示例…...
扩展tinyplay使其自适应不同声道数量的媒体
android原来的tinyplay代码,如果遇到播放媒体的升到数量与打开pcm的声道数量不匹配的情况,会没法继续播放。 本例扩展了tinyplay的代码,将不同声道的音频数据展开/压缩到pcm设备支持的数据,再写入pcm设备。 bplay.c #include &l…...
[Unity] AppLovin Max接入Native 广告 IOS篇
NativeIOS构建流程 (接入之前备份之前打包得Xcode工程) 下载资源 1.将以下文件放入Unity Assets->Plugins->IOS文件夹下 2.Unity更新max版本至12.4.1 UnityPlugin 6.4.3以上(很重要) 3.NativeSDKManager.CS根据以下附…...
跨平台开发技术的探索:从 JavaScript 到 Flutter
随着多平台支持和用户体验一致性在应用程序开发中变得越来越重要,开发者面临的挑战是如何在不同平台上保持代码的可维护性和高效性。本文将探讨如何利用现代技术栈,包括 Flutter、JavaScript、HTML5、WebAssembly、TypeScript 和 Svelte,在统一的平台上进行高效的跨平台开发…...
计算机网络技术基础:2.计算机网络的组成
计算机网络从逻辑上可以分为两个子网:资源子网和通信子网。 一、资源子网 资源子网主要负责全网的数据处理业务,为全网用户提供各种网络资源与网络服务。资源子网由主机、终端、各种软件资源与信息资源等组成。 1)主机 主机是资源子网的主要…...
PKCS#7、Bit padding(位填充)、Byte padding(字节填充)、Zero padding(零填充)
PKCS#7、Bit padding(位填充)、Byte padding(字节填充)、Zero padding(零填充)是密码学常见的填充方式。 Bit padding(位填充): 位填充可以应用于任意长度的消息。在消息…...
在 Kibana 中为 Vega Sankey 可视化添加过滤功能
作者:来自 Elastic Tim Bosman 及 Miloš Mandić 有兴趣在 Kibana 中为 Vega 可视化添加交互式过滤器吗?了解如何利用 “kibanaAddFilter” 函数轻松创建动态且响应迅速的 Sankey 可视化。 在这篇博客中,我们将了解如何启用 Vega Sankey 可视…...
快速部署一套K8s集群-v1.28
快速部署一套K8s集群-v1.28 1.前置知识点 1.1 生产环境可部署Kubernetes集群的两种方式 目前生产部署Kubernetes集群主要有两种方式: kubeadmKubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。 二进制包从github下载发行版的二进…...
python3验证有效正则表达式
Python 中字符串类型本质上没有标记“是否原始”的特性,原始字符串只是为了书写方便。运行时,原始字符串与普通字符串的表现是相同的,唯一的区别是编写代码时是否进行了转义。 因此,如果需要确保某些输入是有效正则表达式&#x…...
Dify+Xinference本地部署Embedding和Rerank模型
文章目录 1、Xinference介绍2、Xinference安装2.1 Xinference Docker安装2.2 pip安装2.3 设置开启自启动(仅针对pip安装用户) 3、部署Embedding和Rerank模型4、Dify调用Xinference模型 1、Xinference介绍 Xinference是一个性能强大且功能全面的分布…...
是时候戒掉小游戏了
玩儿这东西没够!去年本来是要备考CPA,但是赶上写毕业论文,就以此为由,没有去备考,结果论文没完成,考试也没准备,都是游戏惹的祸!今年计划备考,看了两个月书,结…...
ECMAScrip 与 ES2015(ES6):JavaScript 现代化编程的里程碑
在 JavaScript 的发展历程中,ECMASCript 和 ES2015(也称为 ES6)无疑是最具革命性的版本之一。它们不仅引入了大量的新特性和语法糖,还极大地提升了代码的可读性、可维护性和性能。本文将深入探讨 ECMASCrip 和 ES2015 的新特性及其…...
iOS swift开发系列 -- tabbar问题总结
1.单视图如何改为tabbar,以便显示2个标签页 右上角➕,输入tabbar 找到控件,然后选中,把entrypoint移动到tabbar控件 2.改成tabbar,生成两个item,配置各自视图后,启动发现报错 Thread 1: “-[p…...
nginx 部署 ModSecurity3
一、查看本地nginx版本 nginx是yum安装的 # nginx -v nginx version: nginx/1.26.2 二、安装依赖工具 # yum install -y gcc-c flex bison yajl lmdb lua curl-devel curl GeoIP-devel zlib-devel pcre-devel pcre2-devel libxml2-devel ssdeep-devel libtool autoconf aut…...
websocket_asyncio
WebSocket 和 asyncio 指南 简介 本指南涵盖了使用 Python 中的 websockets 库进行 WebSocket 编程的基础知识,以及 asyncio 在异步非阻塞 I/O 中的作用。它提供了构建高效 WebSocket 服务端和客户端的知识,以及 asyncio 的特性和优势。 1. 什么是 WebS…...
一级考试真题(2019)
一级考试真题(2019)...
OpenCV相机标定与3D重建(20)将单应性矩阵分解为旋转矩阵、平移向量和法向量函数decomposeHomographyMat()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将单应性矩阵分解为旋转矩阵、平移向量和法向量。 cv::decomposeHomographyMat 是 OpenCV 库中的一个函数,用于将单应性矩阵…...
题解 - 取数排列
题目描述 取1到N共N个连续的数字(1≤N≤9),组成每位数不重复的所有可能的N位数,按从小到大的顺序进行编号。当输入一个编号M时,就能打印出与该编号对应的那个N位数。例如,当N=3时,可…...
LVGL9.2 鼠标悬停处理
文章目录 前言鼠标悬停处理功能简介使用场景1. **按钮悬停效果**2. **图标高亮**3. **动态工具提示** 实现原理使用方法1. 设置控件样式2. 监听悬停事件 功能亮点注意事项总结 前言 在 v9.2 版本中,新增了许多功能,其中鼠标悬停处理(Mouse H…...
每日计划-1213
1. 完成 SQL2 查询多列 https://www.nowcoder.com/exam/oj?page1tabSQL%E7%AF%87topicId199 2. 八股部分 1) C 中面向对象编程如何实现数据隐藏? 在c中,可以将数据成员声明为私有或受保护,并提供公有的成员函数来访问和修改这些数据成员&am…...
gz中生成模型
生成模型 通过服务调用生成 还记得parameter_bridge 吗? 我们在生成桥接的时候调用了这个cpp文件。 一个 parameter_bridge 实例用于消息传递(传感器数据)。之前的例子 另一个 parameter_bridge 实例用于服务桥接(动态生成模型…...
三相电机不转,如何判断好坏?
在现代工业生产中,三相电机被广泛应用于各类机械设备中,由于其高效能和稳定性,成为驱动设备的首选。然而,在实际使用过程中,三相电机有时会出现不转动的情况,这不仅会影响生产效率,还可能对设备…...
使用观测云排查数据库死锁故障
故障发现 核心应用 pod 发生重启,同时接收到对应使用者反馈业务问题,开始排查。 观测云排查现场 1、根据重启应用信息,查询 APM 执行数据库 update 操作大量报错,执行时间在 5min 以上。 分析 APM 链路异常,发现是触…...
STM32 USB通信知识与应用详解
在嵌入式系统开发中,STM32作为一款性能卓越的微控制器,其USB通信功能的应用十分广泛。本文将深入探讨STM32 USB的相关知识,从基础概念到实际应用,为读者呈现一个全面的STM32 USB通信知识体系。 一、USB基础知识 USB(…...
IoTDB 集群扩容方法
问题 问题1:当时序数据库 IoTDB 集群的存储占用达到多少时,建议增加节点?是等到存储完全满,还是达到一半时就进行扩容?如果集群存储已满,是否需要手动进行数据清理,比如设置 TTL,还…...
控制台报错:Uncaught (in promise):XXXXX问题定位以及前端文件流excel文件下载方法
今天对接上传文件的接口时,明明接口是通的,也正常返回了文件流,然而,控制台就是打印不出返回值,而且一直报错Uncaught (in promise):XXXXX 去查看axios的封装函数,这个internal error是从返回值…...
.NET平台使用C#设置Excel单元格数值格式
设置Excel单元格的数字格式是创建、修改和格式化Excel文档的关键步骤之一,它不仅确保了数据的正确表示,还能够增强数据的可读性和专业性。正确的数字格式可以帮助用户更直观地理解数值的意义,减少误解,并且对于自动化报告生成、财…...
6.2 MapReduce工作原理
MapReduce工作原理涉及将大数据集分割成小块并行处理。Map任务读取数据块并输出中间键值对,而Reduce任务则处理这些排序后的数据以生成最终结果。MapTask工作包括读取数据、应用Map函数、收集输出、内存溢出时写入磁盘以及可选的Combiner局部聚合。ReduceTask工作则…...
C语言指针
1,指针是什么 指针是内存中一个最小内存单元(一个字节)的编号,也就是地址通常口语中说的指针,通常是指指针变量也就是用来存放内存中地址的变量 每个内存单元都有一个地址,这个地址不需要存起来࿰…...
前端(async 和await)
1 async async 将 function 变为成为 async 函数 ●async 内部可以使用 await,也可以不使用,因此执行这个函数时,可以使用 then 和 catch 方法 ●async 函数的返回值是一个 Promise 对象 ●Promise 对象的结果由 async 函数执行的返回值决…...
打造高效的HIS与DAT文件解析工具
在工业数据采集和存储中,HIS 和 DAT 文件是非常常见的二进制数据格式。然而,解析这些固定块大小的二进制文件并将其转换为易读的 CSV 格式并非易事。本文将深入讲解如何使用 Python 和 PyQt5 打造一款图形化工具,轻松解析和转换这些文件&…...
YOLO系列:二、基于yolov8和labelme制作数据集及模型训练
YOLO系列:二、基于yolov8和labelme制作数据集及模型训练 1.新建一个项目1.数据集标注及类型转换1. 1 使用labelme进行数据标注1.1.1打开labelme1.1.2图像标注及存储 1. 2 将数据集转换成yolo类型 2.模型训练的配置文件2. 1打开labelme标注图像2.1.1三级目录 3.模型训…...
PHP搭建环境
一、安装apache 1、获取Apache安装软件 2、双击安装即可:指定对应的路径:E:server/apache 3、选择安装模式:使用自定义模式 4、选择安装位置 二、Apache的目录结构说明 三、Httpd.exe的详细应用 1、服务器进程:运行之后才能够工作...
LeetCode hot100-69-N
https://leetcode.cn/problems/valid-parentheses/description/?envTypestudy-plan-v2&envIdtop-100-liked 20. 有效的括号 已解答 简单 相关标签 相关企业 提示 给定一个只包括 (,),{,},[,] 的字符串 s &#x…...
14:00面试,14:06就出来了,问的问题有点变态。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到5月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…...
ubuntu20.04复现 Leg-KILO
这里写目录标题 opencv版本问题下载3.2.0源代码进入解压后的目录创建构建目录运行 CMake 配置 配置时指定一个独立的安装目录,例如 /opt/opencv-3.2:出错: 使用多线程编译错误1: stdlib.h: 没有那个文件或目录错误2:er…...
Redis应用—1.在用户数据里的应用
大纲 1.社区电商的业务闭环 2.Redis缓存架构的典型生产问题 3.用户数据在读多写少场景下的缓存设计 4.热门用户数据的缓存自动延期机制 5.缓存惊群与穿透问题的解决方案 6.缓存和数据库双写不一致问题分析 7.基于分布式锁保证缓存和数据库双写一致性 8.缓存和数据库双写…...
MySQL InnoDB 中的数据页
文章目录 1. 数据库的存储结构概述1.1 表空间(Tablespace)1.2 段(Segment)1.3 区(Extent)1.4 页(Page) 2. InnoDB 数据页的深入解析2.1 数据页的物理结构2.2 数据页中的行存储2.3 数…...
React Fiber
React Fiber 是 React 16 引入的全新重写的协调(Reconciliation)算法的实现,旨在改善 React 的更新机制和性能,尤其是在复杂应用和大量更新的场景下。它使得 React 更加灵活、可调度,能够实现优先级控制和中断更新等特…...
hive 小文件分析
1、获取fsimage文件: hdfs dfsadmin -fetchImage /data/xy/ 2、从二进制文件解析: hdfs oiv -i /data/xy/fsimage_0000000019891608958 -t /data/xy/tmpdir -o /data/xy/out -p Delimited -delimiter “,” 3、创建hive表 create database if not exists…...
大模型运用-Prompt Engineering(提示工程)
什么是提示工程 提示工程 提示工程也叫指令工程,涉及到如何设计、优化和管理这些Prompt,以确保AI模型能够准确、高效地执行用户的指令,如:讲个笑话、java写个排序算法等 使用目的 1.获得具体问题的具体结果。(如&…...
Linux(网络协议和管理)
后面也会持续更新,学到新东西会在其中补充。 建议按顺序食用,欢迎批评或者交流! 缺什么东西欢迎评论!我都会及时修改的! 在这里真的很感谢这位老师的教学视频让迷茫的我找到了很好的学习视频 王晓春老师的个人空间…...