2022版使用云服务器搭建公网k8s容器集群
总体流程一览
主要流程如下:
1.准备云主机,升级CentOS系统到7.9
2.所有节点上安装Docker和Kubeadm,拉取相关镜像
3.在Master节点初始化集群,包括kubectl和部署CN容器网络插件
4.把Node节点加入k8s集群
可视化界面和私有镜像仓库请参考其他文章:
1.部署Dashboard Web 页面,可视化查看Kubernetes资源,看我下一篇文章:k8s dashboard安装
2.部署Harbor私有仓库,存放镜像资源(非必要,省略介绍)
下面,开始介绍各流程详细配置步骤。
环境准备
云主机
云服务器 | 区域 | CentOS | 节点类型 | 配置 | 公网IP | 安装工具 |
---|---|---|---|---|---|---|
腾讯云 | 上海三区 | 7.9 | master01 | 2C4G | 101.34.112.190 | docker、kubeadm、kubelet、kubectl、flannel |
同上 | 上海二区 | 7.9 | node01 | 1C2G | 81.68.126.69 | 同上 |
同上 | 上海二区 | 7.9 | node02 | 1C2G | 81.68.92.49 | 同上 |
CentOS升级
如果低于CentOS 7.9
,请先升级:
$ yum update -y
$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
PS:请务必不要跳过这步,低版本的CentOS安装Kubeadm时很可能会失败。作者就是失败之后升级CentOS才成功了!!
所有节点CentOS设置
基础设置
PS:该步骤基于:
CentOS Linux release 7.9.2009 (Core)
,7.2 - 7.6 版本好像会失败,如果中途不成功,请考虑升级更换CentOS版本!
可以创建 k8s-pre-install-centos.sh 脚本,一键设置:
$ vim k8s-pre-install-centos.sh#!/bin/shfunction set_base(){# 关闭防火墙,PS:如果使用云服务器,还需要在云服务器的控制台中把防火墙关闭了或者允许所有端口。systemctl stop firewalldsystemctl disable firewalld# 关闭SELinux,这样做的目的是:为了让容器能读取主机文件系统。setenforce 0# 永久关闭swap分区交换,kubeadm规定,一定要关闭swapoff -ased -ri 's/.*swap.*/#&/' /etc/fstab# iptables配置cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOFcat <<EOF | sudo tee /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# iptables生效参数sysctl --system
}set_base
执行上述脚本:
$ chmod 777 k8s-pre-install-centos.sh && ./k8s-pre-install-centos.sh
主机名设置
修改主机名
master执行:
hostnamectl set-hostname master01
节点1执行:
hostnamectl set-hostname node01
节点2执行:
hostnamectl set-hostname node02
修改hosts文件
每台机器上都要执行:
$ vim /etc/hosts
101.34.112.190 master01
81.68.126.69 node01
81.68.92.49 node02
PS:请更换为自己的公网IP(注意是公网IP,不是内网)!
所有节点安装Docker
k8s支持 3种容器运行时,这里我们优先使用熟悉的 Docker
作为容器运行时。请确保CentOS 7以上,最新要求以 官方 为主。
安装yum仓库
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo
安装docker
包括cli、engine、docker compose等
$ sudo yum install docker-ce-20.10.14-3.el7 docker-ce-cli-20.10.14-3.el7 containerd.io docker-compose-plugin
ps:本教程使用的是docker版本:20.10.14
配置Docker守护程序
尤其是使用 systemd
来管理容器的 cgroup,另外还要配置阿里云镜像源,加快拉取速度!
$ sudo mkdir /etc/docker
$ cat <<EOF | sudo tee /etc/docker/daemon.json
{"registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2"
}
EOF
- registry-mirrors:镜像加速。
- cgroupdriver:使用systemd。
- log-driver:使用json日志,大小为100m。
启动docker,并设置为开机启动
$ sudo systemctl enable docker
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
$ systemctl status docker # 确保是running状态
确认Cgroup Driver为systemd
$ docker info | grep "Cgroup Driver"Cgroup Driver: systemd
PS:因为k8s是默认systemd作为cgroup driver,如果Docker使用另外的驱动,则可能出现不稳定的情况。
所有节点安装kubeadm
为保证不过期,请最终以 官方文档 为主:
配置yum源(使用aliyun,google你知道的)
$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[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
EOF$ yum makecache # 更新yum
安装kubeadm, kubelet, kubectl
$ sudo yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 --disableexcludes=kubernetes
PS:k8s升级很快,为了保证教程正确,请使用相同版本。
启动klubelet,并设置为开机启动
$ sudo systemctl start kubelet
$ sudo systemctl enable kubelet
PS:kubeadm 将使用 kubelet 服务以容器方式部署和启动 Kubemetes 的主要服务。
所有节点拉取Docker镜像
ps:该1.23.6版本,需要
docker为20
,超过的不保证成功
拉取Docker镜像
查看初始化需要的镜像
$ kubeadm config images listk8s.gcr.io/kube-apiserver:v1.23.6
k8s.gcr.io/kube-controller-manager:v1.23.6
k8s.gcr.io/kube-scheduler:v1.23.6
k8s.gcr.io/kube-proxy:v1.23.6
k8s.gcr.io/pause:3.6
k8s.gcr.io/etcd:3.5.1-0
k8s.gcr.io/coredns/coredns:v1.8.6
替换k8s镜像源
k8s模式镜像仓库是 k8s.gcr.io
,由于众所周知的原因是无法访问的。
故这里需要创建配置 kubeadm-config-image.yaml 替换成阿里云的源:
$ vim kubeadm-config-image.yamlapiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
# 默认为k8s.gcr.io,但是网络不通,所以要替换为阿里云镜像
imageRepository: registry.aliyuncs.com/google_containers
确认镜像仓库改变
再查看,发现镜像的地址变了,才能执行下一步:
$ kubeadm config images list --config kubeadm-config-image.yamlregistry.aliyuncs.com/google_containers/kube-apiserver:v1.23.6
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.23.6
registry.aliyuncs.com/google_containers/kube-scheduler:v1.23.6
registry.aliyuncs.com/google_containers/kube-proxy:v1.23.6
registry.aliyuncs.com/google_containers/pause:3.6
registry.aliyuncs.com/google_containers/etcd:3.5.1-0
registry.aliyuncs.com/google_containers/coredns:v1.8.6
拉取镜像
$ kubeadm config images pull --config kubeadm-config-image.yaml
在 所有机器
上执行,把这些镜像提前拉好。
Master节点初始化集群
生成默认配置 kubeadm-config.yaml
并更改下面几项:
$ kubeadm config print init-defaults > kubeadm-config.yaml
kubernetes-version
:集群版本,上面安装的kubeadm版本必须小于等于这里的,可以查看这里:https://kubernetes.io/releases/。pod-network-cidr
:pod资源的网段,需与pod网络插件的值设置一致。通常,Flannel网络插件的默认为10.244.0.0/16,Calico插件的默认值为192.168.0.0/16;api-server
:使用Master作为api-server,所以就是master机器的IP地址。image-repository
:拉取镜像的镜像仓库,默认是k8s.gcr.io。nodeRegistration.name
:改成master01
最终如下:
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:- system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages:- signing- authentication
kind: InitConfiguration
localAPIEndpoint:advertiseAddress: 101.34.112.190 # 指定master节点的IP地址(公网)bindPort: 6443
nodeRegistration:criSocket: /var/run/dockershim.sockimagePullPolicy: IfNotPresentname: master01 # 改成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 # 默认为k8s.gcr.io,但是网络不通,所以要替换为阿里云镜像
kind: ClusterConfiguration
kubernetesVersion: 1.23.6 # 指定kubernetes版本号,使用kubeadm config print init-defaults生成的即可
networking:dnsDomain: cluster.localserviceSubnet: 10.96.0.0/12podSubnet: 10.244.0.0/16 # 指定pod网段,10.244.0.0/16用于匹配flannel默认网段
scheduler: {}
上面的配置等价于:
$ kubeadm init \
--kubernetes-version=v1.23.6 \
--image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=101.34.112.190 --ignore-preflight-errors=Swap
或者1核CPU Master初始化(--ignore-preflight-errors=NumCPU
这个如果是1核的ECS服务器一定要添加,不然会报错,因为K8S要求最低核数是2核)::
$ kubeadm init \
--kubernetes-version=v1.23.6 \
--apiserver-advertise-address=101.34.112.190
--ignore-preflight-errors=NumCPU \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers \
--v=6
PS:建议通过配置文件的方式来操作,命令行不直观。
检查环境
$ kubeadm init phase preflight --config=kubeadm-config.yaml
这个命令会检查配置文件是否正确,以及系统环境是否支持kubeadm的安装。
初始化kubeadm集群
只需要在master上执行如下命令:
$ kubeadm init --config=kubeadm-config.yaml
PS:这里是最难的,作者卡在这里卡了一整天,查阅各种资料才解决,所以如果你也失败了,比较正常,这里是相比于内网部署k8s,公网最麻烦也是最难的点,这一步成功了,后面也没啥了。最终参考:https://blog.51cto.com/u_15152259/2690063解决
到这里,会有2种结果:
如果是内网
,上面的docker版本,kubeadm版本没错的话,会成功,直接跳到4步骤。- 如果在
云服务器
(腾讯云,阿里云)上,一定会失败(原因和办法在这里)
:
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests”
// ...
[kubelet-check] Initial timeout of 40s passed.
提示:请一定先执行上面的初始化(目的是为了生成k8s的配置文件
,否则下面的步骤中你会找不到etcd.yaml),失败后再执行下面的步骤!!
云服务器初始化失败解决版本
1)编辑etcd配置文件
配置文件位置:/etc/kubernetes/manifests/etcd.yaml
- --listen-client-urls=https://127.0.0.1:2379,https://101.34.112.190:2379- --listen-peer-urls=https://101.34.112.190:2380
改成
- --listen-client-urls=https://127.0.0.1:2379- --listen-peer-urls=https://127.0.0.1:2380
引用 在腾讯云安装K8S集群 :
此处"118.195.137.68"为腾讯云公网ip,要关注的是"–listen-client-urls"和"–listen-peer-urls"。需要把–listen-client-urls后面的公网IP删除,把–listen-peer-urls改成127.0.0.1:2380
原因是因为腾讯云只要选择VPC网络均是采用NAT方式将公网IP映射到私人网卡的,有兴趣的同学可以了解下NAT。这也就是为什么很多同事无法在腾讯云或阿里云上安装k8s集群的原因
2)手工停止已启动的进程
# 先停止kubelet
$ systemctl stop kubelet
# 把所有kube的进程杀掉
$ netstat -anp |grep kube
请注意,不要执行 kubeadm reset,先 systemctl stop kubelet
,然后手动通过 netstat -anp |grep kube
来找pid,再通过 kill -9 pid
强杀。否则又会生成错误的etcd配置文件
,这里非常关键!!!
3)重新初始化,但是跳过etcd文件已经存在的检查:
# 重新启动kubelet
$ systemctl start kubelet
# 重新初始化,跳过配置文件生成环节,不要etcd的修改要被覆盖掉
$ kubeadm init --config=kubeadm-config.yaml --skip-phases=preflight,certs,kubeconfig,kubelet-start,control-plane,etcd
成功初始化
如果所有配置都正常,很快会输出下面的信息(秒级别
)代表了成功,否则大概率是失败(由于网络超时等):
Your Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou 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/Then you can join any number of worker nodes by running the following on each as root:kubeadm join 192.168.1.200:6443 --token abcdef.0123456789abcdef \--discovery-token-ca-cert-hash sha256:af2a6e096cb404da729ef3802e77482f0a8a579fa602d7c071ef5c5415aac748
保存上面输出的token和sha256值。
也就是下面这一段,这段命令主要是让node节点加入k8s集群:
kubeadm join 101.34.112.190:6443 --token abcdef.0123456789abcdef \--discovery-token-ca-cert-hash sha256:af2a6e096cb404da729ef3802e77482f0a8a579fa602d7c071ef5c5415aac748
常见错误
Initial timeout of 40s passed
- 可能1:检查镜像版本,可能是不匹配或者本地替换tag出错造成的了,或者是因为公网IP ETCD无法启动造成的。执行:
journalctl -xeu kubelet
查看具体错误,或者时候journalctl -f -u kubelet
查看初始化的实时输出,下次初始化之前执行kubeadm reset
重置。 - 可能2:CentOS版本太低,推荐
7.8
以上。我在7.2和7.5都失败了
,执行yum update -y
升级到7.9才成功。
证书忘记
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2> /dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
token忘记
kubeadm token list
配置kubectl(master)
准备配置文件
kubectl需经由API server认证及授权后方能执行相应的管理操作,kubeadm 部署的集群为其生成了一个具有管理员权限的认证配置文件 /etc/kubernetes/admin.conf,它可由 kubectl 通过默认的 “$HOME/.kube/config” 的路径进行加载。
拷贝配置文件到kubectl默认加载路径:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
使用kubectl查看集群信息
在Master节点上执行,输出集群信息:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 NotReady control-plane,master 15m v1.23.6$ kubectl get cs
etcd-0 Healthy {"health":"true","reason":""}
controller-manager Healthy ok
scheduler Healthy ok
这里STATUS是NotReady是因为还没有配置网络的原因,接下来会介绍。
安装CN网络(master)
$ curl https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml>>kube-flannel.yml
$ chmod 777 kube-flannel.yml
$ kubectl apply -f kube-flannel.yml
等待几分钟,再查看Master节点状态,由NotRead变成了Ready状态:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane,master 15m v1.23.6
允许master节点部署pod
此时k8s master节点安装完毕(为了不浪费云服务器资源
,需要让master节点能部署pod,需要运行以下命令)。
- 查看调度策略
$ kubectl describe node|grep -E "Name:|Taints:"Name: master01
Taints: node-role.kubernetes.io/master:NoSchedule
- NoSchedule: 一定不能被调度
- PreferNoSchedule: 尽量不要调度
- NoExecute: 不仅不会调度, 还会驱逐Node上已有的Pod
- 更改master节点可被部署pod
$ kubectl taint nodes --all node-role.kubernetes.io/master-
- 查看是否生效
$ kubectl describe node|grep -E "Name:|Taints:"
Name: master01
Taints: <none>
把Node节点加入集群
在node上执行上面kubeadm输出的命令(注意token和sha256值不同):
$ kubeadm join 192.168.1.200:6443 --token abcdef.0123456789abcdef \--discovery-token-ca-cert-hash sha256:af2a6e096cb404da729ef3802e77482f0a8a579fa602d7c071ef5c5415aac748[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
此时,在master执行以下命令,可以看到node节点已经加入成功了:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane,master 60m v1.23.6
node01 NotReady <none> 54s v1.23.6
等待5分钟左右,node01的状态变成Ready。
另外一台Node节点机器,重复改步骤加入集群即可!
测试集群
创建个nginx Pod
在master节点运行以下命令:
$ kubectl run --image=nginx nginx-app --port=80
$ kubectl run --image=nginx nginx-app1 --port=81
然后再运行:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-app 0/1 ContainerCreating 0 18s$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-app 1/1 Running 0 26s$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-app 1/1 Running 0 57s 10.244.1.2 node01 <none> <none>
可以看到2个pod已经是运行状态,证明k8s集群成功安装
Dashboard可视化界面安装
请移步下一篇文章:k8s dashboard安装
参考
- k8s——部署基于公网的k8s集群
- k8s ip地址变了 报错Error getting node
- k8s在下载docker镜像时无法连接外网
- Kubernetes v1.17 参考指南
- kubeadm部署安装+dashboard+harbor
- k8s-学习笔记总结(从入门到放弃的学习路线)
- Kubernetes零基础快速入门!初学者必看!
- 基于腾讯云搭建简易k8s集群
- 腾讯轻量云服务器搭建k8s环境
- 在腾讯云安装K8S集群
- 【k8s】允许 master 节点运行 pod
2022版使用云服务器搭建公网k8s容器集群相关推荐
- 华为三台服务器虚拟化做集群怎样做,使用三台云服务器搭建真正的Redis集群
三台云服务器搭建redis集群# 今天花了一天的时间弄集群redis:遇到了很多坑,从头开始吧 环境讲解: 两台配置:1核2G,另一台:1核1G: 操作系统:Centos 7.6 Redis:3.2. ...
- 【记录】饥荒联机版+个人云服务器搭建(2020.6.19)
[记录]饥荒联机版+个人云服务器搭建(至2020.6.19有效) 写在前面 所需材料 开始做菜! 1.进入属于自己服务器 2.安装依赖 3.安装SteamCMD及Steam客户端 4.安装饥荒联机版服 ...
- 云服务器大数据高可用集群搭建-----hadoop篇
目录 一.集群配置 二.集群规划 三.Hadoop.Zookeeper.Java.Centos版本 四.Linux配置 4.1 主机名配置 4.1.1 修改Linux主机名 4.1.2 修改linux ...
- steam 平台 饥荒 联机版 Linux云服务器 搭建教程
A:服务器的选购和设置(云服:有效降低游戏 网络延迟,小幅减少主机硬件性能占用) 1: 饥荒是单核游戏,世界/核,地面+洞穴也就是"2 核"就够了,主频越高越好. 2: 内存多点好 ...
- DevOpsSOP 基于阿里云VPC搭建Storm+Kafka+Zookeeper集群
集群搭建之 zookeeper + kafka 环境要求 pre-install Centos下安装Java开发环境 JDK1.8 Cenos下安装Supervisor守护 zookeeper clu ...
- Centos7 单台服务器搭建Elasticsearch6.0.1集群
文章目录 一.环境规划 二.环境搭建 1.创建用户及目录 2.修改配置文件 三.启动和停止服务脚本 四.使用elasticsearch-head 插件查看集群状态 1.安装nodejs 2.拉取ela ...
- 蚂蚁集团俞仁杰:金融级云原生之多活容器集群高可用建设实践
本文整理自蚂蚁集团金融云产品技术部SOFAStack产品专家俞仁杰在2020 GIDC全球互联网数据大会的分享.详细讲解了云原生架构下的多活高可用平台和产品建设相关经验和观点. 过去几年是云原生理念高 ...
- kubernetes(k8s)容器集群管理系统
kubernetes 文章目录 kubernetes 什么是k8s? 为什么需要K8S? 多机编排管理容器 k8s的特性 Kubernetes集群架构与组件 核心组件 Master组件 Kube-ap ...
- CentOS7.2中使用Kubernetes(k8s)1.4.6源码搭建k8s容器集群环境
一.相关准备工作 1.1.准备工作 准备至少两台已安装好CentOS7.2操作系统的物理机或者虚拟机(本文配置时使用的是三台KVM虚拟机): 设置hostname命令: hostnamectl set ...
最新文章
- selenium常用命令之操作页面元素及获取元素内容的事件整理
- 打孔怎么定位_红米K40将要发布,采用居中打孔屏,极窄边框设计
- 日志库 winston 的学习笔记 - logger.info 的实现原理单步调试
- Yet Another Meme Problem(打表找规律)
- 看完这篇文章保你面试稳操胜券——小程序篇
- 指标实现层级_企业如何构建核心指标系统,实现业务运营效率提升90%?
- Mysql(一)——基础知识
- “WPF” VS “Silverlight”
- 快速排序算法的优化思路总结
- 搭建OA系统运维需要了解的知识?
- 重要发布全总结丨一文看懂阿里云弹性计算年度峰会
- mps是什么意思 计算机网络,网络连接的半双工和全双工是啥意思 100MPS和10MPS又有啥区别...
- electron安装报错: Electron failed to install correctly…的解决方案
- 如何在iphone上模拟定位
- 微信小程序 接入第三方地图
- 一个老鼠走迷宫问题的python解法
- 模型学习01——评价类模型(1)
- 快速找到你的另一半——相亲小程序
- 小型企业网络设计与规划
- 鼠标键盘失灵对策(Windows8.1)