前言
K8SFramework是Tars基金会中的一个子项目,致力于将K8s与Tars微服务框架深度融合,可以同时使用TarsWeb和K8S的控制台(如Kubesphere)来管理微服务。本文主要介绍如何离线部署K8SFramework。
理解本节内容需要掌握的知识:
- 了解K8S
- 了解docker镜像仓库
- 了解Tars微服务框架
- 了解helm包管理工具
- 熟悉Linux操作系统基本指令
一、环境准备
- 安装了Dokcer环境,v20.10.8
- 安装了K8S环境,v1.19.8
- 安装了helm3
- 操作系统Debian 10
以上是我的安装环境。
二、搭建本地仓库
您可以使用 Harbor 或者其他任意私有镜像仓库。本教程以 Docker 仓库作为示例,并使用自签名证书(如果您有自己的私有镜像仓库,可以跳过这一步)。
| 使用自签名证书
执行以下命令生成您自己的证书:
mkdir -p certs
openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 36500 -out certs/domain.crt
当您生成自己的证书时,请确保在字段 Common Name 中指定一个域名(必须!)。例如,本示例中该字段被指定为 dockerhub.kubekey.local,如下图:
| 启动 Docker 仓库
docker run -d \
--restart=always \
--name registry \
-v "$(pwd)"/certs:/certs \
-v /home/dockerRegistry:/var/lib/registry \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-p 443:443 \
registry:2
注意:
Docker 使用 /var/lib/docker 作为默认路径来存储所有 Docker 相关文件(包括镜像)。建议您添加附加存储卷,给 /var/lib/docker 挂载至少 20G(根据业务需要)。
或者您可以通过修改/etc/docker/daemon.json文件,来修改Docker文件的存储路径。
| 配置仓库
1、在 /etc/hosts 中添加一个条目,将主机名(即仓库域名,在本示例中是dockerhub.kubekey.local)映射到您机器的私有 IP 地址,如下所示:
# docker registry
172.20.10.8 dockerhub.kubekey.local
2、执行以下命令,复制证书到指定目录,并使 Docker 信任该证书。
mkdir -p /etc/docker/certs.d/dockerhub.kubekey.local
cp certs/domain.crt /etc/docker/certs.d/dockerhub.kubekey.local/ca.crt
说明:
证书的路径与域名相关联。当您复制路径时,如果与上面设置的路径不同,请使用实际域名。
当然,您也可以通过修改客户端docker配置来实现仓库访问,即修改 /etc/docker/daemon.json,添加如下行:
"insecure-registries": [
"dockerhub.kubekey.local"
],
配置好后的daemon.json如下图:
3、要验证私有仓库是否有效,您可以先复制一个镜像到您的本地机器上,然后使用 docker push 和 docker pull 来测试。
也可以执行如下命令进行测试:
root@node-1:/home/parallels/soft# curl --ssl --cacert `pwd`/certs/domain.crt https://dockerhub.kubekey.local/v2/_catalog
{"repositories":[]}
会以json格式返回仓库中的内容。上述结果说明仓库是空的。
镜像导入后,得到的结果如下图:
三、镜像导入
| 镜像拉取
需要下载K8SFramework相关镜像,然后导入到本地仓库(https://dockerhub.kubekey.local)中。镜像包括:
##tars-k8s-controller镜像
docker pull tarscloud/tarscontroller:latest
docker pull tarscloud/tarsagent:latest
##tars-k8s framework镜像
docker pull tarscloud/tars.tarsconfig:latest
docker pull tarscloud/tars.tarsimage:latest
docker pull tarscloud/tars.tarskevent:latest
docker pull tarscloud/tars.tarslog:latest
docker pull tarscloud/tars.tarsnode:latest
docker pull tarscloud/tars.tarsnotify:latest
docker pull tarscloud/tars.tarsproperty:latest
docker pull tarscloud/tars.tarsqueryproperty:latest
docker pull tarscloud/tars.tarsquerystat:latest
docker pull tarscloud/tars.tarsregistry:latest
docker pull tarscloud/tars.tarsstat:latest
docker pull tarscloud/tars.tarsweb:latest
docker pull tarscloud/tars.cppbase:latest
###如果启用es作为日志收集器,就需要拉取这个镜像
docker pull tarscloud/tars.elasticsearch:latest
##编译环境的镜像,包含了所有语言
docker pull tarscloud/base-compiler:latest
##其他语言运行环境镜像,按需下载
docker pull tarscloud/tars.javabase:latest
docker pull tarscloud/tars.nodejsbase:latest
docker pull tarscloud/tars.php74base:latest
注意:
下载的镜像版本一定要保持一致!
由于这个项目较新,更新很频繁,有时版本差了0.0.1也会导致运行异常。可以统一把lastest修改成你想下载的版本(同时也需要修改helm包中的版本)。
如果版本不一致,可能会产生如下错误:
Error: failed pre-install: warning: Hook pre-install tarsframework/templates/tars-frameworkconfig.yaml failed: admission webhook "validating.crd.tars.io-0" denied the request: unsupported validating CREATE v1beta2.TFrameworkConfig
root@node-1:/home/parallels#
root@node-1:/home/parallels#
我第一次部署时tarscontroller是最新版的,Framework是1.2.5版本。对比了下tarscontroller源码,在最新版本中已经把CREATE/UPDATE/DELETE TFrameworkConfig 给去掉了。所以大家要引以为戒,一定要拉齐版本!
这里再吐槽一下:镜像很大,总共加起来超过12G。
| 镜像导入本地仓库
可以手动retag镜像,然后导入到上一步骤创建的仓库中,如:
docker tag tarscloud/tarscontroller:latest dockerhub.kubekey.local/tarscloudtarscontroller:latest
docker push dockerhub.kubekey.local/tarscloudtarscontroller:latest
也可以使用下面这个脚本,批量导入:
./retag-and-push.sh -l images-list.txt -r dockerhub.kubekey.local
参数说明:
-l:镜像列表文件
-r: 镜像仓库地址
脚本retag-and-push.sh内容如下:
#!/usr/bin/env bash
registryurl=""
func() {
echo "Usage:"
echo
echo " $0 [-l IMAGES-LIST] [-r PRIVATE-REGISTRY] "
echo
echo "Description:"
echo " -l IMAGES-LIST : text file with list of images."
echo " -r PRIVATE-REGISTRY : target private registry:port."
echo " -h : usage message"
echo
echo "Examples:"
echo
echo "retag-and-push.sh -l images-list.txt -r dockerhub.kubekey.local"
exit
}
while getopts 'bsl:r:d:v:h' OPT; do
case $OPT in
b) binary="true";;
l) ImagesList="$OPTARG";;
r) Registry="$OPTARG";;
h) func;;
?) func;;
*) func;;
esac
done
if [ -n "${Registry}" ]; then
registryurl=${Registry}
fi
if [[ -n ${registryurl} ]]; then
for image in $(<${ImagesList}); do
if [[ ${image} =~ ^\#\#.* ]]; then
continue
fi
url=${image%%/*}
ImageName=${image#*/}
echo $image
if [ $url == $registryurl ]; then
if [[ $ImageName != */* ]]; then
imageurl=$registryurl"/library/"$ImageName
else
imageurl=$image
fi
elif [ "$(echo $url | grep ':')" != "" ]; then
imageurl=$registryurl"/library/"$image
else
imageurl=$registryurl"/"$image
fi
## push image
echo $imageurl
docker tag $image $imageurl
docker push $imageurl
done
fi
image-list.txt文件的内容就是镜像列表,如下:
tarscloud/base-compiler:latest
tarscloud/tarsagent:latest
tarscloud/tarscontroller:latest
tarscloud/tars.cppbase:latest
tarscloud/tars.elasticsearch:latest
tarscloud/tars.javabase:latest
tarscloud/tars.nodejsbase:latest
tarscloud/tars.php74base:latest
tarscloud/tars.tarsconfig:latest
tarscloud/tars.tarsimage:latest
tarscloud/tars.tarskevent:latest
tarscloud/tars.tarslog:latest
tarscloud/tars.tarsnode:latest
tarscloud/tars.tarsnotify:latest
tarscloud/tars.tarsproperty:latest
tarscloud/tars.tarsqueryproperty:latest
tarscloud/tars.tarsquerystat:latest
tarscloud/tars.tarsregistry:latest
tarscloud/tars.tarsstat:latest
tarscloud/tars.tarsweb:latest
镜像准备好后,就可以按照官方文档安装K8SFramework了。
四、K8SFramework安装
| 准备安装节点
需要对节点打标签,让Tars相关服务可以部署到上面。
kubectl label nodes node-1 node-2 tars.io/node.tars-dev=
其中,node-1、node-2是主机名, tars-dev 是目标 namespace。
如果要在其他 namespace 中部署tars框架,如 tars-dev2,就可以按照如下命令打标签:
kubectl label nodes node-1 node-2 tars.io/node.tars-dev2=
| 给支持LocalPV的节点打标签
K8SFramework提供了本地存储方案,需要通过给节点设置标签来启用。在node-1和node-2上都启用LocalPV:
kubectl label nodes node-1 node-2 tars.io/SupportLocalVolume=
可以看到,LocalPV只跟节点关联,不依赖命名空间。
| 安装tarscontroller
这个步骤中会安装tarscontroller和tarsagent到k8s中。
1、添加helm远程仓库
helm repo add tars-k8s https://tarscloud.github.io/K8SFramework/charts
2、拉取helm安装包到本地
helm pull tars-k8s/tarscontroller
成功后,当前目录下会有这个文件:
tarscontroller-1.2.0.tgz
3、安装controller
需要提前修改values.yaml中的仓库地址(版本号按需修改,建议不动),如下:
注意:
registry这里,一定要到 tarscloud 目录中!
然后执行安装:
##重新打包
helm package tarscontroller
##安装
helm install tarscontroller tarscontroller-1.2.0.tgz
当然,我们也可以直接传入参数进行安装,如下:
helm install tarscontroller --set 'helm.dockerhub.registry=dockerhub.kubekey.local/tarscloud' tarscontroller-1.2.0.tgz
安装成功之后,会在k8s中看到tarscontroller和tarsagent已经启动了:
root@node-1:/home/parallels# kubectl get pods -n tars-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tars-agent-92x9c 1/1 Running 0 2m34s 10.233.69.127 node-2 <none> <none>
tars-agent-w5kjv 1/1 Running 0 2m33s 10.233.112.145 node-1 <none> <none>
tars-controller-manger-848d948d48-mjsmn 1/1 Running 0 3m55s 10.233.69.123 node-2 <none> <none>
4、创建 secret
创建 secret ,指定命名空间为 tars-dev2:
kubectl create secret docker-registry tars-image-secret -n tars-dev2 --docker-server=dockerhub.kubekey.local --docker-username=docker_user --docker-password=docker_pass
官方文档中对参数的解释是:
# 建立 k8s 访问 镜像仓库时使用的 secret
# docker_registry 是您的镜像仓库地址
# docker_user 是您的镜像仓库访问账号
# docker_pass 是您的镜像仓库访问密码
# 如果您没有镜像仓库, 可以暂时填充一个域名占位, 比如 example.com/tars
# 如果您的镜像仓库无需账号密码访问, 可以使用任意账号/密码占位, 比如 docker_user/docker_pass
我们建的仓库没有账号密码,所以这里只修改了命名空间和仓库地址两项:
-n tars-dev2
--docker-server=dockerhub.kubekey.local
其余参数默认不变。
5、安装tarsframework
安装tarsframework到tars-dev2的命名空间中:
helm install tarsframework -n tars-dev2 --set 'helm.dockerhub.registry=dockerhub.kubekey.local/tarscloud,dockerRegistry=dockerhub.kubekey.local/tarsservice,web=web.k8s-tars.com' tarsframework-1.3.1.tgz
参数说明:
#指定tarsframework的镜像仓库
helm.dockerhub.registry=dockerhub.kubekey.local/tarscloud
#指定业务服务的镜像仓库
dockerRegistry=dockerhub.kubekey.local/tarsservice
#指定tarsweb的域名,随便写
web=web.k8s-tars.com
这里的参数跟(tarsframework-1.3.1.tgz中的)values.yaml文件是一一对应的,如下:
注意:
tarsframework镜像仓库的地址,一定要写到tarscloud目录!
即dockerhub.kubekey.local/tarscloud
到这里,不出意外的话你已经完成了tarsframework的安装。正常情况下Pod状态:
6、开启tarsweb
这时候,tarsweb并不可以直接访问,需要修改一些配置。这里只介绍其中一种方式,其他方式参考原文。我们需要执行下面的指令,修改 tserver/tarsweb.spec.k8s.hostNetwork 值为 true:
kubectl edit tserver -n tars-dev2 tars-tarsweb
之后,我们就可以通过 http://$(ip):3000 访问tarsweb管理平台了!
K8S版本的TarsWeb跟原生的TarsWeb区别比较大,后续我们再慢慢研究~
五、异常处理
| 清理 tars-system 空间(和tarscontroller)
如果tarscontroller安装时出现异常,想重新安装,需要清理所有资源,整理如下:
#删掉tars-system下的所有资源(包括namespace)
##删除ns
kubectl delete ns tars-system
##删除strageclass
kubectl delete sc tars-storage-class
##删除clusterRole
kubectl delete ClusterRole tars-system:tars-agent-image-downloader
kubectl delete ClusterRole tars-system:tars-controller
kubectl delete clusterrolebinding tars-system:tars-controller tars-system:tars-agent-local-provisioner tars-system:tars-agent-image-downloader
##继续删
kubectl delete MutatingWebhookConfiguration tars-mutating-webhook
kubectl delete ValidatingWebhookConfiguration tars-validating-webhook
你以为到这里就结束了?NO!如果这时你重新安装tarscontroller,会报错:
Error: cannot re-use a name that is still in use
这是由于helm的release列表还没有清理。
##可以先查看
helm list -n tars-system
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
tarscontroller default 1 2022-05-26 21:24:37.634303236 +0800 CST deployed tarscontroller-1.2.0 v1beta2
##需要删除
helm delete tarscontroller -n tars-system
##删除之后再安装
helm install tarscontroller tarscontroller-1.2.0.tgz
| 清理tarsframework的空间
K8SFramework可以将不同的tars集群安装到不同的namespace中。如果我们发现安装集群时出现错误,怎么办?
我在首次安装时(安装到tars-dev空间),由于tarsframework的仓库地址填写错了(没有写目录tarscloud),导致拉取不到镜像。这时可以选择快速搭建一个新的集群,把namespace更换成tars-dev2即可。
如果想把失败的tars-dev删掉,怎么办?直接删除ns:
root@node-1:/home/parallels# kubectl delete ns tars-dev
namespace "tars-dev" deleted
这个过程中会删除tars-dev2空间下的Pod、Config、磁盘挂载信息。
但是还有一些tarsweb的认证信息没有删除。
如果想重建账号体系(注意:此步骤非必须),还需要删除下面这些资源:
##删除clusterRole
root@node-2:/home/parallels# kubectl delete ClusterRole tars-dev:tars-tarsweb
clusterrole.rbac.authorization.k8s.io "tars-dev:tars-tarsweb" deleted
root@node-2:/home/parallels# kubectl delete ClusterRole tars-dev:tars-tarskevent
clusterrole.rbac.authorization.k8s.io "tars-dev:tars-tarskevent" deleted
root@node-2:/home/parallels#
##删除clusterrolebinding
root@node-2:/home/parallels# kubectl delete clusterrolebinding tars-dev:tars-tarsweb tars-dev:tars-tarskevent
clusterrolebinding.rbac.authorization.k8s.io "tars-dev:tars-tarsweb" deleted
clusterrolebinding.rbac.authorization.k8s.io "tars-dev:tars-tarskevent" deleted
root@node-2:/home/parallels#
到此,tars-dev这个空间才算完全清理干净。tars-dev这个名称可以重新使用了。
写在最后
| 注意事项
总体来说,安装过程中除了镜像比较大之外,没有其他特别需要吐槽的。大家需要格外注意以下几点:
- tarscontroller和tarsframework镜像的版本要一致
- 使用本地仓库时,仓库地址一定要到tarscloud目录
- 重建tarscontroller时,必须删除所有tars-system的相关资源,否则会重建失败
| 使用感受
推荐大家通过本地镜像来部署,可以缩短拉取镜像的耗时,提升部署效率。
这种tars与k8s融合的部署方式比原生的部署方式要简便许多,但学习成本也很高,你需要了解k8s、docker、helm、Tars... 如果团队已经具备基础环境了,还是很推荐选择这种方式来部署的。
原生Tars大家可以放心大胆的在生产环境中使用,但是K8SFramework还需要时间验证。