linux cpu占用率如何看
279
2022-09-11
树莓派组建 k8s 集群(centos版)
一般来讲,一个典型的 k8s 集群通常都由成千上百的服务器构成。对于个人、教育机构和中小企业而言,构建和维护一个具有相当规模的 k8s 集群需要很高的成本,成本、空间和能耗开销都是很棘手的问题。这些问题就会导致很多本来应该基于 k8s 集群的具体工作都很难持续开展。而树莓派是一种低成本、低功耗的基于 ARM 的微型电脑主板,如果能够用一定数量的树莓派组建 k8s 集群且能够做到基本可用,那必然会显著降低 k8s 集群的使用成本。
退一步来说,当树莓派 k8s 集群成功组建后,这样的一套环境也是一个非常实用的学习和实验工具,能够显著降低 k8s 的学习门槛。
树莓派的基本知识
树莓派是一款基于 ARM 的微型电脑主板,旨为学生编程教育而设计,其系统基于 Linux,由注册于英国的慈善组织“Raspberry Pi 基金会”开发,Eben•Upton 为项目带头人。树莓派尺寸仅有信用卡大小,体积和火柴盒相差无几,别看其外表“娇小”,功能却很强大,上网、看视频、听音乐等功能都能支持,可谓是“麻雀虽小,五脏俱全”。而且除了官方系统外,还可以安装其他第三方系统,便携易折腾,因此自问世以来,就深受众多计算机发烧友和创客追捧。
树莓派家族
树莓派集群
2020年6月,笔者在gitchat上发了一篇文章树莓派 k8s 集群入坑指南,该文详细介绍了在树莓派4B上如何从安装操作系统64位ubuntu开始,安装docker、kubernetes、helm直至组建k8s集群、并安装nginx-ingress、kubernetes-dashboard和local-path全过程;后续又陆续基于该集群实践了prometheus、mysql主从复制、redis集群、consul集群、kafka集群、spring cloud微服务项目的安装并分享成文。
时隔一年后,笔者对该集群进行升级,docker、kubernetes和helm分别由对应的18.09.9、1.15.0和2.15升级至19.03.8、1.18.20和3.5.0,这个版本组合已经和笔者工作环境下x86集群中使用到的docker、kubernetes和helm主版本基本一致,另外更有意思的是,2020年下半年linux社区发布了适配树莓派4B的64位centos7.9,从而为笔者的这次升级再添一项重要内容,即将树莓派的操作系统切换为centos后,再行组建k8s集群。
树莓派 4 安装 k8s 集群
安装准备• 硬件:Raspberry Pi 4B-4g 3 台• sd 卡:闪迪 128GB SD 3 张本指南中以 3 个树莓派 4 组建 k8s 集群,用一个做 master,另外两个做 node,docker 版本为19.03.8,k8s 版本为1.18.20,使用 kubeadm 进行安装。具体安装规划如下:
hostname | ip | 型号 | os | kernel | cpu | memory | disk | role |
---|---|---|---|---|---|---|---|---|
pi4-master01 | 10.168.1.101 | raspberry4b | CentOS Linux release 7.9.2009 (AltArch) | 5.4.72-v8.1.el7 | 4c | 4g | 128 | master |
pi4-node01 | 10.168.1.102 | raspberry4b | CentOS Linux release 7.9.2009 (AltArch) | 5.4.72-v8.1.el7 | 4c | 4g | 128 | node |
pi4-node02 | 10.168.1.103 | raspberry4b | CentOS Linux release 7.9.2009 (AltArch) | 5.4.72-v8.1.el7 | 4c | 4g | 128 | node |
安装centos7.9
参考
树莓派4B安装Centos7.9 树莓派4B的centos7.9配置优化 安装docker 参考 树莓派4B安装docker 安装kubernetes 参考 树莓派4B安装kubernetes 设置 hostname: # pi4-master01 hostnamectl set-hostname pi4-master01 # pi4-node01 hostnamectl set-hostname pi4-node01 # pi4-node02 hostnamectl set-hostname pi4-node02 组建k8s步骤 初始化master节点(只在k8s-mater01主机上执行) 创建初始化配置文件,可以使用如下命令生成初始化配置文件 kubeadm config print init-defaults > kubeadm-config.yaml vi kubeadm-config.yaml 编辑配置文件kubeadm-config.yaml apiVersion: kubeadm.k8s.io/v1beta2 bootstrapTokens: groups: system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages: signing authenticationkind: InitConfigurationlocalAPIEndpoint: pi4-master01的ip:10.168.1.101 advertiseAddress: 10.168.1.101bindPort: 6443nodeRegistration:criSocket: /var/run/dockershim.sockname: pi4-master01taints: effect: NoSchedulekey: node-role.kubernetes.io/master apiServer:timeoutForControlPlane: 4m0sapiVersion: kubeadm.k8s.io/v1beta2certificatesDir: /etc/kubernetes/pkiclusterName: kubernetescontrollerManager: {}dns:type: CoreDNSetcd:local:dataDir: /var/lib/etcdimageRepository: k8s.gcr.iokind: ClusterConfiguration 修改版本号 kubernetesVersion: v1.18.20networking:dnsDomain: cluster.local 配置成 Calico 的默认网段 podSubnet: "10.244.0.0/16"serviceSubnet: 10.96.0.0/12scheduler: {} 开启 IPVS 模式 apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationfeatureGates:SupportIPVSProxyMode: truemode: ipvs kubeadm 初始化 # kubeadm 初始化 kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log
配置 kubectl
mkdir -p $HOME/.kubecp -i /etc/kubernetes/admin.conf $HOME/.kube/configchown $(id -u):$(id -g) $HOME/.kube/config
验证是否成功
kubectl get nodeNAME STATUS ROLES AGE VERSIONpi4-master01 NotReady master 7m11s v1.18.20
注意这里返回的 node 是 NotReady 状态,因为没有装网络插件
kubectl get csNAME STATUS MESSAGE ERRORcontroller-manager Unhealthy Get dial tcp 127.0.0.1:10252: connect: connection refused scheduler Unhealthy Get dial tcp 127.0.0.1:10251: connect: connection refused etcd-0 Healthy {"health":"true"}
注意这里返回的 controller-manager和scheduler 是 Unhealthy 状态,下面是解决方案
- 解决controller-manager和scheduler 是 Unhealthy 状态 开启scheduler, control-manager的10251,10252端口 修改以下配置文件: /etc/kubernetes/manifests/kube-scheduler.yaml,把port=0那行注释 /etc/kubernetes/manifests/kube-controller-manager.yaml,把port=0那行注释 ```bash # 重启kubelet systemctl restart kubelet kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-0 Healthy {"health":"true"} # 注意这里返回的 controller-manager和scheduler 已经是 healthy 状态了
安装calico网络组件
# 下载
wget https://docs.projectcalico.org/manifests/calico.yaml
# 替换 calico 部署文件的 IP 为 kubeadm 中的 networking.podSubnet 参数 10.244.0.0
sed -i 's/192.168.0.0/10.244.0.0/g' calico.yaml
# 安装
kubectl apply -f calico.yaml
kubectl get node
NAME STATUS ROLES AGE VERSION
pi4-master01 Ready master 59m v1.18.20
# 注意这里返回的 node 已经是 Ready 状态了
增加 node 节点
登录 pi-node01 执行加入 k8s 集群命令如下:
root@pi4-node01:~# kubeadm join 10.168.1.101:6443 --token o7dosg.zq4df9h80b6ygryp \
> --discovery-token-ca-cert-hash sha256:82c4334bc880f3c6972cee93844d6307d989df10d90bd4d63c93212702604523
登录 pi-node02 执行加入 k8s 集群命令如下:
root@pi4-node02:~# kubeadm join 10.168.1.101:6443 --token o7dosg.zq4df9h80b6ygryp \
> --discovery-token-ca-cert-hash sha256:82c4334bc880f3c6972cee93844d6307d989df10d90bd4d63c93212702604523
登录 pi4-master01 查看 kubernetes 状态:
root@pi4-master01:~/k8s# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
pi4-master01 Ready master 60m v1.18.20 10.168.1.101
可以看到 pi4-node01 和 pi4-node02 已经作为正常的 node 节点加入了集群。
node 节点 ROLES 为 none 处理
如果 ROLES 列为 none,则通过打标签来进行修复。如果 master 节点的 ROLES 为 none,则可为 master 的节点打上标签 node-role.kubernetes.io/master=;如果 node 节点的 ROLES 为 none,则可为 node 节点打上标签 node-role.kubernetes.io/node=。
root@pi4-master01:~/k8s# kubectl label node pi4-node01 node-role.kubernetes.io/node=
node/pi4-node01 labeled
root@pi4-master01:~/k8s# kubectl label node pi4-node02 node-role.kubernetes.io/node=
node/pi4-node02 labeled
root@pi4-master01:~/k8s# kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
pi4-master01 Ready master 3h57m v1.18.20 10.168.1.101
让 Master 也进行 Pod 调度
默认情况下,pod 节点不会分配到 master 节点,可以通过如下命令让 master 节点也可以进行 pod 调度:
root@pi4-master01:~# kubectl taint node pi4-master01 node-role.kubernetes.io/master- node/pi4-master01 untainte
取消 k8s 对外开放默认端口限制
k8s 默认对外开放的端口范围为 30000~32767,可以通过修改 kube-apiserver.yaml 文件重新调整端口范围,在 /etc/kubernetes/manifests/kube-apiserver.yaml 文件中,找到 --service-cluster-ip-range 这一行,在下面增加如下内容,- --service-node-port-range=10-65535
然后重启 kubelet 即可。
systemctl daemon-reload && systemctl restart kubelet
安装 helm3(只在k8s-mater01主机上执行)
# 打印版本号 helm version version.BuildInfo{Version:"v3.5.0", GitCommit:"32c22239423b3b4ba6706d450bd044baffdcf9e6", GitTreeState:"clean", GoVersion:"go1.15.6"}
安装 nginx-ingress
下载ingress-nginx helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx "ingress-nginx" has been added to your repositories helm pull ingress-nginx/ingress-nginx --version=3.39.0 tar -zxf ingress-nginx-3.39.0.tgz && cd ingress-nginx 修改values.yaml # 修改controller镜像地址 repository: wangshun1024/ingress-nginx-controller # 注释掉 digest # digest: sha256:35fe394c82164efa8f47f3ed0be981b3f23da77175bbb8268a9ae438851c8324
dnsPolicy
dnsPolicy: ClusterFirstWithHostNet
使用hostNetwork,即使用宿主机上的端口80 443
hostNetwork: true
使用DaemonSet,将ingress部署在指定节点上
kind: DaemonSet
节点选择,将需要部署的节点打上ingress=true的label
nodeSelector:kubernetes.io/os: linuxingress: "true"
修改type,改为ClusterIP。如果在云环境,有loadbanace可以使用loadbanace
type: ClusterIP
- 安装ingress-nginx
```bash
# 选择节点打label
kubectl label node pi4-master01 pi4-node01 pi4-node02 ingress=true
# 安装ingress
# helm install ingress-nginx ./
NAME: ingress-nginx
LAST DEPLOYED: Sat Nov 20 13:09:11 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
Get the application URL by running these commands:
export POD_NAME=$(kubectl --namespace default get pods -o jsonpath="{.items[0].metadata.name}" -l "app=ingress-nginx,component=controller,release=ingress-nginx")
kubectl --namespace default port-forward $POD_NAME 8080:80
echo "Visit to access your application."
An example Ingress that makes use of the controller:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
name: example
namespace: foo
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: exampleService
servicePort: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- example.com
secretName: example-tls
If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt:
确认nginx- ingress 安装是否 OK。 kubectl get all NAME READY STATUS RESTARTS AGE pod/ingress-nginx-controller-6w8bx 1/1 Running 0 34m pod/ingress-nginx-controller-g9m6k 1/1 Running 0 34m pod/ingress-nginx-controller-lrspp 1/1 Running 0 34m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/ingress-nginx-controller ClusterIP 10.109.127.239
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGEdaemonset.apps/ingress-nginx-controller 3 3 3 3 3 ingress=true,kubernetes.io/os=linux 34m
用浏览器访问 界面如下:  are: 安装是否 OK
kubectl get all -n kube-system |grep kubernetes-dashboard
pod/kubernetes-dashboard-69574fd85c-n4cwc 1/1 Running 0 3m43s
service/kubernetes-dashboard ClusterIP 10.103.120.221
访问kubernetes-dashboard
ip域名映射处理 在访问kubernetes-dashboard之前,我们需要在使用客户端访问电脑建立ip和相关域名的映射关系如下:10.168.1.101 kdb.pi4k8s.com 提示:win10或win7电脑中维护ip和相关域名的文件位置在 C:\Windows\System32\drivers\etc\hosts。
安全风险处理 因为默认安装的kubernetes-dashboard只能通过查看内容含有token的secret
kubectl get secret -n kube-system | grep kubernetes-dashboard-token
kubernetes-dashboard-token-9llx4 kubernetes.io/service-account-token 3 25m
# 查看对应的token
kubectl describe secret -n kube-system kubernetes-dashboard-token-9llx4
Name: kubernetes-dashboard-token-9llx4
Namespace: kube-system
Labels:
创建dashboard-admin.yaml,内容如下
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubernetes-dashboard namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: kubernetes-dashboard namespace: kube-system
给dashboard的serviceaccont授权
kubectl apply -f dashboard-admin.yaml clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard configured
安装 local-path
下载local-path-provisioner
wget https://github.com/rancher/local-path-provisioner/archive/v0.0.19.tar.gz tar -zxf v0.0.19.tar.gz && cd local-path-provisioner-0.0.19
安装local-path-provisioner
kubectl apply -f deploy/local-path-storage.yaml kubectl get po -n local-path-storage NAME READY STATUS RESTARTS AGE local-path-provisioner-5b577f66ff-q2chs 1/1 Running 0 24m [root@k8s-master01 deploy]# kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path rancher.io/local-path Delete WaitForFirstConsumer false 24m
配置 local-path 为默认存储
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' storageclass.storage.k8s.io/local-path patched kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.beta.kubernetes.io/is-default-class":"true"}}}' storageclass.storage.k8s.io/local-path patched [root@k8s-master01 deploy]# kubectl get storageclass NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 27m 25m
验证local-path安装是否OK
kubectl apply -f examples/pod.yaml,examples/pvc.yaml pod/volume-test created persistentvolumeclaim/local-path-pvc created kubectl get pvc,pv NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/local-path-pvc Bound pvc-74935037-f8c7-4f1a-ab2d-f7670f8ff540 2Gi RWO local-path 58s NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-74935037-f8c7-4f1a-ab2d-f7670f8ff540 2Gi RWO Delete Bound default/local-path-pvc local-path 37s
总结
本指南首先介绍了树莓派的基本知识,然后详细讲解了如何用3个树莓派4B组建k8s集群。这套集群是一套完整的k8s环境,能够满足大多数使用场景,比如直接执行docker、k8s和helm等各种命令,或者安装mysql、redis、zookeeper和kafka等各类中间件甚至直接部署我们的学习项目或者工作项目。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~