K8S系列文章之 内外网如何互相访问

K8S中网络这块主要考虑 如何访问外部网络以及外部如何访问内部网络 

访问外网服务的两种方式

需求

k8s集群内的pod需要访问mysql,由于mysql的性质,不适合部署在k8s集群内,故k8s集群内的应用需要链接mysql时,需要配置链接外网的mysql,本次测试 k8s集群ip段为192.168.23.xx。以下提供两种方式,EndpointExternalName方式。

一、创建Endpoint类型的服务

创建命名空间

新建命名空间my-first-app,需要访问外网的Pod,svc,endpoints等 都需要在该命名空间下。

> kubectl create namespace my-first-app

创建 endpoints

创建my-mysql-endpoints.yaml

> mkdir -p  ~/mysql-endpoint
> cd ~/mysql-endpoint> cat <<EOF > my-mysql-endpoints.yaml
apiVersion: v1
kind: Endpoints
apiVersion: v1
metadata:name: my-mysql-endpoint #此名字需与 my-mysql-service.yaml文件中的 metadata.name 的值一致namespace: my-first-app #在固定的命名空间下
subsets:- addresses:- ip: 192.168.23.1 ## 宿主机,由于我的虚拟机ping不通我本机的mysql(安装mysql时候禁用了未打开)- ip: 220.181.38.148 ## 随便取的一个 公网Ipports:- port: 3306
EOF

创建service

创建my-mysql-service.yaml

> cat <<EOF > my-mysql-service.yaml
apiVersion: v1
kind: Service
metadata:name: my-mysql-endpoint #此名字需与 my-mysql-endpoints.yaml文件中的 metadata.name 的值一致namespace: my-first-app  #在固定的命名空间下
spec:ports:- port: 3306###  验证,进入,ping一下配置的Ip地址。
# kubectl exec -it my-first-springcloud-94cdd7487-xxxxx -n  my-first-app -- /bin/sh
# ping 220.181.38.148EOF 

部署pod 进行验证

部署自己的服务到 my-first-app命名空间下,并且进入容器,进行ping测试

> kubectl exec -it my-first-springcloud-94cdd7487-xxxxx -n  my-first-app -- /bin/sh
> ping 220.181.38.148  ## 也可以在容器中直接调用对应的端口测试,此处只演示ping通,就代表能访问了
PING 220.181.38.148 (220.181.38.148): 56 data bytes
64 bytes from 220.181.38.148: seq=0 ttl=127 time=5.356 ms
64 bytes from 220.181.38.148: seq=1 ttl=127 time=4.946 ms
64 bytes from 220.181.38.148: seq=2 ttl=127 time=18.165 ms
。。。。> 也可以查看service的 Endpoints 信息 
> kubectl describe svc my-mysql-endpoint -n my-first-appName:              my-mysql-endpoint
Namespace:         my-first-app
Labels:            <none>
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.102.160.141
Port:              <unset>  3306/TCP
TargetPort:        3306/TCP
Endpoints:         192.168.23.1:3306,220.181.38.148:3306
Session Affinity:  None
Events:            <none>

注意

此种方式只适合Ip访问,对于像阿里云rds等数据库的。需要用域名。则需要用ExternalName方式不而不是Endpoints方式。

二、创建ExternalName类型的服务

创建``

**> mkdir -p  ~/mysql-endpoint
> cd ~/mysql-endpoin
> cat <<EOF > my-mysql-external.yaml
apiVersion: v1
kind: Service
metadata:name: my-mysql-external #此名字随便起namespace: my-first-app  #在固定的命名空间下
spec:type: ExternalName externalName: www.baidu.com ##提供方的服务完全限定域名,如rds域名等。ports:- port: 80###  ExternalName类型的服务创建后,pod可以通过my-mysql-external.default.svc.cluster.local域名连接到外部服务,
####  或者通过my-mysql-external。当需要指向其他外部服务时,只需要修改spec.externalName的值即可。EOF

暴露服务给外网访问的三种方式

NodePort

kubectl run 创建 pod

[root@master ~]#kubectl run nginx --image=nginx:1.14 --port=80 --replicas=3
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/nginx created
[root@master ~]#kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-59d795d786-5ln28   1/1     Running   0          34s
nginx-59d795d786-xnfjq   1/1     Running   0          34s
nginx-59d795d786-z86nn   1/1     Running   0          34s
[root@master ~]#kubectl get all
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-59d795d786-5ln28   1/1     Running   0          59s
pod/nginx-59d795d786-xnfjq   1/1     Running   0          59s
pod/nginx-59d795d786-z86nn   1/1     Running   0          59sNAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   3d9hNAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   3/3     3            3           59sNAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-59d795d786   3         3         3       59s

kubectl expose 发布容器

[root@master ~]#kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx-service --type=NodePort
service/nginx-service exposed# 查看 Pod 网络状态详细信息和 Service 暴露的端口
[root@master ~]#kubectl get svc,pod -o wide
NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE     SELECTOR
service/kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP        3d9h    <none>
service/nginx-service   NodePort    10.96.158.55   <none>        80:31083/TCP   3m37s   run=nginxNAME                         READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
pod/nginx-59d795d786-5ln28   1/1     Running   0          7m48s   10.244.1.3   node01   <none>           <none>
pod/nginx-59d795d786-xnfjq   1/1     Running   0          7m48s   10.244.2.3   node02   <none>           <none>
pod/nginx-59d795d786-z86nn   1/1     Running   0          7m48s   10.244.2.4   node02   <none>           <none>

K8S 模拟项目 pod 发布

2. Loadbalancer

k8s 之 PodIP、ClusterIP 和 ExternalIP
  在 k8s 中创建 service 时,需要指定 type 类型,可以分别指定 ClusterIP、NodePort、LoadBalancer 三种,其中前面两种无论在内网还是公网环境下使用都很常见,只有 LoadBalancer 大部分情况下只适用于支持外部负载均衡器的云提供商(AWS、阿里云、华为云等)使用。
  本地自己安装的 k8s 集群,默认是不支持 LoadBalancer 的,需要自己安装一个组件来支持。而云上的 k8s,肯定是都支持 LoadBalancer 的。如果自己公司搭建集群,那肯定也是需要安装 LoadBalancer 的,支持本地集群 LoadBalancer 的组件:

  • metalLB: Netlify 是一家位于旧金山的云计算公司,为 Web 应用程序和静态网站提供托管和无服务器后端服务。
  • openelb: 之前是 PorterLB,KubeSphere 公司开源的,是有中文文档的,不过改名的过程中, 有点乱。

LoadBalancer 示意图


2.1 确认 strictARP 模式

如果你的网络是运行在 IPVS 模式下(默认是 iptables),那么需要设置 strictARP 模式。 链接

[root@master ~]# curl localhost:10249/proxyMode
ipvs
[root@master ~]# kubectl edit configmap -n kube-system kube-proxy
# 修改其中的 strictARP 为 true,下面字段不是连续的上下行,只展示了需要注意的行数
......apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationmode: "ipvs"ipvs:strictARP: true
......


2.2 安装 metalLB

官网可能执行不了
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

[root@master ~]#kubectl apply -f http://49.232.8.65/yaml/metallb/namespace.yaml
namespace/metallb-system created
[root@master ~]#kubectl apply -f http://49.232.8.65/yaml/metallb/metallb.yaml
......
[root@master ~]#kubectl get pods -n metallb-system
NAME                          READY   STATUS    RESTARTS   AGE
controller-857846f7df-l245m   1/1     Running   0          42s
speaker-5ln28                 1/1     Running   0          42s
speaker-xnfjq                 1/1     Running   0          42s
speaker-z86nn                 1/1     Running   0          42s
# metallb-system 命名空间下有 controller,speaker 等进程已经在 Running 状态,说明正常。
# metallb-system/controller deployment。用于处理 IP 分配的控制器。
# metallb-system/speakerdaemonset。集群中每个节点启动一个协议服务守护进程。


2.3 配置 IP 池

这里我们使用 layer2 协议,毕竟本地测试没有 BGP 设备,如果是正式用,还是要上 BGP 设备的。先申请预留的 IP 端,配置如下:

[root@master ~]#vim metallb.ip.yaml
[root@master ~]#cat metallb.ip.yaml
# 添加一个 ConfigMap 配置 metallb IP 池
apiVersion: v1
kind: ConfigMap
metadata:namespace: metallb-systemname: config
data:config: |address-pools:- name: defaultprotocol: layer2addresses:- 192.168.10.170-192.168.10.200
[root@master ~]#kubectl apply -f metallb.ip.yaml

这样当我们创建一个 loadbalancer 类型的 service 时,EXTERNAL-IP 将会从地址池中获取一个用于外部访问的 IP,当外部流量进入时,ARP 将我们的请求地址广播以获取所属的 service,接着 k8s 内部通过 iptables 规则和 kube-proxy 将流量从服务端点引导到后端。
BGP 类型参考官方文档:链接


2.4 测试效果

现在部署一个 Nginx 看看效果

[root@master ~]#vim nginx-test.yaml
[root@master ~]#cat nginx-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-metallb-test
spec:selector:matchLabels:app: nginx-metallb-testtemplate:metadata:labels:app: nginx-metallb-testspec:containers:- name: nginximage: nginx:1.8ports:- name: httpcontainerPort: 80---
apiVersion: v1
kind: Service
metadata:name: nginx-service
spec:ports:- name: httpport: 80protocol: TCPtargetPort: 80selector:app: nginx-metallb-testtype: LoadBalancer[root@master ~]#kubectl apply -f nginx-test.yaml 
deployment.apps/nginx-metallb-test created
service/nginx-service created

上面声明的 Service 的类型为 LoadBalancer,无其他特殊设置。

[root@master ~]#kubectl get svc -o wide
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE   SELECTOR
kubernetes      ClusterIP      10.96.0.1      <none>           443/TCP        9d    <none>
nginx-service   LoadBalancer   10.96.158.55   192.168.10.170   80:31083/TCP   70s   app=nginx-metallb-test

打开浏览器,访问 EXTERNAL-IP 即可访问 nginx:http://192.168.10.170
如果是正式环境,则使用 DNS 解析到此 IP,使用域名访问服务即可
如果有多个服务,可以使用 Nginx Ingress 来通过域名和路径区分不同的服务

负载均衡可以建立在 OSI 网络模型的不同级别上,主要是在 L4(传输层,例如 TCP/UDP)和 L7(应用层,例如 HTTP)上。在 Kubernetes 中,Services是 L4 的抽象,LoadBalancer 类型负载均衡依然有局限性,同时我们看到每创建一个 service 对应的负载均衡器都会消耗一个静态 IP,这并不合理。当然 k8s 中的另一种资源对象 ingress 可工作在 L7 层实现应用程序协议(HTTP/HTTPS)的负载均衡。

[root@master ~]#curl 192.168.10.170  # 反应可能比较慢,我等待了几分钟,不知道为啥
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>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>

3. Ingress

K8s 网关选型初判:Nginx 还是 Envoy?
我们所说的 Ingress 包含两个部分:

  • ingress 资源对象:流量路由规则的控制。提供 Ingress Kubernetes 对象,能够通过 yaml 进行创建和更新,将服务与域名对应起来。
  • ingress-controller 控制器:控制器的实现有非常多,可参考官方文档中列表 Ingress 控制器,这里我们使用 k8s 官方维护的控制器 NGINX Ingress Controller。

  外部流量进入集群时先经过 ingress-controller,然后根据 ingress 配置的路由规则将请求转发到后端 service。


3.1 安装 ingress controller

  ingress-controller 其实就是守护进程加一个反向代理的应用,守护进程不断监听集群中资源的变化,将 ingress 中的配置信息生成反向代理配置。在 nginx-ingress controller 中即生成 nginx.conf 的配置文件。
  我们上面已经配置好了 loadbalancer 的服务,这样我们创建一个 type 为 LoadBalancer 的 service 关联这组 pod,再把域名解析指向该地址,就实现了集群服务的对外暴露。当然也可以使用 NodePort、Hostnetwork 的方式,本文不讨论。

PS:先前实验用的 v1.17.0,做 ingress 实验的时候换成了 v1.22.5,LoadBalancer 实验按照这个链接重做了一下。

ingress-controller 不是 k8s 内部组件,可以通过 helm 或资源清单方式安装。

[root@master ~]#kubectl apply -f http://49.232.8.65/yaml/deploy.yaml
......
[root@master ~]#kubectl get pods,svc -n ingress-nginx -o wide
NAME                                            READY   STATUS      RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
pod/ingress-nginx-admission-create--1-srl4n     0/1     Completed   0          2m12s   10.244.1.3   node01   <none>           <none>
pod/ingress-nginx-admission-patch--1-vczxf      0/1     Completed   2          2m12s   10.244.2.3   node02   <none>           <none>
pod/ingress-nginx-controller-867b8ccd99-7gdhf   1/1     Running     0          2m12s   10.244.2.4   node02   <none>           <none>NAME                                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE     SELECTOR
service/ingress-nginx-controller             NodePort    10.101.83.140   <none>        80:31700/TCP,443:30401/TCP   2m12s   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
service/ingress-nginx-controller-admission   ClusterIP   10.101.43.212   <none>        443/TCP                      2m12s   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx

编辑 service 修改 spec.type 为 LoadBalancer

[root@master ~]#kubectl edit service/ingress-nginx-controller -n ingress-nginx
......
spec:clusterIP: 10.101.83.140clusterIPs:- 10.101.83.140
......selector:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxsessionAffinity: Nonetype: LoadBalancer
......

这样我们创建好了 nginx-ingress controller,下一步就要配置 ingress 路由规则。


3.2 配置 ingress 路由规则

host:http://k8s.com
基于 url 的路由:
/api/v1
/api/v2

这两个 url 分别路由到不同的 service 中。

[root@master ~]#vim ingress.yaml
[root@master ~]#cat ingress.yaml 
apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:name: testnamespace: trainingannotations:ingress.kubernetes.io/rewrite-target: /
spec:rules:- host: k8s.comhttp:paths:- pathType: Prefixpath: /api/v1backend:service:name: service-apiv1port: number: 80- pathType: Prefixpath: /api/v2backend:service:name: service-apiv2port: number: 80
[root@master ~]#kubectl create ns training
namespace/training created
[root@master ~]#kubectl apply -f ingress.yaml
ingress.networking.k8s.io/test created
[root@master ~]#kubectl get ingress -n training -o wide
NAME   CLASS    HOSTS     ADDRESS   PORTS   AGE
test   <none>   k8s.com             80      45s

ingress.kubernetes.io/rewrite-target 是 nginx-ingress controller 的一个注解,当后端服务中暴露的 URL 与 Ingress 规则中指定的路径不同时可以通过此重定向。

查看 svc 可以看到此时控制器已经获得了一个 EXTERNAL-IP
现在 nginx-ingress controller 和 ingress 路由规则都有了
通过 CCE 使用 K8S_Ingress

[root@master ~]#kubectl get svc -n ingress-nginx    # 这个 EIP 是弹性 IP,我们是模拟出来的,在公有云上是公网的 IP,是购买的 LB 给的(假如我们用的百度云,这个 EIP 就是 BLB 给的,百度的公网负载均衡器,一个集群只需要一个 EIP,作为七层的集群入口。PS:在公有云上 ingress 一般是一台单独的机器,它和 nginx 类似,如果运行在 node 节点,流量太大可能接不住。可以将节点 IP 作为 EIP。)
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.101.83.140   192.168.1.241   80:31700/TCP,443:30401/TCP   44m
ingress-nginx-controller-admission   ClusterIP      10.101.43.212   <none>          443/TCP

我们可以进入到 nginx-ingress controller pod 中查看 nginx.conf 可以看到此时我们的 ingress 配置已经被生成为路由规则

[root@master ~]#kubectl get pods -n ingress-nginx
NAME                                        READY   STATUS      RESTARTS   AGE
ingress-nginx-admission-create--1-srl4n     0/1     Completed   0          90m
ingress-nginx-admission-patch--1-vczxf      0/1     Completed   2          90m
ingress-nginx-controller-867b8ccd99-7gdhf   1/1     Running     0          90m
[root@master ~]#kubectl exec -it ingress-nginx-controller-867b8ccd99-7gdhf -n ingress-nginx /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-5.1$ ls
fastcgi.conf            mime.types              scgi_params
fastcgi.conf.default    mime.types.default      scgi_params.default
fastcgi_params          modsecurity             template
fastcgi_params.default  modules                 uwsgi_params
geoip                   nginx.conf              uwsgi_params.default
koi-utf                 nginx.conf.default      win-utf
koi-win                 opentracing.json
lua                     owasp-modsecurity-crs
bash-5.1$ cat nginx.conf
......


3.3 指定后端服务

接下来就是指定我们的 backend,即上面的 server-apiv1/2。我们添加两个用于暴露的 service 和 deployment,和 loadbalancer 中测试清单一样,我们稍稍修改一下名称即可。

[root@master ~]#vim backend1.yaml
[root@master ~]#vim backend2.yaml
[root@master ~]#cat backend1.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-apiv1namespace: training
spec:selector:matchLabels:app: nginx-apiv1template:metadata:labels:app: nginx-apiv1spec:containers:- name: nginx-apiv1image: nginx:latestports:- name: httpcontainerPort: 80
---
apiVersion: v1
kind: Service
metadata:namespace: trainingname: service-apiv1
spec:ports:- name: httpport: 80protocol: TCPtargetPort: 80selector:app: nginx-apiv1type: NodePort
[root@master ~]#cat backend2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-apiv2namespace: training
spec:selector:matchLabels:app: nginx-apiv2template:metadata:labels:app: nginx-apiv2spec:containers:- name: nginx-apiv2image: nginx:latestports:- name: httpcontainerPort: 80
---
apiVersion: v1
kind: Service
metadata:namespace: trainingname: service-apiv2
spec:ports:- name: httpport: 80protocol: TCPtargetPort: 80selector:app: nginx-apiv2type: NodePort
[root@master ~]#kubectl apply -f backend1.yaml
deployment.apps/nginx-apiv1 created
service/service-apiv1 created
[root@master ~]#kubectl apply -f backend2.yaml
deployment.apps/nginx-apiv2 created
service/service-apiv2 created
[root@master ~]#kubectl get pods,svc -o wide -n training
NAME                               READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
pod/nginx-apiv1-587fb4fd66-ndvhp   1/1     Running   0          48s   10.244.1.4   node01   <none>           <none>
pod/nginx-apiv2-c55b5bf96-dkkfj    1/1     Running   0          45s   10.244.2.5   node02   <none>           <none>NAME                    TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/service-apiv1   NodePort   10.105.238.31   <none>        80:31845/TCP   48s   app=nginx-apiv1
service/service-apiv2   NodePort   10.98.58.30     <none>        80:31481/TCP   45s   app=nginx-apiv2

修改 hosts 解析,C:\Windows\System32\drivers\etc\hosts,我们是模拟的假的域名,所以需要修改,真的域名有公网的 DNS 解析

修改后端访问的 nginx pod 的 index.html,不如访问会 404

pod 中无法使用 vi 解决:
apt-get update
apt-get install vim

[root@master ~]#kubectl get pods -n training
NAME                           READY   STATUS    RESTARTS   AGE
nginx-apiv1-587fb4fd66-ndvhp   1/1     Running   0          25m
nginx-apiv2-c55b5bf96-dkkfj    1/1     Running   0          25m
[root@master ~]#kubectl exec -it nginx-apiv1-587fb4fd66-ndvhp -n training /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-apiv1-587fb4fd66-ndvhp:/# ls
bin  boot  dev	docker-entrypoint.d  docker-entrypoint.sh  etc	home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@nginx-apiv1-587fb4fd66-ndvhp:/# cd /usr/share/nginx/html/
root@nginx-apiv1-587fb4fd66-ndvhp:/usr/share/nginx/html# ls
50x.html  index.html

注意:Linux 访问就修改 /etc/hosts,Windows 访问就修改 C:\Windows\System32\drivers\etc\hosts

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

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

相关文章

Java List(列表)

List 是一个有序、可重复的集合&#xff0c;集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素&#xff0c;可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引&#xff0c;第一个添加到 List 集合中的元素的索引为 0&#xff…

flutter开发实战-video_player视频播放功能及视频缓存

flutter开发实战-video_player视频播放功能及视频缓存 最近开发过程中video_player播放视频&#xff0c; 一、引入video_player 在pubspec.yaml引入video_player video_player: ^2.7.0在iOS上&#xff0c;video_player使用的是AVPlayer进行播放。 在Android上&#xff0c;…

如何在 Android 上恢复已删除的视频|快速找回丢失的记忆

想知道是否有任何成功的方法可以从 Android 手机中检索已删除的视频&#xff1f;好吧&#xff0c;本指南将向您展示分步说明&#xff0c;让您轻松从手机中找回丢失的视频文件&#xff01; 您是否不小心从 Android 智能手机中删除了珍贵的生日视频&#xff1f;难道是无处可寻吗…

【C++刷题集】-- day5

目录 选择题 单选 编程题 统计回文⭐ 【题目解析】 【解题思路 - 穷举】 【优化】 连续最大和⭐ 【题目解析】 【解题思路】 【空间优化】 选择题 单选 1、 在上下文和头文件均正常情况下&#xff0c;以下程序的输出结果是 ( ) int x 1; do {printf("%2d\n&q…

机器学习笔记

文章目录 编码器-解码器Batch Normalization好处 编码器-解码器 第二个input与transformer中的解码器类似。 Batch Normalization 尽量使得w1和w2之间呈现为正圆 训练模型的时候&#xff0c; μ \mu μ和 σ \sigma σ不可以认为是常数&#xff0c;而是包含数据的变量&…

java字符串超详解

目录 1. API 1.1 API 概述 2. String 2.1 String概述 2.2 String 构造方法 2.3 String对象的特点 2.4 字符串的比较 2.5 String中的方法 3. StringBuilder 3.1 StringBuilder 概述 3.2 StringBuilder 的构造方法 3.3 StringBuilder 的添加和反转 3.4 StringBuilder…

区块链实验室(14) - 编译FISCO-BCOS

FISCO-BCOS是一种区块链平台&#xff0c;与Hyperledger和Ethereum有些不同&#xff0c;详见FISCO BCOS 区块链 编译FISCO BCOS源码的目的是修改或者新增其中功能模块&#xff0c;进行对比实验&#xff0c;验证新想法、新创意的效果。编译的步骤很简单&#xff0c;按技术文档一…

Linux修改系统语言

sudo dpkg-reconfigure locales 按pagedown键&#xff0c;移动红色光标到 zh_CN.UTF-8 UTF-8&#xff0c;空格标记*号&#xff08;没标记下一页没有这一项&#xff09;&#xff0c;回车。 下一页选择 zh_CN.UTF-8。 如果找不到 dpkg-reconfigure whereis dpkg-reconfigure …

【C++】继承的概念和简单介绍、基类和派生类对象复制转换、继承中的作用域、派生类的默认成员函数

文章目录 继承1.继承的概念和简单介绍1.1继承的概念1.2继承的定义 2.基类和派生类对象复制转换3.继承中的作用域4.派生类的默认成员函数5.继承与友元6.继承与静态成员 继承 1.继承的概念和简单介绍 1.1继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最…

Spring Boot 系列4 -- 统一功能处理

目录 前言 1. Spring AOP 用户统⼀登录验证的问题 1.1 自定义拦截器 1.2 配置拦截器并配置拦截的规则 1.3 拦截器的原理源码分析 2. 统一异常处理 2.1 实现统一异常处理 2.2 测试统一异常处理 3. 统一的数据格式返回 3.1 统⼀数据返回格式的实现 3.2 测试统一的数据返…

QT 使用单例模式

目录 1. 单例模式介绍 2.单例模式实现 1. 单例模式介绍 有些时候我们在做 qt 项目的时候,要用到很多类. 例如我们用到的类有 A,B,C,D. 其中,A 是 B,C,D 中都需要用到的类,A 类非常的抢手. 但是,A 类非常的占内存,定义一个 A 对象需要 500M 内存,假如在 B,C,D 中都定义一个 A 类…

浏览器不同源的页面之间如何跨域通信

目录 1&#xff0c;需求2&#xff0c;难点3&#xff0c;思路浏览器不同源的页面之间如何跨域通信&#xff1f; 4&#xff0c;实现第1版第2版最终版其他的问题1&#xff0c;页面路径需完全一致。2&#xff0c;事件注册问题 1&#xff0c;需求 现在有2个项目&#xff0c;页面路径…