k8s 集群(不推荐)

 

参考链接

https://blog.csdn.net/real_myth/article/details/78719244

 

服务器IP角色分布

Test-01  172.16.119.214  kubernetes node

Test-02  172.16.119.223  kubernetes node

Test-03  172.16.119.224  kubernetes node

Test-04  172.16.119.225  kubernetes master

 

 

Master节点必需组件

 

组件名称

作用

版本号

etcd

非关系型数据库

v1.9.1

kube-apiserver

核心组件,所有组件均与其通信,提供Http Restful接口

v1.9.1

kube-controller-manager

集群内部管理中心,负责各类资源管理,如RC,Pod,命名空间等

v1.9.1

kube-scheduler

调度组件,负责node的调度

 

 

Node节点必需组件

组件名称

作用

版本号

kubelet

Node节点中核心组件,负责执行Master下发的任务

v1.9.1

kube-proxy

代理,负责kubelet与apiserver网络。相当于负载均衡,将请求转到后端pod中

 

 

准备工作

先设置本机hosts,编译/etc/hosts添加如下内容:

172.16.119.225  test-04

 

修改内核参数

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1
EOF

sysctl --system

 

关闭swap   k8s1.8版本以后,要求关闭swap,否则默认配置下kubelet将无法启动。

swapoff -a

#防止开机自动挂载 swap 分区
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

 

开启ipvs

不是必须,只是建议,pod的负载均衡是用kube-proxy来实现的,实现方式有两种,一种是默认的iptables,一种是ipvs,ipvs比iptable的性能更好而已。
ipvs是啥?为啥要用ipvs?:https://blog.csdn.net/fanren224/article/details/86548398
后面master的高可用和集群服务的负载均衡要用到ipvs,所以加载内核的以下模块

需要开启的模块是
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4

检查有没有开启
cut -f1 -d " " /proc/modules | grep -e ip_vs -e nf_conntrack_ipv4

没有的话,使用以下命令加载
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4

ipvs还需要ipset,检查下有没有。如果没有,安装

yum install ipset -y

 

关闭防火墙,禁用selinux

vi /etc/selinux/config
disabled

systemctl disable firewalld
systemctl stop firewalld

 

 

 

软件安装

1、Mster节点:

yum install etcd  kubernetes flannel

kubeadm:用于k8s节点管理(比如初始化主节点、集群中加入子节占为、移除节点等)。

kubectl:用于管理k8s的各种资源(比如查看logs、rs、deploy、ds等)。

kubelet:k8s的服务。

 

 

配置/etc/etcd/etcd.conf

ETCD_DATA_DIR="/var/lib/etcd/master.etcd"

ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.119.225:2379 "

ETCD_NAME="master"

ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.119.225:2379"

 

启动etcd

systemctl restart etcd  && systemctl enable  etcd 

 

 

检查etcd的健康指标

etcdctl -C http://172.16.119.225:2379 cluster-health

 

配置etcd中关于flannel的key  也就是分配给docker的网段

etcdctl mk /atomic.io/network/config '{ "Network": "10.254.0.0/16" }'

 

配置 /etc/sysconfig/flanneld

FLANNEL_ETCD_ENDPOINTS="http://172.16.119.225:2379"

FLANNEL_ETCD_PREFIX="/atomic.io/network"

 

启动flannel

systemctl start flanneld && systemctl enable flanneld

 

配置/etc/kubernetes/apiserver

KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"   #此参数为绑定不安全地址,绑定安全地址参数是  --bind-address=172.16.119.225KUBE_ETCD_SERVERS="--etcd-servers=http://172.16.119.225:2379"

KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"

KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"

KUBE_API_ARGS=""

  

 重启服务并设置开机自启动

systemctl restart kube-apiserver  && systemctl enable kube-apiserver
 
systemctl restart kube-controller-manager  &&  systemctl enable kube-controller-manager

systemctl restart kube-scheduler   &&  systemctl enable  kube-scheduler 

 

2、node节点:

1、安装配置flannel

yum install flannel

配置flannel:/etc/sysconfig/flanneld

FLANNEL_ETCD_ENDPOINTS="http://172.16.119.225:2379"  # 172.16.119.225为master地址

FLANNEL_ETCD_PREFIX="/atomic.io/network"

 

启动flannel

systemctl start flanneld && systemctl enable flanneld

 

 

 

2、安装kubernetes

yum install kubernetes

不同于master节点,slave节点上需要运行kubernetes的如下组件:

kubelet

kubernets-proxy

 

配置/etc/kubernetes/config

KUBE_LOGTOSTDERR="--logtostderr=true"

# journal message level, 0 is debug

KUBE_LOG_LEVEL="--v=0"

# Should this cluster be allowed to run privileged docker containers

KUBE_ALLOW_PRIV="--allow-privileged=false"

# How the controller-manager, scheduler, and proxy find the apiserver

KUBE_MASTER="--master=http://172.16.119.225:8080"
#172.16.119.225为master地址

 

 

配置 /etc/kubernetes/kubelet

# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=172.16.119.225"

# The port for the info server to serve on
KUBELET_PORT="--port=10250"

# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override= 172.16.119.214"  #node的名字,随意取
# 172.16.119.214为node地址

# location of the api-server
KUBELET_API_SERVER="--api-servers=http://172.16.119.225:6442"
#172.16.119.225为master地址

# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"

# Add your own!
KUBELET_ARGS=""  
 
 

 

启动kube服务

systemctl restart kubelet && systemctl enable  kubelet

systemctl restart kube-proxy && systemctl enable kube-proxy

 

至此,k8s集群的搭建过程就完成一半了

 

验证集群状态

  • 1、查看端点信息:kubectl get endpoints

 

 

  • 2、查看集群信息:kubectl cluster-info

 

 

  • 3、获取集群中的节点状态: kubectl get nodes

 

认证授权设置

参考链接:https://www.cnblogs.com/lemon-le/p/9970783.html

集群搭建好后务必设置认证授权,否则等后面配置Kubernetes Api Server时会因为没有安全配置导致服务器被渗透,参考https://www.jianshu.com/p/e443b3171253

步骤如下:

1、停止原有kubernetes相关服务,包括service,deployments,pods以及运行的所有kubernetes组件

master节点上:

systemctl stop  kube-apiserver
systemctl stop  kube-controller-manager
systemctl stop  kube-scheduler
rm -fr /var/lib/kubelet/*
rm -fr /var/lib/kube-proxy/*

node节点上:

systemctl stop kubelet
systemctl stop kube-proxy
rm -fr /var/lib/kubelet/*
rm -fr /var/lib/kube-proxy/*

 2、设置kube-apiserver的ca证书的相关文件和启动参数

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=test-04" -days 5000 -out ca.crt
openssl genrsa -out server.key 2048

注意:生成ca.crt时  /CN 值为master主机名

然后准备master_ssl.conf文件,该文件用于x509 v3版本证书,文件中主要设置master主机 hostname  、ip、 k8s 虚拟赋权名称和该虚拟服务的ClusterIP地址

内容如下:

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name 
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation,digitalSignature,keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
DNS.5 = test-04      #服务器的hostname
IP.1 = 172.16.119.225   #master ip
IP.2 = 10.254.0.1      #svc的cluster ip  如果cluster网段是 10.254.0.0/16  此处就写10.254.0.1 
 
 

 然后基于master_ssl.conf文件创建server.csr和server.crt文件,在生成server.csr时,-subject参数中 /CN 值为master主机名

openssl req -new -key server.key -subj "/CN=test-04" -config  master_ssl.conf -out server.csr

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile master_ssl.conf -out server.crt

全部执行完毕会生成6个文件:ca.crt  ca.key  ca.srl  server.crt  server.csr  server.key 将这些文件复制到一个目录下,如 /var/run/kubernetes/   

 /var/run/kubernetes/  默认只有apiserver.crt 、 apiserver.key 、kubelet.crt和kubelet.key四个文件

 

 

然后在kube-apiserver文件 KUBE_API_ARGS中添加三个启动参数 --client-ca-file     --tls-cert-file   和  --tls-private-key-file,分别代表CA根证书文件、服务器端证书文件和服务端私钥文件

 同时可以更改KUBE_API_ADDRESS     KUBE_API_PORT  KUBE_API_ARGS参数关掉非安全端口8080,设置安全端口为6442,默认为6443

 

KUBE_API_ADDRESS="--bind-address=172.16.119.225"
KUBE_API_PORT="--secure-port=0"
# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://172.16.119.225:2379"

# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"

# default admission control policies
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"

# Add your own!
KUBE_API_ARGS="--client-ca-file=/var/run/kubernetes/ca.crt   --tls-cert-file=/var/run/kubernetes/server.crt   --tls-private-key-file=/var/run/kubernetes/server.key  --secure-port=6442"

 

最后重启kube-apiserver服务

systemctl restart kube-apiserver

 

 3、设置kube-controller-manager的客户端证书、私钥和启动参数

openssl genrsa -out cs_client.key 2048
openssl req -new -key cs_client.key -subj "/CN=test-04" -out cs_client.csr
openssl x509 -req -in cs_client.csr -CA /var/run/kubernetes/ca.crt -CAkey /var/run/kubernetes/ca.key -CAcreateserial  -out cs_client.crt -days 5000

此步会生成3个文件:cs_client.key   cs_client.crt  cs_client.csr   把生成的证书复制到/var/run/kubernetes/   然后创建/etc/kubernetes/kubeconfig文件,(kube-controller-manager与kube-scheduler共用),配置客户端证书等参数,内容如下:

apiVersion: v1
kind: Config
users:
- name: controllermanager
  user:
     client-certificate: /var/run/kubernetes/cs_client.crt
     client-key: /var/run/kubernetes/cs_client.key
clusters:
- name: local
  cluster:
     certificate-authority: /var/run/kubernetes/ca.crt
contexts:
- context:
   cluster: local
   user: controllermanager
  name: my-context
current-context: my-context

 

然后,设置kube-controller-manager服务启动参数,注意 --master的地址为https安全服务地址

更改/etc/kubernetes/controller-manager   启动参数

KUBE_CONTROLLER_MANAGER_ARGS="--master=https://172.16.119.225:6442  --service_account_private_key_file=/var/run/kubernetes/server.key  --root-ca-file=/var/run/kubernetes/ca.crt --kubeconfig=/etc/kubernetes/kubeconfig"

 

更改/etc/kubernetes/config 里 KUBE_MASTER="--master=http://127.0.0.1:8080"  改成上面设置的安全地址 KUBE_MASTER="--master=https://172.16.119.225:6442" 

 

重启kube-controller-manager服务

systemctl restart kube-controller-manager

 

4、设置kube-scheduler参数

kube-scheduler复用上一步kube-controller-manager创建的客户端证书,只需要修改/etc/kubernetes/scheduler启动参数即可

KUBE_SCHEDULER_ARGS="--master=https://172.16.119.225:6442  --kubeconfig=/etc/kubernetes/kubeconfig"

重启kube-scheduler服务

systemctl restart kube-scheduler

 

5、设置每台node上kubelet的客户端证书、私钥和启动参数

首先复制kube-apiserver的ca.crt和ca.key文件到node上,然后生成kubelet_client.crt证书,生成证书时-CA参数和-CAkey参数使用的是apiserver的ca.crt和ca.key文件;生成kubelet_client.csr是 -subj参数中 /CN 为本机node ip地址

openssl genrsa -out kubelet_client.key 2048
openssl req -new -key kubelet_client.key -subj "/CN=172.16.119.225" -out kubelet_client.csr
openssl x509 -req -in kubelet_client.csr -CA  ca.crt -CAkey  ca.key -CAcreateserial  -out kubelet_client.crt -days 5000

此步会生成3个文件:kubelet_client.key   kubelet_client.csr   kubelet_client.crt   然后把生成的证书复制到/var/run/kubernetes/目录下

接下来创建/etc/kubernetes/kube_client_config文件(kubelet和kube-proxy共用),配置客户端证书等相关参数,内容如下:

apiVersion: v1
kind: Config
users:
- name: kubelet
  user: 
     client-certificate: /var/run/kubernetes/kubelet_client.crt
     client-key: /var/run/kubernetes/kubelet_client.key
clusters:
- name: local
  cluster: 
     certificate-authority: /var/run/kubernetes/ca.crt
contexts:
- context:
   cluster: local
   user: kubelet
  name: my-context
current-context: my-context

 

然后设置kubelet启动参数

# location of the api-server
KUBELET_API_SERVER="--api-servers=https://172.16.119.225:6442"

# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"

# Add your own!
KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kube_client_config"

重启kubelet服务

systemctl restart kubelet

 

6、设置kube-proxy启动参数

kube-proxy复用上一步创建的客户端证书,只需配置启动参数即可

vim /etc/kubernetes/proxy

KUBE_PROXY_ARGS="--master=https://172.16.119.225:6442  --kubeconfig=/etc/kubernetes/kube_client_config"

重启kube-proxy服务

systemctl restart kube-proxy

 

7、设置kubectl客户端使用安全方式访问apiserver

在使用kubectl对kubenetes集群进行操作时,默认使用非安全端口8080对apiserver进行访问,也可以设置设置为安全访问apiserver的模式,此模式需要设置3个证书相关的参数  --certificat-authority   --client-certificate  和 --client-key

分别表示用于CA授权证书、客户端证书和客户端秘钥,其中

--certificat-authority   使用为kube-apiserver生成的ca.crt文件

--client-certificate      使用为kube-controller-manager生成的cs_client.crt文件

--client-key                使用为kube-controller-manager生成的cs_client.key文件

同时指定apiserver的URL地址为HTTPS安全地址,最后输入需要执行的子命令,即可对apiserver进行安全访问了:

 

kubectl --server=https://172.16.119.225:6442 --certificate-authority=/var/run/kubernetes/ca.crt --client-certificate=/var/run/kubernetes/cs_client.crt  --client-key=/var/run/kubernetes/cs_client.key get nodes

 

但每次这样忒麻烦了,所以写个alias,不知道还有没有其他方法

 编辑 ~/.bashrc  

vim ~/.bashrc 增加下面一局然后source ~/.bashrc  即可

 

alias kubectl='kubectl --server=https://172.16.119.225:6442 --certificate-authority=/var/run/kubernetes/ca.crt --client-certificate=/var/run/kubernetes/cs_client.crt  --client-key=/var/run/kubernetes/cs_client.key'

 

 

 DNS服务搭建

https://blog.51cto.com/ylw6006/2067923 

Kubernetes集群机制通过DNS进行服务名和ip的映射,如果没有配置dns,可以通过kubectl get svc 命令查询集群ip,

但Cluster-ip是变化的,如果通过一个create命令一次批量建立一堆具有相互依赖关系的Pod或者RC,就需要配置DNS

DNS 有两种配置方式,在 1.3 之前使用 etcd + kube2sky + skydns 的方式,在 1.3 之后可以使用 kubedns + dnsmasq 的方式。

推荐使用kubedns + dnsmasq 的方式,本次也是使用此方式。

先创建目录,skydns文件都放在/etc/kubernetes/skydns 下

mkdir /etc/kubernetes/skydns

 

1、配置etcd中关于skyDNS的key

 etcdctl mk /skydns/config '{"dns-addr":"10.254.254.254:53","ttl":3600,"domain":"cluster.local."}'

 

2、skynds服务由一个RC和一个Service定义组成,分别由配置文件skydns-rc.yaml和 skydns-svc.yaml定义:

skydns-rc.yaml包含2个容器的定义,需要修改如下几个参数:

--kube_master_url  为master所在的物理主机IP和端口

--domain=cluster.local  设置kubernetes集群中Service所属的域名,本例为cluster.local

apiVersion: v1
kind: ReplicationController
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    version: v12
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 1
  selector:
    k8s-app: kube-dns
    version: v12
  template:
    metadata:
      labels:
        k8s-app: kube-dns
        version: v12
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - name: kube2sky
        image: docker.io/port/kubernetes-kube2sky
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
          requests:
            cpu: 100m
            memory: 50Mi
        args:
        - --kube_master_url=https://172.16.119.225:6442
        - -domain=cluster.local
        - -etcd-server=http://172.16.119.225:2379 
      - name: skydns
        image: docker.io/skynetservices/skydns
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
          requests:
            cpu: 100m
            memory: 50Mi
        args:
        - -machines=http://172.16.119.225:2379
        - -addr=0.0.0.0:53
        - -ns-rotate=false
        - -domain=cluster.local.  # 点 不能少
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
      dnsPolicy: Default

 

 

skydns-svc.yaml

apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP:  10.254.254.254
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

注意,skydns需要指定一个固定的IP,之后每个node节点启动都将使用这个IP,且这个IP一定要是kube-apiserver启动参数--service-cluster-ip-range范围内的IP。

 

创建skydns之前需要修改每个node上kubelet的启动参数。

3、修改node启动参数

编译kubelet文件,添加俩个启动参数

--cluster-dns  上面配置的10.254.254.254
--cluster-domain 上面配置的cluster.local
KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kube_client_config  --cluster-dns=10.254.254.254 --cluster-domain=cluster.local"

然后重启kubelet服务

systemctl restart kubelet

 

4、创建skydns的RC和SVC

kubectl create -f skydns/skydns-rc.yaml 
kubectl create -f skydns/skydns-svc.yaml 

 查看RC pod svc,确保容器启动成功,如果没有启动成功,查看原因是不是镜像地址更改了,如果镜像地址改了,可以登录http://docker.gaoxiaobang.com查看新的镜像地址

如果pod无法启动,可参考文尾解决办法

 

至此,在Kubernetes集群内的虚拟DNS服务已搭建完毕。

 

5、测试效果

部署一个test-dns的Pod进行验证

apiVersion: v1
kind: Pod
metadata:
  name: test-dns
  namespace: default
spec:
  containers:
  - name: test-dns
    image: busybox
    command:
      - sleep
      - "3600"

启动test-dns

 

容器启动成功后,通过下面命令进行测试

kubectl exec -it test-dns  sh

 

 

也可以新建一个pod,然后用 kubectl exec <container_id> nslookup  验证

如果某个Service属于不同的命名空间,则进行Service查找时,需要带上namespace的名字,如:

kubectl exec test-dns  -- nslookup  default.kubernetes

 

 

 安装Dashboard 

1、下载代码

git clone https://github.com/Qihoo360/wayne/
其中 hack/kubernetes 目录下面就是我们需要部署的 Wayne 的资源清单文件

2、我们这里将所有服务都部署到 kube-system 命名空间下面,所以将这里的资源清单中的 namespace 都统一改成 kube-system

     

grep -rl default wayne/hack/kubernetes/wayne/ | xargs sed -i 's/default/kube-system/'

3、由于我们这里是使用上面集群中部署的 MySQL 服务,所以这里需要对 configmap.yaml 文件进行简单的配置,而 360 文档上面的 ConfigMap 是不完整的,需要使用源码里面的 app.conf 文件来进行创建,所以我们这里可以使用 --from-file 关键字来创建 ConfigMap 对象,首先配置下 wayne/src/backend/conf/app.conf 文件,根据个人需要修改,也可以不改,使用默认的配置,然后创建ConfigMap 

   

kubectl create configmap infra-wayne --namespace kube-system --from-file=wayne/src/backend/conf/app.conf

4、然后部署另外俩个应用

kubectl create -f wayne/hack/kubernetes/wayne/deployment.yaml 
kubectl create -f wayne/hack/kubernetes/wayne/service.yaml 

5、创建完成后,可以查看下 Pod 的状态,如果没有错误信息,就证明部署成功了

kubectl get pods -n kube-system

如果失败可用  

kubectl logs -n kube-system  -f infra-wayne-312744915-xdb8b  查看错误信息

或者

 kubectl describe -n kube-system pods infra-wayne-312744915-xdb8b 

 

6、查看端口

kubectl get svc -n kube-system -l app=infra-wayne

 

然后使用本机IP:30771来访问 Wayne 

 

 

 

---------------------------------------------

异常解决

 

1、kubectl create -f  mysql.yaml  后pod无法启动,用kubectl get pod 发现该pod处于ContainerCreating状态

使用kubectl  describe pod mysql-wayne-3939478235-x83pm  查看具体信息时发现报错如下:

 

 解决办法:

各个node节点上都需要安装

yum install *rhsm*

docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest

如果还报错则进行如下步骤

wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm

rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | tee /etc/rhsm/ca/redhat-uep.pem

docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest

然后删除pod 重新创建

kubectl delete -f mysql.yaml

kubectl create -f mysql.yaml

 

 

2、pod无法删除排查

https://www.58jb.com/html/155.html

 

3、etcd简单操作

 ls 查看

get 获取key的值

rm 删除key

更多的参考 etcdctl help

 

转载于:https://www.cnblogs.com/abkn/p/10944838.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值