K3S +Helm+NFS最小化测试安装部署只需十分钟

作者:郝建伟

k3s 简介

官方文档:k3s

什么是k3s

k3s 是一个轻量级的 Kubernetes 发行版
它针对边缘计算、物联网等场景进行了高度优化。
k3s 有以下增强功能:




  1. 打包为单个二进制文件。

  2. 使用基于 sqlite3 的轻量级存储后端作为默认存储机制。同时支持使用 etcd3、MySQL 和 PostgreSQL 作为存储机制。

  3. 封装在简单的启动程序中,通过该启动程序处理很多复杂的 TLS 和选项。

  4. 默认情况下是安全的,对轻量级环境有合理的默认值。

  5. 添加了简单但功能强大的batteries-included功能,例如:本地存储提供程序,服务负载均衡器,Helm controller 和 Traefik Ingress controller。

  6. 所有 Kubernetes control-plane 组件的操作都封装在单个二进制文件和进程中,使 k3s 具有自动化和管理包括证书分发在内的复杂集群操作的能力。

  7. 最大程度减轻了外部依赖性,k3s 仅需要 kernel 和 cgroup 挂载。 k3s 软件包需要的依赖项包括:

    containerd
    Flannel
    CoreDNS
    CNI
    主机实用程序(iptables、socat 等)
    Ingress controller(Traefik)
    嵌入式服务负载均衡器(service load balancer)
    嵌入式网络策略控制器(network policy controller)
    
    
    
    
    

为什么叫 k3s?

k3s内存占用是k8s的一半
kubernetes是一个10个字母的单词,简写为k8s
kubenetes的一半是5个字母,简写为k3s




适用场景

k3s 适用于以下场景:

  1. 边缘计算-Edge

  2. 物联网-IoT

  3. CI

  4. Development

  5. ARM

  6. 嵌入 k8s

由于运行 k3s 所需的资源相对较少,所以 k3s 也适用于开发和测试场景。
在这些场景中,如果开发或测试人员需要对某些功能进行验证,或对某些问题进行重现,那么使用 k3s 不仅能够缩短启动集群的时间,还能够减少集群需要消耗的资源。




架构介绍

k3s server 是运行k3s server命令的机器(裸机或虚拟机),而 k3s worker 节点是运行 k3s worker命令的机器




单节点架构

k3s 单节点集群的架构如下图所示,该集群有一个内嵌 SQLite 数据库的单节点 k3s server。
在这种配置中,每个 worker 节点都注册到同一个 server 节点。
k3s 用户可以通过调用 server 节点上的 k3s API 来操作 Kubernetes 资源。




img

高可用架构

虽然单节点 k3s 集群可以满足各种用例,但对于 Kubernetes control-plane 的正常运行至关重要的环境,您可以在高可用配置中运行 k3s。
一个高可用 k3s 集群由以下几个部分组成:




  1. k3s Server 节点:两个或更多的server节点将为 Kubernetes API 提供服务并运行其他 control-plane 服务

  2. 外部数据库:与单节点 k3s 设置中使用的嵌入式 SQLite 数据存储相反,高可用 k3s 需要挂载一个external database外部数据库作为数据存储的媒介。

k3s高可用架构:

img

固定 worker 节点的注册地址

在高可用 k3s server 配置中,每个节点还必须使用固定的注册地址向 Kubernetes API 注册,注册后,worker 节点直接与其中一个 server 节点建立连接




如下图所示:

image.png

注册 worker 节点

Agent 节点用k3s worker进程发起的 websocket 连接注册,连接由作为代理进程一部分运行的客户端负载均衡器维护。




Agent 将使用节点集群 secret 以及随机生成的节点密码向 k3s server 注册,密码存储在 /etc/rancher/node/password路径下。
k3s server 将把各个节点的密码存储为 Kubernetes secrets,随后的任何尝试都必须使用相同的密码。节点密码秘密存储在kube-system命名空间中,名称使用模板.node-password.k3s




注意:
    在 k3s v1.20.2 之前,k3s server 将密码存储在/var/lib/rancher/k3s/server/cred/node-passwd的磁盘上。
    如果您删除了 worker 的/etc/rancher/node目录,则需要为该 worker 重新创建密码文件,或者从 server 中删除该条目。
    通过使用--with-node-id标志启动 k3s server 或 worker,可以将唯一的节点 ID 附加到主机名中。




自动部署的清单

位于目录路径/var/lib/rancher/k3s/server/manifests 的清单在构建时被捆绑到 k3s 二进制文件中
将由rancher/helm-controller在运行时安装。




k3s默认容器运行时

k3s默认使用 containerd 作为容器运行时
在 goroutine 中以 子进程 方式 启动 containerd




验证:

ps aux | grep “k3s server”




ps -A -ostat,pid,ppid,cmd |grep 7897




准备工作

关闭SELinux

# 临时关闭
setenforce 0

# 永久关闭
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config




关闭swap

# 临时关闭swap分区,当前会话生效,重启失效
swapoff -a  

# 永久关闭swap分区
sed -ri 's/.*swap.*/#&/' /etc/fstab




设置主机名

# 临时修改主机名:hostname newname(本文涉及四台机器:一主三从)
hostname k3s-master1
hostname k3s-node1
hostname k3s-node2
hostname k3s-node3

注:这种方式是立即生效,但是在服务器重启后会恢复成原来的名字

# 永久性修改主机名:修改/etc/sysconfig/network文件内容
vim /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=localhost1

注:这种方式不会立即生效,需要重启服务器才会生效,且永久性修改




离线安装

概述

你可以使用两种不同的方法在离线环境中安装 k3s。
离线环境是不直接连接到 Internet 的任何环境。
你可以部署一个私有镜像仓库,或者你可以手动部署镜像,比如用于小型集群。




离线安装的过程主要分为以下两个步骤:

步骤 1:部署镜像

步骤 2:安装 k3s

**离线升级 k3s 版本: **完成离线安装 k3s 后,您还可以通过脚本升级 k3s 版本,或启用自动升级功能,以保持离线环境中的 k3s 版本与最新的 k3s 版本同步。

部署私有镜像仓库

前提条件

搭建私有仓库 ,例如 harbor仓库




搭建参考Harbor安装

创建镜像仓库 YAML

请按照 K3S 私有镜像仓库配置创建并配置registry.yaml文件。
完成后,现在可以转到下面的[安装 k3s]部分,开始安装 K3




手动部署镜像
前提条件

假设已经在离线环境中创建了节点。
这种方法需要您手动将必要的镜像部署到每个节点,适用于运行无法部署镜像仓库的边缘部署场景。

操作步骤

请按照以下步骤准备镜像目录和 k3s 二进制文件

  1. 从k3s GitHub Release页面获取你所运行的 k3s 版本的镜像 tar 文件。

  2. 将 tar 文件放在images目录下,例如:

    sudo mkdir -p /var/lib/rancher/k3s/worker/images/
    sudo cp k3s-airgap-images-amd64.tar /var/lib/rancher/k3s/worker/images/
    
    
    
    
    
    
  3. 将 k3s 二进制文件放在 /usr/local/bin/k3s路径下,并确保拥有可执行权限。完成后,现在可以转到下面的安装 k3s部分,开始安装 k3s。

    chmod +x k3s && cp k3s /usr/local/bin/
    
    
    
    
    

安装 k3s

更多安装选项参考 安装选项介绍 | Rancher文档

前提条件

  1. 在安装 k3s 之前,完成上面的部署私有镜像仓库或手动部署镜像,导入安装 k3s 所需要的镜像。

  2. 从 release 页面下载 k3s 二进制文件,k3s 二进制文件需要与离线镜像的版本匹配。将二进制文件放在每个离线节点的 /usr/local/bin 中,并确保这个二进制文件是可执行的。

  3. 下载 k3s 安装脚本:https://get.k3s.io 。将安装脚本放在每个离线节点的任意地方,并命名为 install.sh。

当使用 INSTALL_K3S_SKIP_DOWNLOAD 环境变量运行 k3s 脚本时,k3s 将使用本地的脚本和二进制。

单节点安装

server节点

INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh




image.png

worker节点

# 将 myserver 替换为 server 的 IP 或有效的 DNS
# 将 mynodetoken 替换 server 节点的 token
# token 通常在/var/lib/rancher/k3s/server/node-token

INSTALL_K3S_SKIP_DOWNLOAD=true 
K3S_URL=https://172.16.100.126:6443 K3S_TOKEN=K10ccf50e87c24f9a1db535bdc5f6cd0c7e87b4b7b321118c393563b07e0fa8b39f::server:6b9604a66f7a2d2ac22a2835e3aa7500 ./install.sh






注意:k3s 还为 kubelets 提供了一个–resolv-conf标志,这可能有助于在离线网络中配置 DNS

![image-20221118231106968](/Users/haojianwei1/Library/Application Support/typora-user-images/image-20221118231106968.png)

添加worker角色标签

# 设置worker角色,工作节点不能默认添加 worker 角色,需要手动执行命令添加,新版本可能已修复此问题,
# kubectl label nodes 节点名字 node-role.kubernetes.io/你想要的roles(=/-)
# 最后括号里的加减号,减号就是删除roles,等号就是增加roles

kubectl label node k3s-node1 node-role.kubernetes.io/worker=true --overwrite
kubectl label node k3s-node2 node-role.kubernetes.io/worker=true --overwrite
kubectl label node k3s-node3 node-role.kubernetes.io/worker=true --overwrite
# --overwrite 代表如果已经存在worker角色标签,则覆盖(新标签创建时此操作不生效)




image.png

kubectl命令行补全

yum install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc




高可用安装

需要调整安装命令,以便指定INSTALL_K3S_SKIP_DOWNLOAD=true并在本地运行安装脚本。您还将利用INSTALL_K3S_EXEC='args’为 k3s 提供其他参数。

例如,使用外部数据库实现高可用安装指南的第二步提到了以下内容:

curl -sfL https://get.k3s.io | sh -s - server \
--datastore-endpoint='mysql://username:password@tcp(hostname:3306)/database-name'




由于在离线环境中无法使用curl命令进行安装,所以您需要参考以下示例,将这条命令行修改为离线安装:

INSTALL_K3S_SKIP_DOWNLOAD=true INSTALL_K3S_EXEC='server' K3S_DATASTORE_ENDPOINT='mysql://username:password@tcp(hostname:3306)/database-name' ./install.sh




升级 k3s

通过脚本升级

离线环境的升级可以通过以下步骤完成:

  1. 从k3s GitHub Release页面下载要升级到的 k3s 版本。将 tar 文件放在每个节点的/var/lib/rancher/k3s/worker/images/目录下。删除旧的 tar 文件。

  2. 复制并替换每个节点上/usr/local/bin中的旧 k3s 二进制文件。复制https://get.k3s.io 的安装脚本(因为它可能在上次发布后发生了变化)。再次运行脚本。

  3. 重启 k3s 服务。

启用自动升级功能

除了可以通过脚本升级 k3s 以外,您还可以启用自动升级功能,以保持离线环境中的 k3s 版本与最新的 k3s 版本同步。

从 v1.17.4+k3s1 开始,k3s 支持自动升级。要在离线环境中启用此功能,您必须确保所需镜像在您的私有镜像仓库中可用。

  1. 你将需要与你打算升级到的 k3s 版本相对应的 rancher/k3s-upgrade 版本。

    注意,镜像标签将 k3s 版本中的+替换为-,因为 Docker 镜像不支持+。

  2. 你还需要在你要部署的system-upgrad-controller manifestYAML 中指定的 system-upgrad-controller和kubectl的版本。

    在这里检查 system-upgrad-controller 的最新版本,并下载 system-upgrad-controller.yaml来确定你需要推送到私有镜像仓库的版本。例如,在system-upgrade-controller的 v0.4.0 版本中,在 manifest YAML 中指定了这些镜像:

    rancher/system-upgrade-controller:v0.4.0
    rancher/kubectl:v0.17.0
    
    
    
    
    
  3. 将必要的 rancher/k3s-upgrade、rancher/system-upgrade-controller 和 rancher/kubectl 镜像添加到您的私有镜像仓库中以后 ,就可以按照k3s 自动升级指南进行操作。

停止k3s

server节点停止k3s

# 停止k3s
systemctl stop k3s
systemctl disable k3s
# 杀掉进程的kill命令
/usr/local/bin/k3s-killall.sh
# 如果使用的是docker,需要执行发下命令
docker ps -a|grep -v CONTAINER|awk '{print $1}'|xargs docker  stop
docker ps -a|grep -v CONTAINER|awk '{print $1}'|xargs docker  rm
systemctl stop docker
systemctl disable docker




worker节点停止k3s

# 停止k3s-agent
systemctl stop k3s-agent
systemctl disable k3s-agent
# 如果使用的是docker,需要执行发下命令
docker ps -a|grep -v CONTAINER|awk '{print $1}'|xargs docker  stop
docker ps -a|grep -v CONTAINER|awk '{print $1}'|xargs docker  rm
systemctl stop docker
systemctl disable docker




卸载 k3s

卸载 k3s 会删除集群数据和所有脚本。

要使用不同的安装选项重新启动集群,请使用不同的标志重新运行安装脚本。

server 节点卸载 k3s

/usr/local/bin/k3s-uninstall.sh




worker 节点卸载 k3s

/usr/local/bin/k3s-agent-uninstall.sh




Helm简介

​ Helm 是 Kubernetes 生态系统中的一个软件包管理工具。本文将介绍 Helm 中的相关概念和基本工作原理,并通过一个具体的示例学习如何使用 Helm 打包、分发、安装、升级及回退 Kubernetes 应用。

Kubernetes 应用部署的挑战

​ Kubernetes 是一个提供了基于容器的应用集群管理解决方案,Kubernetes 为容器化应用提供了部署运行、资源调度、服务发现和动态伸缩等一系列完整功能。

​ Kubernetes 的核心设计理念是: 用户定义要部署的应用程序的规则,而 Kubernetes 则负责按照定义的规则部署并运行应用程序。如果应用程序出现问题导致偏离了定义的规格,Kubernetes 负责对其进行自动修正。例如:定义的应用规则要求部署两个实例(Pod),其中一个实例异常终止了,Kubernetes 会检查到并重新启动一个新的实例。

​ 用户通过使用 Kubernetes API 对象来描述应用程序规则,包括 Pod、Service、Volume、Namespace、ReplicaSet、Deployment、Job等等。一般这些资源对象的定义需要写入一系列的 YAML 文件中,然后通过 Kubernetes 命令行工具 Kubectl 调 Kubernetes API 进行部署。

​ 以一个典型的三层应用 Wordpress 为例,该应用程序就涉及到多个 Kubernetes API 对象,而要描述这些 Kubernetes API 对象就可能要同时维护多个 YAML 文件。

img

从上图可以看到,在进行 Kubernetes 软件部署时,我们面临下述几个问题:

  • 如何管理、编辑和更新这些这些分散的 Kubernetes 应用配置文件。

  • 如何把一套相关的配置文件作为一个应用进行管理。

  • 如何分发和重用 Kubernetes 的应用配置。

Helm 的出现就是为了很好地解决上面这些问题。

Helm 是什么?

Helm 是Deis开发的一个用于 Kubernetes 应用的包管理工具,主要用来管理 Charts。有点类似于 Ubuntu 中的 APT 或 CentOS 中的 YUM。

Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata,以便于应用程序的分发。

对于应用发布者而言,可以通过 Helm 打包应用、管理应用依赖关系、管理应用版本并发布应用到软件仓库。

对于使用者而言,使用 Helm 后不用需要编写复杂的应用部署文件,可以以简单的方式在 Kubernetes 上查找、安装、升级、回滚、卸载应用程序。

Helm 组件及相关术语

  • Helm

Helm 是一个命令行下的客户端工具。主要用于 Kubernetes 应用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。

  • Tiller

Tiller 是 Helm 的服务端,部署在 Kubernetes 集群中。Tiller 用于接收 Helm 的请求,并根据 Chart 生成 Kubernetes 的部署文件( Helm 称为 Release ),然后提交给 Kubernetes 创建应用。Tiller 还提供了 Release 的升级、删除、回滚等一系列功能。

  • Chart

Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。

  • Repoistory

Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。

  • Release

使用helm install命令在 Kubernetes 集群中部署的 Chart 称为 Release。

注:需要注意的是:Helm 中提到的 Release 和我们通常概念中的版本有所不同,这里的 Release 可以理解为 Helm 使用 Chart 包部署的一个应用实例。

Helm 工作原理

这张图描述了 Helm 的几个关键组件 Helm(客户端)、Tiller(服务器)、Repository(Chart 软件仓库)、Chart(软件包)之间的关系。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FPKvkbuQ-1669789873748)(https://www.hi-linux.com/img/linux/helm02.png)]

Chart Install 过程

  • Helm 从指定的目录或者 TAR 文件中解析出 Chart 结构信息。

  • Helm 将指定的 Chart 结构和 Values 信息通过 gRPC 传递给 Tiller。

  • Tiller 根据 Chart 和 Values 生成一个 Release。

  • Tiller 将 Release 发送给 Kubernetes 用于生成 Release。

Chart Update 过程

  • Helm 从指定的目录或者 TAR 文件中解析出 Chart 结构信息。

  • Helm 将需要更新的 Release 的名称、Chart 结构和 Values 信息传递给 Tiller。

  • Tiller 生成 Release 并更新指定名称的 Release 的 History。

  • Tiller 将 Release 发送给 Kubernetes 用于更新 Release。

Chart Rollback 过程

  • Helm 将要回滚的 Release 的名称传递给 Tiller。

  • Tiller 根据 Release 的名称查找 History。

  • Tiller 从 History 中获取上一个 Release。

  • Tiller 将上一个 Release 发送给 Kubernetes 用于替换当前 Release。

Chart 处理依赖说明

Tiller 在处理 Chart 时,直接将 Chart 以及其依赖的所有 Charts 合并为一个 Release,同时传递给 Kubernetes。因此 Tiller 并不负责管理依赖之间的启动顺序。Chart 中的应用需要能够自行处理依赖关系。

部署 Helm

安装 Helm 客户端

Helm 的安装方式很多,这里采用二进制的方式安装。更多安装方法可以参考 Helm 的官方帮助文档。

  • 使用官方提供的脚本一键安装
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh$ chmod 700 get_helm.sh
./get_helm.sh




  • 手动下载二进制包安装
# 下载 Helm 
wget https://get.helm.sh/helm-v3.9.3-linux-amd64.tar.gz

# 解压 Helm$ 
tar -zxvf helm-v3.9.3-linux-amd64.tar.gz

# 复制客户端执行文件到 bin 目录下
cp linux-amd64/helm /usr/local/bin/




Tiller 是以 Deployment 方式部署在 Kubernetes 集群中的,只需使用以下指令便可简单的完成安装。

helm init




注:**storage.googleapis.com**默认是不能访问的,该问题请自行解决。如果不清楚是否能访问,当你把这行命令cp linux-amd64/helm /usr/local/bin/完,看一下是否都是ok的

image.png

可以可以看到 Tiller 的 Service、Deployment是正常的,
但是Pod是不正常的;镜像拉取失败,默认我们是注:storage.googleapis.com 默认是不能访问的,换个源下载一下;
参考:https://www.hi-linux.com/posts/21466.html  换源




由于 Helm 默认会去storage.googleapis.com拉取镜像,如果你当前执行的机器不能访问该域名的话可以使用以下命令来安装:

# 使用某云镜像安装并把默认仓库设置为某云上的镜像仓库$ helm init --upgrade --tiller-image 某云镜像地址/google_containers/tiller:v2.12.2 --stable-repo-url https://某云镜像地址/charts

可以看出现在已经正常running了,
查看详细的信息
kubectl describe pod tiller-deploy-dc95dbd5c-gvldb --namespace=kube-system




接下来查看状态

image.png

上图可看出:现在,helm version已经能够查看到服务器的版本信息了,部署完成

后面下载包会报错,是因为从 Kubernetes 1.6 版本开始,API Server 启用了 RBAC 授权。目前的 Tiller 部署时默认没有定义授权的 ServiceAccount,这会导致访问 API Server 时被拒绝。所以我们需要明确为 Tiller 部署添加授权。

生成.kube配置

## 当使用helm 部署 Pod 的时候如果报以下错误,需要执行此步骤操作(说明没有访问kube-apiserver 权限)
## 如果 kubectl 在其他非master节点部署时同样也报如下错误,也需要执行此步骤操作
Error: INSTALLATION FAILED: Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp [::1]:8080: connect: connection refused

## 不可用的时候需要复制master节点的/etc/rancher/k3s/k3s.yaml文件内容复制至客户端$HOME/.kube/config
cat /etc/rancher/k3s/k3s.yaml
mkdir -p $HOME/.kube
sudo touch $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config




安装NFS

部署说明

Kubernetes网络文件系统,主要用于ES、Kafka、Minio等持久化存储。

nfs搭建

# ===========服务端(nfs节点)操作如下===========
# 通过yum目录安装nfs服务和rpcbind服务
yum -y install nfs-utils rpcbind

# 启动服务
systemctl start rpcbind
systemctl enable rpcbind
systemctl start nfs
systemctl enable nfs

# 查看nfs服务是否安装正常
rpcinfo -p localhost

# 或者是通过公网测试服务端的nfs服务是否可用。
rpcinfo -p ServerIP

# 显示如下即正常
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
...
100024 1 udp 45993 status
100024 1 tcp 39431 status
...
100005 1 udp 20048 mountd
100005 1 tcp 20048 mountd
...
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
...
100021 3 tcp 33941 nlockmgr
100021 4 tcp 33941 nlockmgr

# ===========客户端(k8s节点)操作如下===========
# 通过yum目录安装nfs服务和rpcbind服务
yum -y install nfs-utils rpcbind




配置共享目录

# ===========以下全部为nfs节点操作如下===========
# 比如我们在服务端的共享目录为/export/nfs-share,接着输入以下命令
echo "/export/nfs-share 172.16.100.0/20(rw,sync,no_root_squash,no_all_squash)" > /etc/exports

# 要保证/export/nfs-share目录已经存在节点上,然后输入以下命令使共享目录生效。
exportfs -r

# 重新启动服务
systemctl restart rpcbind
systemctl restart nfs

# 测试
showmount -e localhost

# 或者
showmount -e 公网ip
showmount 命令查询“mountd”守护进程,以显示NFS服务器加载的信息




部署Pod遇到的问题

Helm部署Chart时报错

Error: INSTALLATION FAILED: create: failed to create: Request entity too large: limit is 3145728

以上报错信息,一般是由于chart目录里面存在大文件,把不必要的文件删除,只保留chart相关的,再次helm install即可




部署 nfs pod时报错

image.png

# 上面的原因一般是由于nfs运行所在的节点,访问nfs不通,需要在集群的全部工作节点执行安装nfs客户端命令:
yum -y install nfs-utils rpcbind





Pod拉取镜像超时报错

image.png

以上报错信息,一般是由于官网方法部署k3s,默认使用的是containerd作为容器运行环境,使用的是海外的镜像仓库,导致拉镜像超时,可在pod配置镜像加速,设置地址为国内,参考常用命令:crictl命令使用 --> 配置containerd镜像加速

注:如果受公网限制,可能在有公网的环境下,把对应的镜像先自行下载下来,再上传到集群用命令行导入到镜像库




常用命令行

kubectl命令

node的标签操作

# 查看当前所有node的标签
kubectl get nodes --show-labels




image.png

# 查看某个node的标签
kubectl describe node k3s-master  # k3s-master 节点名




image.png

# node自定义标签
kubectl label node k3s-master1 project=k8snew
node/k3s-master1 labeled

kubectl label node k3s-master1 node=second-node
node/k3s-master1 labeled




# yaml引用node的label示范
# vim haproxyDep.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: k8s-new
  name: haproxy-deployment
  labels:
    app: haproxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: haproxy
  template:
    metadata:
      labels:
        app: haproxy
    spec:
      containers:
      - name: haproxy
        image: k8s.org/haproxy-2.5.0:v1
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 200m
            memory: 200Mi
        ports:
        - containerPort: 9999
          protocol: TCP
          name: status
        - containerPort: 9527
          protocol: TCP
          name: haproxy01
      nodeSelector:         #注意必须配置在containers参数结束后的部分
        node: first-node    #之前配置的192.168.1.96节点的label




# 自定义node label的删除
kubectl label nodes k3s-master1 project-

注:命令格式即:kubectl  label  nodes  node节点名称/nodeIP  node对应的key-




ctr 命令使用

containerd 相比于docker , 多了namespace概念, 每个image和container 都会在各自的namespace下可见

# 查询ctr版本
ctr version




# 查看ctr image可用操作
ctr image list
ctr i list
ctr i ls




# 镜像标记tag
ctr -n k8s.io i tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 k8s.gcr.io/pause:3.2

# 若新镜像reference 已存在, 需要先删除新reference, 或者如下方式强制替换
ctr -n k8s.io i tag --force registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 k8s.gcr.io/pause:3.2




# 删除镜像
ctr -n k8s.io i rm k8s.gcr.io/pause:3.2




# 拉取镜像
ctr -n k8s.io i pull -k k8s.gcr.io/pause:3.2




# 推送镜像
ctr -n k8s.io i push -k k8s.gcr.io/pause:3.2




# 导出镜像
ctr -n k8s.io i export pause.tar k8s.gcr.io/pause:3.2




# 导入镜像
# 不支持 build,commit 镜像
ctr -n k8s.io i import pause.tar




# 查看容器相关操作
ctr c




# 运行容器
–null-io: 将容器内标准输出重定向到/dev/null
–net-host: 主机网络
-d: 当task执行后就进行下一步shell命令,如没有选项,则会等待用户输入,并定向到容器内
–mount 挂载本地目录或文件到容器
–env 环境变量
ctr -n k8s.io run --null-io --net-host -d \
–env PASSWORD="123456"
–mount type=bind,src=/etc,dst=/host-etc,options=rbind:rw




# 容器日志
注意: 容器默认使用fifo创建日志文件, 如果不读取日志文件,会因为fifo容量导致业务运行阻塞

如要创建日志文件,建议如下方式创建:
ctr -n k8s.io run --log-uri file:///var/log/xx.log




ctr,crictl,docker命令对比

Ctr命令Crictl命令Docker命令详细描述
ctr task lscrictl ps -adocker ps查看运行中的容器
ctr image lscrictl imagesdocker images获取image列表信息
ctr image pull zookeepercrictl pull zookeeperdocker pull zookeeper拉取镜像
ctr image push zookeeperdocker push zookeeper推送镜像
ctr image rmicrictl rmidocker rmi删除镜像
ctr image export zookeeper.tar docker.io/bitnami/zookeeper:3.4.14docker save -o zookeeper.tar docker.io/bitnami/zookeeper:3.4.14导出镜像
ctr image import zookeeper.tardocker load -i zookeeper.tar导入本地镜像
ctr run -d zookeeper zookeeperdocker run -d --name=kafka zookeeper运行容器
ctr image tag zookeeper-new-tag zookeeperdocker tag zookeeper-new-tag zookeeper镜像打tag

crictl 命令使用

# 进入容器:
命令:crictl exec -it CONTAINER-ID bash
例如:crictl exec -it f57ba7a2d9df4 bash




# 查询容器:
命令:crictl ps -a




# 查询日志:
命令:crictl logs -f CONTAINER-ID
例如:crictl logs -f f57ba7a2d9df4




配置containerd镜像加速

# 拷贝配置文件,原文件不要删除
cp /var/lib/rancher/k3s/agent/etc/containerd/config.toml /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl




# 修改配置文件
vim /var/lib/rancher/k3s/agent/etc/containerd/config.toml.tmpl 在最后增加以下配置

[plugins.cri.registry]
  [plugins.cri.registry.mirrors]
    [plugins.cri.registry.mirrors."docker.io"]
      endpoint = ["https://mirror地址"]
    [plugins.cri.registry.mirrors."gcr.io"]
      endpoint = ["https://mirror地址"]
    [plugins.cri.registry.mirrors."k8s.gcr.io"]
      endpoint = ["https://mirror地址"]
    [plugins.cri.registry.mirrors."quay.io"]
      endpoint = ["https://mirror地址"]




# 重启k3s使配置生效
systemctl restart k3s




#检查配置是否生效
crictl info|grep  -A 30 registry




其他命令:

crictl images list 列出镜像
crictl ps 查看运行中的容器




几种Containerd常用命令对比

# 查看容器运行状态

# 1.ctr
ctr container ls
#指定命名空间
ctr --namespace=k8s.io container ls

# 2.crictl
crictl ps

# 3.nerdctl
nerdctl ps




# 查看镜像

# 1.ctr
ctr image ls
#指定命名空间
ctr --namespace=k8s.io image ls

# 2.crictl
crictl image

# 3.nerdctl
nerdctl image




# 查看容器日志

# 1.ctr
没有相关命令

# 2.crictl
crictl logs

# 3.nerdctl
nerdctl logs




# 修改镜像标签

# 1.ctr
ctr image tag

# 2.crictl
没有相关命令

# 3.nerdctl
nerdctl tag




# 导出镜像

# 1.ctr
ctr image export

# 2. crictl
没有相关命令

# 3.nerdctl
nerdctl save




# 导入镜像

# 1.ctl
ctr image import

# 2.crictl
没有相关命令

# 3.nerdctl
nerdctl load




7.删除镜像

# 1.ctr
ctr image rm

# 2.crictl
crictl rmi

#3. nerdctl
nerdctl rmi




8.拉取镜像

# 1.ctr
ctr image pull

# 2.crictl
crictl pull

# 3.nerdctl
nerdctl pull




9.推送镜像

# 1.ctr
ctr image push

# 2.crictl
没有相关命令

# 3.nerdctl
nerdctl push



相关推荐

AI 会写代码之后,交付为什么还没变快?

AI 写代码,只是这场变革的起点,而不是终点。真正决定一个组织能否吃到 AI 红利的,不是"能不能用 AI 写出代码",而是敢不敢用 AI 重新设计交付流程、重新划分角色分工、重新组织团队结构。研发视角能把工具和个人推到极致,却会在组织的边界前止步;只有站上组织视角,把AI × 工具一路推进到AI × 组织,那些被 AI 照出来的摩擦,才会真正被抹平。国际技术部 Multi AI Native 想做的,正是这件事——让 Agent 成为你可靠的数字战友,让每一次迭代交付都快一个量级;

京东科技开发者 246

OxygenData-Vibe搭建:用 AI Coding重新定义数据看板搭建

长期以来,数据看板开发主要有两种方式:一种是使用标准化 BI 工具,交付快、成本低,但图表样式、交互体验和功能扩展都受限于 BI 本身的能力;另一种是自研定制开发,能够充分满足复杂和个性化需求,但需要投入大量研发资源,交付周期也更长。比如一个通过 BI 只需要 1 天就能搭建出来的看板,如果采用自研方式,可能需要投入 30 PD 的研发人力。既然 BI 交付这么快,为什么不把所有看板需求都交给 BI?原因在于,业务某些场景需要的不只是把数据展示出来。

京东科技开发者 309

当我谈数据库高可用时我谈些什么

大家都经常听到说数据库的双1,那双1指的是什么呢?参数=1(最安全)≠1(更快但可能丢)每次提交都把 redo 刷盘0/2:攒着刷,崩溃丢最近 1 秒每次提交都把 binlog 刷盘0/N:攒着刷,崩溃丢最近若干条"双 1"(都设为 1)= 单机不丢已提交事务的前提。生产核心库必须双 1;代价是每次提交两次 fsync。小结:单机层用 WAL 提速、用 2PC 保证 redo/binlog 一致、用崩溃恢复裁决半成品事务、用双 1 兜底持久性。

京东科技开发者 271

ScoAI:面向供应链的运筹原生决策智能

ScoAI 关注的并非 AI 能否进入供应链,而是 AI 参与供应链决策之后,哪些内容适合通过数据学习,哪些关系必须显式计算,以及哪些结果需要依据执行记录进行验证。其基本分工是:供应链业务定义问题、资源与行动后果,运筹学表达目标、约束和协同关系,AI 提供可复用的估计与判断。真正用于改进后续决策的,不仅是模型生成的初始结果,还包括实际采取的行动及其产生的业务反馈。

京东科技开发者 367

拆解海博 AI-Native 落地保障:海博团队 AI 知识库能力建设

绕了一大圈,回头看,我们其实一直在解开头那三个结:AI 读不懂系统、影响面靠人脑记、测试预期没处查。做到这里,本质上是把"AI 用不好"这个问题,从"是不是该换个更强的模型"重新定义成了"怎么把上下文经营好"。顺着这个思路,我们攒下了这么几样东西:•。

京东科技开发者 518

从零构建一个生产级记忆型 AI Agent —— AgentScope 项目全景技术与学习指南

domain 层端口接口(domain)职责适配器实现(infra)对话流水账读写经验记忆检索/落库请求级幂等四态会话元数据 CRUD会话级 Skill 选择态Skill 元数据HITL 权限网关(domain 内含逻辑,见第四篇)StreamSink技术中立的流式下沉(client 层桥接)以幂等端口为例,头部注释明确写道:实现 domain 端口,持有实体不出 infra 边界,对外只暴露嵌套视图GateResult。

京东科技开发者 571

数据涅槃:Agentic 重塑搜推数据生产体系

当前大模型已经能够理解需求、生成代码和解释错误,但数据生产的难点并不只是“写出一段 SQL”。一个需求还要经过数据源确认、口径澄清、加工编排、资源规划、任务提交、调度运行、结果交付和故障处置。任何一步缺少都可能让“看起来正确”的任务变成生产事故。

京东科技开发者 337

81.8 秒的视频,我们改了 15 个版本:一次纯 Codex 驱动的 AI-native 视频实践

81.8 秒、15 个版本,这些数字真正想说明什么?视频制作正在从一组专业软件里的复杂操作,变成一场围绕目标、参考和反馈展开的持续对话。AI 已经可以接住从脚本到交付的大量工作。你可以把精力留给更重要的部分:理解观众、选择故事、判断好坏。过去停在 PPT 和脑海里的想法,现在有机会被快速做成一支能看、能改、也愿意转发的视频。如果明天就要介绍你手头的项目,你最想先把哪一步交给 AI?

京东科技开发者 433

Codex 驱动的移动端AI全栈开发:从 Relay 原型图到可交付链路

AI 编程工具降低了跨端开发门槛,但“让 AI 写页面”并不等于“完成移动端交付”。PC 运营端页面通常以功能闭环为中心,设计约束较弱,研发可以基于组件库快速搭建;移动端 C 端页面直接面对用户,Relay 原型图和 UI 设计稿不仅是视觉参考,更是交互、信息层级、状态反馈和业务信任感的综合契约。

京东科技开发者 566

Claude Code vs Codex 记忆体系深度对比

Claude Code —— 分层自动记忆系统四层分层架构(CLAUDE.md / Auto Memory / Session Memory / AutoDream)构成自优化闭环,系统主动捕获、分类、去冗并跨会话接力经验。走的是自动化优先路线——让机器替人记忆、替人整理,以少量可控性的不确定换取强大的经验积累能力。Codex —— 声明式契约系统两层扁平架构(AGENTS.md 静态声明层 + 会话上下文层),记忆完全由人显式订立、显式修改,系统只读契约、绝不擅自变更。走的是可控性优先。

京东科技开发者 605

上游给空、下游拿到 -1,我把故障一直追到了 commons-beanutils 的构造函数

这篇手记是一份事后复盘,写在我们已经把修复推上线、把测试用例跑绿、把约束文档沉淀进团队库之后。非研发同事,可以直接从第八章开始看,前七章都是讲排障和代码分析。故障本身不复杂,修复也不复杂,但这次排查真正让我想写下来的,不是技术本身——而是从问题提报到解决全程AI的作用:问题定位:业务方反馈了一个异常单号说「下发失败」,一线运维同事直接在日志系统捞到相关的系统日志,用IDE打开下游代码库,把异常信息给到JoyCode——AI 直接指向了问题是serialType值非法,系统只接受0和1,而当前上游给的是-1。

京东科技开发者 703

SKill测评:谁才是真正的Skill之王?

巧合的是,阿里近期开源了一款名为 Skill-Up 的测评工具——它专门面向 Agent Skill 开发者,支持在 Claude Code、Codex、Qoder CLI 等真实 Agent Engine 环境中验证 Skill 的功能正确性,并可将失败用例转化为精准的修复指引,同时支持本地与 CI 环境的持续回归。2026年,Skill 的热度不减,已成为 AI 辅助编程领域的标配。在日常研发中,无论是沉淀个人经验,还是将团队的优秀范本标准化,将知识“蒸馏”为 Skill 已是大家的常规操作。

京东科技开发者 618

让AI真正参与工作!JoyDesk已上线京东云

JoyDesk提供覆盖AI资产管理、权限控制、安全策略、审批审计、运营监控等企业级治理能力,支持按组织、角色和项目进行精细化权限管理,并支持私有化部署,确保企业数据边界清晰、AI行为全程可追溯、安全策略灵活可配置,满足金融、政企等行业对数据安全和合规治理的要求,让AI真正成为企业可信赖的生产力。JoyDesk支持MCP协议、标准API、技能等多种开放接入方式,可快速连接企业现有业务系统,将业务能力封装为AI可调用的技能和专家,让AI能够理解业务流程、调用业务系统、完成业务任务,而无需改变企业原有IT架构。

京东科技开发者 652

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手【最终版】

这个项目展示了AI Agent 在垂直内容创作领域端到端自动化:从内容理解到播客输出,全流程 AI 驱动多模态融合:文字、图片、音频、视频统一处理专业级音频质量:音色设计 + 智能混音,输出广播级品质低门槛使用:可视化配置 + 自然语言交互,无需技术背景。

京东科技开发者 556

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(高级篇)

这是一个 AI 驱动的播客创作助手,专注于从文字/视频/音频内容识别到播客制作的全流程。你可以用自然语言与它对话,也可以上传视频和音频,它会理解意图、调用相应的语音合成工具,把他们变成真实的播客音频。

京东科技开发者 720

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(进阶篇)

这是一个AI 驱动的音频内容创作助手。你可以用自然语言与它对话,它会理解意图、调用相应的语音合成工具,把文字变成真实的播客音频,并保存在本地。关于项目的详细介绍见第一篇文章:第一个 AI Agent 项目:从零搭建 AI 音频创作助手(入门篇)这篇文章更多介绍进阶篇添加的功能。

京东科技开发者 545

【全栈实践】第一个 AI Agent 项目:从零搭建 AI 音频创作助手(入门篇)

这个项目让我第一次把前端、后端、AI Agent 三块内容独立串联起来。技术选型上每一块都是当下主流的方案,实际跑通整条链路之后对"全栈"有了更具体的感受。框架版本要锁定:LangChain 这类快速迭代的框架,版本差异带来的问题远比你想象的多先跑通链路,再追求完美:新手阶段能把用户输入 → AI 处理 → 结果展示这条链跑通,比深入某个技术点更有价值多看官方文档:相比博客和教程,官方文档更新及时,特别是 LangGraph 这种新框架后续计划继续迭代,欢迎交流!

京东科技开发者 602

ICLR 2026 | 面向序列决策的贝叶斯集成方法

在这篇工作中,我们关注的是。

京东科技开发者 294

ICML 2026|NaviAgent:面向 Oxygen 智能体的可扩展工具编排

大型语言模型(LLM)越来越多地作为函数调用代理,调用外部工具来处理超出其静态知识范围的任务。然而,它们通常一次只调用一个工具,缺乏对任务结构的全局视图。由于工具之间往往相互依赖,这会导致错误累积和可扩展性差,尤其是在扩展到数百或数千个工具时。为了解决这些局限性,我们提出了NaviAgent,一种显式的双层架构,它通过基于图的工具关系建模将任务规划与工具执行解耦。在规划层,基于 LLM 的代理决定是直接响应、澄清意图,还是检索并执行一个独立于工具间复杂性的工具链。

京东科技开发者 383

实测 9 款 AI 架构图工具:从 Mermaid 美化到 GPT-Image2,一份选型清单

支持 5 类图(架构图、工作流图、时序图、数据流图、生命周期/状态机图),主题 4 种(Classic、Signal Flow、Blueprint、Editorial)+ 3 种色彩模式(Dark / Light / System Auto),输出格式含 HTML、PNG、SVG、WebM、Share Card PNG、JSON IR。它把提示词图库、图像生成案例、参考图编辑流程和命令行工具整合在一起,让 AI Agent 能直接调用 GPT Image 2 模型完成文生图、图生图、参考图编辑等任务。

京东科技开发者 895

别再守着 Claude Code 了——学会指挥它自主干活

回到开头那句:别再一句一句地喂它、然后守着屏幕。真正的用法是——把一件事想清楚、划好边界、给它一个能自我验证的目标,然后交出去。你会发现,省下来的时间不是一点半点。把重复的判断和执行还给机器,把真正需要你的判断留给自己。

京东科技开发者 584

CVPR 2026|Oxygen XR 团队在原生鱼眼高斯泼溅技术上带来新突破

京东零售技术团队联合清华大学提出DirectFisheye-GS框架,创新性地将鱼眼相机模型原生嵌入3D高斯泼溅管线,通过跨视角联合优化策略直接处理鱼眼图像,避免了传统去畸变预处理导致的信息损失。该方案在多个公开数据集上达到SOTA性能,有效解决了单视角优化引起的几何畸变和视角不一致问题,同时保持与现有3DGS工具链的兼容性。技术已应用于电商3D重建和4D体积视频等场景,显著提升了沉浸式体验。相关论文被CVPR 2026接收,为宽视场场景重建提供了高效解决方案。

京东科技开发者 353

拆解海博 AI-Native 落地保障:Harness、双 Loop、知识库与技能自主迭代实践

海博研发RoadMap 的落地,彻底终结了 AI 编程“对话式玄学”的旧模式,真正落地了AI Native 研发工程化。它证明 AI 规模化赋能研发的核心,不在于堆砌大模型能力,而在于用工程思维重构 AI 的工作范式:用结构化流程替代随机对话,用固化规则约束模型行为,用持续沉淀实现能力复利,用分层架构支撑规模化落地。

京东科技开发者 633

让 AI 快速「读懂」你的代码仓:Joy-Code-Graph 云端图谱服务的三次进化

代码知识图谱不是要取代 AI 的智能,而是要补齐它对代码全局关系的认知盲区。当 AI 能一眼看清「谁调用了谁、改动会波及哪里」,它写出的代码才真正靠谱;当这份认知安全地留在自己手里、随时被 Joygen 调用、并且永久沉淀在代码仓里——AI 编程的体验,才算真正上了一个台阶。这,就是我们做 Joy-Code-Graph 云端服务的初衷。能力共享,数据自主;一次建图,长期受用。

京东科技开发者 751

【Coding生态】从代码托管到 AI 能力底座:与Coding一起共建 AI 研发生态

前两种框架能够很好地支撑对话式能力和预设流程式能力。它们适合基于提示词或预设工作流完成研发问答、知识查询、流程编排等任务。但在更复杂的研发场景中,仅仅“回答问题”还不够。当用户业务逻辑复杂时,一旦场景进入真实落地阶段,例如下载代码、修改文件、执行命令、安装依赖、运行测试、读取完整代码文件,或者与自有系统联动、将结果渲染到 Coding 页面、推送到京 ME,AI 应用需要的不只是知识能力,还需要真实的代码库操作能力和独立可执行环境。

京东科技开发者 768

GPT-5.6、ChatGPT Work 与 Codex 更新食用指南

三档模型当前都提供 1,050,000 tokens 上下文、922,000 tokens 最大输入和 128,000 tokens 最大输出,接受文本与图像输入、输出文本,并支持 web search、file search、Computer Use、MCP、Tool Search、Skills、Apply Patch 等工具。Work 可以读取你提供的文件,通过插件连接 Slack、Google Drive、SharePoint、邮箱、日历、CRM 或项目系统,调用获批工具,并在执行中展示进度。

京东科技开发者 860

把业务流程沉淀成高质量 Skill 的实践路径

使用Record & Replay创建的Skill,尽管创建流程简单,但它的本质实际是让 AI 去操作页面,这不但有可能影响我们对电脑的操作,还有可能无法稳定复现。创建Skill时,可以使用 Codex 的 Record & Replay 插件,把一次手工操作录下来,再让 AI 生成可复用流程。刚开始切换时,很容易遇到接口报错,可以让Codex排查原因进行优化,直到可以稳定执行;补充相应业务背景,说明这件事为什么要做,谁会用,输入从哪来,输出给谁看。电脑休眠、关机、软件没开时,本地任务可能无法执行。

京东科技开发者 835

政企前台AI-Agent的架构实践:打造可复用的 AI 服务平台-【灯塔计划】

不止是爆火的龙虾,还是各种Skills,MCP、Agent,脱离的具体的场景谈方案,最后只会是一场空。这一套可复用的 AI 服务平台,截止目前,通过前后端对接规范文档,多项能力已快速接入到各个场域的不同端平台,大幅降低研发成本, 并且各业务线新场景的接入从原来的 “开发驱动” 转为 “配置驱动”,接入周期从天维度缩短至小时级。

京东科技开发者 860

京东 Oxygen xLLM 大模型推理引擎正式捐赠开放原子开源基金会,共建国产 AI Infra 生态

下一阶段 AI 基础设施的核心命题,不是简单的算力堆叠,而是让工程本身变得智能——让调度系统能自主感知负载特征并动态优化,让推理引擎能根据模型结构和硬件特性自动生成最优执行方案,让整个 AI 工程链路具备自感知、自决策、自优化的能力。未来,Oxygen xLLM 的项目官网、社区沟通渠道及微信社区将陆续向开发者开放,诚邀芯片厂商、模型厂商、云厂商、企业用户及个人开发者共同参与,让国产大模型推理引擎在开放生态中加速成长。硬件层,原生支持 GPU / NPU / MLU 多类 AI 芯片,深度适配国产芯片。

京东科技开发者 1000

【京东云】全球首个!京东全栈开源JoyAI-VL-Interaction,让大模型从“一问一答”走向“边看边说”

开源一套系统,而不只是一个模型在实时视频流中,JoyAI-VL-Interaction每秒都会做一次判断,比如,继续观察、保持沉默,发现关键事件、主动回应,遇到复杂任务,交给后台Agent处理。一个好的AI 助手,不应该一直打扰用户,而应该知道什么时候该出现,什么时候该安静,以及什么时候自己解决,什么时候交由agent解决。深耕零售、物流、健康、工业等实体产业二十余年,京东拥有全球领先的物理世界运营网络,覆盖仓储、配送、门店、直播、客服、售后海量真实场景,每天都在发生人、货、场的实时互动。

京东科技开发者 1029
上一篇: Function 源码解析与实践
下一篇: 为什么mysql不推荐使用雪花ID作为主键
京东云开发者
京东云开发者 企业官方账号 企业官方账号
博客等级 码龄8年 1万+粉丝 2139原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值