k8s Service 服务

news/2024/11/16 14:57:04/文章来源:https://www.cnblogs.com/misakivv/p/18415089

目录
  • 一、为什么需要 Service
  • 二、Kubernetes 中的服务发现与负载均衡 -- Service
  • 三、用例解读
    • 1、Service 语法
    • 2、创建和查看 Service
  • 四、Headless Service
  • 五、集群内访问 Service
  • 六、向集群外暴露 Service
  • 七、操作示例
    • 1、获取集群状态信息
    • 2、创建 Service、Deployment
    • 3、创建客户端的测试 Pod
    • 4、集群内访问 Service 的三种方式
      • 4.1、直接通过 Service 的 clusterIP 访问
      • 4.2、直接访问 Service 名
      • 4.3、通过环境变量访问
    • 5、集群外部访问服务
      • 5.1、NodePort
        • 5.1.1、创建 NodePort 类型的 Service(NodePort的端口范围是 30000-32767)
        • 5.1.2、创建 Deployment 模拟后端一组应用 Pod
        • 5.1.3、创建并查看
        • 5.1.4、通过节点 IP:port 访问
        • 5.1.5、通过nodename 也可以访问
      • 5.2、LoadBalancer
        • 5.2.1、安装METALLB
        • 5.2.2、查看MetalLB的安装方式:Installation by manifest
        • 5.2.3、创建 MetalLB 的命名空间
        • 5.2.4、下载 MetalLB 的安装文件
        • 5.2.5、查看 MetalLB 需要的镜像
        • 5.2.6、修改 metallb.yaml 文件
        • 5.2.7、worker节点提前下载speaker和controller镜像
        • 5.2.8、安装 MetalLB
        • 5.2.9、查看 Pod 验证安装情况
        • 5.2.10、配置地址池
        • 5.2.11、创建地址池
        • 5.2.12、创建 LoadBalancer 类型的 SVC
        • 5.2.13、通过 svc 的 EXTERNAL-IP 访问集群内部的服务
      • 5.3、Ingress
      • 5.4、HostNetwork
        • 5.4.1、给 node 节点添加 role 标签
        • 5.4.2、创建使用 hostnetwork 的 Deployment
        • 5.4.3、通过节点 ip 访问
      • 5.5、HostPort
        • 5.5.1、给 node 节点添加 role 标签
        • 5.5.2、创建使用 hostport 的deployment
        • 5.5.3、通过标签节点 ip + port / pod ip 访问
      • 5.6、ExternalName
        • 5.6.1、创建 ExternalName 类型的 Service
        • 5.6.2、启动临时 pod 测试 DNS 解析
        • 5.6.3、域名解析
  • 八、架构设计
    • 1、Kubernetes 服务发现架构
      • 1.1、组件
      • 1.2、实际访问链路

一、为什么需要 Service

在 K8s 集群里面会通过 pod 去部署应用,与传统的应用部署不同,传统应用部署在给定的机器上面去部署,我们知道怎么去调用别的机器的 IP 地址;但是在 K8s 集群里面应用是通过 pod 去部署的, 而 pod 生命周期是短暂的。在 pod 的生命周期过程中,比如它创建或销毁,它的 IP 地址都会发生变化,这样就不能使用传统的部署方式,不能指定 IP 去访问指定的应用。

另外在 K8s 的应用部署里,之前虽然学习了 deployment 的应用部署模式,但还是需要创建一个 pod 组,这些 pod 组需要提供一个统一的访问入口,以及怎么去控制流量负载均衡到这个组里面。

比如说测试环境、预发环境和线上环境,其实在部署的过程中需要保持同样的一个部署模板以及访问方式。因为这样就可以用同一套应用的模板在不同的环境中直接发布。

二、Kubernetes 中的服务发现与负载均衡 -- Service

最后应用服务需要暴露到外部去访问,需要提供给外部的用户去调用的。我们知道 pod 的网络跟机器不是同一个段的网络,那怎么让 pod 网络暴露到去给外部访问呢?这时就需要服务发现。

service-1

在 K8s 里面,服务发现与负载均衡就是 K8s Service。

上图就是在 K8s 里 Service 的架构,K8s Service 向上提供了外部网络以及 pod 网络的访问,即外部网络可以通过 service 去访问,pod 网络也可以通过 K8s Service 去访问。

向下,K8s 对接了另外一组 pod,可以通过 K8s Service 的方式去负载均衡到一组 pod 上面去,这样相当于解决了前面所说的复发性问题,或者提供了统一的访问入口去做服务发现,然后又可以给外部网络访问,解决不同的 pod 之间的访问,提供统一的访问地址。

三、用例解读

1、Service 语法

cat >> my-service.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: my-servicelabels:app: my-service
spec:selector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376
EOF

定义了用于 K8s Service 服务发现的一个协议以及端口。声明了一个名叫 my-service 的一个 K8s Service,它有一个 app:my-service 的 label,它选择了 app:MyApp 这样一个 label 的 pod 作为它的后端。

最后是定义的服务发现的协议以及端口,我们定义的是 TCP 协议,端口是 80,目的端口是 9376,效果是访问到这个 service 80 端口会被路由到后端的 targetPort,就是只要访问到这个 service 80 端口的都会负载均衡到后端 app:MyApp 这种 label 的 pod 的 9376 端口。

2、创建和查看 Service

kubectl apply -f my-service.yamlkubectl describe svc my-service

img

service 创建好之后,可以看到它的名字是 my-service。Namespace、Label、Selector 这些都跟我们之前声明的一样,这里声明完之后会生成一个 IP 地址,这个 IP 地址就是 service 的 IP 地址,它在集群里面可以被其它 pod 所访问,相当于通过这个 IP 地址提供了统一的一个 pod 的访问入口,以及服务发现。

这里还有一个 Endpoints 的属性,就是我们通过 Endpoints 可以看到:通过前面所声明的 selector 去选择了哪些 pod?以及这些 pod 都是什么样一个状态?比如说通过 selector,我们看到它选择了这些 pod 的一个 IP,以及这些 pod 所声明的 targetPort 的一个端口。

service-2

在 service 创建之后,它会在集群里面创建一个虚拟的 IP 地址以及端口,在集群里,所有的 pod 和 node 都可以通过这样一个 IP 地址和端口去访问到这个 service。这个 service 会把它选择的 pod 及其 IP 地址都挂载到后端,这样通过 service 的 IP 地址访问时,就可以负载均衡到后端这些 pod 上面去。

当 pod 的生命周期有变化时,比如说其中一个 pod 销毁,service 就会自动从后端摘除这个 pod。这样实现了:就算 pod 的生命周期有变化,它访问的端点是不会发生变化的。

四、Headless Service

service 创建的时候可以指定 clusterIP:None,告诉 K8s 说我不需要 clusterIP(就是刚才所说的集群里面的一个虚拟 IP),然后 K8s 就不会分配给这个 service 一个虚拟 IP 地址,它没有虚拟 IP 地址怎么做到负载均衡以及统一的访问入口呢?

它是这样来操作的:pod 可以直接通过 service_name 用 DNS 的方式解析到所有后端 pod 的 IP 地址,通过 DNS 的 A 记录的方式会解析到所有后端的 Pod 的地址,由客户端选择一个后端的 IP 地址,这个 A 记录会随着 pod 的生命周期变化,返回的 A 记录列表也发生变化,这样就要求客户端应用要从 A 记录把所有 DNS 返回到 A 记录的列表里面 IP 地址中,客户端自己去选择一个合适的地址去访问 pod。

apiVersion: v1
kind: Service
metadata:name: my-servicelabels:app: my-service
spec:clusterIP: Noneselector:app: MyAppports:- protocol: TCPport: 80targetPort: 9376

可以从看到跟刚才我们声明的模板的区别,就是在spec下加了一个 clusterIP:None,即表明不需要虚拟 IP。

service-3

Headless Service 实际效果就是集群的 pod 访问 my-service 时,会直接解析到所有的 service 对应 pod 的 IP 地址,返回给 pod,然后 pod 里面自己去选择一个 IP 地址去直接访问。

五、集群内访问 Service

在集群里面,其他 pod 要怎么访问到我们所创建的这个 service 呢?

有三种方式:

  • 首先我们可以通过 service 的虚拟 IP 去访问,比如说刚创建的 my-service 这个服务,通过 kubectl get svc 或者 kubectl discribe service 都可以看到它的虚拟 IP 地址是 10.96.47.23,端口是 80,然后就可以通过这个虚拟 IP 及端口在 pod 里面直接访问到这个 service 的地址;
  • 第二种方式直接访问服务名,依靠 DNS 解析,就是同一个 namespace 里 pod 可以直接通过 service 的名字去访问到刚才所声明的这个 service。不同的 namespace 里面,我们可以通过 service 名字加“.”,然后加 service 所在的哪个 namespace 去访问这个 service,例如我们直接用 curl 去访问,就是 my-service:80 就可以访问到这个 service;
  • 第三种是通过环境变量访问,在同一个 namespace 里的 pod 启动时,K8s 会把 service 的一些 IP 地址、端口,以及一些简单的配置,通过环境变量的方式放到 K8s 的 pod 里面。在 K8s pod 的容器启动之后,通过读取系统的环境变量比读取到 namespace 里面其他 service 配置的一个地址,或者是它的端口号等等。

比如在集群的某一个 pod 里面,可以直接通过 curl $ 取到一个环境变量的值,比如取到 MY_SERVICE_SERVICE_HOST 就是它的一个 IP 地址,MY_SERVICE 就是刚才我们声明的 my-service,SERVICE_PORT 就是它的端口号,这样也可以请求到集群里面的 MY_SERVICE 这个 service。

kubectl get pods -l app=MyAppkubectl exec -it my-deployment-6866788946-8v9m6 /bin/bashecho $MY_SERVICE_SERVICE_HOSTecho $MY_SERVICE_SERVICE_PORT

img

六、向集群外暴露 Service

前面介绍的都是在集群里面 node 或者 pod 去访问 service,service 怎么去向外暴露呢?怎么把应用实际暴露给公网去访问呢?

NodePort:这种方法会在集群的所有节点上开放一个端口(称为 NodePort),外部可以通过任意节点的 IP 地址加上这个端口号来访问服务。NodePort 的端口范围默认是 30000-32767。例如,如果你有一个名为 my-service 的服务,Kubernetes 可能会随机分配一个端口,比如 30001,那么你可以通过 :30001 来访问服务 。

LoadBalancer:在支持外部负载均衡器的云服务提供商(如 AWS、Azure、GCP 等)上,你可以创建一个 LoadBalancer 类型的服务。这将自动创建一个外部负载均衡器,并将外部流量转发到服务。LoadBalancer 类型的服务会在云提供商的负载均衡器上配置一个公共 IP 地址,你可以通过这个 IP 地址访问服务 。

ExternalName:这种方式通过 CNAME 记录将服务映射到一个外部域名。这意味着当请求发送到 Kubernetes 集群时,DNS 服务会返回一个 CNAME 记录,指向你指定的外部域名。这种方法不涉及流量的转发,而是在 DNS 层面上进行重定向 。

External IP:为服务分配一个或多个外部可访问的 IP 地址。这些 IP 地址通常由云服务提供商管理,可以是静态或动态分配。通过 Service 的 externalIPs 字段指定外部 IP 地址,外部流量可以通过指定的 IP 地址访问 Service。

Ingress:Ingress 是 Kubernetes 的一种 API 对象,它管理外部访问到集群内服务的 HTTP 流量。通过定义 Ingress 规则,你可以控制如何将外部请求路由到集群内的服务。Ingress 通常与 Ingress Controller 一起使用,后者负责实现 Ingress 规则并将流量转发到正确的服务 。

HostPort:在 Pod 级别使用,将 Pod 内的端口映射到宿主机的特定端口。这种方式不是通过 Service 资源实现的,而是在 Pod 定义中使用 hostPort 字段。

HostNetwork:在 Pod 级别使用,允许 Pod 直接使用宿主机的网络命名空间。这意味着 Pod 会绕过 Kubernetes 的网络代理,直接在宿主机上监听网络请求。这种方式不是通过 Service 资源实现的,而是在 Pod 定义中设置 hostNetwork: true。

七、操作示例

1、获取集群状态信息

kubectl get cs

img

2、创建 Service、Deployment

cat >> service.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: nginx-testlabels:run: nginx
spec:selector:run: nginxports:- protocol: TCPport: 80targetPort: 80
EOF
cat >> server.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-testlabels:run: nginx
spec:replicas: 2selector:matchLabels:run: nginxtemplate:metadata:labels:run: nginxspec:containers:- name: nginximage: nginx:1.16.0imagePullPolicy: IfNotPresent
EOF
kubectl apply -f service.yaml -f server.yamlkubectl get pods -o wide -l run=nginxkubectl describe svc nginx-test

img

3、创建客户端的测试 Pod

现在去创建一个客户端的 pod 实际去感受一下如何去访问这个 K8s Service

cat >> client-test.yaml << EOF
apiVersion: v1
kind: Pod
metadata:name: test-client
spec:containers:- name: client-testimage: busybox:1.31.0command:- sleep- "3600"
EOF

img

4、集群内访问 Service 的三种方式

4.1、直接通过 Service 的 clusterIP 访问

kubectl exec -it test-client /bin/shwget -qO- 10.96.252.19

img

4.2、直接访问 Service 名

wget -qO- nginx-test

img

不同命名空间时也可以通过 .namespace 来访问 service

img

4.3、通过环境变量访问

通过执行 env 命令看一下它实际注入的环境变量的情况。看一下 nginx-test 的 service 的各种配置已经注册进来了。

env

img

wget -qO- $NGINX_TEST_SERVICE_HOST

img

5、集群外部访问服务

5.1、NodePort

NodePort 类型的 Service 提供了一种将集群内部的服务暴露给外部客户端访问的方式。通过创建一个类型为 NodePortService,Kubernetes 控制器会在每个运行中的节点上打开一个固定的端口(默认范围是30000-32767,但可以根据需要进行配置)。外部流量可以通过这个节点端口访问到集群内的服务。

service-4

5.1.1、创建 NodePort 类型的 Service(NodePort的端口范围是 30000-32767)

cat >> nodeport-svc.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: nodeport-service
spec:type: NodePortports:- port: 8080targetPort: 80nodePort: 30120selector:app: nginx
EOF

5.1.2、创建 Deployment 模拟后端一组应用 Pod

cat >> nodeport-deploy.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:name: nodeport-deploy
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.16.0ports:- containerPort: 80
EOF

5.1.3、创建并查看

kubectl apply -f nodeport-deploy.yaml -f nodeport-svc.yamlkubectl get pods -l app=nginxkubectl get svckubectl describe svc nodeport-service

image-20240909211205121

5.1.4、通过节点 IP:port 访问

curl 192.168.112.10:30120 

image-20240909211248989

5.1.5、通过nodename 也可以访问

image-20240909211531139

5.2、LoadBalancer

当创建一个 LoadBalancer 类型的服务时,Kubernetes 会尝试通过云提供商或第三方负载均衡解决方案来创建一个负载均衡器。这个负载均衡器会分配一个静态的外部IP地址(或 DNS 名称),并会将外部流量路由到集群内的服务。

image-20240911170505139

5.2.1、安装METALLB

使用LoadBalancer的方式进行服务发布,需要借助第三方的工具(METALLB)。

每个svc都有一个私有地址,只能在集群内部访问,如果我们把svc的类型设置为LoadBalancer,则svc会获取到一个外部IP,这个外部IP来自地址池,示例使用METALLB配置地址池。

METALLB官网

image-20240911105532138

5.2.2、查看MetalLB的安装方式:Installation by manifest

image-20240911110444602

5.2.3、创建 MetalLB 的命名空间

kubectl create ns metallb-system

5.2.4、下载 MetalLB 的安装文件

wget https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/metallb.yamlwget https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/namespace.yaml

5.2.5、查看 MetalLB 需要的镜像

grep image metallb.yaml

image-20240911151517243

5.2.6、修改 metallb.yaml 文件

image同级下添加如下字段
imagePullPolicy: IfNotPresent

image-20240911152027558

5.2.7、worker节点提前下载speaker和controller镜像

所有节点都执行拉取操作

docker pull quay.io/metallb/speaker:v0.11.0docker pull quay.io/metallb/controller:v0.11.0

5.2.8、安装 MetalLB

kubectl apply -f namespace.yaml -f metallb.yaml 

5.2.9、查看 Pod 验证安装情况

kubectl get pods -n metallb-system

image-20240911155914175

5.2.10、配置地址池

image-20240911160155842

cat >> IPAddressPool.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:namespace: metallb-systemname: config
data:config: |address-pools:- name: defaultprotocol: layer2addresses:- 192.168.112.100-192.168.112.200
EOF

5.2.11、创建地址池

kubectl apply -f IPAddressPool.yaml 

image-20240911161216177

5.2.12、创建 LoadBalancer 类型的 SVC

cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:name: podtestlabels:app: podtest
spec:containers:- name: nginximage: nginx:1.16.0ports:- containerPort: 80
EOF
kubectl expose pod podtest --name=loadbalancer-svc --port=80 --target-port=80 --type=LoadBalancer --selector=app=podtest

image-20240911162611118

查看svc,EXTERNAL-IP地址是从地址池里分配的(默认为首个可分配的ip地址)

5.2.13、通过 svc 的 EXTERNAL-IP 访问集群内部的服务

浏览器访问

192.168.112.100

image-20240911162822506

curl 192.168.112.100

image-20240911163325409

5.3、Ingress

Ingress 是 Kubernetes 中另一种将集群内部的服务暴露给外部的方式。不同于 Service 类型(如 NodePortLoadBalancer),Ingress 提供了一个更高级别的抽象,允许管理员定义更加复杂的路由规则,以便于管理和扩展HTTP和HTTPS服务。

image-20240911175551983

TODO

下一篇单独讲讲吧

5.4、HostNetwork

hostNetwork 是 Kubernetes 中的一个特性选项,但它并不是直接用于将集群内部服务暴露给外部访问的方式,而是指在创建 Pod 时是否使用宿主机的网络栈来进行网络通信。当在 Pod 的规格中设置了 hostNetwork: true 时,Pod 将直接使用宿主机的网络接口而不是 Kubernetes 的服务网络。

5.4.1、给 node 节点添加 role 标签

kubectl label nodes k8s-node1 role=node1kubectl get nodes -L role

image-20240910083452858

5.4.2、创建使用 hostnetwork 的 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname: nginx-deployment
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:nodeSelector:     role: node1hostNetwork: truecontainers:- image: nginx:1.16.0imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 8080

5.4.3、通过节点 ip 访问

image-20240910085902482

在和containers 同级的 hostNetwork: true,表示pod使用宿主机网络,配合 nodeSelector,把pod实例化在固定节点,如上,给node1节点加上标签role: node1 , 通过nodeSelector,nginx就会实例化在node1节点,这样就可以通过node1节点的ip就可以访问这个nginx了。

5.5、HostPort

在 Kubernetes 中,hostPort 是一种配置 Pod 的方式,使得 Pod 内部的应用可以通过特定的端口监听宿主机的网络接口。当 Pod 的容器配置了 hostPort,它将能够接收来自宿主机对应端口的流量。这种方式可以实现外部服务访问集群内部服务的需求,但需要注意的是,使用 hostPort 需要注意端口冲突及安全性问题。

5.5.1、给 node 节点添加 role 标签

kubectl label k8s-node2 role=node2kubectl get nodes -L role

image-20240910090850208

5.5.2、创建使用 hostport 的deployment

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname: hostport-deploy
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec: nodeSelector:role: node2containers:- image: nginx:1.16.0imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 8080hostPort: 80

5.5.3、通过标签节点 ip + port / pod ip 访问

image-20240910092951088

hostNetwork相比多了映射能力,可以把容器端口映射为node节点不同端口,hostPort,当然也需要nodeSelector来固定节点,不然每次创建,节点不同,ip也会改变

5.6、ExternalName

ExternalName 类型的 Service 是 Kubernetes 中用于提供从集群内部访问外部 DNS 名称的一种方式。它的主要目的是简化集群内部应用访问外部服务的过程。当你创建一个类型为 ExternalNameService 时,Kubernetes 会为这个 Service 创建一个 DNS 条目,该条目将解析为指定的外部 DNS 名称。

NodePortLoadBalancer 类型的 Service 不同,ExternalName 类型的 Service 不会暴露任何集群内部的服务到外部网络,而是相反,它让集群内部的服务可以访问外部的服务。

image-20240915100516628

5.6.1、创建 ExternalName 类型的 Service

cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:name: service-externalnamelabels:type: externalname
spec:type: ExternalNameexternalName: www.baidu.com
EOF
kubectl get svc -l type=externalname

image-20240915104651442

5.6.2、启动临时 pod 测试 DNS 解析

可以看到集群内部是可以访问外部服务www.baidu.com

kubectl run -it --rm --image=alpine:latest dns-test -- sh

image-20240915105138081

5.6.3、域名解析

  • 查看 kube-dns 的 ip 地址
kubectl get svc kube-dns -n kube-system -o custom-columns='ClusterIP:.spec.clusterIP'
  • 安装 dig 命令
yum provides digyum install -y bind-utils-9.11.4-26.P2.el7_9.16.x86_64
  • 从集群内部解析 ExternalName 类型的 Service
dig @172.16.0.10 service-externalname.default.svc.cluster.local

image-20240915111039114

八、架构设计

1、Kubernetes 服务发现架构

service-5

如上图所示,K8s 服务发现以及 K8s Service 是这样整体的一个架构。

K8s 分为 master 节点和 worker 节点:

  • master 里面主要是 K8s 管控的内容;
  • worker 节点里面是实际跑用户应用的一个地方。

在 K8s master 节点里面有 APIServer,就是统一管理 K8s 所有对象的地方,所有的组件都会注册到 APIServer 上面去监听这个对象的变化,比如说我们刚才的组件 pod 生命周期发生变化这些事件。

1.1、组件

这里面最关键的有三个组件:

  • 一个是 Cloud Controller Manager,负责去配置 LoadBalancer 的一个负载均衡器给外部去访问;

  • 另外一个就是 Coredns,通过 Coredns 去观测 APIServer 里面的 service 后端 pod 的一个变化,去配置 service 的 DNS 解析,实现可以通过 service 的名字直接访问到 service 的虚拟 IP,或者是 Headless 类型的 Service 中的 IP 列表的解析;

  • 在每个 node 里面会有 kube-proxy 这个组件,它通过监听 service 以及 pod 变化,然后实际去配置集群里面的 node pod 或者是虚拟 IP 地址的一个访问。

1.2、实际访问链路

比如说从集群内部的一个 Client Pod3 去访问 Service:

Client Pod3 首先通过 Coredns 这里去解析出 ServiceIP,Coredns 会返回给它 ServiceName 所对应的 service IP 是什么,这个 Client Pod3 就会拿这个 Service IP 去做请求,它的请求到宿主机的网络之后,就会被 kube-proxy 所配置的 iptables 或者 IPVS 去做一层拦截处理,之后去负载均衡到每一个实际的后端 pod 上面去,这样就实现了一个负载均衡以及服务发现。

对于外部的流量,比如说刚才通过公网访问的一个请求。它是通过外部的一个负载均衡器 Cloud Controller Manager 去监听 service 的变化之后,去配置的一个负载均衡器,然后转发到节点上的一个 NodePort 上面去,NodePort 也会经过 kube-proxy 配置的一个 iptables,把 NodePort 的流量转换成 ClusterIP,紧接着转换成后端的一个 pod 的 IP 地址,去做负载均衡以及服务发现。

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

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

相关文章

获取动态页面html

AJAX AJAX(异步JavaScript和XML)是一种无需重新加载整个页面的情况下,与服务器交换数据,将增量信息局部更新在用户界面上的技术。AJAX具有异步性,AJAX请求不会阻塞用户界面,用户可以在请求处理的同时继续与页面交互,具有更强的交互性。AJAX能使网页从浏览器请求少量信息…

V-By-One协议详解

V-By-One协议详解 V-By-One协议简介 V-by-One是一种高速串行接口技术,由日本赛恩电子公司(THine Electronics)开发,主要用于平板显示器的信号传输。它旨在替代传统的LVDS(Low Voltage Differential Signaling)技术,提供更高的传输速率和更低的功耗。 V-By-One协议特点及…

(2)Proteus8.7添加STM32F103C6直接使用编译xxx.hex文件关键步骤

1)新建工程中选项 2)Protues8.7支持芯片如下:3)点击STM32选择 Keil编译生成的 xxx.hex文件 4)使用virtual terminal显示串口信息。仿真状态,点击Debug菜单项,按图操作。

AI 框架作用是什么?

AI 框架作用 深度学习范式主要是通过发现经验数据中,错综复杂的结构进行学习。通过构建包含多个处理层的计算模型(网络模型),深度学习可以创建多个级别的抽象层来表示数据。例如,卷积神经网络 CNN 可以使用大量图像进行训练,例如对猫狗分类去学习猫和狗图片的特征。这种类…

分布式学习:Raft算法以及具体实现

Raft算法 一致性算法的要求:安全性,网络延迟、分区、丢包、重复和乱序等错误需要保证正确 可用性:集群中只需要大多数机器即可运行 不依赖时序保证一致性三种状态:follower,candidate,leader 任期:逻辑时钟的作用,每一段任期从一次选举开始分票可能会导致一个任期没有l…

通过API接口获取下来的数据需要怎样应用?

在当今数字化时代,通过API接口获取数据已成为企业获取、处理和分析信息的重要手段。API接口不仅能够提高数据交互的效率,还能促进数据的安全性和灵活性。以下是如何将通过API接口获取的数据有效应用的一些方法和策略。数据整合与分析 企业可以通过API接口将不同来源的数据整合…

OpenCore Legacy Patcher 2.0.0 发布,83 款不受支持的 Mac 机型将能运行最新的 macOS Sequoia

OpenCore Legacy Patcher 2.0.0 发布,83 款不受支持的 Mac 机型将能运行最新的 macOS Sequoia在不受支持的 Mac 上安装 macOS Sequoia (OpenCore Legacy Patcher v2.0.0) Install macOS on unsupported Macs 请访问原文链接:https://sysin.org/blog/install-macos-on-unsuppo…

校园食堂明厨亮灶智能视频监控

校园食堂明厨亮灶智能视频监控对餐厅摄像头拍照视频监控画面进行实时分析,校园食堂明厨亮灶智能视频监控针对厨师不穿厨师服、不戴厨师帽口罩、陌生人员进入后厨、厨师工作时间玩手机打电话、后厨出现猫狗老鼠等异常行为现象,系统会自动识别抓拍报警,进而实现食品卫生安全日…

.NET 的 Native AOT 现在是什么样的?

今天要写的这篇文章源自昨天在朋友圈发的文章《UWP 通过 .NET 9 和Native AOT 的支持实现 UWP 应用的现代化》[1],一位小伙伴的对话让我想全面梳理下Native AOT的现在的进展。.NET 9 的 Native AOT(Ahead-of-Time Compilation)是微软在.NET 9版本中重点发展的一项技术,旨在提…

工地车辆未冲洗识别抓拍系统

工地车辆未冲洗识别抓拍系统主要是对施工工地的出入的车辆进行冲洗监管、冲洗识别、未冲洗告警。工地车辆未冲洗识别抓拍系统 由现场监控摄像头与后台系统构成。利用前端摄像头(不分品牌)正对施工工地进出口对来往车辆实时分析识别清洗情况,将违规未清洗车辆,抓拍报警,并上…

秸秆焚烧视频监控系统

秸秆焚烧视频监控系统借助现场已经安装的视频监控摄像头,运用边缘+Ai视觉、深度学习、视频ai分析技术,对监控地区的秸秆燃烧行为进行7*24小时不间断识别监控。秸秆焚烧视频监控系统自动识别现场出现烟火时,自动生成预警信息发送到监控后台中心提醒工作人员及时确认,并能够及…

循环语句与条件语句的细节与思想 --进阶C语言

目录if-else组合if的执行顺序操作符的执行顺序测试方法C语言的布尔类型switch case组合(补充) 屏蔽警告的方法在case中执行多条语句,建议case后都带上花括号.多个case执行同样语句do、while、for循环的基本结构continue跳转的位置循环设计的思想推荐推荐使用for的前闭后开写法n…