docker详解
内容详细
docker入门
# 什么是虚拟化
在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件 对资源充分利用
虚拟化技术种类很多,例如:软件虚拟化、硬件虚拟化、内存虚拟化、网络虚拟化(vip)、桌面虚拟化、服务虚拟化、虚拟机等等
# 名词解释
-kvm,VMware:kvm:Kernel-based Virtual Machine,linux上虚拟化的技术,把一台机器虚拟化成多台
-openstack:python写的,创建,管理,销毁 虚拟机的管理工具,web管理界面,点点点就能创建,删除虚拟机
-kvm+openstack的方案:公司多台服务器,openstack是管理虚拟机的工具
-docker:容器技术
-k8s:kubernetes,kubernetes是管理container(docker)的工具,多机容器管理(多机容器编排)
-公司主流:k8s+docker
kvm+k8s+docker
功能上:kubernetes是管理container的工具,openstack是管理VM的工具。
业务上:openStack是定位于laaS平台的项目,Kubernetes是定位于PaaS平台的项目
时间上:云平台方案的第一阶段:虚拟机;云平台方案的第二阶段:容器技术
# 什么是Docker
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护
Docker 的基础是 Linux 容器(LXC)等技术
用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单:把docker容器当成一个虚拟机装了一个操作系统
# docker的好处
-轻量级
-统一环境
-可以快速扩展到多台机器
# 容器与虚拟机比较
-虚拟机需要虚拟化出操作系统:笨重,资源消耗大
-容器:轻量级,资源消耗小
# IAAS PAAS SAAS FAAS
一 IaaS基础设施服务
-IaaS: Infrastructure-as-a-Service(基础设施即服务)
-第一层叫做IaaS,有时候也叫做Hardware-as-a-Service,几年前如果你想在办公室或者公司的网站上运行一些企业应用,你需要去买服务器,或者别的高昂的硬件来控制本地应用,让你的业务运行起来。
-但是现在有IaaS,你可以将硬件外包到别的地方去。IaaS公司会提供场外服务器,存储和网络硬件,你可以租用。节省了维护成本和办公场地,公司可以在任何时候利用这些硬件来运行其应用。
- 一些大的IaaS公司包括Amazon, Microsoft, VMWare, Rackspace和Red Hat.
# 买了阿里云的服务器,就相当于买了阿里云的IAAS服务
二 paas平台即服务
-不仅卖服务器,还卖软件
-OSS对象存储,阿里云mysql服务,阿里云的redis
三 saas软件即服务
-多租户
-社保局:社保软件
四 FAAS:函数及服务
-Serverless:无服务
# 补充:运维软件的名词
-混合云:公司自己有服务器(私有云),买了云服务器(公有云)
-nginx: web服务器:请求转发,负载均衡
-ansible:python+paramiko写的,批量操作服务器的软件
-paramiko
-ssh链接,最多操作服务器不超过500台
-服务端,无agent
-SaltStack:python+消息队列-批量操作服务器的软件
-服务端,客户端,被控机装客户端
-zabbix:php写的,web服务器,监控软件,监控进程
-Prometheus+Grafana:go写的,监控软件,主要用来监控容器,监控进程
-jenkins:java写的,自动化构建工具
-CI(CI-Continuous integration,持续集成)
持续集成是指多名开发者在开发不同功能代码的过程当中,可以频繁的将代码行合并到一起并切相互不影响工作。
持续集成的目的,是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成
-CD(CD-continuous deployment,持续部署)
是基于某种工具或平台实现代码自动化的构建、测试和部署到线上环境以实现交付高质量的产品,持续部署在某种程度上代表了一个开发团队的更新迭代速率
-docker:容器技术
-k8s:容器编排,多机容器编排
docker组件介绍
# Docker:容器技术 ,隔离
-dotCloud go写的软件
- Docker 的基础是 Linux 容器(LXC)等技术
- LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单
# 好处:
-举例说明:
-开发阶段:win上开发的,python3.8 ,第三方模块
-上线阶段:linux python3.8 第三方模块 不同平台有差异
-使用docker统一开发和部署环境
-只要部署项目运行器一个容器即可(python+django+drf+uwsgi+代码)
-java容器:(jdk+tomcat+java代码)
# docker cs架构软件
-服务器端,客户端
-客户端cli
-客户端和服务端交互使用resfulapi
-客户端:docker ps----》http请求,符合resful规范----》服务端 执行
# 架构
- 客户端cli
- 服务端 server:docker 主进程,负责接受docker 客户端传过来的命令
-Images:重点,镜像,一堆文件:当成虚拟机上装的操作系统的iso文件(操作系统+某个软件)
-containers:重点:容器,运行的:当成在虚拟机上装了操作系统后开机了(centos系统,centos+redis)
-networks:网络:网络模式,容器间通信,容器跟宿主机通信
-Volumes:数据卷,存放容器中软件,文件的地方
- Registry:远程仓库,镜像是从远程仓库下载下来的
-镜像
# 镜像和容器
-镜像是从远程拉去下来的文件
-容器是镜像运行后得到的,一个镜像可以运行多个容器
-面向对象中得 类:镜像 对象:容器
-容器:把容器当做一个操作系统上运行了软件
-运行了redis容器:一个操作系统运行了redis
docker安装启动
# docker 可以安装在各个操作系统之上
-centos 7.5
-win10 以上可以
-mac
-最好,在虚拟机的centos上安装
# 版本介绍
Docker-CE指Docker社区版,由社区维护和提供技术支持,为免费版本,适合个人开发人员和小团队使用。
Docker-EE指Docker企业版,为收费版本,由售后团队和技术团队提供技术支持,专为企业开发和IT团队而设计
# 卸载:
- 停止服务: systemctl stop docker
-yum list installed | grep docker
-yum remove docker-ce.x86_64 docker-ce-cli.x86_64 docker-ce.x86_64 docker-ce-cli.x86_64
-rm -rf /var/lib/docker
# 安装
- 安装一些依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
-把yum源设置为阿里云
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装docker
sudo yum install docker-ce -y
-查看docker版本
docker -v # Docker version 20.10.22, build 3a2c30b
# win和mac :https://get.daocloud.io/#install-docker-for-mac-windows
# 配置国内镜像站:仓库在国外,下载镜像很慢,配置国内镜像站
-阿里云:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
-mkdir -p /etc/docker
-vim /etc/docker/daemon.json
-写入
{
"registry-mirrors": ["https://x1566319.mirror.aliyuncs.com"]
}
-重启
sudo systemctl daemon-reload
sudo systemctl restart docker
# docker 命令
# 启动docker:
systemctl start docker
#停止docker:
systemctl stop docker
#重启docker:
systemctl restart docker
#查看docker状态:
systemctl status docker
#开机启动:
systemctl enable docker
#查看docker概要信息
docker info # docker客户端,服务端的概要信息
docker镜像操作
# 搜索镜像
docker search 镜像名字 # 直接去网站搜索
# 从远程仓库拉取文件
docker pull centos:centos7.9.2009
docker pull python:3.8-slim
docke pull redis # 最新版
docker pull mysql:5.7
# 查看本地镜像
docker images
# 删除镜像
docker rmi 镜像id
# 一次性删除所有镜像
docker rmi `docker images -q`
# 一次性删除所有容器
docker rm `docker ps -aq`
# 下面做了解
-自己制作了一个镜像,想传到自己的仓库里
- 把本地的镜像打个标签
docker tag 镜像id liuqingzheng/xxxx
docker login #输入用户名密码
docker push liuqingzheng/xxxx
你的仓库你就能看到了
# 镜像分层:好处 面试题
-镜像上传到远程仓库
-从远程仓库下载镜像
-做加速
-只要在容器中新增了文件,就会多一层
# 如何获取镜像:
- docker pull 拉取
- 压缩包还原
- 容器反打包成镜像
- dockerfile构建
docker容器操作
# 1 基于镜像运行成容器
-创建容器,运行容器
# -it和-id区别 :it进入到容器内部 ,id以守护进程运行容器,不进入
# --name=名字 不写会随机
# centos:7 镜像的名字和tag
# -p 3307:3306 把宿主机的3307端口映射到容器的3306端口,以后访问宿主机的3307,就等于访问容器的3306
# -v /root/lqz:/home 把宿主机的/root/lqz映射到容器的 /home ,以后再宿主机或容器内修改这个文件夹,都会相互影响
# 在容器内部,退出来:exit ---》只要退出,容器也退出了
-docker run -it --name=centos centos:7 # 基于centos:7镜像 创建并运行容器,进入到容器中,名字为centos
# 2 查看正在运行的容器
docker ps
# 3 查看所有容器
docker ps -a
# 4 在容器上执行命令
docker exec 容器id ls
docker exec 12a6a0281168 ls
docker exec -it 12a6a0281168 /bin/bash
# 5 停止容器
docker stop 容器id
# 6 运行容器
docker start 容器id
# 7 删除
docker rm 容器id # 正在运行的容器不能删
# 8 文件拷贝
-把宿主机文件cp到容器内部
docker cp 宿主机文件 容器id:容器路径
-把容器内部文件cp到宿主机
docker cp 容器id:路径/文件 /root/ss.py
# 9 查看容器信息
docker inspect 容器id
docker inspect --format='{{.NetworkSettings.IPAddress}} 容器id # 查看ip地址
# 你能不能基于centos镜像运行成容器---》在容器中安装python解释器
应用部署
mysql部署
# 在宿主机上不需要安装mysql了,直接拉取mysql镜像,运行成容器即可
# 部署步骤
-1 创建文件夹
mkdir /root/mysql
mkdir /root/mysql/conf.d
mkdir /root/mysql/data/
-2 基于镜像运行成容器(端口映射,目录映射)
docker run -id --name=mysql -p 3306:3306 -v /root/mysql/conf.d:/etc/mysql/conf.d -v /root/mysql/data/:/var/lib/mysql -v /root/mysql/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
# 运行mysql 需要传入环境变量
MYSQL_ROOT_PASSWORD #root超级管理员的密码
-3 mysql配置文件,新建
-在mysql文件夹下
touch my.cnf
-4 运行2 的命令
-5 远程链接mysql ,创建库,创建表
-6 在容器中链接mysql,可以看到库和表
-7 删除容器
-8 创建一个新容器,数据还在[一定要做目录映射]
my.cnf
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
redis部署
# 步骤:
-1 拉取redis镜像
-2 创建文件夹和文件
mkdir reids
mkdir reids/conf
mkdir reids/data
vim ./reids/conf/redis.conf
-3 配置文件
bind 0.0.0.0
daemonize NO
protected-mode no
requirepass 123456
-4 docker命令
# low一些,没有做目录映射
docker run -di --name=myredis -p 6379:6379 redis
# 咱们用这个
docker run -id -p 6379:6379 --name redis_6379 -v /root/reids/conf/redis.conf:/etc/redis/redis.conf -v /root/reids/data:/data redis redis-server /etc/redis/redis.conf --appendonly yes
部署nginx
# 步骤
-1 拉取nginx镜像
-2 docker 命令
docker run -id --name=nginx -p 80:80 nginx
-3 从win机器浏览器可以访问:10.0.0.205:80
-4 今日容器内部,修改index /usr/share/nginx/html
-5 修改index.html
-vi vim都没有,安装发现yum也没有,它不是centos
-apt-get update
-apt-get install vim
-6 访问,发现页面变了
迁移与备份
容器做成镜像
# 把容器,打包成镜像--->容器中装了很多软件
-python 镜像,基于debain做的
-基于centos ,装python3.8解释器----》镜像---》放到网上给别人用
# 咱们案例,基于ngixn+vim+index改了的 做成镜像
-docker commit 427066d078c3 nginx_vim
# 基于自己做的镜像,运行成容器
docker run -id --name=xxx -p 8080:80 nginx_vim:latest
把镜像备份成压缩包
# 把镜像做成tar文件
docker save -o mynginx.tar nginx_vim
# 把压缩包load成镜像
docker load -i mynginx.tar
Dockerfile(非常重要)
Dockerfile是由一系列命令和参数构成的脚本,这些命令应用于基础镜像并最终创建一个新的镜像,文件名必须叫Dockerfile
# 镜像哪里来?
-1 远程仓库下载的
-2 容器做的
-3 xx.tar 解压出来的
-4 通过dockerfile构建
普通文件,文件中写了很多命令,根据这些命令创建出镜像来
# 常用命令
#1 FROM image_name:tag 基于哪个基础镜像来构建
#2 MAINTAINER lqz 声明镜像的创建者
#3 ENV key value 设置环境变量 (可以写多条)
ENV DB_PASSWORD lqz123 运行容器 -e参数指定 -e DB_PASSWORD=xxxx
#4 RUN command 是Dockerfile的核心部分(可以写多条),
command linux命令
# 5 ADD 宿主机路径文件 容器路径文件 将宿主机的文件复制到容器内,如果是一个压缩文件,将会在复制后自动解压
# 6 COPY 宿主机路径文件 容器路径文件 将宿主机的文件复制到容器内
# 7 WORKDIR path_dir 设置工作目录 docker exec 进入到容器,在某个路径下
# 8 CMD 命令 运行容器默认执行的命令,它可以被替换
CMD:添加启动容器时需要执行的命令。多条只有最后一条生效。可以在启动容器时被覆盖和修改
简单案例基于centos创建一个镜像,里面带vim软件
Dockerfile
FROM centos:7
MAINTAINER lqz
WORKDIR /home
RUN yum install -y vim
RUN mkdir lqz
ADD ./xx.txt ./yy.txt
构建镜像
docker build -t='centos_lqz_vim' .
制作django项目的镜像,运行
# 步骤:
-1 books项目准备好
-2 在项目路径下编写Dockerfile
FROM python:3.8
MAINTAINER lqz
WORKDIR /soft
COPY ./requirements.txt /soft/requirements.txt
RUN pip install -r requirements.txt -i https://pypi.doubanio.com/simple
CMD ["python","manage.py","runserver","0.0.0.0:8080"]
-3 把books代码提交到git
-4 部署项目的机器,clone 项目
git clone https://gitee.com/liuqingzheng/books.git
-5 cd books 文件夹下,执行构建镜像命令
docker build -t='django_books' .
-6 有个镜像django_books,运行成容器
docker run -id --name=books -v /root/books:/soft -p 8080:8080 books_django:latest
-7 win操作系统的浏览器中访问虚拟机地址,就可以访问项目了
-8 继续开发项目,改了代码,提交到git
-9 部署项目的机器,拉去最新代码
-10 重启docker容器即可(第三方依赖变了)--》重写构建镜像,运行容器
私有仓库
# docker pull拉取,都是从hub.docker 上拉取的,公司自己做的docker镜像,放在哪比较合适
# docker push 推到 hub.docker,如果是公开,大家都可以下载,公司内部只希望公司的人用,其他人不能用
# 公司内部,需要有个仓库管理自己的镜像--->私有仓库 私服
#以后拉取镜像时,先从自己服务器拉取,没有再去hub.docker拉取,咱们自己制作的镜像,传到私有仓库中,别人看不到
把自己制作的镜像上传到hub.docker
# 操作步骤:
1 给镜像打标签 (id号还是一样)
docker tag 03cf0f47aec0 liuqingzheng/djagno_books
2 登录
docker login # 输入用户名密码
3 推送
docker push liuqingzheng/djagno_books
搭建私有仓库
# harbor私有仓库:企业中使用多一些,有好看的图形化界面
-使用docker搭建harbor
# 咱们讲的是:registry ,老一点,没有图形化界面,不太好看,使用docker搭建
# 搭建步骤:
-1 拉取registry镜像
docker pull registry
-2 把镜像运行成容器
docker run -di --name=registry -p 5000:5000 registry
# 你使用浏览器访问宿主机5000端口,就能看到一个web服务
-3 宿主机浏览器访问:http://10.0.0.200:5000/v2/_catalog
-4 修改配置文件
vi /etc/docker/daemon.json
# 我
{"insecure-registries":["10.0.0.200:5000"]}
# 你们
{"insecure-registries":["192.168.1.143:5000"]}
-5 重启docker
systemctl restart docker
-6 启动私有仓库容器
docker start registry
-7 给镜像打标签
docker tag nginx_vim 192.168.1.143:5000/nginx_vim
-8 把自己制作的镜像,传到私有仓库
docker push 192.168.1.143:5000/nginx_vim
-9 公司内部的人,你们都要能访问到这个:http://10.0.0.200:5000/v2/_catalog
docker pull 192.168.1.143:5000/nginx_vim
docker-compose介绍
# 使用了docker 面临一个比较大的问题,如果一个djagno项目,使用mysql,redis,不要一次性把所有服务都放到一个容器中,每个服务一个容器,批量的管理多个容器,比较难以操作,于是有了docker-compose
# Docker Compose是一个能一次性定义和管理多个Docker容器的工具,单机容器编排【定义和管理】
-docker swarm:公司里用的不多
-k8s是多机容器编排工具,go语言写了k8s
Compose中定义和启动的每一个容器都相当于一个服务(service)
Compose中能定义和启动多个服务,且它们之间通常具有协同关系
管理方式:
使用YAML文件来配置我们应用程序的服务。
使用单个命令(docker-compose up),就可以创建并启动配置文件中配置的所有服务。
# 安装:
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.14.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# yaml 文件写法
docker-compose命令
docker-compose up # 会自动搜索当前路径下的 docker-compose.yml文件
docker-compose up -d # 后台执行,一般我们看日志输出,不用这个
docker-compose stop # 停止,不会删除容器和镜像
docker-compose down # 停止,并删除关联的容器
docker-compose start # 启动yml文件管理的容器
docker-compose ps # 正在运行的容器
docker-compose images # docker-compose管理的容器
docker-compose exec yml文件中写的service /bin/bash # 进入到容器内
docker-compose部署flask项目
编写一个Dockerfile
FROM python:3.8
COPY . /app
WORKDIR /app
RUN pip install flask redis -i https://pypi.tuna.tsinghua.edu.cn/simple
EXPOSE 5000
CMD [ "python", "app.py" ]
编写flask代码app.py
from flask import Flask
from redis import Redis
import os
import socket
app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return '你好! 查看 %s 次, hostname 是 %s.\n' % (redis.get('hits'),socket.gethostname())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
docker-compose的yaml文件 docker-compose.yml
version: "3"
services:
redis:
image: redis
web:
build:
context: .
dockerfile: Dockerfile
ports:
- 8080:5000
environment:
REDIS_HOST: redis
一键部署
# 如果redis服务的名字叫redis,我在web服务中(容器中),根据redis名字就能拿到容器
ping redis
# 进入到了web,ping redis
# 安装ping命令,
apt-get update
apt-get install inetutils-ping
ping redis
# 一键部署:redis,和flask ,每个都在一个容器中
docker-compose up
docker-compose部署luffy项目
# 一台服务器:
-python3.8 环境 djagno +uwsgi+代码
-nginx软件
-mysql 5.7
-redis 5
# 每个都做成一个容器
-djagno项目容器:python3.8 构建的django,模块,uwsgi,代码
-nginx容器:目录映射,映射到宿主机,代理vue前端,编译后的静态文件
-mysql 容器:创建,创用户,密码,luffy库
-redis 容器,跑起来即可
# docker-compose yml文件配置,一键启动
-git clone https://gitee.com/liuqingzheng/luffy.git
-目录结构
luffy
luffy_api # 后台项目
Dockerfile
luffycity # 前台项目
docker_compose_files # 放数据的文件夹
-docker-compose.yml #ymal文件
-Dockefile 文件
- 修改前端链接后台的地址:luffycity/src/access/xx.js
-编译:npm run build
-提交到git
-要部署的服务器:git clone https://gitee.com/liuqingzheng/luffy.git
-docker,docker-compose装好
-docker-compose up
-访问宿主机的 80 端口
Dockerfile
#依赖镜像名称和ID
FROM python:3.8
#指定镜像创建者信息
MAINTAINER lqz
#切换工作目录
RUN mkdir /soft
WORKDIR /soft
COPY ./requestment.txt /soft/requestment.txt
RUN pip install -r requestment.txt -i https://pypi.doubanio.com/simple
#CMD ["uwsgi", "-x", "./luffy.xml"]
CMD ["uwsgi", "./luffy.ini"]
#CMD ["python", "manage_pro.py", "runserver"]
docker-compose yml文件配置
version: "3"
services:
nginx:
image: nginx
container_name: luffy_nginx
ports:
- "80:80"
- "8000:8000"
restart: always
volumes:
- ./luffycity/dist:/var/www/html
- ./docker_compose_files/nginx:/etc/nginx/conf.d
depends_on:
- django
networks:
- web
django:
build:
context: ./luffy_api
dockerfile: Dockerfile
container_name: luffy_django
# command: python manage_pro.py makemigrations && python manage_pro.py migrate && uwsgi ./luffy.ini
restart: always
ports:
- "8080:8080"
volumes:
- ./luffy_api:/soft
environment:
- TZ=Asia/Shanghai
depends_on:
- mysql
- redis
networks:
- web
redis:
image: redis:6.0-alpine
container_name: luffy_redis
ports:
- "6379:6379"
volumes:
- ./docker_compose_files/redis/data:/data
- ./docker_compose_files/redis/redis.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
networks:
- web
mysql:
image: mysql:5.7
container_name: luffy_mysql
restart: always
ports:
- "3306:3306"
env_file:
- ./docker_compose_files/mysql.env
volumes:
- ./docker_compose_files/mysql/data:/var/lib/mysql
- ./docker_compose_files/mysql/logs:/var/log/mysql
- ./docker_compose_files/mysql/conf:/etc/mysql/conf.d
networks:
- web
networks:
web:
一键启动
docker-compose up
补充
-centos,redhat 装软件都是 yum
-乌班图,debian 装软件 apt-get
# 面试题:CMD、RUN 和 ENTRYPOINT?
-dockerfile的指令
-CMD:启动容器时执行的命令
-RUN:用在在容器内部执行的命令,构建镜像的时候执行的
-ENTRYPOINT 用起来跟CMD一样,但是CMD的命令可以被替换,ENTRYPOINT不可以
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库