32

DockOne微信分享(二二 九):蔚来汽车的Kubernetes实践

 4 years ago
source link: https://www.tuicool.com/articles/uqueeuR
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【编者的话】Kubernetes已经成为当下最火热的一门技术,未来一定也会有更好的发展,围绕着云原生的周边产物也越来越多,使得上云更加便利更加有意义,本文主要讲解一些蔚来汽车从传统应用落地到Kubernetes集群的一些实践经验,提供给大家在落地之前的一些思考和注意点,并且让大家在实施的时候能够有一些借鉴,提供一些使用过程中的注意事项。

项目背景

Docker诞生于2013年初,随着时间的推移Docker项目也逐渐火热起来,也形成了自己的生态,为了能够灵活调度容器,编排技术也变得非常重要,Swarm,Mesos,Kubernetes属于比较出众的容器编排技术,然而不得不说Kubernetes绝对是当下最火热的技术。Kubernetes项目的基础特性,并不是几个工程师突然“拍脑袋”想出来的东西,而是Google公司在容器化基础设施领域多年来实践经验的沉淀与升华,容器编排使得容器本身也有了生命,几乎所有大公司都在使用Kubernetes,另外云原生周边也发展的越来越好,这使得Kubernetes的功能越来越强大。

我们从2017年开始调研Kubernetes,2018年开始小规模使用,当时使用的是1.9版本,现在用的是1.11版本,最新已经到了1.16,可谓版本更新之快,未来会考虑再升级到最新版本。

Kubernetes给我们带来的一些好处:

  • 解决资源利用率低的问题,原来是按照服务去单独分配机器,资源得不到充分利用
  • 服务的资源管理、依赖管理等比较复杂,Docker的镜像管理充分简化了相关工作,使得DevOps理念能够深入实施
  • 降低了服务扩容的复杂性
  • 横向扩展功能也使得服务在应对大流量场景更加灵活
  • 不再需要专门地写脚本去监控服务的健康状态
  • 未来结合云原生中的Service Mesh使服务之间的调用更加灵活,功能更加强大

集群建设落地

建设落地前的思考

在落地之前我们对以下一些点做了相应的考量,做好提前的选型及测试。

  • 部署方式的选择,在EKS、kops、kubeadm、Minikube、binary中我们选择了binary的安装方式,选择二进制的安装方式是比较灵活的,
  • Kubernetes版本选型:1.11.7,这个版本也是当时官方提供的最新版本。
  • 网络插件的选型:Flannel,Flannel官方说明会有一定的网络性能损耗,但在我们使用的公有云上可以忽略这一点。随着业务量增加及安全隔离需求,后续会考虑改用Calico,因为发现业务多了的话网络隔离还是很有必要的,另外Canal插件其实也是跟Flannel结合实现网络策略,但是官方对这个项目的维护貌似已经不活跃就不太考虑了。
  • Service实现的选型:IPVS,早期的Service都是iptables实现的,所以早期我们就用的iptables,但是当集群节点数量到达几千台的话iptables性能应该会有很大的衰减,于是在我们升级到1.11版本后果断使用IPVS的方式实现Service。
  • 周边工具选型:Harbor、Rancher、Prometheus、CoreDNS,以上这几款工具都是云原生周边产物,热度都很高,也能够快速简单的支撑业务。
  • 集群优化的考虑:网络MTU、内核版本、网段优化、swap优化等,在集群落地之前要把一些优化点提前考虑好,内核我们用的是4.18,当时的一个最新版本,高版本支持了cgroup2,隔离性应该会比cgroup1更加稳定。
  • 日志方案的考虑:ELK,ELK一直是我们日志方案解决的工具,所以服务上云之后我们依然沿用,其中Filebeat是以DaemonSet模式运行,性能消耗目前来看还是可以接受的。
  • 监控方案的考虑:Prometheus,随着容器技术的迅速发展,Kubernetes已然成为大家追捧的容器集群管理系统。Prometheus作为生态圈CNCF中的重要一员,其活跃度仅次于Kubernetes,现已广泛用于Kubernetes集群的监控系统中,毋庸置疑监控方面的选型非Prometheus莫属。
  • CI/CD的方案:自研的运维平台,相信各个公司都有自己的运维平台,我们的CI/CD也是与我们自己的平台结合,有着一套完善的规范和流程,如果规模不大也可以考虑和Rancher的CI/CD结合,感觉也不错。
  • Namespace的划分考虑,Namespace的划分也比较重要,涉及到业务的隔离与划分,通常要考虑到不同Namespace之间服务的调用问题,内部域名调用问题,安全划分问题,机器分配使用问题等等。

Kubernetes数据备份恢复

其实Kubernetes的数据也就是etcd中的数据,那么我们日常就需要备份etcd中的数据,以及考虑数据的恢复,理论上etcd的数据恢复场景应该很难用到,一切操作尽量都通过平台规范化使用,但是针对灾难性的场景就可以用etcd数据备份来救场了。

这里给大家展示下etcd备份和恢复,具体细节大家根据自己环境再调整。

etcd数据备份

#!/bin/sh



source /etc/profile

nowtime=`date +%Y%m%d%H%M`

# 备份的数据目录

workdir="/data/etcd-bak"

# etcd的数据目录

datadir="/data/etcd"

ep=`/sbin/ip addr|grep eth0|sed -nr 's#^.*inet (.*)/22.*$#\1#gp'`

capath="/etc/kubernetes/ssl/ca.pem"

certpath="/etc/etcd/ssl/etcd.pem"

keypath="/etc/etcd/ssl/etcd-key.pem"

etcdctlpath="--endpoints "https://${ep}:2379" --cacert=$capath --cert=$certpath --key=$keypath"

hostname=`hostname`

alertcontent="$hostname-etcd-bak-is-false-please-check-etcd-${nowtime}"

# 备份数据保留天数

delday=7

s3path="s3://etcd/etcd-${ep}"

s3alertcontent="$hostname-etcd-snapshot-to-s3-false-please-check"

etcdctlcmd=`whereis etcdctl|awk '{print $NF}'`





function deloldbak () {

find $workdir -name "etcd-*.gz" -mtime +${delday}|xargs rm -f

}



if [ ! -f /data/etcd-bak/etcd-${nowtime}.tar.gz ];then

mkdir -p /data/etcd-bak/etcd-${nowtime}/

else

echo "need wait to next time"

echo "need wait to next time" >>$workdir/etcd-bak.log

exit 1

fi



echo "===================================  begin $nowtime =================================="

echo "===================================  begin $nowtime ==================================" >>$workdir/etcd-bak.log

export ETCDCTL_API=3

echo "===================================  run snapshoting =================================" >>$workdir/etcd-bak.log

$etcdctlcmd $etcdctlpath  snapshot save $workdir/etcd-${nowtime}/snap-${nowtime}.db >>$workdir/etcd-bak.log

echo "===================================  run snapshoting =================================" >>$workdir/etcd-bak.log

if [ $? -eq 0 ]

then

    echo "etcd snapshot etcd-${nowtime}/snap-${nowtime}.db is successful"

    echo "etcd snapshot etcd-${nowtime}/snap-${nowtime}.db is successful" >>$workdir/etcd-bak.log

else

    echo "etcd snapshot etcd-${nowtime}/snap-${nowtime}.db is failed"

    echo "etcd snapshot etcd-${nowtime}/snap-${nowtime}.db is failed" >>$workdir/etcd-bak.log

fi



cp -fr $datadir/* $workdir/etcd-${nowtime}/

if [ $? -eq 0 ]

then

    echo "etcd snapshot etcd-${nowtime}/member is successful"

    echo "etcd snapshot etcd-${nowtime}/member is successful" >>$workdir/etcd-bak.log

else

    echo "etcd snapshot etcd-${nowtime}/member is failed"

    echo "etcd snapshot etcd-${nowtime}/member is failed" >>$workdir/etcd-bak.log

fi





$etcdctlcmd $etcdctlpath --write-out=table endpoint status

$etcdctlcmd $etcdctlpath --write-out=table endpoint status >>$workdir/etcd-bak.log



cd $workdir

tar zcf ./etcd-${nowtime}.tar.gz etcd-${nowtime}

rm -fr etcd-${nowtime}

aws s3 cp $workdir/etcd-${nowtime}.tar.gz $s3path/

if [ $? -eq 0 ]

then

    echo "etcd snapshot s3 is successful"

    echo "etcd snapshot s3 is successful" >>$workdir/etcd-bak.log

else

    echo "etcd snapshot s3 is failed"

    echo "etcd snapshot s3 is failed" >>$workdir/etcd-bak.log

fi

deloldbak





echo "===================================  end `date +%Y%m%d%H%M%S` =================================="

echo "===================================  end `date +%Y%m%d%H%M%S` ==================================" >>$workdir/etcd-bak.log

etcd数据恢复

#!/bin/bash



# 使用etcdctl snapshot restore生成各个节点的数据



# 比较关键的变量是

# --data-dir 需要是实际etcd运行时的数据目录

# --name  --initial-advertise-peer-urls  需要用各个节点的配置

# --initial-cluster  initial-cluster-token 需要和原集群一致

# 注意http和https区别



# 无需更改

workdir=/root



# etcd1,2,3为节点名称 ETCD1,2,3为对应节点ip

ETCD_1=1.1.1.1

ETCD_2=2.2.2.2

ETCD_3=3.3.3.3

etcd1=etcd1

etcd2=etcd2

etcd3=etcd3



# 同上面一样需要对应设置

arra=(1.1.1.1 2.2.2.2 3.3.3.3)

arrb=(etcd1 etcd2 etcd3)



# etcd是否使用https tls加密如果使用需要配置证书,若是http请置空此变量

etcdkey="--cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem"

# 恢复数据存放目录,只是用于恢复存放数据,可以随意设置,跟原有的路径没有关系

etcddatapath="/root/etcd-recover-data/etcd"

# 备份数据根路径

bakdatapath="/data/etcd-bak"

# 备份数据完整路径

bakdbpath="$bakdatapath/etcd-201906161945/snap-201906161945.db"

# ansible site执行路径

ansiblepath="/root/etcd-bak-ansible"



function ansibleoperate ()

{

rm -fr $ansiblepath/roles/etcd-bak-ansible/files/*

cp -fr $(echo $etcddatapath|awk -F "[/]" '{print "/"$2"/"$3}')/* $ansiblepath/roles/etcd-bak-ansible/files/

cd $ansiblepath

ansible-playbook -i hosts site.yaml

}



if [ ! -d $(echo $etcddatapath|awk -F "[/]" '{print "/"$2"/"$3}') ];then

mkdir -p $(echo $etcddatapath|awk -F "[/]" '{print "/"$2"/"$3}')

fi



for i in ${arra[@]}

do

echo -e "\t$i\c" >>$workdir/etcdiplist.log

#echo -e "$i"

done





for i in ${arrb[@]}

do

echo -e "\t$i\c" >>$workdir/etcdnamelist.log

#echo -e "$i"

done



while true

do

let cnt++

etcdiplist=`awk -v column=$cnt '{print $column}' $workdir/etcdiplist.log`

etcdnamelist=`awk -v column=$cnt '{print $column}' $workdir/etcdnamelist.log`



if [ "$etcdiplist" = "" ]

    then

        echo "conf is down will to break"

        break

fi

echo $etcdiplist $etcdnamelist

export ETCDCTL_API=3

# 如果用原有member中的db恢复,由于不存在完整的hash性,需要在下面添加 --skip-hash-check \ 跳过hash检查

etcdctl snapshot $etcdkey  restore $bakdbpath  \

--data-dir=$etcddatapath \

--name $etcdnamelist \

--initial-cluster ${etcd1}=https://${ETCD_1}:2380,${etcd2}=https://${ETCD_2}:2380,${etcd3}=https://${ETCD_3}:2380 \

--initial-cluster-token etcd-cluster-0 \

--initial-advertise-peer-urls https://$etcdiplist:2380 && \

mv $etcddatapath $(echo $etcddatapath|awk -F "[/]" '{print "/"$2"/"$3}')/etcd_$etcdiplist



echo "--initial-cluster ${etcd1}=https://${ETCD_1}:2380,${etcd2}=https://${ETCD_2}:2380,${etcd3}=https://${ETCD_3}:2380 "





done



rm -f $workdir/etcdiplist.log

rm -f $workdir/etcdnamelist.log



#如果不需要Ansible自动恢复集群,需要手动恢复的话请注释以下操作

ansibleoperate

镜像管理

镜像仓库我们选择的是Harbor,比较成熟并且社区维护更新也非常快。我们最早使用1.2版本,现在使用1.6版本。目前Harbor最新是1.8版本,下面给大家展示下新旧版本功能上的差异,新版本还是有很多好功能的。

1.2版本和1.6版本功能对比

2eAZz2z.png!web

升级后具备的优势

  • 存储支持S3:镜像从保存在本地改为存储到S3,这样可以节省存储费用,也不用考虑本地磁盘扩容的事情。
  • 登录接入LDAP:规范管理用户,并且可以使用LDAP的组进行用户的划分。
  • 用户限制,用户分组:这块主要是结合LDAP组进行划分,在Harbor中建好各个对应的项目,配置开发权限。
  • 漏洞扫描:每天定时扫描镜像,不过想保证所有镜像都不存在危险貌似不太容易,开发自定义等不规范镜像会经常出现。
  • 镜像签名:安全度高的镜像会考虑开启该功能。
  • 高可用负载:官方提供了HA的功能,主要就是访问的HA,数据库的HA,存储的HA。
  • 证书认证:访问通过https,更加安全。
  • 数据库更加简单:原来是有MySQL、PostgreSQL,现在新版本全部统一使用PostgreSQL,管理更加方便。

线上镜像仓库架构图

yYBz6rV.png!web

上面是我们的架构图,通过DNS解析将不同环境的访问分流到对应环境的镜像仓库,所有的镜像仓库都连接着后端数据库集群,镜像统一保存到了S3中,对于仓库的扩容也是十分方便的,拷贝一份配置启动就可以了。

镜像仓库升级

备份之前先停止老的Harbor:

cd harbor

docker-compose down

备份原来的Harbor目录:

mv harbor /my_backup_dir/harbor

备份数据库:

cp -r /data/database /my_backup_dir/

后续升级镜像下载:

docker pull goharbor/harbor-migrator:[tag]

升级harbor.cfg或者harbor.yml文件:

docker run -it --rm -v ${harbor_cfg}:/harbor-migration/harbor-cfg/harbor.cfg -v ${harbor_yml}:/harbor-migration/harbor-cfg-out/harbor.yml goharbor/harbor-migrator:[tag] --cfg up

如果没有yaml文件,低版本理论上只有cfg文件,那就升级cfg文件就可以了:

docker run -it --rm -v ${harbor_cfg}:/harbor-migration/harbor-cfg/harbor.cfg goharbor/harbor-migrator:[tag] --cfg up

解压新的版本离线包:

tar -zxvf harbor-offline-installer-v1.7.4.tgz

覆盖harbor.cfg,把之前升级的harbor.cfg文件或者yml文件拷贝到新版本解压的目录里替换相应的文件:

cd harbor

mv harbor.cfg harbor.bak

cp /root/harbor-bak/harbor.cfg .

安装Notary,Clair和Helm Chart服务,安装之前可以perpare脚本生成下配置文件:

./install.sh --with-notary --with-clair --with-chartmuseum

进行查看:

docker-compose -f ./docker-compose.yml -f ./docker-compose.clair.yml ps

清除旧版本镜像:

docker images|grep 1.6.2| awk '{print $3}'|xargs docker rmi

日志方案落地

日志落盘, DaemonSet部署Filebeat,采集进Kafka,最终进ES,落盘日志定期清理。

ymYZ3mF.jpg!web

jM77nq2.png!web

这个是基于Node级别的一种日志收集方案,我们大多使用这种方案进行日志的收集,优点就是可以和服务完全解耦,性能好,便于管理。

这种方式的一个弊端就是日志格式必须按照约定的方式配置输出,对不能满足约定格式的情况改用sidecar的方式进行日志的收集。

67FJ3ab.png!web

这种方式就是扩展性强,配置可以跟随服务进行制定的收集,弊端就是会浪费资源,并且有一定耦合性,所以我们线上并未大面积采取这个方式的使用。

监控方案落地

Prometheus想必在大家的公司中都已经在使用了,是监控领域里现在最火热的一款监控工具,在这里也不多赘述了,基本的使用大家应该都比较了解,下面主要简单展示下我们线上对于服务应用是如何上报监控,配置也并不复杂,大家看图解读。

Service里面增加配置:

prometheus.io/scrape: "true" 

是否监控就看是否在Service中开启了这个开关。

以下是Prometheus配置过滤规则:

6JvUj2z.jpg!web

qaUreyV.jpg!web

nI3y22B.jpg!web

后续工作

  • Service Mesh使用:Istio调研及使用(灰度、限流、链路跟踪、熔断、降级)
  • LXCFS解决容器CPU、内存资源可见性问题
  • 有状态应用部署至Kubernetes:ES、Kafka等
  • CRD在prometheus-operator的应用

Q&A

Q:请问Kubernetes数据备份与恢复,这个是包括kubectl-proxy,etcd,网络配置等吗?如何进行多集群下的数据备份?

A:备份的其实就是etcd中的数据,我们网络是用的Flannel,一些关键网段信息也是存在etcd中的,对于多集群来看的话,还是要针对数据存放对应的etcd集群数据去进行备份。

Q:请问一下业务日志太多,一天一个节点的业务日志有200G,怎么做日志收集及监控告警:

A:一天一个节点200G的话,这个要看你们集群节点多不多,我们上百个节点,一个节点的量大概在100G左右,线上日志量都是几十T的数据,用我分享的方案去落地应该是没问题的,ELK的整体性能还是非常不错的,Filebeat现在最高的性能分配是占用500M CPU,1G内存,收集起来也是能应对的,这个根据你的量再调整,监控的话肯定就用Prometheus就好,官方都是有自动发现的配置,很便利,当然如果你要对日志进行分析,这块就比较复杂了,可以通过ES接口去聚合数据,当然日志的字段也要规范好。

Q:生产环境Kubernetes采用二进制方式搭建还是kubeadm ,还是其他方案?

A:线上采用的是二进制的方法,因为我们上Kubernetes的时候kubeadm还是测试版本,当然现在高版本的kubeadm应该已经是正式版本,但是觉得还是二进制更方便一些,你改配置,以及自定义一些参数会方便一些。

Q:生产环境Kubernetes都用哪种网络模式?

A:我们用的是Flannel,不过后续会考虑打算换成Calico,现在发现线上有一定网络限制的需求,Calico的性能相对也会更好,但是维护的复杂度比较高,在集群节点多的情况下,要添加路由反射器,这个比较关键,而且网络选型前一定对未来的规模有个规划,规划好使用的网段。

Q:请问生产环境中etcd的数据需要备份吗?怎么备份?还有二进制安装etcd集群由3个节点增加到5个节点,需要重新生etcd证书后再重启etcd服务吗?增加节点重启策略是一个一个节点依次重启吗?

A:建议备份,其实主要用到的就是etcd的snapshot功能,不复杂,看下我分享的脚本即可,添加节点用你现有的证书就好,官方的方法是要一台一台执行的,线上etcd节点我做过测试,即使操作失误都down掉的话也不会影响你现有服务的运行,而且保证法定节点的存在就更好。

Q:你分享的Prometheus是Operator方式吗?你的监控数据是有经过二次开发后作为标准格式输出吗?对于Nginx和Java监控如何实现呀?

A:Prometheus没有用Operator的方式,是用的官方的yaml文件创建的,我们线上Java服务居多,都是通过Spring官方的Prometheus插件就可以自定义监控数据,Nginx的话我们还真的不多,这个估计你要用相应的exporter就好,监控数据是开发自定义上传的,我们没有做限制。

Q:Pod挂掉之后如何保留现场,比如做内存Dump有什么好的方案没?

A:我们这边是这样,对于健康检查没有添加Liveness的检查,也是防止容器的重启,尤其是在第一次项目上线,难免无法正常启动,如果加了Liveness就会一直重启,不太方便查问题,所以只加了Readiness,只是保证不影响线上访问,对于生产中,Java项目遇到最多的就是OOM问题,这个我们也对Pod重启的原因加了报警,至于Dump我们还没这方面的操作,需要开发自行检查了。

Q:传统系统架构如何改造成Kubernetes架构?

A:这个问题有点宽泛呢,还是得看您这边实际的场景,我觉得更多的也是得需要开发一起配合的,尽量保证服务模块都能够做到微服务话,不要耦合的太紧,您可以先搭建一个测试集群,然后从开发那边找一个模块进行Docker化的转换,然后一点一点再去试吧。

Q:是否有Ingress tcp/udp应用的生产级网络方案?

A:我们没有用Ingress,我们的用法也算是一种比较简单的用法,我们是把网关直接加入到Kubernetes集群中,这样网关就可以调用到Kubernetes的Service,因为我们以网关为中心,做了一些安全及认证功能,所以之前的网关必须要用到,而且加了Ingress相当于多加了一层性能消耗,所以也没有用,最后我们把之前部署在虚拟机上的网关也变成Docker化去部署到集群内部。

Q:传统数据库负载过高时查询缓慢,但是会有结果,Kubernetes架构数据库负载过高直接Pod重启,导致没有结果返回,请问应该如何处理的?

A:我们集群还没有跑数据库这种有状态的服务,但是听您描述,还是得看看Pod重启的具体原因,如果Pod都重启了,理论上跑在机器上一定也会有问题,还是在上云之前做好充分的性能压测,并且您可以考虑取消Liveness的健康检查,只保留Readness访问的检查。

Q:采集日志过程中,fluentd或fluent bit通过读取Node节点docker log目录采集日志,该目录包含了所有服务的日志。请问如何在output阶段中根据Namespace和container_name创建Elasticsearch的index,并作为index的命名前缀?

A:首先不建议通过Docker目录的方式采集,日志还是落盘到具体路径为好,因为我也碰到过您这个困惑,因为Docker的目录都是软链接,而且当Docker重启后路径会改变,当然我们线上用的是Filebeat采集,不知道Fluentd能不能解决这个问题,由于是软链接,很难用相对路径,必须用绝对路径采集到真正存放的那个目录日志,我们对于es index名称的创建是通过日志提供的一个index名称字段去匹配的,索引名称会引用这个变量进行区分不同的index。

Q:fileneat node模式采集,多个相同Pod在同一节点情况下,如何映射日志目录而不互相干扰,另外如何配置Filebeat做到Pod变动时的采集?

A:您这个情况我们也遇到过,多个Pod跑在同一个节点确实存在这个问题,因为你的deploy yaml是定死的,很难处理这种情况,我们的解决方法是添加Pod的亲和性,保证每个节点都尽量只跑一个Pod,当然如果节点非常小的情况下,这种做法有一定问题,以生产使用上来看,我们最初多个Pod跑在一个节点同时写一个文件的话也是还可接受。

Q:持续集成系统具体的细节可以透露下吗?基于GitLab CI还是Jenkins?或者小公司可以直接用Spinnaker这些吗?

A:CI/CD的话因为我们有自己现有的发布平台,背后的原理实际上还是调用Jenkins去处理。

Q:日志收集的sidectar模式具体是咋部署的。Filebeat和应用部署在一个Pod里吗?

A:对的,部署在一个Pod里,相当于你的deploy yaml里会有两个image配置,一个是你的服务,另一个是Filebeat,具体的配置看下我的截图,把这部分配置放到你的服务配置后面即可,但是就像我分享说的,这种方式可能会比较消耗资源,但是确实自定义比较方便,但也增加了yaml配置。

Q:我司测试环境搭建的Harbor版本是1.5,使用docker-compose来按照Harbor各个组件的依赖顺序来启动的,但是当系统或者Docker重启后,Harbor的容器就无法按照依赖顺序来启动,经常会有容器启动失败。请问下这个该如何优化呢?

A:其实你需要在Docker中注意一个参数,live-restore : true,这个参数很有用,你可能没有添加,这个参数能保证在你维护重启Docker的时候,还能保证不影响正在运行的Docker容器,另外你可以对Harbor进行监控,如果down了的话大不了做个自动重启的操作也不妨大碍。

Q:(1)Kubernetes平台上线前有什么测试,如何测试?可以上线的依据?(2)常见互联网架构的业务,需要改造才可以在Kubernetes跑吗,需要如何改造?有什么坑?(3)你们多个业务线都共用同一套Kubernetes?如何实现不会因为一个业务的高峰影响其他业务?(4)有什么方案可以实现最大限度的不丢日志?

A:1. 因为我不是测试,对于测试这块可能干涉的不是很多,对于运维来讲可能更多的是比较关注上线之前的压力测试,这块会跟后续的稳定性有很大关系;2. 常见的架构业务理论上改造应该不需要很大,最主要的是解决Docker镜像化,遇到的坑可能更多的是对于Dockerfile打镜像理解的不好,导致一些启动问题以及配置的丢失等等;3. 我们是通过Namespace区分业务线,需要提前规划好业务,指定的业务线只跑在对应的机器上比较关键;4. 我使用的ELK过程中还真的很少遇到过丢日志,只要你架构足够健壮应该是没什么问题的,另外ELK中一定要用消息队列,降低你消息传递的压力,保证每个组件都不要出现性能瓶颈,如果实在怕丢日志,可以让Logstash在消费的时候把消息落盘,ES也要合理配置好刷新的频率以及内存多大落盘等参数,提前做好各个组件的压测是保障。

Q:你好,我是蔚来ES8车主,很高兴看到蔚来的分享。我想了解下你们存储的方案,之前听说是用的Portworx,具体方案可以透露一下么?你们这个team在北京还是上海? 用AWS的话有没有考虑直接使用AWS的Kubernetes服务?ES也运行在Kubernetes里吗?

A:您好,我们team在北京,因为我们的集群还未上有状态服务,所以暂时还未考虑分布式存储的问题,这块确实是很重要的一个环节,我们线上的服务基本也是通过S3去存储一些数据使用,Portworx这个好像也出了很久了,当时在还没有Kubernetes的时候调研过,不过想大面积使用貌似是要花钱用商业版,建议还是用现在比较流行的Ceph可能会更好一些吧,我们还未用到AWS自己的Kubernetes服务,ES有运行在Kubernetes里的业务,但是不是通过Operator部署,后端数据也没用到分布式存储,由于量不大,只是落在本地了,后期会进一步调研Ceph以支持后期的有状态服务的迁移。

Q:请问是否考虑过fluent-bit ,目前Filebeat有没有性能上的问题呢?

A:因为在虚拟机的时候我们就用的Filebeat,就沿用下去了,Filebeat暂时还未发现性能问题,可以直接使用,总日志量我们应该有几十T的样子,在生产使用的过程中感觉Filebeat还是比较靠谱的。

Q:Kubernetes一年的证书问题,你们怎么解决的呢?

A:Kubernetes的证书我们的时间都设置的是十年,kubelet可能是一年,这个我们最初疏忽了,碰到过一次,最终通过删除现有的配置,让kubelet重启自动生成,当然如果您是最初规划的话,可以加上证书自动到期认证的功能,据了解好像现在高版本的Kubernetes已经不存在这个问题,我还没了解的那么多,您可以再查查。

Q:Kubernetes生产环境上的安全相关的配置有哪些呢?

A:安全的话这个比较宽泛啊,这个还是要从各个方面完善,首先起码要保证流量流入方向的各个环节的安全限制,以及服务接口调用上的安全认证,以及开发人员使用时候的权限控制等等。

Q:Prometheus自定义监控具体怎么搞得,比如想要监控容器的端口连接数?

A:容器端口的连接数监控确实还未添加,在原来宿主机的时候是有的,这块有些忽略了,加的话也不是很费劲,可以通过你们自己自定义的exporter去监控。

Q:落盘的日志怎么定期清理?

A:落盘的日志通过写好的清理任务进行清理,因为我们的日志都是规范的落到统一的目录,并且目录名称也是很规范的,所以清理起来很方便,写个简单的脚本就可以啦,定时清理就OK。

Q:Kubernetes里Java服务,你们是怎么做资源限制的?

A:我们是在yaml注入了能获取设置资源的env参数,然后在CI打镜像的时候统一规范了服务启动的start脚本,JVM里配置的是Kubernetes配置的资源,所以Java服务的使用也不会超过我们分配资源的使用。

以上内容根据2019年10月10日晚微信群分享内容整理。 分享人 朱嘉骏,蔚来汽车运维工程师,负责Kubernetes的推广及应用维护,推进企业从传统应用迁移到Kubernetes,解决运维基础建设与云结合中遇到的问题 。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiese,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK