基于VMware采用kubeadm方式部署单节点k8s集群(练习使用)

1.虚拟机安装centos7.6

1.1 导入镜像

这里选择的版本是:CentOS-7-x86_64-DVD-2207-02.iso(即centos7.6的镜像)

镜像下载地址:

http://mirrors.neusoft.edu.cn/centos/7/isos/x86_64/

 

1.2  选择空间剩余充足的磁盘为安装目录,设置虚拟机名称

否则会造成后续磁盘空间不足的问题:

1.3 设置核数:2核(资源充足可多设置)

1.4 设置内存:2G(资源充足可多设置)

1.5 设置网络类型为NAT

用于虚拟机共享主机网络

 

 以下皆为默认

 

1.6 分配磁盘容量为:50G

接下来默认直接安装即可:

 

1.7 选择语言

默认英语即可:

1.8 选择时间

1.9 磁盘默认即可

1.10 设置网络与hostname

 即可开始安装

1.10 设置root用户

1.12 设置普通用户

1.13 远程控制 

因VMware显示十分简陋,需要连接远程进行使用,可阅读性强

先查看IP地址:

ip addr

 再打开远程控制工具进行控制:

2.基础环境设置

2.1 yum安装必要软件

切换到sudo用户安装vim,netstat等基础工具

 yum -y install vim net-tools  wget

2.2 设置普通用户hadoop免密sudo用户

vim /etc/sudoers

验证:

切换到hadoop用户看是否执行成功,即可成功

sudo su root

2.3 关闭防火墙

sudo systemctl stop firewalld && sudo systemctl disable firewalld

 验证如下:

sudo systemctl status firewalld 

 2.4 关闭selinx

# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

2.5 关闭Linux 的 swap 分区,提升 Kubernetes 的性能

sudo swapoff -a
sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab

2.6 调整DNS设置文件

 sudo vim /etc/resolv.conf

验证:

ping www.baidu.com

2.7 主机名调整,设置主机名清单

sudo hostnamectl set-hostname k8s-master

 修改主机名清单中加入如下内容:

sudo vim /etc/hosts
192.168.170.1xx    k8s-master

 验证:

ping k8s-master

2.8 修改内核参数和模块

转发 IPv4 并让 iptables 看到桥接流量 通过运行 lsmod | grep br_netfilter 来验证 br_netfilter 模块是否已加载。

若要显式加载此模块,请运行 sudo modprobe br_netfilter。

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

 为了让 Linux 节点的 iptables 能够正确查看桥接流量,请确认 sysctl 配置中的 net.bridge.bridge-nf-call-iptables 设置为 1。例如:

# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

3.docker安装

3.1 安装docker

sudo yum update
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

 这里选择的docker版本是docker20.10.7版本

sudo yum -y install docker-ce-20.10.7 docker-ce-cli-20.10.7 containerd.io-1.4.6 docker-compose-plugin

3.2 设置docker

启动docker服务;将当前的用户breath加入 Docker 的用户组,这是因为操作 Docker 必须要有 root 权限,而直接使用 root 用户不够安全,加入 Docker 用户组是一个比较好的选择,这也是 Docker 官方推荐的做法。

sudo systemctl enable docker      #设置docker服务开机启动
sudo systemctl start docker       #启动docker服务
sudo usermod -aG docker ${USER}   #当前用户加入docker组
sudo chmod  777 /var/run/docker.sock

 使用docker version会输出 Docker 客户端和服务器各自的版本信息:

docker version

使用docker info会显示当前 Docker 系统相关的信息,例如 CPU、内存、容器数量、镜像数量、容器运行时、存储文件系统等等:

docker info

3.3 修改docker 的配置

修改Docker 的配置,在/etc/docker/daemon.json里把 cgroup 的驱动程序改成 systemd ,然后重启 Docker 的守护进程。

cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker

4.docker-compose安装

Docker Compose是一个用来定义和运行复杂应用的Docker工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器。

Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。

sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

加入软连接并验证

sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
sudo docker-compose --version

5.k8s安装

5.1 设置国内阿里源

sudo vim /etc/yum.repos.d/kubernetes.repo

 加入如下内容:

[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

5.2 安装指定版本,这里选择1.23.4

sudo yum install -y kubelet-1.23.4 kubeadm-1.23.4 kubectl-1.23.4

5.3 设置开机启动

systemctl enable kubelet 

6.设置master节点可运行pod

6.1 生成初始文件

sudo mkdir /opt/k8s && sudo chown hadoop:hadoop /opt/k8s && cd /opt/k8s && kubeadm config print init-defaults > kubeadm-config.yaml

6.2 修改配置文件

对生成的配置文件进行如下设置

配置文参考如下:

apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.170.1xx
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  imagePullPolicy: IfNotPresent
  name: k8s-master
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.23.4
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/16
scheduler: {}

6.3 预先拉取所需镜像

kubeadm config images pull --config=kubeadm-config.yaml

如果出现如下问题: 

 则需要修改主机名

sudo hostnamectl set-hostname  k8s-master

 同时修改 /etc/hosts文件

sudo  vim /etc/hosts

 修改配置文件

继续执行如下命令: 

kubeadm config images pull --config=kubeadm-config.yaml

 验证如下命令,则证明成功:

docker images

6.4 初始化

加上 tee kubeadm-init.log,方便后续查看 token 和初始化信息

 sudo  kubeadm init --config=kubeadm-config.yaml | tee kubeadm-init.log

同时,返回的信息中还提示我们需要完成几步工作要做。这几部工作分别是

客户端配置文件

To start using your cluster, you need to run the following as a regular user:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

 增加网络插件

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/

增加worker node(设置master节点可运行pod则不需要)

kubeadm join 192.168.6.1xx:6443 --token 8m9ctp.n6bbyo39h0r6zl4b \
      --discovery-token-ca-cert-hash sha256:a417bbd22599f46f437ce9533c341f8cf5b32a941f7104b8dbe52eba4221xx9c

6.5 客户端配置

本地建立一个.kube目录,然后拷贝kubectl的配置文件,这些信息用于用户进行操作kubernetes集群。

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

 可以通过kubectl versionkubectl get node查看当前状态。

kubectl version
kubectl get node

需要注意,此时是notready状态,只有安装软件插件后才能变为ready状态 

6.6 安装网络插件

Kubernetes 定义了 CNI 标准,有很多网络插件,这里我选择最常用的 Flannel

6.6.1 创建配置文件

sudo   mkdir  /opt/flannel && sudo chown  hadoop:hadoop /opt/flannel  &&  cd  /opt/flannel  && wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

6.6.2 生成 flannel 插件

kubectl apply -f kube-flannel.yml

 验证如下:

 kubectl  get po -A |grep flannel
 docker ps  -a | grep flannel
 kubectl get node

到这一步证明网络插件安装成功

如果没有成功,多半是镜像没有拉取成功,可以修改文件,确保版本号如下:

当然之前的命名空间需要删除,执行如下命令: 

 kubectl delete ns kube-flannel   --force --grace-period=0

6.7 设置master节点可运行pod

使用 kubeadm 部署的 kubernetes 集群,其 master 节点默认拒绝将 pod 调度运行于其上的,加点官方的术语就是:master 默认被赋予了一个或者多个“污点(taints)”,“污点”的作用是让该节点拒绝将 pod 调度运行于其上。那么存在某些情况,比如测试环境资源不足,想让 master 也成为工作节点可以调度pod运行怎么办呢?两种方式:(1)去掉“污点”(taints)【生产环境不推荐】;(2)让 pod 能够容忍(tolerations)该节点上的“污点”。

通过 kubectl describe 命令也即可得知,业务 pod 默认不可运行于 master 之上:

kubectl describe nodes k8s-master | grep Taints

如果想让业务 pod 可以运行在 master 之上,可以执行如下命令(去掉“污点”)来实现(生产环境不推荐!!!)

kubectl taint node k8s-master node-role.kubernetes.io/master:NoSchedule-

 若执行以上命令,再次查看 kubectl describe 结果应如下:

kubectl describe nodes k8s-master | grep Taints

 此时,master节点上也可以运行pod了。此时就有一个单节点的k8s测试集群了。

6.8 添加worker节点(这里主要是部署单节点的k8s测试集群,可以跳过)

另外还有一个很重要的“kubeadm join”提示,其他节点要加入集群必须要用指令里的 token 和 ca 证书。如果你成功安装了 Master 节点,那么 Worker 节点的安装就简单多了,只需要用之前拷贝的那条 kubeadm join 命令就可以了。

Worker节点的配置跟master节点的配置相同,只是不需要执行kubeadm init,而是通过kubeadm join来添加到集群。当然如果你不提前下载镜像可以通过指定--image-repository参数,记得要用 sudo 来执行:

sudo kubeadm join 192.168.6.1xx:6443 --token 8m9ctp.n6bbyo39h0r6zl4b \
        --discovery-token-ca-cert-hash sha256:a417bbd22599f46f437ce9533c341f8cf5b32a941f7104b8dbe52eba422xxx9c

执行完毕后可以通过kubectl get node来观看添加worker节点的状态。

7.Dashboard部署

我们从kubernetes dashboard release页面找到支持kubernetes v1.23的最新dashboard版本为v2.5.1。从v2.5.1版本release文档看,可以兼容kubernetes v1.23.

7.1 创建配置文件

sudo   mkdir  /opt/Dashboard  && sudo chown  hadoop:hadoop /opt/Dashboard  &&  cd  /opt/Dashboard  && wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/recommended.yaml 

7.2 启动kubernetes dashboard

kubectl apply -f recommended.yaml 

 等待镜像下载完毕,查看对应的镜像及pod。

docker images |grep kubernetesui
kubectl get po -A |grep dashboard

 如果下载不下来镜像手动下载然后导入依然可以 

7.3 创建样例用户

 访问dashboard需要创建ServiceAccount和ClusterRoleBinding,我们使用dashboard-adminuser.yaml进行创建,如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

执行命令创建:

kubectl apply -f dashboard-adminuser.yaml

如果要删除样例用户可以使用如下命令: 

kubectl -n kubernetes-dashboard delete serviceaccount admin-user
kubectl -n kubernetes-dashboard delete clusterrolebinding admin-user

7.4 获取Bearer Token

需要生成Token在登录页面使用:

kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"

生成Token如下:

eyJhbGciOiJSUzI1NiIsImtpZCI6IkdBRmFUckJrRE5YdEZDbVlVanZZNEtGeTYzcEdaTUowQnM5eDJVdWdkY00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50xxxxxxxiZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLWdiam56Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI0OGY1ZjEwMi0xOTFlLTQzM2QtODQ2Ni1lZWU3OGE1ODkzNmQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.r9QxJ1NrqI9PG6Iae5l80KiRHY4Qy4HCUIAbnDv-1r-f0JMveQ4ywD5xEG3DGpxccBPOitcuwTNFCo3JjmvI8ptYkFTpvjWI7Ujsw7i7mUMTdsruNdNYICZqKOq0dG2WDmk4VGkUndABiGUoAUN2rkUvoJQOd6sqpcnSnW2SHVVCqVWmjKKdwHrlJZptLSzT9q0UuQSbSMRm0xrsLTGj82Yv-kC3EM7W-p-_Xdyu0WmIdaWZ24uYKC45Y50p96lhmqG2ZYKkJzNwfIbsF0FGawGpXsPR6kcpaREI745VSgoBuqZGZyGlWg3dbfoUdhZsNvG_B9jeGJsJodUS5kcdWg

7.5 服务类型改为NodePort

kubectl -n kubernetes-dashboard patch services kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}'
service/kubernetes-dashboard patched

 命令空间kubernetes-dashboard中的kubernetes-dashboard服务的端口地址,暴露端口为32701(这个数字是随机生成的):

kubectl -n kubernetes-dashboard get service kubernetes-dashboard

这时在外部机器浏览器输入IP加32701,(注意必须是 https)即可访问:

https://192.168.170.1xx:32701/

备注:如果未出现上述网页,请在当前页面敲打以下文字 

thisisunsafe

8.metrics-server部署

8.1 版本选择

因安装的k8s版本是1.23.4 所以需要找皮匹配的Metric-server

https://github.com/kubernetes-sigs/metrics-server

Releases · kubernetes-sigs/metrics-server选择下载如下内容: 

8.2 文件下载与修改

sudo  mkdir /opt/metrics-server && sudo chown  hadoop:hadoop /opt/metrics-server && cd /opt/metrics-server && wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.0/components.yaml –no-check-certificate

执行如上命令发现下载不下来,需要手动下载如下文件:

https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.0/components.yaml

文件中需要作如下改在,如下:

 全部文档内容如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-view: "true"
  name: system:aggregated-metrics-reader
rules:
- apiGroups:
  - metrics.k8s.io
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
rules:
- apiGroups:
  - ""
  resources:
  - nodes/metrics
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - pods
  - nodes
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server-auth-reader
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server:system:auth-delegator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    k8s-app: metrics-server
  name: system:metrics-server
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:metrics-server
subjects:
- kind: ServiceAccount
  name: metrics-server
  namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  ports:
  - name: https
    port: 443
    protocol: TCP
    targetPort: https
  selector:
    k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: metrics-server
  name: metrics-server
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        - --kubelet-insecure-tls
        image: docker.io/bitnami/metrics-server:0.6.0
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /livez
            port: https
            scheme: HTTPS
          periodSeconds: 10
        name: metrics-server
        ports:
        - containerPort: 4443
          name: https
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /readyz
            port: https
            scheme: HTTPS
          initialDelaySeconds: 20
          periodSeconds: 10
        resources:
          requests:
            cpu: 100m
            memory: 200Mi
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
      nodeSelector:
        kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      serviceAccountName: metrics-server
      volumes:
      - emptyDir: {}
        name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  labels:
    k8s-app: metrics-server
  name: v1beta1.metrics.k8s.io
spec:
  group: metrics.k8s.io
  groupPriorityMinimum: 100
  insecureSkipTLSVerify: true
  service:
    name: metrics-server
    namespace: kube-system
  version: v1beta1
  versionPriority: 100

镜像地址更换是因为源地址无法下载

添加参数是因为缺少参数会报错误导致无法生效,报错如下:

controller.go:116] loading OpenAPI spec for "v1beta1.metrics.k8s.io" failed

参考:

https://developer.aliyun.com/article/793487

8.3 启动 metrics-server

kubectl apply -f components.yaml

执行如下命令查看效果:

watch -n 1  'kubectl top nodes'

网页端效果需要等一段时间 

9.结果展示

9.1 系统资源

9.2 Dashboard页面展示

10.参考文档

1.k8s报错:pod状态为pending,coredns的状态是pending的解决办法

https://blog.csdn.net/baidu_38803985/article/details/105966464

2.初始化集群coredns容器一直处于pending状态

https://blog.csdn.net/weixin_41831919/article/details/108349510

3.Centos7国内环境下安装kubeadm、kubelet、kubectl并建立k8s集群、安装gitlab,测试spring boot 项目的CICD

https://blog.csdn.net/m2099797280/article/details/123463738

4.Kubernetes Dashboard 部署应用以及访问

https://blog.csdn.net/yangfenggh/article/details/125996950

5.Kubernetes 之 yaml文件 详解汇总

https://blog.csdn.net/m0_61433200/article/details/126155568

6.Kubernetes — Dashboard

https://caixm.blog.csdn.net/article/details/127217339

7.k8s 监控程序Metric-server pod运行异常报:it doesn't contain any IP SANs

https://developer.aliyun.com/article/793487

8.Kubernetes网络三部曲:

https://blog.csdn.net/yang75108/category_9317769.html

9.K8S 快速入门:

https://blog.csdn.net/weixin_41947378/category_10426192.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值