使用树莓派搭建的k8s集群部署第一个应用并尝试动态扩缩容

前情提要

去年使用树莓派搭建了一个k8s集群,当时对这方面了解得很少,所以只是搭建了一个简单集群,安装了网络插件,只有一个简单的dashboard, 没有部署任何实际的应用,以前的文章链接:手把手教大家使用树莓派4B搭建k8s集群

最近又心血来潮,重新用积木做了一个新的机箱,测试部署一个应用。今天总结一下最近经历所有的过程和问题,供大家参考

前置问题处理

更换网络插件

上一篇文章写到安装了网络插件colico,也就是最近发现colico插件pod启动失败,试了很久都没有成功只有重装了,按之前的教程安装也不行,只能重新fannel插件。

删除网络插件

先删除网络插件

kubectl delete -f calico.yaml
复制代码

此时有一个tunl0的虚拟网卡残留,可以使用ifconfig查看,卸载它,因为自己尝试了很多遍,把很多条shell命令组合成了一条命令,可以根据自己的实际情况修改:

ifconfig tunl0 down;ip link delete tunl0;rm -f /etc/cni/net.d/*;kubectl delete -f calico.yaml;systemctl start kubelet; systemctl start docker
复制代码

集群重置

在3台机器上执行集群初始化命令:

kubeadm reset
复制代码

三台机器删除掉配置文件:

rm -rf $HOME/.kube;rm -rf /etc/cni/net.d
复制代码

重启docker和kubelet,防火墙规清除:

systemctl daemon-reload;systemctl stop kubelet; systemctl stop docker; iptables --flush; iptables -tnat --flush;systemctl start kubelet; systemctl start docker
复制代码

集群安装

跟上篇文章一样,这里就不详细描述了 Master节点安装

sudo kubeadm init --image-repository=registry.aliyuncs.com/google_containers --kubernetes-version=v1.20.0 --apiserver-advertise-address=192.168.2.181 --pod-network-cidr=192.168.0.0/16 --ignore-preflight-errors=all
复制代码

Node节点加入命令

kubeadm join 192.168.2.181:6443 --token jqll23.kc3nkji7vxkaefro  --discovery-token-ca-cert-hash sha256:1b475725b680ed8111197eb8bfbfb69116b38a8d2960d51d17af69188b6badc2 --ignore-preflight-errors=all 
复制代码

查看所有的Node命令:

kubectl get pods --all-namespaces
复制代码

有时候机器重启后执行命令会报错: The connection to the server localhost:8080 was refused - did you specify the right host or port?
解决方案 : 原因:kubernetes master没有与本机绑定,集群初始化的时候没有绑定,此时设置在本机的环境变量即可解决问题。

扫描二维码关注公众号,回复: 13769093 查看本文章
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile

source /etc/profile
复制代码

可以把source /etc/profile 放在开机自动执行的脚本中彻底解决这个问题

pod运行错误,查看日志

自己尝试了很多遍,经常会安装网络插件之后pod没有运行成功,可以使用一下命令查看日志原因:

kubectl logs -f test-k8s-68bb74d654-9wwbt -n kube-system
复制代码

test-k8s-68bb74d654-9wwbt 就是具体的pod名称

安装网络插件

使用了官方的yaml文件

curl -sSL https://raw.githubusercontent.com/coreos/flannel/v0.12.0/Documentation/kube-flannel.yml | kubectl apply -f -*
复制代码

没想到直接成功了,之前都是无法连接10.1244.***.**的报错.

查看所有pod

kubectl get pods --all-namespaces
复制代码

image.png 现在是第一个应用安装完成了,pod名称test-k8s的应用就是我安装的应用,它命名空间是default的,跟其他的不同。

查看所有Node

kubectl get node --all-namespaces
复制代码

跟上个命令一样的,改了一个地方 image.png

安装第一个应用

制作镜像

安装应用就应该写一个yaml文件,和一个可用的镜像,我参考的是B站的广州云科的视频教程,但是他的测试的应用是基于X86平台的,镜像直接运行报错如下:

c33c444a5e810da7fb889eb3358874b.png

所以只有自己重新制作镜像,先找到项目地址:test-k8s 把代码全部克隆到树莓派机器上:

image.png 要弄一个镜像仓库提供给集群拉取,然后我自己测试使用的阿里云的容器镜像服务,要设置成开放的仓库,允许所有的人拉取这个镜像

image.png 别人的DockerFile已经写好了我们直接使用docker build命令打包镜像(现在为了重新推送测试,我把所有镜像都和容器删掉) 主要根据阿里云的教程就行了,如下:

image.png

打包&推送到阿里云

先本地打包,打包镜像名为k8s,-t为镜像标签的简写,tag的意思。可以在构建中设置多个标签

docker build -t test-k8s .
复制代码

镜像打一个新tag

docker tag test-k8s:latest registry.cn-shenzhen.aliyuncs.com/koala9527/testapp:latest
复制代码

推送

docker push registry.cn-shenzhen.aliyuncs.com/koala9527/testapp:latest
复制代码

image.png

到现在这个镜像就在阿里云的容器镜像服务中了,镜像地址为: registry.cn-shenzhen.aliyuncs.com/koala9527/testapp:latest

写第一个应用的yaml文件

文件名testapp.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  # 部署名字
  name: test-k8s
spec:
  replicas: 3
  # 用来查找关联的 Pod,所有标签都匹配才行
  selector:
    matchLabels:
      app: test-k8s
  # 定义 Pod 相关数据
  template:
    metadata:
      labels:
        app: test-k8s
    spec:
      # 定义容器,可以多个
      containers:
      - name: test-k8s # 容器名字
        image: registry.cn-shenzhen.aliyuncs.com/koala9527/testapp:v1  # 镜像
        resources:
          requests:
            cpu: 100m
复制代码

这里稍微解释复习一下这些资源描述文件中字段得意思,虽然上篇文章也有解释
apiVersion:api版本,我的理解就是资源控制的相关版本控制,k8s里的功能在高速迭代,不同的资源控制器使用不同的api版本,不同版本集群支持的api不同,写的yaml文件需要配合真实的集群环境,资源控制器类型就是用kind字段指定。

可以使用kubectl api-versions查看集群的api版本 image.png

kind:控制器类型,集群里面的所有资源都被k8s高度抽象化,kind就是表明这些资源的类型,Deployment就是一个定义一个多副本的无状态资源对象。
name: test-k8s :指定资源控制器的名字为test-k8s replicas:初始化指定的pod的个数 matchLabels:选择器标签,要用其他资源控制指定这个资源的时候用这个标签值
template这个字段下面就是包含这个pod的相关数据,app: test-k8s指定pod的名字,imagepod的镜像拉取地址,requests申请的CPU资源,0.1m等于0.1个CPU资源。

部署应用

kubectl apply -f testapp.yaml
复制代码

这时候就有3个pod了 image.png 可以使用 kubectl get pod -o wide查看pod详细信息,主要是看下IP:

 kubectl get pod -o wide
复制代码

image.png

登录其中一个pod访问另一个pod试试(这里是进入第一个pod访问第二个pod):

kubectl exec -it test-k8s-68b9f5c6c7-hn25x -- bash
curl 10.244.1.173:8080
复制代码

效果如图: image.png 可以看到输出了正确的pod得名称
但是这时候只能在pod之前进行互相访问,上篇文章有说pod可以一个单独的物理机,共用一个网络,要供集群外访问就要新建一个另外的资源,下面接着说。

微信截图_20220404212645.png

新建service资源控制器

yaml文件

service的特性:

  • Service 通过 label 关联对应的 Pod
  • Servcie 生命周期不跟 Pod 绑定,不会因为 Pod 重创改变 IP
  • 提供了负载均衡功能,自动转发流量到不同 Pod
  • 可对集群外部提供访问端口
  • 集群内部可通过服务名字访问

所有的资源都是通过yaml文件描述,写一个描述servie的yaml文件,文件名为service.yaml

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  type: NodePort  
  ports:
    - port: 8080        # 本 Service 的端口,内部访问
      targetPort: 8080  # 容器端口,也就是test-k8s这个应用的
      nodePort: 31000 #暴露出集群的端口

复制代码

值得说的是service这个资源控制的中type这个关键字类型,这里指定的是NodePort类型,在每个Node上开放一个端口,可以访问,如果不指定这个type,默认的类型就是ClusterIp,这个就是不允许集群外访问的,只允许集群内部访问,其他还有LoadBalance类型,负载均衡的意思,一般是云厂商提供的这个资源类型,不常见。

还要注意NodePort暴露的端口固定范围为: 30000-32767

应用Service:

和应用Deployment一样:

kubectl apply -f service.yaml
复制代码

查看k8s中Service资源

kubectl get svc
复制代码

image.png

测试效果

这个机器的内网IP为192.168.2.187,刚才设置的端口为31000

image.png

动态扩缩容

安装资源指标查看工具

使用动态扩缩容之前需要安装一个资源指标获取工具,用来监控集Node,Pod资源占用CPU,运行内存情况,名为metrics-server,集群默认不会安装这个,安装十分简单,在官方的GitHub下载安装:

wget <https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml>
kubectl apply -f components.yaml
复制代码

后面出错了,其相关pod不能启动,需要替换yaml文件内的一段内容,替换成如下,具体原因不清楚:

接下里就可以使用top命令查看pod和node CPU和运行内存资源占用情况 image.png

安装水平自动伸缩服务

控制pod的动态扩缩容又是一个资源控制器,叫HorizontalPodAutoscaler,字面意思是水平自动伸缩,跟service.yaml一样简单,文件名:hpa.yaml

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  namespace: default
  name: test-k8s-scaler
  labels:
    app: test-k8s-scaler
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: test-k8s
  minReplicas: 2
  maxReplicas: 100
  targetCPUUtilizationPercentage: 45

复制代码

水平自动伸缩控制器metadata里的数据来表示这个控制器的基本信息,spac里面的scaleTargetRef用来指定监控的哪些资源,minReplicas指定最小副本数,maxReplicas指定副本数,这个最小副本数会覆盖最初的定义replicas中的数量,targetCPUUtilizationPercentage指定触发伸缩时的CPU指标,k8s有一个复杂的算法(《Kubernetes in Action》这本书中有简要说明),会在一定的间隔观察这些pod资源使用情况来进行自动调整, 这里我体会到的是只要pod的CPU占用超过45%就会触发扩容策略进行扩容,还可以指定其他指标进行监控,但是一般是CPU和运行内存。

使用kubectl apply -f hpa.yaml 安装这个自动伸缩控制器

还可以使用kubectl get hpa查看这个水平自动伸缩控制器的基本状态,现在是0%

image.png

使用AB压力测试自动扩缩

下载地址 在windows上直接下载,解压,然后进入到bin目录运行一下命令:

./ab.exe -n 10000 -c 100 http://192.168.2.181:31000/
复制代码

意思是总共1w个请求,100个线程同时请求 然后执行watch kubectl get hpa,pod 实时监控自动伸缩的情况和pod个数详细参数 image.png

请求完成等几分钟pod个数又会回到2个,到这时候所有的测试完成了。

微信截图_20220404212522.png

总结

使用可以demo的应用部署到集群里面了,整个过程并不复杂,没有复杂烧脑的特性,K8s里的水平扩缩容是最吸引我的地方,所以部署应用成功后第一步就尝试实现这个功能了,接下来准备会结合Gitlab进行真的CI/CD用自动部署应用,不用手动敲命令了,提交代码合并分支就触发部署命令,或者尝试安装其他可以提供真正服务的应用,用来发挥它真正的作用,感谢大家看到这里。

猜你喜欢

转载自juejin.im/post/7082743804272312333