k8s volcano + deepspeed多机训练 + RDMA ROCE+ 用户权限安全方案【建议收藏】

目录

一、k8s环境配置

1.安装gpu-operator

2. 安装 rdma-shared-plugin

3. 安装volcano调度器

4. 创建research rbac认证

 二、宿主机环境配置

1. 安装docker 客户端

2. 创建系统用户

3. 修改docker /etc/docker/daemon.json 文件如下

4. 修改系统 /etc/subuid

三、制作基于deepspeed的基础镜像

1. Dockerfile

2. ssh_config  

3. sshd_config

4. start.sh

 四、k8s yaml文件


前提:nvidia、cuda、nvidia-fabricmanager等相关的组件已经在宿主机正确安装,如果没有安装可以参考我之前发的文章
GPU A800 A100系列NVIDIA环境和PyTorch2.0基础环境配置【建议收藏】_a800多卡运行环境配置-CSDN博客文章浏览阅读1.1k次,点赞8次,收藏16次。Ant系列GPU支持 NvLink & NvSwitch,若您使用多GPU卡的机型,需额外安装与驱动版本对应的nvidia-fabricmanager服务使GPU卡间能够互联,否则可能无法正常使用GPU实例。【摘要】 Nvidia A系列裸金属服务器安装NVIDIA和CUDA驱动,安装conda和pytorch2.0并验证cuda的有效性。选择安装环境相关版本: GPU驱动版本为530.30.02、CUDA版本为12.1.0。注意事项: 不能选择Driver, 否则会覆盖已安装的NVIDIA驱动._a800多卡运行环境配置https://blog.csdn.net/weixin_43798031/article/details/136853839?spm=1001.2014.3001.5501

一、k8s环境配置

1.安装gpu-operator

使用官方的helm chart进行安装 gpu-operator-v24.3.0.tgz

# 创建namespace
kubectl  create  ns gpu-operator

# 下载chart
wget https://github.com/NVIDIA/gpu-operator/releases/download/v24.3.0/gpu-operator-v24.3.0.tgz

# 解压
tar xf gpu-operator-v24.3.0.tgz

# 其中有一些插件是可选择的,可以根据环境的情况进行修改
# 安装
helm isntall -f values.yaml  gpu-operator -n gpu-operator

2. 安装 rdma-shared-plugin

特此说明一下,这篇文章用的是RDMA ROCE方案,采用的宿主机网络模式所以下面的这个插件可以选择性的安装,

k8s-rdma-shared-dev-plugin-config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: rdma-devices
  namespace: kube-system
data:
  config.json: |
    {
        "periodicUpdateInterval": 300,
        "configList": [
           {
             "resourceName": "shared_ibs",
             "rdmaHcaMax": 1000,
             "selectors": {
               "ifNames": ["GPU0", "GPU1", "GPU2", "GPU3"]  #根据实际的ib网卡名称修改
             }
           }
        ]
    }
k8s-rdma-shared-dev-plugin-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: rdma-shared-dp-ds
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: rdma-shared-dp-ds
  template:
    metadata:
      labels:
        name: rdma-shared-dp-ds
    spec:
      hostNetwork: true
      priorityClassName: system-node-critical
      containers:
      - image: mellanox/k8s-rdma-shared-dev-plugin
        name: k8s-rdma-shared-dp-ds
        imagePullPolicy: IfNotPresent
        securityContext:
          privileged: true
        volumeMounts:
          - name: device-plugin
            mountPath: /var/lib/kubelet/
          - name: config
            mountPath: /k8s-rdma-shared-dev-plugin
          - name: devs
            mountPath: /dev/
      volumes:
        - name: device-plugin
          hostPath:
            path: /var/lib/kubelet/
        - name: config
          configMap:
            name: rdma-devices
            items:
            - key: config.json
              path: config.json
        - name: devs
          hostPath:
            path: /dev/
测试是否安装成功,登陆到容器中查看ib网卡
rdma-test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mofed-test-pod
spec:
  restartPolicy: OnFailure
  containers:
  - image: mellanox/rping-test
    name: mofed-test-ctr
    securityContext:
      capabilities:
        add: [ "IPC_LOCK" ]
    resources:
      limits:
        rdma/shared_ibs: 1
    command:
    - sh
    - -c
    - |
      ls -l /dev/infiniband /sys/class/infiniband /sys/class/net
      sleep 1000000

3. 安装volcano调度器

相关的部署文件在这里,具体的调度规则大家可以根据实际的情况去配置,第一次接触volcano的同学可能要增加一些学习成本

https://download.csdn.net/download/weixin_43798031/89397746icon-default.png?t=N7T8https://download.csdn.net/download/weixin_43798031/89397746

kubectl  apply -f volcano-development.yaml 

#测试一下
kubectl  apply -f  test-job.yaml

apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: test-job4
spec:
  minAvailable: 1
  schedulerName: volcano
  policies:
    - event: PodEvicted
      action: RestartJob
  plugins:
    ssh: []
    env: []
    svc: []
  maxRetry: 5
  queue: default
  tasks:
    - name: "postproc"
      replicas: 1
      template:
        metadata:
          name: postproc
        spec:
          containers:
            - image: nginx
              imagePullPolicy: IfNotPresent
              name: postproc
              resources:
                requests:
                  cpu: "1"
          restartPolicy: OnFailure
    - name: "agent"
      replicas: 1
      template:
        metadata:
          name: agent
        spec:
          containers:
            - image: nginx
              imagePullPolicy: IfNotPresent
              name: agent
              resources:
                requests:
                  cpu: "1"
          restartPolicy: OnFailure

4. 创建research rbac认证

可以参考我的这篇文章

k8s rbac 权限管理控制创建过程+理论知识_子账号无权限执行kubectl config get-contexts命令-CSDN博客

openssl genrsa -out research.key 2048

opensopenssl req -new -key research.key -out research.csr -subj "/CN=research/O=default"


openssl x509 -req -in research.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out research.crt -days 3650

    
kubectl config set-credentials research --client-certificate=research.crt --client-key=research.key 

    
kubectl config set-context research-context --cluster=kubernetes --namespace=default --user=research --kubeconfig=research.conf


切到research-context 用户上下文
kubectl config use-context research-context 

显示当前上下文
kubectl config get-contexts

切回admin 
kubectl config use-context kubernetes-admin@kubernetes 

 二、宿主机环境配置

1. 安装docker 客户端

因为我们已经使用containerd 为runtime,

2. 创建系统用户

# 创建research用户并指定uid和gid, 指定uid和gid时一定要选择一个没有占用的,因为我们要在每台机器都要指定
ansible -i ip.txt all -m shell -a 'sudo useradd -m -s /bin/bash -u 2000 -g 2000 research'

# 将research用户加入到docker 组,这样research 用户就可以使用docker命令了
ansible -i ip.txt all -m shell -a 'sudo usermod -aG docker research' 

# 创建.kube目录
ansible -i ip.txt all -m shell -a 'mkdir /home/research/.kube/'

# 将上面的k8s config 发送到每台机器
ansible -i ip.txt  all -m copy -a 'src=/home/sunwenbo/rbac/research.conf dest=/home/research/.kube/config'

# 修改权限
ansible -i ip.txt all -m shell -a 'chown -R research:research /home/research/.kube/'

3. 修改docker /etc/docker/daemon.json 文件如下

普通用户启动docker 挂载宿主机目录,如果容器使用的root用户,则输出的文件权限为root,那么普通用户在宿主机则无法读取和使用则会有问题
 


{
  "userns-remap": "research",   
  "max-concurrent-downloads": 10,
  "log-driver": "json-file",
  "log-level": "warn",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
    },
  "data-root": "/var/lib/data/docker",
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": ["https://uyah70su.mirror.aliyuncs.com"],
  "insecure-registries": [ "a800-harbor.bigmodel.cn"],
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}

 配置说明: "userns-remap": "research",   这个配置代表Docker将会使用research用户和组进行用户命名空间映射,说白了就是将系统的research用户映射到容器里,但是这么设置会有一个问题就是root导入到镜像或者是容器就看不到了。

4. 修改系统 /etc/subuid 和subgid

每台机器都要修改research的uid为2000

research:2000:65536

ansible -i ip.txt all -m shell -a "sed  -i  's/^research:[0-9]\+:65536/research:2000:65536/' /etc/subuid"

ansible -i ip.txt all -m shell -a "sed  -i  's/^research:[0-9]\+:65536/research:2000:65536/' /etc/subgid"

简单描述一下3,4步骤,主要目的就是为了解决当启动一个容器挂载宿主机数据时解决文件权限的问题。通过3,4的设置我们在容器中产生的数据的权限会保持为research

三、制作基于deepspeed的基础镜像

所需要的文件

Dockerfile  ssh  ssh_config  sshd_config  start.sh

./ssh:
authorized_keys  id_rsa  id_rsa.pub  known_hosts  known_hosts.old

文件说明:

Dockerfile:制作镜像

ssh: 我们需要提前创建好公钥和私钥并下发给集群的每台机器,实现可以免密ssh登陆

ssh_config:  镜像中sshd服务的客户端配置文件,需要指定连接时使用的默认端口和关闭登录时验证

sshd_config: 镜像中sshd服务的服务端配置文件, 需要修改默认端口

start.sh: 镜像启动脚本



1. Dockerfile

research用户说明:

考虑到安全问题,因为我们在gpu服务器上同时部署了共享存储Glusterfs,我们的每台机器只对算法开放普通用户权限。

过程中遇到使用k8s时启动训练任务因为挂载了宿主机共享存储的数据,而容器中默认情况下使用的都是root用户,这个时候就会导致训练输出的产物权限变为了root。 系统用户research 则没有权限去对这个文件进行操作

# 使用基础镜像
FROM nvcr.io/nvidia/pytorch:23.12-py3

# 创建research用户并设置密码
RUN groupadd -g 2000 research && \
    useradd -m -u 2000 -g 2000 -s /bin/bash research

# COPY start script
COPY start.sh /start.sh

#COPY ssh config to /etc/ssh
COPY ssh /home/research/.ssh/

# Install SSH server
RUN apt-get update && apt-get install -y --no-install-recommends openssh-server ssh net-tools pdsh && \
    apt-get clean && \
    chown -R root:root /usr/lib && \
    chown -R research:research /home/research/.ssh && \
    rm -rf /var/lib/apt/lists/* && \
    chmod 600 /home/research/.ssh/authorized_keys && \
    chmod 700 /home/research/.ssh && \
    mkdir /var/run/sshd

# 安装deepspeed
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \                                                                                                       
    pip install deepspeed && \                                                                                                                                                          
    pip install tiktoken && \                                                                                                                                                          
    pip install lmdb  && \                                                                                                                                                          
    pip install sentencepiece   

# 设置环境变量,指定时区
ENV TZ=Asia/Shanghai \
    DEBIAN_FRONTEND=noninteractive

ENV CUDA_DEVICE_MAX_CONNECTIONS="1"

RUN apt update \
    && apt install -y tzdata \
    && ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime \
    && echo ${TZ} > /etc/timezone \
    && dpkg-reconfigure --frontend noninteractive tzdata \
    && rm -rf /var/lib/apt/lists/*

COPY ssh_config sshd_config /etc/ssh/

EXPOSE 2222


CMD ["/start.sh"]

2. ssh_config  

Include /etc/ssh/ssh_config.d/*.conf

Host *
    StrictHostKeyChecking no
    Port 2222
    SendEnv LANG LC_*
    HashKnownHosts yes
    GSSAPIAuthentication yes

3. sshd_config

Include /etc/ssh/sshd_config.d/*.conf
Port 2222
KbdInteractiveAuthentication no
UsePAM yes
X11Forwarding yes
PrintMotd no
AcceptEnv LANG LC_*
Subsystem       sftp    /usr/lib/openssh/sftp-server

4. start.sh

#!/bin/bash

# Start the SSH server
/usr/sbin/sshd -D

# 执行传入的命令
exec "$@"

执行docker build后我们会得到一个镜像

docker build -t xxx.service.xxx.cn/xxx/xxx-base:v2 .

备注:根据docker 可以看到我们创建了一个research用户,当开始训练时我们需要使用research 用户去连接其他机器。同时需要做到免密登陆和认证 。另外

 四、k8s yaml文件

apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: xxxxxx  #可以修改名字,防止跟别人冲突导致K8S Pod无法启动
  namespace: default
spec:
  minAvailable: 5
  schedulerName: volcano
  policies:
    - event: PodFailed
      action: TerminateJob
    - event: PodEvicted
      action: TerminateJob
    - event: TaskFailed
      action: TerminateJob
    - event: TaskCompleted
      action: CompleteJob
  plugins:
    env: []
    svc: []
  maxRetry: 5
  queue: default
  ttlSecondsAfterFinished: 10
  tasks:
    - name: "main"
      replicas: 1
      template:
        metadata:
          name: training
        spec:
          securityContext:
            runAsUser: 2000   # research 用户的 UID
            fsGroup: 2000     # research 用户的 GID
          volumes:
            - name: dshm
              emptyDir:
                medium: Memory
                sizeLimit: 50Gi
            - name: xxx-code-path
              hostPath:
                path: /home/bmm-system/data/private/xxx   #挂载代码路径
                type: Directory
          containers:
            - name: main
              image: xxx.service.xxx.cn/delivery/xxxx:v2.1
                #imagePullPolicy: IfNotPresent
              imagePullPolicy: Always
              securityContext:
                capabilities:
                  add:
                  - IPC_LOCK
              volumeMounts:
                - name: dshm
                  mountPath: /dev/shm
                - name: xxx-code-path
                  mountPath: /home/bmm-system/data/private/xxx    #挂载代码路径
                    #args: ["/bin/sh", "-c", "cd xxxx"]  #执行的命令
              args: ["/bin/sh", "-c", "sleep 600000"]  # 根据实际运行命令去做修改
              env:
                - name: NODE_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: spec.nodeName
                - name: NODE_IP
                  valueFrom:
                    fieldRef:
                      fieldPath: status.hostIP
                - name: TRITON_CACHE_DIR
                  value: "/tmp/.triton"
          restartPolicy: OnFailure
          imagePullSecrets:
          - name: xxx-registry
    - name: "worker"
      replicas: 4    #副本数,也就是训练所需要的节点数
      template:
        metadata:
          name: training
        spec:
          hostNetwork: true  # 采用宿主机网络模式
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: TrainingMachine
                    operator: In
                    values: ["5", "6", "7", "8"]        #制定训练用的节点,A800的10台机器按照1,2...10来指定
          volumes:
            - name: dshm
              emptyDir:
                medium: Memory
                sizeLimit: 50Gi
            - name: user-root
              hostPath:
                path: /home/bmm-system/data/private/xxxx   #宿主机挂载路径,指定数据所在位置
                type: Directory
            - name: xxx-ckpt-path
              hostPath:
                path: /home/bmm-system/data/ckpt   #宿主机挂载路径,指定到权重所在位置
                type: Directory
          containers:
            - name: worker
              image: xxx.service.xxx.cn/delivery/xxx-base:v2.1
                #imagePullPolicy: IfNotPresent
              imagePullPolicy: Always
              securityContext:
                capabilities:
                  add:
                  - IPC_LOCK
              volumeMounts:
                - name: dshm
                  mountPath: /dev/shm
                - name: user-root
                  mountPath: /home/bmm-system/data/private/xxx   #宿主机挂载路径,指定数据所在位置
                - name: xxx-ckpt-path
                  mountPath: /home/bmm-system/data/ckpt   #宿主机挂载路径,指定到权重所在位置
                  readOnly: true
              command: ["/bin/bash"]
              args: ["-c", "/start.sh"]
              env:
                - name: NODE_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: spec.nodeName
                - name: NODE_IP
                  valueFrom:
                    fieldRef:
                      fieldPath: status.hostIP
                - name: TRITON_CACHE_DIR
                  value: "/tmp/.triton"
              resources:
                requests:
                  nvidia.com/gpu: 8
                limits:
                  nvidia.com/gpu: 8
          restartPolicy: OnFailure
          imagePullSecrets:
          - name: xxx-registry

说明:

1. 可以看到该yaml中在main pod 指定了research的uid和gid,即代表使用该用户去启动训练任务       

runAsUser: 2000   # research 用户的 UID
fsGroup: 2000     # research 用户的 GID

这样就可以解决挂载数据权限的问题和上面docker启动容器遇到的问题同理。

2. 还有一个配置得说明一下就是env中的

- name: TRITON_CACHE_DIR
  value: "/tmp/.triton"

由于使用了deepspeed 框架,在启动训练任务时框架内部逻辑会在当前目录下创建一些临时的隐藏文件,而我们不需要对这些文件进行存储个人建议将这个目录修改为/tmp下。这样当训练任务结束后这个文件就会自动被清理

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

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

相关文章

APP终极瘦身方案

具体可参见 github.com/shwenzhang/… 优化META-INF MANIFEST.MF:是摘要文件,程序会遍历apk包中所有的文件,对非文件夹、非签名文件的文件,逐个编码生成摘要信息,并记录于此。如果逆向修改了任何文件,那么…

异地数据中心的数据实时同步,该怎样智能化实现?

为了提高系统的可用性和容错性,越来越多的企业和机构采用两地三中心方案等来进行异地数据中心的建设。数据中心建立后,数据需要同步至总部或其他数据中心及系统,以确保数据的冗余性、可用性、可靠性和一致性。在分布式系统、云计算、容灾备份…

游戏工厂:AI(AIGC/ChatGPT)与流程式游戏开发

游戏工厂:AI(AIGC/ChatGPT)与流程式游戏开发 码客 卢益贵 ygluu 关键词:AI(AIGC、ChatGPT、文心一言)、流程式管理、好莱坞电影流程、电影工厂、游戏工厂、游戏开发流程、游戏架构、模块化开发 一、前言…

3D开发工具HOOPS为BIM应用提供支持:复杂大模型实现Web端轻量化!

在数字化转型的浪潮中,Tech Soft 3D以其HOOPS SDK工具包,为软件开发人员提供了强大的支持。这一工具包不仅支持Windows、Linux、OSX和移动平台等多样化的操作系统,还使得开发人员能够构建出庞大而复杂的建筑和BIM应用程序。HOOPS SDK的多格式…

RIP动态路由配置

1、搭建网络 搭建拓扑、规划IP地址、划分网段、设置端口 2、配置交换机,路由器 三层交换机配置 Switch>enable Switch#conf t Enter configuration commands, one per line. End with CNTL/Z. Switch(config)#hostname S3560S3560(config)#vlan 10 S3560(con…

fot循环语句

概念: 循环是一种重复执行一段代码的结构,只要满足循环的条件,会一种执行这个代码。 循环条件:在一定范围内,按照指定的次数来执行循环 循环体:在指定的次数内,执行的命令序列。只要条件满足…

GD32F4xx 移植agile_modbus软件包与电能表通信

目录 1. agile_modbus1.1 简介1.2 下载2. agile_modbus使用2.1 源码目录2.2 移植3. 通信调试3.1 代码3.3 通信测试1. agile_modbus 1.1 简介 agile_modbus是一个轻量级的Modbus协议栈,主要特点: 支持RTU和TCP协议,采用纯C语言开发,不涉及任何硬件接口,可直接在任何形式的…

2024年【N1叉车司机】考试及N1叉车司机考试题库

题库来源:安全生产模拟考试一点通公众号小程序 N1叉车司机考试是安全生产模拟考试一点通总题库中生成的一套N1叉车司机考试题库,安全生产模拟考试一点通上N1叉车司机作业手机同步练习。2024年【N1叉车司机】考试及N1叉车司机考试题库 1、【多选题】《中…

一站式实时数仓Hologres整体能力介绍

讲师:阿里云Hologres PD丁烨 一、产品定位 随着技术的进步,大数据正从规模化转向实时化处理。用户对传统的T1分析已不满足,期望获得更高时效性的计算和分析能力。例如实时大屏,城市大脑的交通监控、风控和实时的个性化推荐&…

计算机专业:昔日万金油,明日科技潮头的弄潮儿

高考后的十字路口:计算机专业,依旧闪耀吗? 随着2024年高考的尘埃落定,数百万青春洋溢的脸庞再次凝视着未来的迷雾,试图在繁星点点的专业宇宙中找到那颗最亮的星——计算机科学与技术。长久以来,计算机专业…

如何在Windows 11和10上清除更新缓存?这里提供了几种方法

​Windows 11和Windows 10都可以非常轻松地清除Windows更新缓存。可以使用图形方法或命令行选项删除保存的更新文件。我们将向你展示你的可用选项。 为什么要清除Windows更新缓存 你可能希望清除Windows更新缓存的原因有很多。 你可能在查找或安装更新时遇到问题,清除缓存通…

ansible 模块进阶及变量

yum 模块进阶 - name: install pkgs hosts: webservers tasks: - name: install web pkgs # 此任务通过yum安装三个包 yum: name: httpd,php,php-mysqlnd state: present # 根据功能等,可以将一系列软件放到一个组中,安装软件包组,将会把很…

IK分词器---Elasticsearch(standard、ik_smart、ik_max_word、拓展词典---ik_max_word)

IK分词器 Elasticsearch的关键就是倒排索引,而倒排索引依赖于对文档内容的分词,而分词则需要高效、精准的分词算法,IK分词器就是这样一个中文分词算法。 1.4.1.安装IK分词器 方案一:在线安装 运行一个命令即可: do…

稳态与敏态业务阶段

稳态业务就是比如你登录学校的图书馆教务处这些业务系统 用户数量和数据基本上不会发生太大的变化 业务系统的更新也不是很频繁,比较方便资源的采购 敏态业务就是比如我开发一个应用上线了,我不知道有多少用户和数量,无法预估 这就没办法…

ru俄罗斯域名如何申请SSL证书?

我们日常看到的都是com这种国际域名比较普遍,尤其是主流网站,主要原因考虑的其通用性,那么对于地方性的域名大家很少看到,比如俄罗斯国家域名.ru大家还是有些陌生的,但要说中国.CN域名那你就很熟悉了。 有用户在申请过…

python子类调用其他.py文件的父类

main.py需要使用os.py中的构造类。 os.py中定义了一个Ui_MainWindow类 在main.py中定义了一个MyMainWindow子类,传入两个父类的变量名 super(Ui_MainWindow, self).__init__()super() super() 是一个内置函数,用于返回一个代表父类的对象,…

使用Mysql模糊查询指定多个字段条件,输出结果的详细教程!

本篇文章主要讲解:通过mysql实现对多个列字段进行模糊查询的方式说明,通过本篇文章你可以快速掌握对多条件查询的方法 日期:2024年6月22日 作者:任聪聪 一、准备工作 步骤一、新建一个test数据库,如下图: …

使用C语言实现植物大战僵尸教程

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习…

如何使用kimi智能助手:您的智能生活小助手

Kimi智能助手是一款功能强大的AI工具,旨在帮助用户提高工作效率和生活品质。下面小编将详细介绍如何使用Kimi智能助手,涵盖其主要功能以及一些实用技巧。 一、Kimi智能助手的主要功能 多语言对话能力:Kimi擅长中文和英文的对话,可…

Ubuntu编译安装sqlite3库

基础环境说明:本机使用Windows 11 家庭版本搭载 Ubuntu 22.04.4 LTS 子系统。进行sqlite3 数据库源码编译和库函数生成。 sqlite3的简介 什么是SQLite3? sqlite3是一个进程内的库,实现了自给自足、无服务器、零配置、事务性的SQL数据库引擎…