本萌新在搭建KubeEdge时踩了很多坑,走了很多弯路,浪费了很多时间,大多数问题都是墙的原因。此贴尽可能采用了手动部署yaml文件的方式,最终部署成功,故记录过程用于反思与回顾,请大神多多批评指正。
主机名 | IP地址 | 最低配置 | 操作系统 | 内核版本 |
---|---|---|---|---|
ke-cloud | 192.168.129.135 | 4C 4G | CentOS 7.6 | 3.10.0-957.el7.x86_64 |
ke-edge1 | 192.168.129.136 | 2C 2G | CentOS 7.6 | 3.10.0-957.el7.x86_64 |
$ systemctl stop firewalld
$ systemctl disable firewalld
# 临时关闭
$ setenforce 0
# 永久关闭
$ sed -i 's/enforcing/disabled/' /etc/selinux/config
$ swapoff -a
$ sed -i 's/.*swap.*/#&/' /etc/fstab
#添加hosts
$ cat >> /etc/hosts << EOF
192.168.129.140 cloud
192.168.129.141 edge1
140.82.114.3 github.com
EOF
#1、安装docker依赖软件包
$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2
#2、添加Yum源,国内源速度快很多
#国内源安装快很多
$ sudo yum-config-manager \
--add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
#3、安装docker-ce
$ yum install docker-ce docker-ce-cli containerd.io -y
$ systemctl start docker && systemctl enable docker
systemctl start cloudcore.service && systemctl enable cloudcore.service
$ docker info |grep Cgrou
#4、验证安装是否成功
$ docker version
Client: Docker Engine - Community
Version: 20.10.6
API version: 1.41
Go version: go1.13.15
Git commit: 370c289
Built: Fri Apr 9 22:45:33 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.6
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: 8728dd2
Built: Fri Apr 9 22:43:57 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.6
GitCommit: d71fcd7d8303cbf684402823e425e9dd2e99285d
runc:
Version: 1.0.0-rc95
GitCommit: b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7
docker-init:
Version: 0.19.0
GitCommit: de40ad0
# 快照《安装docker》
#1、配置内核参数,将桥接的IPv4流量传递到iptables的链
$ cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system
#2、配置国内kuberneetes的yum源,由于网络原因,中国无法直接连接到google的网络,需要配置阿里云的yum源
$ cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
#3、安装kubectl、kubeadm、kubelet
$ yum install -y kubelet-1.17.1 kubeadm-1.17.1 kubectl-1.17.1
//输出信息
Installed:
kubeadm.x86_64 0:1.17.1-0 kubectl.x86_64 0:1.17.1-0 kubelet.x86_64 0:1.17.1-0
Dependency Installed:
conntrack-tools.x86_64 0:1.4.4-7.el7 cri-tools.x86_64 0:1.19.0-0 kubernetes-cni.x86_64 0:0.8.7-0
libnetfilter_cthelper.x86_64 0:1.0.0-11.el7 libnetfilter_cttimeout.x86_64 0:1.0.0-7.el7 libnetfilter_queue.x86_64 0:1.0.2-2.el7_2
socat.x86_64 0:1.7.3.2-2.el7
$ systemctl enable kubelet
$ reboot
#4、初始化集群,在cloudmaster上执行kubeadm init
$ kubeadm init --kubernetes-version=1.17.1 \
--apiserver-advertise-address=192.168.129.140 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
//以下是执行完毕后输出的部分信息
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/.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/
Then you can join any number of worker nodes by running the following on eac
h as root:
kubeadm join 192.168.129.140:6443 --token a8h86d.zt3nv5yvn0jl2vha \
--discovery-token-ca-cert-hash sha256:345e373e14a82caad48fb1061682b045915b2097d662336db53b6a02d1f80662
#5、配置kubectl工具
$ mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
#6、查看主节点状态
$ kubectl get node
$NAME STATUS ROLES AGE VERSION
cloudmaster NotReady master 27h v1.17.1
$ kubectl get pods -n kube-system
#7、部署flannel网络
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#若该文件拉取不到,使用如下部署文件
$ yum install vim -y
$ vim kube-flannel.yaml
kube-flannel.yaml
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: psp.flannel.unprivileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
privileged: false
volumes:
- configMap
- secret
- emptyDir
- hostPath
allowedHostPaths:
- pathPrefix: "/etc/cni/net.d"
- pathPrefix: "/etc/kube-flannel"
- pathPrefix: "/run/flannel"
readOnlyRootFilesystem: false
# Users and groups
runAsUser:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
fsGroup:
rule: RunAsAny
# Privilege Escalation
allowPrivilegeEscalation: false
defaultAllowPrivilegeEscalation: false
# Capabilities
allowedCapabilities: ['NET_ADMIN']
defaultAddCapabilities: []
requiredDropCapabilities: []
# Host namespaces
hostPID: false
hostIPC: false
hostNetwork: true
hostPorts:
- min: 0
max: 65535
# SELinux
seLinux:
# SELinux is unused in CaaSP
rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['psp.flannel.unprivileged']
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-system
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-amd64
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: registry.cn-hangzhou.aliyuncs.com/kubernetes_ns/flannel:v0.11.0-amd64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: registry.cn-hangzhou.aliyuncs.com/kubernetes_ns/flannel:v0.11.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-arm64
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- arm64
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.11.0-arm64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.11.0-arm64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-arm
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- arm
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.11.0-arm
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.11.0-arm
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-ppc64le
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- ppc64le
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.11.0-ppc64le
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.11.0-ppc64le
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds-s390x
namespace: kube-system
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/os
operator: In
values:
- linux
- key: beta.kubernetes.io/arch
operator: In
values:
- s390x
hostNetwork: true
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.11.0-s390x
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.11.0-s390x
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
部署完成后等待cloudmaster
处于ready状态既可
$ kubectl apply -f kube-flannel.yaml
$ kubectl get po -A
//输出
[root@ke-cloud ~]# kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-9d85f5447-7xhlw 1/1 Running 0 8m36s
kube-system coredns-9d85f5447-vktkx 1/1 Running 0 8m36s
kube-system etcd-ke-cloud 1/1 Running 0 8m54s
kube-system kube-apiserver-ke-cloud 1/1 Running 0 8m54s
kube-system kube-controller-manager-ke-cloud 1/1 Running 0 8m54s
kube-system kube-flannel-ds-amd64-48qg6 1/1 Running 0 33s
kube-system kube-proxy-2tdch 1/1 Running 0 8m36s
kube-system kube-scheduler-ke-cloud 1/1 Running 0 8m54s
安装有两种方式,一种源码编译手动安装,还有一种是使用ke提供的工具-keadm。手动安装比较繁琐,对于新手而言是一种很大的心智负担,最好大家还是都用keadm这个工具去安装,但是,这种方式安装最大的问题就是国内的墙的问题会导致很多某些资源无法下载,比如说 CRD的yaml,cloudcore启动的service,所以我会结合两者,采用半手动半工具的安装方式去完成ke的集群搭建。
#1、下载keadm
$ mkdir kubeedge
$ cd kubeedge/
$ yum install wget -y
# 快照《安装k8s》
$ wget https://github.com/kubeedge/kubeedge/releases/download/v1.5.0/keadm-v1.5.0-linux-amd64.tar.gz #失败的话建议手动安装
#解压
$ tar -zxvf keadm-v1.5.0-linux-amd64.tar.gz
$ cd keadm-v1.5.0-linux-amd64/keadm && chmod +x keadm && mv keadm /usr/local/bin
#验证keadm是否安装成功
$ keadm version
version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.0", GitCommit:"8b0913e04ef4ef826af6715d336e23a66e3774df", GitTreeState:"clean", BuildDate:"2020-11-13T08:04:56Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
#快照《安装keadm》
#2、使用keadm安装cloudcore
$ keadm init --advertise-address=192.168.129.140 --kubeedge-version=1.5.0
Kubernetes version verification passed, KubeEdge installation will start...
--2021-06-1 13:20:41-- https://raw.githubusercontent.com/kubeedge/kubeedge/master/build/crds/devices/devices_v1alpha2_device.yaml
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.76.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.76.133|:443... connected.
Unable to establish SSL connection.
Converted links in 0 files in 0 seconds.
Error: failed to run 'sh -c cd /etc/kubeedge/crds/devices && wget -k --no-check-certificate --progress=bar:force https://raw.githubusercontent.com/kubeedge/kubeedge/master/build/crds/devices/devices_v1alpha2_device.yaml' because of error : exit status 4
Usage:
keadm init [flags]
Examples:
keadm init
- This command will download and install the default version of KubeEdge cloud component
keadm init --kubeedge-version=1.5.0 --kube-config=/root/.kube/config
- kube-config is the absolute path of kubeconfig which used to secure connectivity between cloudcore and kube-apiserver
Flags:
--advertise-address string Use this key to set IPs in cloudcore's certificate SubAltNames field. eg: 10.10.102.78,10.10.102.79
--domainname string Use this key to set domain names in cloudcore's certificate SubAltNames field. eg: www.cloudcore.cn,www.kubeedge.cn
-h, --help help for init
--kube-config string Use this key to set kube-config path, eg: $HOME/.kube/config (default "/root/.kube/config")
--kubeedge-version string Use this key to download and use the required KubeEdge version
--master string Use this key to set K8s master address, eg: http://127.0.0.1:8080
--tarballpath string Use this key to set the temp directory path for KubeEdge tarball, if not exist, download it
F0211 13:20:41.433946 15198 keadm.go:27] failed to run 'sh -c cd /etc/kubeedge/crds/devices && wget -k --no-check-certificate --progress=bar:force https://raw.githubusercontent.com/kubeedge/kubeedge/master/build/crds/devices/devices_v1alpha2_device.yaml' because of error : exit status 4
goroutine 1 [running]:
k8s.io/klog.stacks(0xc0000d3e00, 0xc000026480, 0x122, 0x176)
/root/codes/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/klog.go:883 +0xb9
k8s.io/klog.(*loggingT).output(0x2cb3c80, 0xc000000003, 0xc0000b4b60, 0x29d13f1, 0x8, 0x1b, 0x0)
/root/codes/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/klog.go:834 +0x35f
k8s.io/klog.(*loggingT).printDepth(0x2cb3c80, 0xc000000003, 0x1, 0xc000843f68, 0x1, 0x1)
/root/codes/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/klog.go:706 +0x12d
k8s.io/klog.(*loggingT).print(...)
/root/codes/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/klog.go:697
k8s.io/klog.Fatal(...)
/root/codes/src/github.com/kubeedge/kubeedge/vendor/k8s.io/klog/klog.go:1264
main.main()
/root/codes/src/github.com/kubeedge/kubeedge/keadm/cmd/keadm/keadm.go:27 +0x8a
–advertise-address=xxx.xx.xx.xx 这里的xxx.xx.xx.xx换成master机器的ip,可以是内网地址,也可以是公网ip地址,–kubeedge-version=1.5.0 意思是指定安装的ke的版本,如果你默认不指定那么keadm会自动去下载最新的版本。很遗憾,我在执行
keadm init --advertise-address=xxx.xx.xx.xx --kubeedge-version=1.5.0
命令的时候出错了,这个错的问题在于网络被墙了,特别是在公有云的虚拟机上,出现这种问题的概率特别大,这种问题咋解决,一种是翻出去,另外一种是在/etc/hosts下添加如下内容
# GitHub Start
52.74.223.119 github.com
192.30.253.119 gist.github.com
54.169.195.247 api.github.com
185.199.111.153 assets-cdn.github.com
151.101.76.133 raw.githubusercontent.com
151.101.108.133 user-images.githubusercontent.com
151.101.76.133 gist.githubusercontent.com
151.101.76.133 cloud.githubusercontent.com
151.101.76.133 camo.githubusercontent.com
151.101.76.133 avatars0.githubusercontent.com
151.101.76.133 avatars1.githubusercontent.com
151.101.76.133 avatars2.githubusercontent.com
151.101.76.133 avatars3.githubusercontent.com
151.101.76.133 avatars4.githubusercontent.com
151.101.76.133 avatars5.githubusercontent.com
151.101.76.133 avatars6.githubusercontent.com
151.101.76.133 avatars7.githubusercontent.com
151.101.76.133 avatars8.githubusercontent.com
# GitHub End
如果试了上述方法还是不行,只能手动把相对应的文件下载到本地,下载地址 https://github.com/kubeedge/kubeedge/tree/master/build/crds
$ mkdir -p /etc/kubeedge/crds/devices && mkdir -p /etc/kubeedge/crds/reliablesyncs
$ tree /etc/kubeedge/ #以下是需要准备的文件
kubeedge/
├── cloudcore.service
├── crds
│ ├── devices
│ │ ├── devices_v1alpha2_devicemodel.yaml
│ │ └── devices_v1alpha2_device.yaml
│ └── reliablesyncs
│ ├── cluster_objectsync_v1alpha1.yaml
│ └── objectsync_v1alpha1.yaml
└── kubeedge-v1.5.0-linux-amd64.tar.gz
# devices_v1alpha2_devicemodel.yaml
$ cd /etc/kubeedge/crds/devices/
$ vim devices_v1alpha2_devicemodel.yaml
# devices_v1alpha2_device.yaml
$ cd /etc/kubeedge/crds/devices/
$ vim devices_v1alpha2_device.yaml
# cluster_objectsync_v1alpha1.yaml
$ cd /etc/kubeedge/crds/reliablesyncs/
$ vim cluster_objectsync_v1alpha1.yaml
# objectsync_v1alpha1.yaml
$ cd /etc/kubeedge/crds/reliablesyncs/
$ vim objectsync_v1alpha1.yaml
# cloudcore.service
$ cd /etc/kubeedge/
$ ls
$ vim cloudcore.service
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: devicemodels.devices.kubeedge.io
spec:
group: devices.kubeedge.io
names:
kind: DeviceModel
plural: devicemodels
scope: Namespaced
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
properties:
description: 'Required: List of device properties.'
items:
properties:
description:
description: The device property description.
type: string
name:
description: 'Required: The device property name.'
type: string
type:
description: 'Required: PropertyType represents the type and data
validation of the property.'
properties:
int:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
type: string
enum:
- ReadOnly
- ReadWrite
defaultValue:
format: int64
type: integer
maximum:
format: int64
type: integer
minimum:
format: int64
type: integer
unit:
description: The unit of the property
type: string
required:
- accessMode
type: object
string:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
type: string
enum:
- ReadOnly
- ReadWrite
defaultValue:
type: string
required:
- accessMode
type: object
double:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
type: string
enum:
- ReadOnly
- ReadWrite
defaultValue:
format: double
type: number
maximum:
format: double
type: number
minimum:
format: double
type: number
unit:
description: The unit of the property
type: string
required:
- accessMode
type: object
float:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
type: string
enum:
- ReadOnly
- ReadWrite
defaultValue:
format: float
type: number
maximum:
format: float
type: number
minimum:
format: float
type: number
unit:
description: The unit of the property
type: string
required:
- accessMode
type: object
boolean:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
type: string
enum:
- ReadOnly
- ReadWrite
defaultValue:
type: boolean
required:
- accessMode
type: object
bytes:
properties:
accessMode:
description: 'Required: Access mode of property, ReadWrite
or ReadOnly.'
type: string
enum:
- ReadOnly
- ReadWrite
required:
- accessMode
type: object
type: object
required:
- name
- type
type: object
type: array
type: object
version: v1alpha2
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: devices.devices.kubeedge.io
spec:
group: devices.kubeedge.io
names:
kind: Device
plural: devices
scope: Namespaced
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
deviceModelRef:
description: 'Required: DeviceModelRef is reference to the device model
used as a template to create the device instance.'
type: object
nodeSelector:
description: NodeSelector indicates the binding preferences between
devices and nodes. Refer to k8s.io/kubernetes/pkg/apis/core NodeSelector
for more details
type: object
protocol:
description: 'Required: The protocol configuration used to connect to
the device.'
properties:
bluetooth:
description: Protocol configuration for bluetooth
properties:
macAddress:
description: Unique identifier assigned to the device.
type: string
type: object
modbus:
description: Protocol configuration for modbus
properties:
slaveID:
description: Required. 0-255
format: int64
type: integer
minimum: 0
maximum: 255
required:
- slaveID
type: object
opcua:
description: Protocol configuration for opc-ua
properties:
certificate:
description: Certificate for access opc server.
type: string
password:
description: Password for access opc server.
type: string
privateKey:
description: PrivateKey for access opc server.
type: string
securityMode:
description: Defaults to "none".
type: string
securityPolicy:
description: Defaults to "none".
type: string
timeout:
description: Timeout seconds for the opc server connection.???
format: int64
type: integer
url:
description: 'Required: The URL for opc server endpoint.'
type: string
userName:
description: Username for access opc server.
type: string
required:
- url
type: object
common:
description: Common part of protocol configuration
properties:
com:
properties:
baudRate:
description: Required. BaudRate 115200|57600|38400|19200|9600|4800|2400|1800|1200|600|300|200|150|134|110|75|50
format: int64
type: integer
enum:
- 115200
- 57600
- 38400
- 19200
- 9600
- 4800
- 2400
- 1800
- 1200
- 600
- 300
- 200
- 150
- 134
- 110
- 75
- 50
dataBits:
description: Required. Valid values are 8, 7, 6, 5.
format: int64
type: integer
enum:
- 8
- 7
- 6
- 5
parity:
description: Required. Valid options are "none", "even",
"odd". Defaults to "none".
type: string
enum:
- none
- even
- odd
serialPort:
description: Required.
type: string
stopBits:
description: Required. Bit that stops 1|2
format: int64
type: integer
enum:
- 1
- 2
required:
- baudRate
- dataBits
- parity
- serialPort
- stopBits
type: object
tcp:
properties:
ip:
description: Required.
type: string
port:
description: Required.
format: int64
type: integer
required:
- ip
- port
type: object
commType:
description: Communication type, like tcp client, tcp server or COM
type: string
reconnTimeout:
description: Reconnection timeout
type: integer
reconnRetryTimes:
description: Reconnecting retry times
type: integer
collectTimeout:
description: 'Define timeout of mapper collect from device.'
format: int64
type: integer
collectRetryTimes:
description: 'Define retry times of mapper will collect from device.'
format: int64
type: integer
collectType:
description: 'Define collect type, sync or async.'
type: string
enum:
- sync
- async
customizedValues:
description: Customized values for provided protocol
type: object
type: object
customizedProtocol:
description: Protocol configuration for customized Protocol
properties:
protocolName:
description: The name of protocol
type: string
configData:
description: customized config data
type: object
required:
- protocolName
type: object
type: object
propertyVisitors:
description: 'Required: List of property visitors which describe how
to access the device properties. PropertyVisitors must unique by propertyVisitor.propertyName.'
items:
properties:
bluetooth:
description: Bluetooth represents a set of additional visitor
config fields of bluetooth protocol.
properties:
characteristicUUID:
description: 'Required: Unique ID of the corresponding operation'
type: string
dataConverter:
description: Responsible for converting the data being read
from the bluetooth device into a form that is understandable
by the platform
properties:
endIndex:
description: 'Required: Specifies the end index of incoming
byte stream to be considered to convert the data the
value specified should be inclusive for example if 3
is specified it includes the third index'
format: int64
type: integer
orderOfOperations:
description: Specifies in what order the operations(which
are required to be performed to convert incoming data
into understandable form) are performed
items:
properties:
operationType:
description: 'Required: Specifies the operation
to be performed to convert incoming data'
type: string
enum:
- Add
- Subtract
- Multiply
- Divide
operationValue:
description: 'Required: Specifies with what value
the operation is to be performed'
format: double
type: number
type: object
type: array
shiftLeft:
description: Refers to the number of bits to shift left,
if left-shift operation is necessary for conversion
format: int64
type: integer
shiftRight:
description: Refers to the number of bits to shift right,
if right-shift operation is necessary for conversion
format: int64
type: integer
startIndex:
description: 'Required: Specifies the start index of the
incoming byte stream to be considered to convert the
data. For example: start-index:2, end-index:3 concatenates
the value present at second and third index of the incoming
byte stream. If we want to reverse the order we can
give it as start-index:3, end-index:2'
format: int64
type: integer
required:
- endIndex
- startIndex
type: object
dataWrite:
description: 'Responsible for converting the data coming from
the platform into a form that is understood by the bluetooth
device For example: "ON":[1], "OFF":[0]'
type: object
required:
- characteristicUUID
type: object
modbus:
description: Modbus represents a set of additional visitor config
fields of modbus protocol.
properties:
isRegisterSwap:
description: Indicates whether the high and low register swapped.
Defaults to false.
type: boolean
isSwap:
description: Indicates whether the high and low byte swapped.
Defaults to false.
type: boolean
limit:
description: 'Required: Limit number of registers to read/write.'
format: int64
type: integer
offset:
description: 'Required: Offset indicates the starting register
number to read/write data.'
format: int64
type: integer
register:
description: 'Required: Type of register'
type: string
enum:
- CoilRegister
- DiscreteInputRegister
- InputRegister
- HoldingRegister
scale:
description: The scale to convert raw property data into final
units. Defaults to 1.0
format: double
type: number
required:
- limit
- offset
- register
type: object
opcua:
description: Opcua represents a set of additional visitor config
fields of opc-ua protocol.
properties:
browseName:
description: The name of opc-ua node
type: string
nodeID:
description: 'Required: The ID of opc-ua node, e.g. "ns=1,i=1005"'
type: string
required:
- nodeID
type: object
customizedProtocol:
description: customized protocol
properties:
protocolName:
description: The name of protocol
type: string
configData:
description: customized config data
type: object
required:
- protocolName
- configData
type: object
propertyName:
description: 'Required: The device property name to be accessed.
This should refer to one of the device properties defined in
the device model.'
type: string
reportCycle:
description: 'Define how frequent mapper will report the value.'
format: int64
type: integer
collectCycle:
description: 'Define how frequent mapper will collect from device.'
format: int64
type: integer
customizedValues:
description: Customized values for visitor of provided protocols
type: object
required:
- propertyName
type: object
type: array
data:
properties:
dataTopic:
description: 'Topic used by mapper, all data collected from dataProperties
should be published to this topic,
the default value is $ke/events/device/+/data/update'
type: string
dataProperties:
description: A list of data properties, which are not required to be processed by edgecore
items:
properties:
propertyName:
description: 'Required: The property name for which the desired/reported
values are specified. This property should be present in the
device model.'
type: string
metadata:
description: Additional metadata like filter policy, should be k-v format
type: object
required:
- propertyName
type: object
type: array
type: object
required:
- deviceModelRef
- nodeSelector
type: object
status:
properties:
twins:
description: A list of device twins containing desired/reported desired/reported
values of twin properties. A passive device won't have twin properties
and this list could be empty.
items:
properties:
desired:
description: 'Required: the desired property value.'
properties:
metadata:
description: Additional metadata like timestamp when the value
was reported etc.
type: object
value:
description: 'Required: The value for this property.'
type: string
required:
- value
type: object
propertyName:
description: 'Required: The property name for which the desired/reported
values are specified. This property should be present in the
device model.'
type: string
reported:
description: 'Required: the reported property value.'
properties:
metadata:
description: Additional metadata like timestamp when the value
was reported etc.
type: object
value:
description: 'Required: The value for this property.'
type: string
required:
- value
type: object
required:
- propertyName
type: object
type: array
type: object
version: v1alpha2
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: clusterobjectsyncs.reliablesyncs.kubeedge.io
spec:
group: reliablesyncs.kubeedge.io
names:
kind: ClusterObjectSync
plural: clusterobjectsyncs
scope: Cluster
subresources:
status: {}
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
objectType:
description: NodeSelector indicates the binding preferences between
devices and nodes. Refer to k8s.io/kubernetes/pkg/apis/core NodeSelector
for more details
type: string
objectName:
description: 'Required: The protocol configuration used to connect to
the device.'
type: string
status:
properties:
objectResourceVersion:
description: 'Required: DeviceModelRef is reference to the device model
used as a template to create the device instance.'
type: string
version: v1alpha1
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
labels:
controller-tools.k8s.io: "1.0"
name: objectsyncs.reliablesyncs.kubeedge.io
spec:
group: reliablesyncs.kubeedge.io
names:
kind: ObjectSync
plural: objectsyncs
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
objectType:
description: NodeSelector indicates the binding preferences between
devices and nodes. Refer to k8s.io/kubernetes/pkg/apis/core NodeSelector
for more details
type: string
objectName:
description: 'Required: The protocol configuration used to connect to
the device.'
type: string
status:
properties:
objectResourceVersion:
description: 'Required: DeviceModelRef is reference to the device model
used as a template to create the device instance.'
type: string
version: v1alpha1
[Unit]
Description=cloudcore.service
[Service]
Type=simple
ExecStart=/etc/kubeedge/kubeedge-v1.5.0-linux-amd64/cloud/cloudcore/cloudcore --logtostderr=false --log-file=/var/log/kubeedge/cloudcore.log -v=3
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
6)、kubeedge-v1.5.0-linux-amd64.tar.gz (如果下面命令无法下载,自行手动在github下载)
$ wget https://github.com/kubeedge/kubeedge/releases/download/v1.5.0/kubeedge-v1.5.0-linux-amd64.tar.gz
$ cd /etc/kubeedge/
$ keadm init --advertise-address=192.168.129.140 --kubeedge-version=1.5.0
//输出
Kubernetes version verification passed, KubeEdge installation will start...
Expected or Default KubeEdge version 1.7.0 is already downloaded and will checksum for it.
kubeedge-v1.7.0-linux-amd64.tar.gz checksum:
checksum_kubeedge-v1.7.0-linux-amd64.tar.gz.txt content:
kubeedge-v1.7.0-linux-amd64.tar.gz in your path checksum failed and do you want to delete this file and try to download again?
[y/N]:
# 此处输入N,checksum失败不影响配置,不必担心。选择y通过不了。
Kubernetes version verification passed, KubeEdge installation will start...
Expected or Default KubeEdge version 1.5.0 is already downloaded and will checksum for it.
kubeedge-v1.5.0-linux-amd64.tar.gz checksum:
checksum_kubeedge-v1.5.0-linux-amd64.tar.gz.txt content:
[Run as service] service file already exisits in /etc/kubeedge//cloudcore.service, skip download
kubeedge-v1.5.0-linux-amd64/
kubeedge-v1.5.0-linux-amd64/edge/
kubeedge-v1.5.0-linux-amd64/edge/edgecore
kubeedge-v1.5.0-linux-amd64/cloud/
kubeedge-v1.5.0-linux-amd64/cloud/csidriver/
kubeedge-v1.5.0-linux-amd64/cloud/csidriver/csidriver
kubeedge-v1.5.0-linux-amd64/cloud/admission/
kubeedge-v1.5.0-linux-amd64/cloud/admission/admission
kubeedge-v1.5.0-linux-amd64/cloud/cloudcore/
kubeedge-v1.5.0-linux-amd64/cloud/cloudcore/cloudcore
kubeedge-v1.5.0-linux-amd64/version
KubeEdge cloudcore is running, For logs visit: /var/log/kubeedge/cloudcore.log
CloudCore started
如果你想把cloudcore交给systemed托管的话切记把cloudcore.service移到**/etc/systemed/system下面然后再执行下systemctl daemon-reload**
3.4、查看cloudedge加入集群的token
[root@ke-cloud ~]# keadm gettoken
#安装keadm命令
#方法一
$ mkdir -p /etc/kubeedge && wget https://github.com/kubeedge/kubeedge/releases/download/v1.5.0/keadm-v1.5.0-linux-amd64.tar.gz
#方法二
[root@ke-cloud ~]# ll /usr/local/bin/ | grep keadm
-rwxr-xr-x 1 root root 40522216 Nov 13 2020 keadm
[root@ke-cloud ~]# ll /usr/local/bin/
total 73056
-rwxr-xr-x 1 root root 34283520 Jan 14 12:02 cloudcore
-rwxr-xr-x 1 root root 40522216 Nov 13 2020 keadm
[root@ke-edge1 ~]# mkdir -p /etc/kubeedge
[root@ke-edge1 ~]# ll /usr/local/bin/ | grep keadm
[root@ke-edge1 ~]# scp [email protected]:/usr/local/bin/keadm /usr/local/bin/
The authenticity of host '192.168.129.135 (192.168.129.135)' can't be established.
ECDSA key fingerprint is SHA256:gKdt3xeAAwUwa25CIP2Tu1RRIymeC4ixcn4OvPKUca8.
ECDSA key fingerprint is MD5:fe:38:24:61:13:70:48:b5:02:d5:51:9e:d4:40:61:99.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.129.135' (ECDSA) to the list of known hosts.
[email protected]'s password:
keadm 100% 39MB 31.9MB/s 00:01
[root@ke-edge1 ~]# keadm version
version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.0", GitCommit:"8b0913e04ef4ef826af6715d336e23a66e3774df", GitTreeState:"clean", BuildDate:"2020-
11-13T08:04:56Z", GoVersion:"go1.15", Compiler:"gc", Platform:"linux/amd64"}
# 配置文件
[root@ke-edge1 kubeedge]# cd /etc/kubeedge/
[root@ke-edge1 kubeedge]# vi edgecore.service
[root@ke-edge1 kubeedge]# scp [email protected]:/etc/kubeedge/kubeedge-v1.5.0-linux-amd64.tar.gz .
[email protected]'s password:
kubeedge-v1.5.0-linux-amd64.tar.gz 100% 46MB 57.6MB/s 00:00
#加入集群
$ cd /etc/kubeedge/
$ keadm join --cloudcore-ipport=192.168.129.140:10000 --kubeedge-version=1.5.0 --token=
-cloudcore-ipport表示的是cloudcore的对外暴露的ip就是公网ip了,如果你是在公有云服务器上的记得打开安全组的端口
--kubeedge-version就是ke的版本
--token= 这个token是上一步集群的token
[y/N]:
# 此处输入N,checksum失败不影响配置,不必担心。选择y通过不了。
提示:如果github下载不下来就将master上的文件拷贝过来
edgecore.service
[Unit]
Description=cloudcore.service
[Service]
Type=simple
ExecStart=/etc/kubeedge/kubeedge-v1.5.0-linux-amd64/edge/edgecore --logtostderr=false --log-file=/var/log/kubeedge/edgecore.log -v=3
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
[root@master kubeedge]# kubectl get node
NAME STATUS ROLES AGE VERSION
cloudmaster Ready cloudmaster 27h v1.17.1
cloudedge Ready agent,edge 4h24m v1.19.3-kubeedge-v1.5.0
# 查看 systemd托管列表
$ systemctl list-unit-files
$ systemctl start cloudcore.service && systemctl enable cloudcore.service
# 查看节点状态
$ kubectl get node
$ kubectl get po -A
$ kubectl get po -n kube-system
$ kubectl get po -o wide
#查看网络状态
$ yum install net-tools -y
$ netstat -ntlp
#查看docker状态docker
$ docker images | grep kubeedge-pi-counter
# 传文件
$ scp kubeedge-pi-counter.tar 192.168.129.151:/root/
tmp目录下的文件
注意事项:
1、一般情况下,使用完成尽量挂起虚拟机,不然容器停掉,启动后node会处于not reday状态。
2、如果node处于not reday状态了,执行一下重启脚本,执行命令如下:
bash restart_kubeedge.sh
脚本内容:
#!/bin/bash
for i in `docker ps -a | awk '{print $1}' | grep -v CONT`;do docker restart $i;done
for i in `docker ps -a | awk '{print $1}' | grep -v CONT`;do docker restart $i;done