k8s介绍-搭建k8s

官网:https://kubernetes.io/

应用部署方式演变

  1. 传统部署:互联网早期,会直接将应用程序部署在物理机上

优点:简单,不需要其他技术的参与

缺点:不能为应用程序定义资源使用边界,很难合理地分配计算资源,而且程序之间容器产生影响

  1. 虚拟化部署:可以在一台物理机上运行多个虚拟机,每个虚拟机都是独立的一个环境

优点:程序环境不会相互产生影响,提供了一定程度的安全性

缺点: 增加了操作系统,浪费了部分资源

  1. 容器化部署:与虚拟化类似,但是共享了操作系统

优点:可以保证每个容器拥有自己的文件系统、CPU、内存、进程空间等

运行应用程序所需要的资源都被容器包装,并和底层基础架构解耦

容器化的应用程序可以跨云服务商、跨Linux操作系统发行版进行部署

 容器化部署方式给带来很多便利,但是也会出现一些问题,比如说:

  1. 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器
  2. 当并发访问量变大的时候,怎么样做到横向扩展容器数量

这些容器管理的问题统称为容器编排问题,为了解决这些容器编排问题,就产生了一些容器编排的软件:

Swarmdocker自己的容器编排工具

Mesosapache的一个资源统一管控的工具,需要和marathon结合使用

Kubernetesgoogle开源的容器编排工具

kubernetes简介

Kubernetes,是一个全新的基于容器技术的分布式架构领先方案,是谷歌严格保密十几年的秘密武器---Borg系统的一个开源版本,于2014年9月发布第一个版本,2015年7月发布第二个正式版本。

Kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:

  1. 自我修复:一旦某个容器崩溃,能够在1秒中左右迅速启动新的容器
  2. 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整。
  3. 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
  4. 负载均衡:如果一个服务启动了多个容器,能够自动实现请求的负载均衡
  5. 版本回退:如果发现新发布的程序版本问题,可以立即回退到原来的版本
  6. 存储编排:可以根据容器自身的需求自动创建存储卷

 kubernetes组件

一个kubernetes集群主要是由控制节点(master)、工作节点(node)构成,每个节点上都会安装不同的组件。

Master:集群的控制平面,负责集群的决策(管理)

Apiserver:资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制。

Scheduler:负责集群资源调度,按照预定的调度策略将pod调度到相应的node节点上。

ControllerManager:负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等。

Etcd:负责存储集群中各种资源对象的信息。

Node:集群的数据平面,负责为容器提供运行环境(干活)

Kubelet:负责维护容器的生命周期,即通过控制docker来创建、更新、销毁容器

Docker:负责节点上容器的各种操作


下面以部署一个nginx服务来说明kubernetes系统各个组件的调用关系:

  1. 首先要明确,一旦kubernetes环境启动之后,master和node都会想自身的信息存储导etcd数据库中
  2. 一个nginx服务的安装请求会首先被发送到master节点的apiserver组件
  3. Apiserver组件会调用scheduler组件来决定到底应该把这个服务安装导哪个node节点上
  4. Apiserver调用controller-manager去调度node节点安装nginx服务
  5. Kubelet接收到指令后,会通知docker,然后由docker来启动一个nginx的pod,pod是kubernetes的最小操作单元,容器必须跑在pod中

一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理,这样外界用户就可以访问集群中的nginx服务了。

 kubernetes概念

Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控

Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行

Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器

Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等

Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod

Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签

Namespace:命名空间,用来隔离pod的运行环境

 k8s集群环境搭建

1、集群类型

Kubernetes集群大体上分为两类:一主多从和多主多从

一主多从:一台master节点和多台node节点,搭建简单,但是有单机故障风险,适用于测试

多主多从:多台master节点和多台node节点,搭建麻烦,安全性高,适用于生产环境

2、安装方式

Kubernetes有多种部署方式,目前主流的方式有kubeadm、minikube、二进制包

1、Minikube:一个用于快速搭建单节点kubernetes的工具

2、Kubeadm:一个用于快速搭建kubernetes集群的工具,https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/

3、二进制包:从官网下载每个组件的二进制包,依次去安装,此方式对于理解kubernetes组件更加有效,https://github.com/kubernetes/kubernetes

说明:现在需要安装kubernetes的集群环境,但是又不想过于麻烦,所有选择使用kubeadm方式

三台主机 

192.168.100.10                master

192.168.100.20                node1

192.168.100.30                node2

 环境搭建

本次环境搭建需要安装三台Linux系统(一主二从),内置rocky系统,然后在每台linux中分别安装docker。kubeadm,kubelet,kubectl.

  1. 操作系统环境:cpu2个  内存2G  硬盘50G  rocky9
  2. 主机名设置:

Master节点:master

Node节点:node1

Node节点:node2

环境初始化

 关闭防火墙,

selinux,

设置时钟同步

配置主机名解析

三台主机都需要做

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.10 master
192.168.100.10 node1
192.168.100.30 node2

三台主机做免密钥登录

禁用swap分区---------三个节点都需要配置

vim /etc/fstab

注释掉swap分区那一行

swapoff  -a



开启IP转发,和修改内核信息---------三个节点都需要配置

vim /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1modprobe   br_netfilter
sysctl -p  /etc/sysctl.d/k8s.conf

配置IPVS功能(三个节点都做)

Rockylinux9中
/etc/modules-load.d/ipvs.modules这个文件
vim /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_shchmod +x /etc/modules/ipvs.modules
bash /etc/modules/ipvs.modules
lsmod | grep -e ip_vs [root@master ~]# lsmod |grep ip_vs
ip_vs_sh               16384  0
ip_vs_wrr              16384  0
ip_vs_rr               16384  0
ip_vs                 237568  6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack          217088  1 ip_vs
nf_defrag_ipv6         24576  2 nf_conntrack,ip_vs
libcrc32c              16384  3 nf_conntrack,xfs,ip_vs

部署k8s

安装docker

三台主机都需要做

yum install -y yum-utils device-mapper-persistent-data lvm2yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum -y install docker-ce-25.0.5-1.el9

配置镜像加速器

三台都需要做

vim /etc/docker/daemon.json{"registry-mirrors": ["https://dockerpull.com","https://docker.anyhub.us.kg","https://dockerhub.jobcher.com","https://dockerhub.icu","https://docker.awsl9527.cn"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2"
}[root@master ~]# systemctl daemon-reload 
[root@master ~]# systemctl restart docker
[root@master ~]# systemctl enable docker

 下载cri-docker

将提前下载好的包上传上去进行解压
[root@master ~]# ls
anaconda-ks.cfg  cri-dockerd-0.3.9.amd64.tgz
[root@master ~]# tar -xvf cri-dockerd-0.3.9.amd64.tgz --strip-components=1 -C /usr/local/bin/
下载cri-docker service文件
[root@master01 ~]# wget -O /etc/systemd/system/cri-docker.service https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.service
[root@master01 ~]# wget -O /etc/systemd/system/cri-docker.socket https://raw.githubusercontent.com/Mirantis/cri-dockerd/master/packaging/systemd/cri-docker.socket
编辑cri-docker.server
[root@master ~]# cd /etc/systemd/system/
[root@master system]# vim cri-docker.service 
修改ExecStart行内容为ExecStart=/usr/local/bin/cri-dockerd --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.9 --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock --cri-dockerd-root-directory=/var/lib/dockershim --cri-dockerd-root-directory=/var/lib/docker
编辑cri-docker.socket
[root@master system]# vim cri-docker.socket修改ListenStream行内容为
ListenStream=/var/run/cri-dockerd.sock
复制cri-dockerd到其他节点
[root@master ~]# scp cri-dockerd-0.3.9.amd64.tgz root@node1:/root
cri-dockerd-0.3.9.amd64.tgz                               100%   14MB 125.4MB/s   00:00    
[root@master ~]# scp cri-dockerd-0.3.9.amd64.tgz root@node2:/root
cri-dockerd-0.3.9.amd64.tgz                               100%   14MB 126.4MB/s   00:00    
节点解压cri-docker
[root@node1 ~]# tar -xvf cri-dockerd-0.3.9.amd64.tgz --strip-components=1 -C /usr/local/bin/[root@node2 ~]# tar -xvf cri-dockerd-0.3.9.amd64.tgz --strip-components=1 -C /usr/local/bin/
复制修改好的service文件到其他节点
[root@master ~]# cd /etc/systemd/system/
[root@master system]# scp cri-docker.s* root@node1:/etc/systemd/system/
cri-docker.service                                        100% 1523     3.0MB/s   00:00    
cri-docker.socket                                         100%  210   533.3KB/s   00:00    
[root@master system]# scp cri-docker.s* root@node2:/etc/systemd/system/
cri-docker.service                                        100% 1523     3.3MB/s   00:00    
cri-docker.socket                                         100%  210   327.4KB/s   00:00    

启动并设置开机自启

[root@master system]# systemctl daemon-reload 
[root@master system]# systemctl restart cri-docker
[root@master system]# systemctl enable cri-docker

部署k8s源

三台都需要做

[root@master ~]# cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key
EOF
安装集群所需软件包kubelet kubeadm kubectl(全部节点)
[root@master ~]# yum install -y kubelet kubeadm kubectl
配置k8s Cgoup控制组(全部节点)
vim /etc/sysconfig/kubeletKUBELET_EXTRA_ARGS="--cgroup-driver=systemd"[root@master ~]# systemctl restart kubelet.service 
[root@master ~]# systemctl enable kubelet.service 
配置kubelet自启动(全部节点)
[root@master ~]# kubeadm config images list
I0923 11:00:25.255094    3466 version.go:256] remote version is much newer: v1.31.0; falling back to: stable-1.28
registry.k8s.io/kube-apiserver:v1.28.14
registry.k8s.io/kube-controller-manager:v1.28.14
registry.k8s.io/kube-scheduler:v1.28.14
registry.k8s.io/kube-proxy:v1.28.14
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.15-0
registry.k8s.io/coredns/coredns:v1.10.1

打印集群初始化配置文件(master节点运行)

[root@master ~]# kubeadm config print init-defaults > kubeadm-config.yaml

修改参数(master节点)

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:- system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages:- signing- authentication
kind: InitConfiguration
localAPIEndpoint:advertiseAddress: 192.168.100.10         #修改,集群初始化的主节点IP  bindPort: 6443
nodeRegistration:criSocket: unix:///var/run/cri-dockerd.sock          #修改使用dockeimagePullPolicy: IfNotPresentname: master                            #修改节点名称taints: null........imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers        #修改使用阿里云镜像仓库 

使用配置文件初始化(master节点运行)

[root@master ~]#  kubeadm init --config kubeadm-config.yaml --upload-certs--upload-certs参数是将集群密钥添加到etcd数据库
[init] Using Kubernetes version: v1.28.0
[preflight] Running pre-flight checks[WARNING FileExisting-socat]: socat not found in system path/// 有一个软件包没有安装,先安装在进行初始化
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
^C
安装
[root@master ~]# yum -y install socat再次进行初始化
[root@master ~]# kubeadm init --config kubeadm-config.yaml --upload-certs

配置环境变量(master节点运行)

根据初始化完成提示配置

[root@master ~]# cat /etc/profile.d/k8s.sh 
export KUBECONFIG=/etc/kubernetes/admin.conf

传给另外两台主机

[root@master ~]# scp /etc/profile.d/k8s.sh root@node1:/etc/profile.d/
k8s.sh                                             100%   45    65.4KB/s   00:00    
[root@master ~]# scp /etc/profile.d/k8s.sh root@node2:/etc/profile.d/
k8s.sh                                             100%   45    73.6KB/s   00:00    [root@master ~]# scp /etc/kubernetes/admin.conf root@node1:/etc/kubernetes/
admin.conf                                                100% 5650    10.4MB/s   00:00    
[root@master ~]# scp /etc/kubernetes/admin.conf root@node2:/etc/kubernetes/
admin.conf                                                100% 5650     9.0MB/s   00:00    都需要 source /etc/profile.d/k8s.sh

工作节点加入集群(工作节点运行)

根据初始化完成提示将工作节点添加入集群

kubeadm join 192.168.100.10:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:b195b482a4294f2727f3115298492fb1b148eded3a6d6f15cd243bee168aad0b --cri-socket=unix:///var/run/cri-dockerd.sock

注意:--cri-socket=unix:///var/run/cri-dockerd.sock参数是指定使用docker作为容器管理引擎

下载calico文件(master节点运行)

Calico是为集群中的 Pod 提供网络功能

[root@master ~]# wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml
创建calico网络(master节点运行)
[root@master ~]# kubectl apply -f calico.yaml
查看集群各节点状态
[root@master ~]# kubectl get nodes
NAME     STATUS   ROLES           AGE   VERSION
master   Ready    control-plane   49m   v1.28.14
node1    Ready    <none>          37m   v1.28.14
node2    Ready    <none>          36m   v1.28.14
查看k8s集群的各组件
[root@master ~]# kubectl get pod -n kube-system
NAME                                      READY   STATUS    RESTARTS   AGE
calico-kube-controllers-9d57d8f49-jjbc7   1/1     Running   0          8m11s
calico-node-8sptx                         1/1     Running   0          8m11s
calico-node-fd7pc                         1/1     Running   0          8m11s
calico-node-xsqp6                         1/1     Running   0          8m11s
coredns-6554b8b87f-4pkpz                  1/1     Running   0          52m
coredns-6554b8b87f-hsbcm                  1/1     Running   0          52m
etcd-master                               1/1     Running   0          52m
kube-apiserver-master                     1/1     Running   0          52m
kube-controller-manager-master            1/1     Running   0          52m
kube-proxy-8qvrh                          1/1     Running   0          39m
kube-proxy-jzxqs                          1/1     Running   0          52m
kube-proxy-zsghb                          1/1     Running   0          41m
kube-scheduler-master                     1/1     Running   0          52m

测试

使用k8s集群创建一个pod,运行nginx容器,然后进行测试

[root@master ~]# kubectl create  deployment  nginx  --image nginx
deployment.apps/nginx created
[root@master ~]# kubectl  expose  deployment  nginx  --port 80  --type NodePort
service/nginx exposed查看容器在哪个节点中运行的
[root@master ~]# kubectl  get  pods  -o  wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
nginx-7854ff8877-xgdpz   1/1     Running   0          32s   172.16.104.1   node2   <none>           <none>[root@master ~]# kubectl  get  services
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        55m
nginx        NodePort    10.99.81.235   <none>        80:32585/TCP   29s

测试访问

[root@master ~]# curl http://172.16.104.1
<!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>

修改网页内容

[root@master ~]# kubectl  get  pods  -o  wide
NAME                     READY   STATUS    RESTARTS   AGE     IP             NODE    NOMINATED NODE   READINESS GATES
nginx-7854ff8877-xgdpz   1/1     Running   0          6m26s   172.16.104.1   node2   <none>           <none>[root@master ~]# kubectl exec -it pod/nginx-7854ff8877-xgdpz -- /bin/bash
root@nginx-7854ff8877-xgdpz:/# cd /usr/share/nginx/html/
root@nginx-7854ff8877-xgdpz:/usr/share/nginx/html# ls
50x.html  index.html
root@nginx-7854ff8877-xgdpz:/usr/share/nginx/html# echo hello wuhan > index.html // 修改网页内容
root@nginx-7854ff8877-xgdpz:/usr/share/nginx/html# 

再次访问

[root@master ~]# curl http://172.16.104.1
hello wuhan

https://blog.csdn.net/huangjinjin520/article/details/140583970

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

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

相关文章

简单的spring缓存 Cacheable学习

简单的spring缓存 Cacheable学习 1.需求 项目中有很多的方法查询的数据其实是不会经常变的&#xff0c;但是其整体的查询sql以及调用第三方数据获取数据花费的时间很长&#xff0c;现在考虑对此类型的接口进行优化&#xff0c;首先想到的是对其进行缓存操作&#xff0c;所以简…

CVE-2024-46103

前言 CVE-2024-46103 SEMCMS的sql漏洞。 漏洞简介 SEMCMS v4.8中&#xff0c;SEMCMS_Images.php的search参数&#xff0c;以及SEMCMS_Products.php的search参数&#xff0c;存在sql注入漏洞。 &#xff08;这个之前就有两个sql的cve&#xff0c;这次属于是捡漏了&#x1f6…

[vulnhub] Hackademic.RTB1

第一次打靶机&#xff0c;思路看的红队笔记 https://www.vulnhub.com/entry/hackademic-rtb1,17/ 环境&#xff1a;kali Linux - 192.168.75.131&#xff0c;靶机 - 192.168.75.132 主机发现和端口扫描 扫描整个网络有哪台机子在线&#xff0c;不进行端口扫描 nmap -sP 192.16…

JavaSE高级(3)——lombok、juint单元测试、断言

一、lombok的使用 默认jvm不解析第三方注解&#xff0c;需要手动开启 链式调用 二、juint单元测试 下载juint包 public class TestDemo {// 在每一个单元测试方法执行之前执行Beforepublic void before() {// 例如可以在before部分创建IO流System.out.println("befor…

力扣周赛 —— 416

前言 只做出了第一道&#xff0c;第二第三道都超时。 痛&#xff0c;太痛了。 题目 Q1.举报垃圾信息 给你一个字符串数组 message 和一个字符串数组 bannedWords。 如果数组中 至少 存在两个单词与 bannedWords 中的任一单词 完全相同&#xff0c;则该数组被视为 垃圾信息。…

HTML讲解(三)通用部分

目录 1.空格标记 2.特殊文字的标记 3.注释语句 4.对文字字体的设置 5.修改文字形态 6.换行标记 7.居中标记 8.水平线标记 9.设置滚动弹幕 1.空格标记 在HTML中&#xff0c;我们想打印空格并不能直接敲一个空格键&#xff0c;因为如果是敲空格键&#xff0c;那无论你敲…

【已解决】ElementPlus 的 el-menu 组件如何用 js 控制展开某个子菜单,并在其他组件中控制使用呢?

文章目录 需求几次探索官网寻找线索&#xff08;解决办法&#xff09; 需求 我如何用代码来实现 ElementPlus 的菜单的展开和收缩呢&#xff1f; 几次探索 尝试通过找到节点之后&#xff0c;使用 click 事件&#xff0c;失败了 // 伪代码如下 const handleFindNodeAndClick …

vue Echart使用

一、在vue中使用Echarts 1.安装Echarts npm install echarts --save2.准备一个呈现图表的盒子 给盒子起名字是建议使用id选择器 这个盒子通常来说就是我们熟悉的 div &#xff0c;这个 div 决定了图表显示在哪里&#xff0c;盒子一定要指定宽和高 <div id"main&quo…

Scott Brinker:营销运营这一角色很棒可能会变得更棒;以下是关于相关职位的最新数据

营销运营职位晋升频繁 如果你在市场营销部门工作&#xff0c;生活可能相当不错。74%的营销人员表示&#xff0c;他们对自己的角色有些满意或非常满意。在过去的一年里&#xff0c;超过一半的人得到了晋升或找到了新工作。平均而言&#xff0c;他们的薪水比组织中其他类型的营销…

二、八、十、十六进制的相互转换(期末考试必备)

本文中写的计算方法和计算流程不一定就是正确规范的。。。 参考&#xff0c;仅供参考&#xff0c;如果有问题欢迎指出 目录 一、二进制 1.1 【二】进制转换【十】进制 1.2 【二】进制转换【八】进制 1.3 【二】进制转换【十六】进制 二、八进制 2.1 【八进制】转【二进…

Vue学习记录之八(局部组件,全局组件,递归组件,动态组件)

一、局部组件 在src\components\Card.vue 建立一个文件&#xff0c;代码如下&#xff1a; <template><div class"card"><header><div>标题</div><div>副标题</div></header><section>内容</section>&…

【HTML5】html5开篇基础(1)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

【标准库的典型内容】std::declval

一、 d e c l v a l declval declval的基本概念和常规范例 s t d : : d e c l v a l std::declval std::declval 是 C 11 C11 C11标准中出现的一个函数模板。这个函数模板设计的比较奇怪&#xff08;没有实现&#xff0c;只有声明&#xff09;&#xff0c;因此无法被调用&…

Android15之编译Cuttlefish模拟器(二百三十一)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

OpenCV特征检测(5)检测图像中的角点函数cornerMinEigenVal()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算用于角点检测的梯度矩阵的最小特征值。 该函数类似于 cornerEigenValsAndVecs&#xff0c;但它计算并存储协方差矩阵导数的最小特征值&…

MovieLife 电影生活

MovieLife 电影生活 今天看到一个很有意思的项目&#xff1a;https://www.lampysecurity.com/post/the-infinite-audio-book “我有一个看似愚蠢的想法。通常&#xff0c;这类想法只是一闪而过&#xff0c;很少会付诸实践。但这次有所不同。假如你的生活是一部电影&#xff0c…

vi | vim基本使用

vim三模式&#xff1a;① 输入模式 ②命令模式 ③末行模式&#xff08;编辑模式&#xff09; vim四模式&#xff1a;① 输入模式 ②命令模式 ③末行模式&#xff08;编辑模式&#xff09; ④V模式 一、命令模式进入输入模式方法&#xff1a; 二、命令模式基…

影刀RPA实战:java结合影刀同步采购订单数据

1.实战目标 本次实战我们用java语言结合影刀&#xff0c;实现从自用ERP系统同步订单到旺店通中&#xff0c;在工作中&#xff0c;有时候我们的运营数据不是直接在旺店通ERP中操作&#xff0c;比如我们有自己的ERP&#xff0c;完成一些特定的内部工作后&#xff0c;再把数据同步…

Rustrover2024.2 正式发布:个人非商用免费,泰裤辣

如果这个世界本身 已经足够荒唐 那究竟什么才能算是疯狂 爱情就是这样 一旦错过了 就会有另一个人代替 我们知道 jetbrains 在今年的早些时候正式为 rust 语言发布了专用的 IDE &#xff0c;也就是 rustrover。如今 rustrover 也正式跻身为 jetbrains IDE 系列的一员猛将。…

Python | Leetcode Python题解之第424题替换后的最长重复字符

题目&#xff1a; 题解&#xff1a; class Solution:def characterReplacement(self, s: str, k: int) -> int:num [0] * 26n len(s)maxn left right 0while right < n:num[ord(s[right]) - ord("A")] 1maxn max(maxn, num[ord(s[right]) - ord("…