0 环境说明
泰山2000 arm64架构服务器。
操作系统openEuler 20.03。
内核:Linux 4.19.90-2112.8.0.0131.oe1.aarch64
1 关闭防火墙
默认openEuler会安装并启动firewalld防火墙,需要提前关闭,否则在后续操作中可能会出现无法连接主机的问题。
systemctl stop firewalld
systemctl disable firewalld
2 部署rancher
使用rancher安装。
首先安装docker:
wget -O /etc/yum.repos.d/openEulerOS.repo https://repo.huaweicloud.com/repository/conf/openeuler_aarch64.repo
yum clean all
yum makecache
yum install docker
然后运行rancher的docker镜像进行集群管理。
docker run --privileged -d --restart=unless-stopped -p 3080:80 -p 3443:443 rancher/rancher:v2.5.15
注意这里一定不能使用2.6.x版本,否则集群部署遇到问题的时候不方便得到kubeconfig.json文件。
安装镜像之后,需要等待一会儿,最终会变成ready状态。
创建自定义集群,然后选择k8s版本为1.18。注意:下面选择Network(网络插件)要改成Flannel!!!,如果使用默认的canel,会拉取不到arm64对应版本的镜像导致部署失败,即使按照下面安装问题中解决了部署的问题,插件也无法正常使用,会出现不同节点不能ping通其他节点上部署的pod的情况。
参考文章https://cloud.tencent.com/developer/article/1768489
安装问题
Runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
原因:
先从cluster的overview界面右上角那里拿到kubeconfig file的内容,存入~/.kube/config
中,之后kubectl就可以访问这个未完成的集群了。使用kubectl get pod -n kube-system
命令查看集群中kube-system的pod运行情况,发现是一个pod卡住了。通过kubectl describe pod
命令查看这个pod的信息,发现其镜像是rancher/mirrored-calico-node:v3.13.4,然而去docker hub上查找发现,Calico该版本没有arm64的image,因此pod卡在ImagePullBackOff上。
解决方案:
kubectl apply -f https://docs.projectcalico.org/v3.11/manifests/calico.yaml
手动安装一个calico之后,就正常了。
如果后续不需要该节点作为集群的节点,可以用以下脚本清理:
#!/bin/sh
docker rm -f $(docker ps -qa)
docker volume rm $(docker volume ls -q)
cleanupdirs="/var/lib/etcd /etc/kubernetes /etc/cni /opt/cni /var/lib/cni /var/run/calico /opt/rke"
for dir in $cleanupdirs; do
echo "Removing $dir"
rm -rf $dir
done
遇到其他问题时,首先冷静想想,是否是因为Docker镜像没有对应的arm64版本。
获取kubeconfig.json
在rancher的界面上,cluster的overview处右上角有kubeconfig文件
按钮。点击按钮,复制所有文件内容,并覆盖写入~/.kube/config文件,之后就可以使用kubectl访问和操作集群。
获取api token
首先绑定角色。kubectl create -f admin-role.yml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: admin
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
然后运行kubectl -n kube-system get secret|grep admin-token
会出现一个admin-token-xxx
最后运行kubectl -n kube-system describe secret admin-token-xxx
,将显示出的非常长的一串token复制出来。
参考文章https://jimmysong.io/kubernetes-handbook/guide/auth-with-kubeconfig-or-token.html
通过rancher安装的k8s集群中已经有metrics,因此可以直接使用java fabric8 api进行访问和使用。
工具安装
- kubens 快速切换namespace。
添加rancher节点
在新的节点主机上首先要关闭防火墙。
然后在Rancher上找到Registration Cmd。复制后一定要加上 -e CATTLE_NODE_NAME=xxx来指定主机名,将新的节点加入到集群中。
还有一点需要注意的是,如果只添加work角色,会导致一直卡在等待注册(原因还不明)。
3 GlusterFS配置持久化卷
提前安装glusterfs和heketi,并配置好。
安装启动glusterfs:
yum install glusterfs
systemctl start glusterd
systemctl enable glusterd
安装heketi:https://github.com/heketi/heketi。只需要解压将可执行文件放入/usr/local/bin即可。
创建k8s的StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: seecoder-paas
provisioner: kubernetes.io/glusterfs
reclaimPolicy: Retain
allowVolumeExpansion: true
parameters:
resturl: "http://172.29.7.102:5080" #glusterfs service url
restauthenabled: "true"
restuser: "admin"
restuserkey: "WJNJqeGZGBJC6k1kaRxd"
volumetype: "none"
注意,如果是单节点部署的glusterfs,必须要使用volumetype: "none"
选项,否则创建持久卷会失败。
4 部署PaaS
数据库
先运行一个mysql数据库,供后端使用。
这里采用docker部署:
mkdir -p /mnt/mysql-data && docker run --restart=always -p 3306:3306 -p 33060:33060 --name my-mysql -v /mnt/mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql
然后新建seecoder_paas
数据库备用。
后端
安装java。
docker仓库地址:
在application.yml里面使用的docker仓库地址应该为 nexus.seecoder.cn:8092
需要将这个http网址加入到docker的配置文件的insecure中,否则在拉取镜像时会报错。另外还需要配置一个镜像站点,否则部署时拉取镜像会很慢。修改所有部署节点的/etc/docker/daemon.json
如下所示:
{
"registry-mirrors":["https://8eemjwlo.mirror.aliyuncs.com"],
"insecure-registries":["nexus.seecoder.cn:8092"]
}
可以使用app.sh进行部署,需要对脚本文件中的一些变量进行修改。脚本使用同目录下的config.yml作为后端SpringBoot的配置文件。
运行目录中,要新建docker-config.json文件并填入以下内容,paas构建镜像后,会读取其中的账号密码并将镜像推送到私有的镜像仓库中:
{
"auths": {
"172.19.51.6:8092": {
"username": "admin",
"password": "NJU67nexus"
}
}
}
必须要新建seec的namespace,应用才可以正常部署。
kubectl create -f ns.yml
apiVersion: v1
kind: Namespace
metadata:
name: seec
前端
使用nginx静态部署。如果部署前端的机器上面运行有集群,则需要避开80和443端口。
Nginx
由于含有websocket连接,需要进行特殊分流配置。
参考的nginx配置文件如下:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream websocket {
server 127.0.0.1:8080;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2 ;
root /srv/paas-ui/dist;
server_name paas-test-seec.claws.top;
ssl_certificate_key /root/cert/paas-test-seec.claws.top/cert.key;
ssl_certificate /root/cert/paas-test-seec.claws.top/fullchain.cer;
location ~ /ws {
proxy_pass http://websocket;
proxy_read_timeout 3h;
proxy_send_timeout 3h;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
location ~ / {
if ($request_uri ~* (api)) {
proxy_pass http://127.0.0.1:8080;
}
try_files $uri $uri/ /index.html;
}
}
终端问题
无法连接:服务器nginx必须使用ssl加密,因为前端里面写死的wss。
连接之后出现unable to start container process: open /dev/pts/0: operation not permitted: unknown错误:在服务器上运行kubectl exec仍然有问题,重启pod解决。
5 配置ingress相关
rancher建立集群的时候,如果全部采用默认选项,就会自动开启一个nginx ingress controller,但是会占用宿主机原有的80和443端口。
paas的配置文件中deployment-host就是域名后缀的内容,先将这里设置好,然后解析泛域名到自己的服务器,就可以正常通过域名前缀和后缀的组合得到完整域名访问服务了。此时证书还是不正确的。
配置证书首先需要去OHTTPS上面申请一个泛域名证书,然后来到rancher的控制台,在seec的命名空间下添加一个新的secret,插入tls.crt(证书内容)和tls.key(证书私钥)两个值之后保存。如果rancher里面不能直接给seec插入,则需要先把seec命名空间加入到default的project的下面。最后在后端的config.yaml中修改secret-name,改成该证书secret的名字即可。
ingress 部署后访问时可能会出现 504Gateway Time-out的错误,是因为两个节点互相不能访问到对方节点上部署的pod。
6 后续维护Q&A
- Q:运行环境时出现镜像架构不正确的问题。A:检查镜像(尤其是build使用的基本镜像)是否是官方镜像,有出现类似
java:8-jre-alpine
的镜像不是官方镜像(可能是阿里的一个什么镜像),manifest书写不规范导致arm64的机器也可以pullamd64版本的镜像,但是后续运行就出现问题了。一定要使用官方镜像,防止出现架构不符的问题导致环境部署失败!