k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
目录
1 MetailLB 搭建
1.1 MetalLB 的作用和原理
1.2 MetalLB功能
1.3 部署 MetalLB
1.3.1 创建deployment控制器和创建一个服务
1.3.2 下载MealLB清单文件
1.3.3 使用 docker 对镜像进行拉取
1.3.4 将镜像上传至私人仓库
1.3.5 将官方仓库地址修改为本地私人地址
1.3.6 运行清单文件部署服务
1.3.7 配置 MetalLB 分配地址段
2 Ingress-nginx 原理及部署
2.1 ingress-nginx 功能
2.2 Ingress-Nginx 的作用和原理
2.3 MetalLB 和 Ingress-Nginx 的搭配原理
2.4 Ingress 部署
2.4.1 下载ingress-nginx yaml清单
2.4.2 下载镜像并上传私有仓库
2.4.3 修改清单镜像拉取地址
2.4.4 安装 Ingress-nginx
2.5 测试 Ingress-nginx
2.5.1 查看是否正常并修改服务类型
2.5.2 创建 ingress 资源类型
2.5.3 声明 ingress 资源类型
2.5.4 测试 ingress-nginx 是否实现
2.5.5 回收资源
3 Ingress-nginx 的高级用法
3.1 基于路径的访问微服务
3.1.1 将 nginx 命名两个版本v1与v2
3.1.2 暴露端口并指定微服务类型
3.1.3 进入 pod 修改默认发布文件
3.1.4 测试 service 是否正常
3.1.5 创建 ingress 资源类型
3.1.6 实现 路径识别 ingress 控制器清单文件配置的解释
3.1.7 声明 ingress 清单文件 并测试
3.2 基于域名访问的微服务
3.2.1 创建 Ingress 资源类型
3.2.2 声明并测试是否正常访问
3.2.3 建立 tls 加密
3.2.4 建立 auth 认证
3.2.5 Igress 实现 rewrite 重定向
1 MetailLB 搭建
1.1 MetalLB 的作用和原理
-
提供外部 IP 地址:
- MetalLB 的主要作用是为 Kubernetes 集群中的服务提供外部可访问的 IP 地址。在没有云服务提供商提供负载均衡器的情况下,MetalLB 可以模拟实现类似功能。
- MetalLB 支持两种地址分配模式:二层模式 和 边界网关协议(BGP)模式。
- 二层模式:通过在局域网中广播地址解析协议(ARP)请求来宣告服务的 IP 地址,将流量引导到拥有该 IP 地址的节点上。
- BGP 模式:使用 BGP 协议与网络中的路由器进行通信,宣告服务的 IP 地址,并引导外部流量进入集群。
-
负载均衡流量:
- 在将流量引导到拥有服务 IP 地址的节点后,MetalLB 可以根据配置的策略将流量分发到不同的后端 Pod 上。
- 例如,在二层模式下,可以使用轮询或随机等方式进行流量分发。
MetalLB官网https://metallb.universe.tf/installation/
1.2 MetalLB功能
为 LoadBalancer 分配 vip
LoadBalancer类型的Service
LoadBalancer和NodePort很相似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群的外部再来做一个负载均衡设备,而这个设备需要外部环境支持的,外部服务发送到这个设备上的请求,会被设备负载之后转发到集群中。
1.3 部署 MetalLB
1.3.1 创建deployment控制器和创建一个服务
[root@k8s-master metalb]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d14h[root@k8s-master metalb]# kubectl create deployment dep \
--image nginx:latest \
--dry-run=client \
--port 80 --replicas 3 -o yaml > dep.yml# 修改好的如下
[root@k8s-master metalb]# cat dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: depname: dep
spec:replicas: 3selector:matchLabels:app: deptemplate:metadata:labels:app: depspec:containers:- image: nginx:latestname: nginxports:- containerPort: 80[root@k8s-master metalb]# kubectl apply -f dep.yml [root@k8s-master metalb]# kubectl get pods
NAME READY STATUS RESTARTS AGE
dep-79fcdcdfc7-27qzq 1/1 Running 0 63s
dep-79fcdcdfc7-sjjzz 1/1 Running 0 63s
dep-79fcdcdfc7-x7rdz 1/1 Running 0 63s# 此时还没有创建服务
[root@k8s-master metalb]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d15h# 创建服务
[root@k8s-master metalb]# kubectl expose deployment dep \
--name=svc-nginx \
--type=LoadBalancer \
--port=80 --target-port=80 \
--dry-run=client -o yaml >> dep.yml # 修改之后
[root@k8s-master metalb]# cat dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: depname: dep
spec:replicas: 3selector:matchLabels:app: deptemplate:metadata:labels:app: depspec:containers:- image: nginx:latestname: nginxports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:labels:app: depname: svc-nginx
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: deptype: LoadBalancer[root@k8s-master metalb]# kubectl apply -f dep.yml # 没有提供IP 因为是裸金属模式,需要借助插件来完成 如 MetalLB
[root@k8s-master metalb]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d15h
svc-nginx LoadBalancer 10.106.13.221 <peding> 80/TCP 69m
1.3.2 下载MealLB清单文件
[root@k8s-master metalb]# wget https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml1698 image: quay.io/metallb/controller:v0.14.8
1795 image: quay.io/metallb/speaker:v0.14.8
1.3.3 使用 docker 对镜像进行拉取
# 将镜像上传到私人仓库
[root@harbor harbor]# docker pull quay.io/metallb/controller:v0.14.8
[root@harbor harbor]# docker pull quay.io/metallb/speaker:v0.14.8
1.3.4 将镜像上传至私人仓库
[root@harbor ~]# docker login reg.shuyan.com
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store[root@harbor harbor]# docker tag registry.k8s.io/ingress-nginx/controller:v1.11.2 reg.shuyan.com/ingress-nginx/controller:v1.11.2
[root@harbor harbor]# docker push reg.shuyan.com/ingress-nginx/controller:v1.11.2[root@harbor ~]# docker tag quay.io/metallb/speaker:v0.14.8 reg.shuyan.com/metallb/speaker:v0.14.8
[root@harbor ~]# docker push reg.shuyan.com/metallb/speaker:v0.14.8
1.3.5 将官方仓库地址修改为本地私人地址
[root@k8s-master metalb]# ls
metallb-native.yaml[root@k8s-master metalb]# sed -i 's/quay.io\/metallb\/controller:v0.14.8/reg.shuyan.com\/metallb\/controller:v0.14.8/g' metallb-native.yaml
[root@k8s-master metalb]# sed -i 's/quay.io\/metallb\/speaker:v0.14.8/reg.shuyan.com\/metallb\/speaker:v0.14.8/g' metallb-native.yaml
1.3.6 运行清单文件部署服务
[root@k8s-master metalb]# kubectl apply -f metallb-native.yaml
namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/servicel2statuses.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
role.rbac.authorization.k8s.io/controller created
role.rbac.authorization.k8s.io/pod-lister created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/controller created
rolebinding.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
configmap/metallb-excludel2 created
secret/metallb-webhook-cert created
service/metallb-webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created# 查看命名空间是否建立
[root@k8s-master metalb]# kubectl get namespaces
NAME STATUS AGE
default Active 3d14h
dev Active 45h
kube-flannel Active 3d14h
kube-node-lease Active 3d14h
kube-public Active 3d14h
kube-system Active 3d14h
metallb-system Active 14s# 查看镜像是否正确拉取
[root@k8s-master metalb]# kubectl -n metallb-system get pods
NAME READY STATUS RESTARTS AGE
controller-65957f77c8-mt8w8 1/1 Running 0 52s
speaker-f5znb 1/1 Running 0 52s
speaker-slsf7 1/1 Running 0 52s
speaker-wj79v 1/1 Running 0 52s
1.3.7 配置 MetalLB 分配地址段
Configuration :: MetalLB, bare metal load-balancer for KubernetesMetalLB, bare metal load-balancer for Kuberneteshttps://metallb.universe.tf/configuration/
将以上官网的代码复制下来修改
[root@k8s-master metalb]# vim configmap.yml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:name: first-poolnamespace: metallb-system # 注意命名空间一定要和上面实体清单创建的一样
spec:addresses:- 192.168.239.240-192.168.239.250 # 注意此地址池一定要是本网段可用的地址---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:name: examplenamespace: metallb-system # 注意命名空间一定要和上面实体清单创建的一样
spec:ipAddressPools:- first-pool
声明地址池清单文件并访问测试
[root@k8s-master metalb]# kubectl apply -f configmap.yml
ipaddresspool.metallb.io/first-pool created
l2advertisement.metallb.io/example created[root@k8s-master metalb]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d15h
svc-nginx LoadBalancer 10.106.13.221 192.168.239.240 80:30668/TCP 12s[root@k8s-master metalb]# curl 192.168.239.240
<!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>
2 Ingress-nginx 原理及部署
Ingress-nginx官网https://kubernetes.github.io/ingress-nginx/deploy/
2.1 ingress-nginx 功能
-
一种全局的、为了代理不同后端 Service 而设置的负载均衡服务,支持7层
-
Ingress由两部分组成:Ingress controller和Ingress服务
-
Ingress Controller 会根据你定义的 Ingress 对象,提供对应的代理能力。
-
业界常用的各种反向代理项目,比如 Nginx、HAProxy、Envoy、Traefik 等,都已经为Kubernetes 专门维护了对应的 Ingress Controller。
2.2 Ingress-Nginx 的作用和原理
定义路由规则:
- Ingress-Nginx 是一个 Kubernetes Ingress 控制器,它根据 Ingress 资源定义的规则来路由外部 HTTP(S)流量到集群内的服务。
- Ingress 资源可以定义多个规则,每个规则可以指定一个主机名(如 example.com)和一个或多个路径(如 /path1 和 /path2),并将这些路径映射到后端服务。
反向代理和负载均衡:
- 当外部请求到达 Ingress-Nginx 控制器时,它作为反向代理将请求转发到相应的后端服务,具体是基于定义的规则来确定。
- Ingress-Nginx 可以实现负载均衡功能,将流量分发到多个后端 Pod 上。它支持多种负载均衡算法,如轮询、最少连接数等。
2.3 MetalLB 和 Ingress-Nginx 的搭配原理
部署 MetalLB:
- 在集群中部署 MetalLB,并通过配置来指定可用的 IP 地址池。这些 IP 地址将用于暴露集群内部的服务。
部署 Ingress-Nginx:
- 部署 Ingress-Nginx 控制器,通常会创建一个或多个服务(Service)来暴露 Ingress 控制器本身。这些服务可以配置为 NodePort 或者 LoadBalancer 类型。
- 由于在裸金属环境中可能没有 LoadBalancer 类型的支持,因此可以使用 MetalLB 来替代 LoadBalancer,将 Ingress-Nginx 控制器暴露给外部网络。
配置 Ingress 资源:
- 创建 Ingress 资源来定义 HTTP(S) 流量的规则。这些规则将告诉 Ingress-Nginx 如何处理来自外部的请求。
- Ingress 资源通常会引用前面创建的 Ingress-Nginx 控制器。
ingress 如何链接后端 service :
1、修改服务类型
ingress 会创建自己的service 叫做 ingress-nginx-controller 修改 服务类型为 LoadBalancer
2、创建 ingress 资源类型:
在ingress的资源纪录类型中一定要注明service的名称否则无法正确转发
2.4 Ingress 部署
2.4.1 下载ingress-nginx yaml清单
[root@k8s-master metalb]# mkdir ingress[root@k8s-master metalb]# cd ingress/[root@k8s-master ingress]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/aws/deploy.yaml
2.4.2 下载镜像并上传私有仓库
[root@k8s-master ingress]# vim deploy.yaml 451 image: registry.k8s.io/ingress-nginx/controller:v1.11.2
552 image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3[root@harbor ~]# docker pull registry.k8s.io/ingress-nginx/controller:v1.11.2[root@harbor ~]# docker pull registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3[root@harbor ~]# docker tag registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3 reg.shuyan.com/ingress-nginx/kube-webhook-certgen:v1.4.3[root@harbor ~]# docker push reg.shuyan.com/ingress-nginx/kube-webhook-certgen:v1.4.3[root@harbor harbor]# docker tag registry.k8s.io/ingress-nginx/controller:v1.11.2 reg.shuyan.com/ingress-nginx/controller:v1.11.2
[root@harbor harbor]# docker push reg.shuyan.com/ingress-nginx/controller:v1.11.2
2.4.3 修改清单镜像拉取地址
[root@k8s-master ingress]# ls
deploy.yaml
[root@k8s-master ingress]# sed -i 's/registry.k8s.io\/ingress-[root@k8s-master ingress]# nginx\/controller:v1.11.2/reg.shuyan.com\/ingress-nginx\/controller:v1.11.2/g' deploy.yaml
[root@k8s-master ingress]# sed -i 's/registry.k8s.io\/ingress-nginx\/kube-webhook-certgen:v1.4.3/reg.shuyan.com\/ingress-nginx\/kube-webhook-certgen:v1.4.3/g' deploy.yaml
2.4.4 安装 Ingress-nginx
[root@k8s-master ingress]# kubectl apply -f deploy.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created[root@k8s-master ingress]# kubectl get namespaces
NAME STATUS AGE
default Active 3d15h
dev Active 46h
ingress-nginx Active 37m
kube-flannel Active 3d15h
kube-node-lease Active 3d15h
kube-public Active 3d15h
kube-system Active 3d15h
metallb-system Active 62m
2.5 测试 Ingress-nginx
2.5.1 查看是否正常并修改服务类型
[root@k8s-master ingress]# kubectl -n ingress-nginx get pods
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-dtnhp 0/1 Completed 0 40m
ingress-nginx-admission-patch-l9dp4 0/1 Completed 0 40m
ingress-nginx-controller-7d4db76476-hb9th 1/1 Running 0 40m#修改微服务为loadbalancer
[root@k8s-master ~]# kubectl -n ingress-nginx edit svc ingress-nginx-controller
49 type: LoadBalancer# 查看是否正确分配
[root@k8s-master ingress]# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.104.94.174 192.168.239.241 80:30654/TCP,443:32569/TCP 40m
ingress-nginx-controller-admission ClusterIP 10.104.152.104 <none> 443/TCP 40m
2.5.2 创建 ingress 资源类型
[root@k8s-master ingress]# kubectl create ingress webcluster \
--rule '/=svc-nginx:80' \
--class nginx \
--dry-run=client -o yaml > ingress.yml# 以下是修改过的文件
[root@k8s-master ingress]# cat ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: webcluster
spec:ingressClassName: nginxrules:- http:paths:- backend:service:name: svc-nginxport:number: 80path: / # 这里指访问网站根的时候就会访问名为svc-nginx的这个服务pathType: Prefix# Exact(精确匹配),# ImplementationSpecific(特定实现),# Prefix(前缀匹配),# Regular expression(正则表达式匹配)
2.5.3 声明 ingress 资源类型
[root@k8s-master ingress]# kubectl apply -f ingress.yml # 在此时svc-nginx 就不需要使用 LoadBlance 了可以换成ClusterIP实现后端pod负载均衡,
# ingress-nginx 使用 MetalLB 分配的地址,为自己使用,然后再将收到的数据传到后端service
# 有点像nginx的反向代理,流量先到 ingress-nginx 控制器再传到指定的 service
# 后端 service 不需要与外界通讯了自然就不需要用到 LoadBlance 去获得对外访问的IP了
# 只需要 ingress-nginx 对所有的 service 做一个管理,可以实现复杂的正则匹配。# 修改名为 svc-nginx 的服务类型为 ClusterIP,从而实现后端各pod的负载均衡
[root@k8s-master metalb]# kubectl edit service svc-nginx 33 type: ClusterIP# 检查是否改过来了
[root@k8s-master metalb]# kubectl get service svc-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx ClusterIP 10.106.13.221 <none> 80/TCP 6h50m
2.5.4 测试 ingress-nginx 是否实现
[root@k8s-master metalb]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dep-79fcdcdfc7-27qzq 1/1 Running 0 7h2m 10.244.2.51 k8s-node2 <none> <none>
dep-79fcdcdfc7-sjjzz 1/1 Running 0 7h2m 10.244.1.32 k8s-node1 <none> <none>
dep-79fcdcdfc7-x7rdz 1/1 Running 0 7h2m 10.244.2.52 k8s-node2 <none> <none>[root@k8s-master metalb]# kubectl exec -it pods/dep-79fcdcdfc7-27qzq -- bashroot@dep-79fcdcdfc7-27qzq:/# echo this is `hostname -I` > /usr/share/nginx/html/index.html[root@k8s-master metalb]# kubectl exec -it pods/dep-79fcdcdfc7-sjjzz -- bash
root@dep-79fcdcdfc7-sjjzz:/# echo this is `hostname -I` > /usr/share/nginx/html/index.html[root@k8s-master metalb]# kubectl exec -it pods/dep-79fcdcdfc7-x7rdz -- bash
root@dep-79fcdcdfc7-x7rdz:/# echo this is `hostname -I` > /usr/share/nginx/html/index.html [root@k8s-master metalb]# kubectl get service svc-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx ClusterIP 10.106.13.221 <none> 80/TCP 7h4m
[root@k8s-master metalb]# curl 10.106.13.221
this is 10.244.2.51
[root@k8s-master metalb]# curl 10.106.13.221
this is 10.244.1.32
[root@k8s-master metalb]# curl 10.106.13.221
this is 10.244.2.52[root@k8s-master metalb]# kubectl -n ingress-nginx get service ingress-nginx-controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.104.94.174 192.168.239.241 80:30654/TCP,443:32569/TCP 6h53m[root@k8s-master metalb]# curl 192.168.239.241
this is 10.244.2.51[root@k8s-master metalb]# curl 192.168.239.241
this is 10.244.2.52[root@k8s-master metalb]# curl 192.168.239.241
this is 10.244.1.32
2.5.5 回收资源
[root@k8s-master metalb]# cd ingress/
[root@k8s-master ingress]# ls
deploy.yaml ingress.yml[root@k8s-master ingress]# cat ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: webcluster
spec:ingressClassName: nginxrules:- http:paths:- backend:service:name: svc-nginxport:number: 80path: /pathType: Prefix[root@k8s-master ingress]# kubectl delete -f ingress.yml [root@k8s-master ingress]# cd ..[root@k8s-master metalb]# ls
configmap.yml dep.yml ingress metallb-native.yaml[root@k8s-master metalb]# kubectl get deployments.apps dep
NAME READY UP-TO-DATE AVAILABLE AGE
dep 3/3 3 3 7h19m[root@k8s-master metalb]# kubectl delete -f dep.yml
deployment.apps "dep" deleted
service "svc-nginx" deleted[root@k8s-master metalb]# kubectl get deployments.apps
No resources found in default namespace.[root@k8s-master metalb]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d22h
3 Ingress-nginx 的高级用法
3.1 基于路径的访问微服务
3.1.1 将 nginx 命名两个版本v1与v2
# 创建版本v1的deployment资源类型的nginx
[root@k8s-master ingress]# kubectl create deployment nginx-v1 \
--image nginx:latest \
--dry-run=client \
--port 80 \
--replicas 1 \
-o yaml > nginx-v1.yml[root@k8s-master ingress]# cat nginx-v1.yml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-v1 # 此标签一定要与微服务的标签对得上,不然微服务无法找到deploymentname: nginx-v1
spec:replicas: 1selector:matchLabels:app: nginx-v1template:metadata:labels:app: nginx-v1spec:containers:- image: nginx:latestname: nginx-v1ports:- containerPort: 80# 创建版本 v2 的 deployment 资源类型的 nginx
[root@k8s-master ingress]# kubectl create deployment nginx-v2 \
--image nginx:latest \
--dry-run=client \
--port 80 \
--replicas 1 \
-o yaml > nginx-v2.yml[root@k8s-master ingress]# cat nginx-v2.yml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-v2name: nginx-v2
spec:replicas: 1selector:matchLabels:app: nginx-v2template:metadata:labels:app: nginx-v2spec:containers:- image: nginx:latestname: nginx-v2ports:- containerPort: 80# 声明这两个版本的清单文件
[root@k8s-master ingress]# kubectl apply -f nginx-v1.yml
deployment.apps/nginx-v1 created[root@k8s-master ingress]# kubectl apply -f nginx-v2.yml
deployment.apps/nginx-v2 created# 查看deployment是否正常运行
[root@k8s-master ingress]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-v1 1/1 1 1 12s
nginx-v2 1/1 1 1 6s
3.1.2 暴露端口并指定微服务类型
创建微服务清单文件并将其加入到deployment的清单文件中
# 创建清单文件追加到deployment清单文件中
[root@k8s-master ingress]# kubectl expose deployment nginx-v1 \
--name=svc-nginx-v1 \
--port 80 --target-port 80 \
--dry-run=client \
--type=ClusterIP -o yaml >> nginx-v1.yml [root@k8s-master ingress]# kubectl expose deployment nginx-v2 \
--name=svc-nginx-v2 --port 80 --target-port 80 \
--dry-run=client \
--type=ClusterIP -o yaml >> nginx-v2.yml [root@k8s-master ingress]# cat nginx-v1.yml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-v1name: nginx-v1
spec:replicas: 1selector:matchLabels:app: nginx-v1template:metadata:labels:app: nginx-v1spec:containers:- image: nginx:latestname: nginx-v1ports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:labels:app: nginx-v1name: svc-nginx-v1
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: nginx-v1type: ClusterIP[root@k8s-master ingress]# cat nginx-v2.yml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginx-v2name: nginx-v2
spec:replicas: 1selector:matchLabels:app: nginx-v2template:metadata:labels:app: nginx-v2spec:containers:- image: nginx:latestname: nginx-v2ports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:labels:app: nginx-v2name: svc-nginx-v2
spec:ports:- port: 80protocol: TCPtargetPort: 80selector:app: nginx-v2type: ClusterIP# 重新声明更新配置[root@k8s-master ingress]# kubectl apply -f nginx-v1.yml [root@k8s-master ingress]# kubectl apply -f nginx-v2.yml # 服务创建成功
[root@k8s-master ingress]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d22h
svc-nginx-v1 ClusterIP 10.107.76.175 <none> 80/TCP 15s
svc-nginx-v2 ClusterIP 10.100.188.171 <none> 80/TCP 9s
3.1.3 进入 pod 修改默认发布文件
[root@k8s-master ingress]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-v1-dbd4bc45b-49hhw 1/1 Running 0 5m35s
nginx-v2-bd85b8bc4-nqpv2 1/1 Running 0 5m29s[root@k8s-master ingress]# kubectl exec -it pods/nginx-v1-dbd4bc45b-49hhw -- bashroot@nginx-v1-dbd4bc45b-49hhw:/# echo this is nginx-v1 `hostname -I` > /usr/share/nginx/html/index.html [root@k8s-master ingress]# kubectl exec -it pods/nginx-v2-bd85b8bc4-nqpv2 -- bashroot@nginx-v2-bd85b8bc4-nqpv2:/# echo this is nginx-v2 `hostname -I` > /usr/share/nginx/html/index.html
3.1.4 测试 service 是否正常
[root@k8s-master ingress]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d22h
svc-nginx-v1 ClusterIP 10.107.76.175 <none> 80/TCP 15s
svc-nginx-v2 ClusterIP 10.100.188.171 <none> 80/TCP 9s[root@k8s-master ingress]# curl 10.107.76.175
this is nginx-v1 10.244.2.54[root@k8s-master ingress]# curl 10.100.188.171
this is nginx-v2 10.244.1.35
创建七层负载
-- 基于路径识别访问哪个微服务
3.1.5 创建 ingress 资源类型
[root@k8s-master ingress]# kubectl create ingress webcluster \
--class nginx \
--rule "/v1=svc-nginx-v1:80" \
--rule "/v2=svc-nginx-v2:80" \
--dry-run=client -o yaml > ingress-route.yml
3.1.6 实现 路径识别 ingress 控制器清单文件配置的解释
[root@k8s-master ingress]# cat ingress-route.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: webclusterannotations:nginx.ingress.kubernetes.io/rewrite-target: / # 由于在下面基于路径访问,实际传到后端服务的路径为 192.168.239.241/v1 或者 /v2# 但是在后端nginx中默认发布路径中并没有这个目录,所以会无法找到。# 所以就有了以上的配置 -- rewrite-target 重定向。# 此条配置实现的效果:# 比如说访问版本一按下面配置路径最终为192.168.239.241/v1/index.html# 但加上rewrite-target: / 的这条配置 那么 Nginx Ingress 会将请求重写为 # 192.168.239.241/index.html
spec:ingressClassName: nginxrules:- http:paths:- backend:service:name: svc-nginx-v1port:number: 80path: /v1pathType: Prefix- backend:service:name: svc-nginx-v2port:number: 80path: /v2pathType: Prefix# Exact(精确匹配),
# ImplementationSpecific(特定实现),
# Prefix(前缀匹配),
# Regular expression(正则表达式匹配)在这个例子中,任何匹配 /v1 和 /v2 的请求都会被重写为新的目标路径 /,
然后转发到名为 svc-nginx-v1 和 svc-nginx-v2 的后端服务。
3.1.7 声明 ingress 清单文件 并测试
# 声明创建ingress控制器
[root@k8s-master ingress]# kubectl apply -f ingress-route.yml
ingress.networking.k8s.io/webcluster created# 查看ingress-nginx控制器是否正常
[root@k8s-master ingress]# kubectl -n ingress-nginx get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.104.94.174 192.168.239.241 80:30654/TCP,443:32569/TCP 7h30m
ingress-nginx-controller-admission ClusterIP 10.104.152.104 <none> 443/TCP 7h30m# 查看分配的IP
[root@k8s-master ingress]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
webcluster nginx * 192.168.239.241 80 56s# 测试版本是否正常访问
[root@k8s-master ingress]# curl 192.168.239.241/v1
this is nginx-v1 10.244.2.54[root@k8s-master ingress]# curl 192.168.239.241/v2
this is nginx-v2 10.244.1.35
3.2 基于域名访问的微服务
在 3.1 的基础上做
3.2.1 创建 Ingress 资源类型
# 回收以上的ingress类型
[root@k8s-master ingress]# kubectl delete -f ingress-route.yml# 注意创建ingress资源类型的时候 类必须为nginx 因为在ingress部署的时候类名就已经定好了[root@k8s-master ingress]# kubectl get ingressclasses
NAME CONTROLLER PARAMETERS AGE
nginx k8s.io/ingress-nginx <none> 35h# deploy.yml 为ingress的部署文件
[root@k8s-master ingress]# grep -A 9 Ingress deploy.yaml
kind: IngressClass
metadata:labels:app.kubernetes.io/component: controllerapp.kubernetes.io/instance: ingress-nginxapp.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxapp.kubernetes.io/version: 1.11.2name: nginx# 创建ingress的资源类型
[root@k8s-master ingress]# kubectl create ingress dum --class nginx \
--rule "nginxv1.shuyan.com/=svc-nginx-v1:80" \
--rule "nginxv2.shuyan.com/=svc-nginx-v2:80" \
--dry-run=client -o yaml > nginx-dum.yml# 由于生成的文件还是与目标需求文件有些差异,下面是修改好的yaml文件
[root@k8s-master ingress]# cat nginx-dum.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: dum
spec:ingressClassName: nginxrules:- host: nginxv1.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v1port:number: 80path: /pathType: Prefix- host: nginxv2.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v2port:number: 80path: /pathType: Prefix
3.2.2 声明并测试是否正常访问
[root@k8s-master ingress]# kubectl apply -f nginx-dum.yml # 查看是否正确创建
[root@k8s-master ingress]# kubectl describe ingress dum
Name: dum
Labels: <none>
Namespace: default
Address: 192.168.239.241 # IP 有了证明成功了
Ingress Class: nginx
Default backend: <default>
Rules:Host Path Backends---- ---- --------nginxv1.shuyan.com # 域名有了也证明成功了/ svc-nginx-v1:80 (10.244.2.54:80)nginxv2.shuyan.com / svc-nginx-v2:80 (10.244.1.35:80)
Annotations: <none>
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Sync 20m (x2 over 21m) nginx-ingress-controller Scheduled for sync# 客户端做好域名解析
[root@harbor ~]# vim /etc/hosts
192.168.239.241 nginxv1.shuyan.com nginxv2.shuyan.com# 测试是否成功
[root@harbor ~]# curl nginxv1.shuyan.com
this is nginx-v1 10.244.2.54[root@harbor ~]# curl nginxv2.shuyan.com
this is nginx-v2 10.244.1.35
3.2.3 建立 tls 加密
创建 secret 加密类型
# 回收之前的ingress资源[root@k8s-master ingress]# kubectl delete -f nginx-dum.yml # 由于创建secret需要依靠证书来生成,所以得先有证书
[root@k8s-master tls]# yum install openssl[root@k8s-master tls]# openssl req -newkey rsa:2048 \
-nodes -keyout tls.key \
-x509 -days 365 \
-subj "/CN=nginx-svc/O=nginx-svc" \
-out tls.crtGenerating a 2048 bit RSA private key
.......+++
...............................................................................................................+++
writing new private key to 'tls.key'
-----# 创建secret使用tls加密方式,命名为web-tls-secret,并指定证书的私钥和证书的路径[root@k8s-master tls]# kubectl create secret tls web-tls-secret \
--key /root/tls/tls.key \
--cert /root/tls/tls.crt # 查看 secret 是否正确创建[root@k8s-master tls]# kubectl get secrets
NAME TYPE DATA AGE
web-tls-secret kubernetes.io/tls 2 34m[root@k8s-master tls]# kubectl describe secrets
Name: web-tls-secret
Namespace: default
Labels: <none>
Annotations: <none>Type: kubernetes.io/tlsData
====
tls.crt: 1147 bytes
tls.key: 1708 bytes
创建Igress资源类型,添加所需的 secret 到 Igress资源清单中,使得最后运行能正确识别此secret
# 创建资源类型
[root@k8s-master tls]# kubectl create ingress tls \
--class nginx \
--rule "nginxv1.shuyan.com/=svc-nginx-v1:80" \
--rule "nginxv2.shuyan.com/=svc-nginx-v2:80" \
--dry-run=client -o yaml > tls.yml [root@k8s-master tls]# cat tls.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: tls
spec:
# 增加了tls:以下的参数使得可以识别到 创建的secrettls:- hosts:- nginxv1.shuyan.com- nginxv2.shuyan.comsecretName: web-tls-secretingressClassName: nginxrules:- host: nginxv1.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v1port:number: 80path: /pathType: Prefix- host: nginxv2.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v2port:number: 80path: /pathType: Prefix
3.2.4 建立 auth 认证
创建认证文件
[root@k8s-master auth]# yum install httpd-tools -y[root@k8s-master auth]# htpasswd -bcm auth shuyan 123456[root@k8s-master auth]# ls
auth [root@k8s-master auth]# cat auth
shuyan:$apr1$Cqhl913B$Pexoaitb4OnILCdEZm/Kv0
建立 secret 并使用 generic 类型
[root@k8s-master auth]# kubectl create secret generic auth-web \
--from-file /root/auth/auth[root@k8s-master auth]# kubectl describe secrets auth-web
Name: auth-web
Namespace: default
Labels: <none>
Annotations: <none>Type: OpaqueData
====
auth: 45 bytes
创建 ingress 资源类型
[root@k8s-master auth]# kubectl create ingress auth \
> --class nginx \
> --rule "nginxv1.shuyan.com/=svc-nginx-v1:80" \
> --rule "nginxv2.shuyan.com/=svc-nginx-v2:80" \
> --dry-run=client -o yaml > auth.yml# 以下是修改后的ingress资源清单
[root@k8s-master auth]# cat auth.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
# 增加以下三行annotations:nginx.ingress.kubernetes.io/auth-type: basic # 选择认证类型nginx.ingress.kubernetes.io/auth-secret: auth-web # 选择 secret 的名字nginx.ingress.kubernetes.io/auth-realm: "Please input username and password"name: auth
spec:ingressClassName: nginxrules:- host: nginxv1.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v1port:number: 80path: /pathType: Prefix- host: nginxv2.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v2port:number: 80path: /pathType: Prefix[root@k8s-master auth]# kubectl apply -f auth.yml [root@k8s-master auth]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
auth nginx nginxv1.shuyan.com,nginxv2.shuyan.com 192.168.239.241 80 38s
客户端测试测试是否成功
[root@harbor ~]# curl -k https://nginxv1.shuyan.com
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx</center>
</body>
</html>[root@harbor ~]# curl -k https://nginxv1.shuyan.com -ushuyan:123456
this is nginx-v1 10.244.2.54[root@harbor ~]# curl -k https://nginxv2.shuyan.com -ushuyan:123456
this is nginx-v2 10.244.1.35
3.2.5 Igress 实现 rewrite 重定向
# 回收上面的镜像
[root@k8s-master auth]# kubectl delete -f auth.yml # 查看 service 名字
[root@k8s-master auth]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d2h
svc-nginx-v1 ClusterIP 10.107.76.175 <none> 80/TCP 2d4h
svc-nginx-v2 ClusterIP 10.100.188.171 <none> 80/TCP 2d4h# 创建资源类型
[root@k8s-master ingress-rewrite]# kubectl create ingress rewrite \
--class nginx \
--rule "nginxv1.shuyan.com/=svc-nginx-v1:80" \
--dry-run=client -o yaml > ingress-rewrite-app-root.yml# 以下是修改过的配置,增加了几条参数
[root@k8s-master ingress-rewrite]# cat ingress-rewrite-app-root.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/app-root: /index.html # 指定根目录文件name: rewrite
spec:ingressClassName: nginxrules:- host: nginxv1.shuyan.com # 域名访问的ingresshttp:paths:- backend:service:name: svc-nginx-v1 # 指定service名字port:number: 80path: / pathType: Prefix[root@k8s-master ingress-rewrite]# kubectl apply -f ingress-rewrite-app-root.yml [root@k8s-master ingress-rewrite]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
rewrite nginx nginxv1.shuyan.com 192.168.239.241 80 20s
测试是否成功访问
[root@harbor ~]# curl -L http://nginxv1.shuyan.com # 重定向
this is nginx-v1 10.244.2.54
有一个问题就是假如中间惨咋着其他的目录他就会识别不到,为了解决这个问题,可以使用路径重定向
[root@harbor ~]# curl -L http://nginxv1.shuyan.com/shuyan/index.html
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>
回收以上的资源类型
[root@k8s-master ingress-rewrite]# kubectl create ingress rewrite \
--class nginx \
--rule "nginxv1.shuyan.com/=svc-nginx-v1:80" \
--rule "nginxv2.shuyan.com/=svc-nginx-v2:80" \
--dry-run=client -o yaml > ingress-rewrite.yml# 以下清单文件做了稍微的修改
[root@k8s-master ingress-rewrite]# cat ingress-rewrite.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: rewriteannotations:nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:ingressClassName: nginxrules:- host: nginxv1.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v1port:number: 80path: /pathType: Prefix- host: nginxv2.shuyan.comhttp:paths:- backend:service:name: svc-nginx-v2port:number: 80path: /shuyan(/|$)(.*) # 正则匹配类型将/shuyan 结尾的 还有 /shuyan/ 的 还有/shuyan/index.html 都转换为 /index.htmlpathType: ImplementationSpecific # 由于使用到正则匹配需要改变类型# 声明并查看
[root@k8s-master ingress-rewrite]# kubectl apply -f ingress-rewrite.yml [root@k8s-master ingress-rewrite]# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
rewrite nginx nginxv1.shuyan.com,nginxv2.shuyan.com 192.168.239.241 80 8m53s
测试重定向是否成功
[root@harbor ~]# curl http://nginxv2.shuyan.com/shuyan/index.html -L
this is nginx-v2 10.244.1.35[root@harbor ~]# curl http://nginxv2.shuyan.com/shuyan -L
this is nginx-v2 10.244.1.35[root@harbor ~]# curl http://nginxv2.shuyan.com/shuyan/ -L
this is nginx-v2 10.244.1.35
相关文章:

k8s 中微服务之 MetailLB 搭配 ingress-nginx 实现七层负载
目录 1 MetailLB 搭建 1.1 MetalLB 的作用和原理 1.2 MetalLB功能 1.3 部署 MetalLB 1.3.1 创建deployment控制器和创建一个服务 1.3.2 下载MealLB清单文件 1.3.3 使用 docker 对镜像进行拉取 1.3.4 将镜像上传至私人仓库 1.3.5 将官方仓库地址修改为本地私人地址 1.3.6 运行清…...

南昌网站建设让你的企业网站更具竞争力
南昌网站建设让你的企业网站更具竞争力 在当今竞争激烈的市场环境中,一个高质量的网站不仅是企业形象的展示平台,更是吸引客户、提升业绩的重要工具。南昌作为江西的省会城市,互联网产业的蓬勃发展为企业网站建设提供了良好的机遇。 首先&am…...

【重学 MySQL】五十三、MySQL数据类型概述和字符集设置
【重学 MySQL】五十三、MySQL数据类型概述和字符集设置 MySQL数据类型概述MySQL字符集设置注意事项 MySQL数据类型概述 MySQL是一个流行的关系型数据库管理系统,它支持多种数据类型,以满足不同数据处理和存储的需求。理解并正确使用这些数据类型对于提高…...

《计算机原理与系统结构》学习系列——计算机的算数运算(上)
系列文章目录 目录 ALU行波进位加法器超前进位加法器整数运算加减法乘法无符号数相乘N位乘法数的工作流程N位乘法器改进:硬件资源更快速的乘法 MIPS中的乘法除法 32位除法器流程除法器改进 更快速的除法 MIPS中的除法总结 ALU ALU功能:对a,…...

如何在华为云服务器查看IP地址,及修改服务器登录密码!!!
1.在华为云服务器查看IP地址 (1).第一步: 先找到控制台 (2).第二步: 点击华为云Flexus云服务 (3)第三步: 找到公网IP,就找到华为云服务器IP地址啦。 注意:在操作以上步骤的前提是要已注册华为云账号及购买云服务器…...

JAVA并发编程高级——JDK 新增的原子操作类 LongAdder
LongAdder 简单介绍 前面讲过,AtomicLong通过CAS提供了非阻塞的原子性操作,相比使用阻塞算法的同步器来说它的性能已经很好了,但是JDK开发组并不满足于此。使用AtomicLong 时,在高并发下大量线程会同时去竞争更新同一个原子变量,但是由于同时只有一个线程的CAS操作会成功,…...

常见的基础系统
权限管理系统支付系统搜索系统报表系统API网关系统待定。。。 Java 优质开源系统设计项目 来源:Java 优质开源系统设计项目 | JavaGuide 备注:github和gitee上可以搜索到相关项目...

在 window 系统下安装 Ubuntu (虚拟机)
文章目录 零、Ubuntu 和 Vmware workstation 资源一、下载 Ubuntu二、下载 Vmware Workstation Pro三、安装 Vmware Workstation Pro四、创建虚拟机五、配置 Ubuntu 零、Ubuntu 和 Vmware workstation 资源 如果觉得自己下载 Ubuntu 和 Vmware workstation 麻烦,也…...

鸿蒙开发(NEXT/API 12)【访问控制应用权限管控概述】程序访问控制
默认情况下,应用只能访问有限的系统资源。但某些情况下,应用存在扩展功能的诉求,需要访问额外的系统数据(包括用户个人数据)和功能,系统也必须以明确的方式对外提供接口来共享其数据或功能。 系统通过访问…...

(10)MATLAB莱斯(Rician)衰落信道仿真1
文章目录 前言一、莱斯分布随机变量二、仿真代码与结果1.仿真代码2.仿真结果画图 后续 前言 首先给出莱斯衰落信道模型,引入了莱斯因子K,并给出莱斯分布的概率密度函数公式。然后导出莱斯分布随机变量的仿真表示式,建立MATLAB仿真代码&#…...

什么是重卡充电桩?
有什么广告?没有广告,纯纯的介绍。 在政策与市场双重驱动下,充电桩市场已经开启加速模式,行业的火苗越烧越旺。同时,随着新能源重卡的广泛普及,重卡充电桩也迎来了新的发展机遇。 此种背景下 ,…...

模拟实现消息队列(基于SpringBoot实现)
提要:此处的消息队列是仿照RabbitMQ实现(参数之类的),实现一些基本的操作:创建/销毁交互机(exchangeDeclare,exchangeDelete),队列(queueDeclare,…...

C语言:预编译过程的剖析
目录 一.预定义符号和#define定义常量 二.#define定义宏 三.宏和函数的对比 四、#和##运算符 五、条件编译 在之前,我们已经介绍了.c文件在运行的过程图解,大的方面要经过两个方面。 一、翻译环境 1.预处理(预编译) 2.编译 3…...

算法——单调栈
单调栈: 保持栈内的元素始终递增或递减。 单调递增 待处理数组{1,5,2,5,7,2,8} public void sameyIncrease(int[] nums) {Stack<Integer> stack new Stack<>();for(int i 0; i < nums.length; i) {//当栈空的时候可以直接进栈或者要进栈的数大于…...

LeetCode讲解篇之695. 岛屿的最大面积
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历二维矩阵,如果当前格子的元素为1进行深度优先搜索,将搜索过的格子置为0,防止重复访问,然后对继续深度优先搜索上下左右中为1的格子 题解代码 func maxAr…...

招联2025校招内推倒计时
【投递方式】 直接扫下方二维码,或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus,使用内推码 igcefb 投递) 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…...

vite学习教程01、vite构建vue2
文章目录 前言一、vite初始化项目二、修改配置文件2.1、修改main.js文件2.2、修改App.vue文件2.3、修改helloworld.vue2.4、修改vite.conf.js2.5、修改vue版本--修改package.json文件 三、安装vue2和vite插件四、启动服务资料获取 前言 博主介绍:✌目前全网粉丝3W&…...

强化学习部分代码的注释分析
引言 对一些代码块进行注释。我直接复制过来的,不能运行的话别怪我。 多臂赌博机 代码来自链接。欢迎回到原来的链接学习。 %I thought what Id do was Id pretend I was one of those deaf-mutes,or should I ?clear all; epsilon[0.5,0.2,0.1,0.0…...

ctf.bugku-备份是个好习惯
访问页面得到字符串 这串字符串是重复的; d41d8cd98f00b204e9800998ecf8427e 从前端、源码上看,除了这段字符串,没有其他信息;尝试解密,长度32位;各种解密方式试试; MD5免费在线解密破解_MD5在…...

C++面试速通宝典——14
220. static关键字的作用 static关键字在编程中有多种作用: 在类的成员变量前使用,表示该变量属于类本身,而不是任何类的实例。在类的成员函数前使用,表示该函数不需要对象实例即可调用,且只能访问类的静…...

k8s的简介和部署
一、k8s简介 在部署应用程序的方式上面,主要经历了三个阶段: 传统部署:互联网早期,会直接将应用程序部署在物理机上优点:简单,不需要其它技术的参与缺点:不能为应用程序定义资源使用边界,很难合理地分配计算资源&…...

Thingsboard 网关实战 modbus通信 rpc下发控制指令
我们这里说的是Thingsboard通过网关modbus通信接入设备,然后通过rpc下发指令去控制开关信号的设备,不会网关通过modbus接入设备的,可以看我之前的文章,从小白教学。 下面我们就说如何下发rpc开关信号指令 第一步.在modbus配置文…...

基于pytorch的手写数字识别
import pandas as pd import numpy as np import torch import matplotlib import matplotlib.pyplot as plt from torch.utils.data import TensorDataset, DataLoadermatplotlib.use(tkAgg)# 设置图形配置 config {"font.family": serif,"mathtext.fontset&q…...

MySQL 实验 7:索引的操作
MySQL 实验 7:索引的操作 索引是对数据表中一列或多列的值进行排序的一种结构,索引可以大大提高 MySQL 的检索速度。合理使用索引,可以大大提升 SQL 查询的性能。 索引好比是一本书前面的目录,假如我们需要从书籍查找与 xx 相关…...

为Floorp浏览器添加搜索引擎及搜索栏相关设置. 2024-10-05
Floorp浏览器开源项目地址: https://github.com/floorp-Projects/floorp/ 1.第一步 为Floorp浏览器添加搜索栏 (1.工具栏空白处 次键选择 定制工具栏 (2. 把 搜索框 拖动至工具栏 2.添加搜索引擎 以添加 搜狗搜索 为例 (1.访问 搜索引擎网址 搜狗搜索引擎 - 上网从搜狗开始 (2…...

如何设置WSL Ubuntu在Windows开机时自动启动
如何设置WSL Ubuntu在Windows开机时自动启动 步骤详解1. 创建批处理脚本2. 添加到Windows启动项 注意事项结语 在使用Windows Subsystem for Linux (WSL) 时,我们可能希望Ubuntu能够在Windows启动时自动运行。本文将介绍如何实现这一功能,让您的开发环境更加便捷。 步骤详解 …...

使用TensorBoard可视化模型
目录 TensorBoard简介 神经网络模型 可视化 轮次-损失曲线 轮次-准确率曲线 轮次-学习率曲线 迭代-评估准确率曲线 迭代-评估损失曲线 TensorBoard简介 TensorBoard是一款出色的交互式的模型可视化工具。安装TensorFlow时,会自动安装TensorBoard。如图: TensorFlow可…...

《深度学习》OpenCV 图像拼接 原理、参数解析、案例实现
目录 一、图像拼接 1、直接看案例 图1与图2展示: 合并完结果: 2、什么是图像拼接 3、图像拼接步骤 1)加载图像 2)特征点检测与描述 3)特征点匹配 4)图像配准 5)图像变换和拼接 6&am…...

Hive数仓操作(三)
一、Hive 数据库操作 1. 创建数据库 基本创建数据库命令: CREATE DATABASE bigdata;说明: 数据库会在 HDFS 中以目录的形式创建和保存,数据库名称会存储在 Hive 的元数据中。如果不指定目录,数据库将在 /user/hive/warehouse 下…...

TDSQL-C电商可视化,重塑电商决策新纪元
前言: 在数字化浪潮席卷全球的今天,电子商务行业以其独特的魅力和无限潜力,成为了推动全球经济增长的重要引擎。然而,随着业务规模的急剧扩张,海量数据的涌现给电商企业带来了前所未有的挑战与机遇。如何高效地处理、…...