作者简介 王瀚兴,SUSE软件工程师,主要负责Rancher产品线相关的研发工作。 欧拉开源社区的RFOSIG正在努力将openEuler与Rancher整合,以推动社区的云原生版图发展。而openEuler如何在云环境开箱即用是一个非常重要的基础,本篇将主要介绍openEulerAWSAMI镜像制作的详细过程。 通过创建AWSAMI镜像可将openEuler与AWS云服务相结合,支持云环境中标准的sshkey注入、分区扩容、用户数据执行等功能,并使用cloudinit机制实现自动启动RancherRKE2集群。今后,openEulerCloudImages的工作也将成为RFOSIG的一部分,逐步扩展支持更多的云平台。调整硬盘分区大小 openEuler官方提供的qcow2格式的镜像为一个总磁盘大小为40G的虚拟机镜像,在qemu中启动虚拟机,查看分区情况。 可以看到磁盘含有两个分区,其中2G为boot分区,38G为root分区。 使用NetBasedDisk(NBD)将qcow2镜像的分区加载到Linux系统中,之后使用resize2fs压缩ext4文件系统的体积,并使用分区调整工具fdisk调整分区的大小。加载NBD内核模块sudomodprobenbdmaxpart3加载qcow2镜像中的分区至系统sudoqemunbdcdevnbd0openEuler22。03LTSx8664。qcow2lsblkNAMEMAJ:MINRMSIZEROTYPEMOUNTPOINTnbd043:0040G0disknbd0p143:102G0partnbd0p243:2038G0part调整ext4文件系统大小至6Gsudoresize2fsdevnbd0p26G使用fdisk调整分区大小至6Gsudofdiskdevnbd0Welcometofdisk(utillinux2。34)。Changeswillremaininmemoryonly,untilyoudecidetowritethem。Becarefulbeforeusingthewritecommand。Command(mforhelp):dPartitionnumber(1,2,default2):2Partition2hasbeendeleted。Command(mforhelp):nPartitiontypepprimary(1primary,0extended,3free)eextended(containerforlogicalpartitions)Select(defaultp):Usingdefaultresponsep。Partitionnumber(24,default2):2Firstsector(419430483886079,default4194304):Lastsector,sectorsorsize{K,M,G,T,P}(419430483886079,default83886079):6GCreatedanewpartition2oftypeLinuxandofsize6GiB。Partition2containsaext4signature。Doyouwanttoremovethesignature?〔Y〕es〔N〕o:NCommand(mforhelp):wThepartitiontablehasbeenaltered。Callingioctl()torereadpartitiontable。Syncingdisks。从系统中卸载qcow2镜像的分区sudoqemunbdddevnbd0 之后使用qemuimg将qcow2镜像缩小至8G,并转换为RAW格式。qemuimgresizeopenEuler22。03LTSx8664。qcow2shrink8GqemuimgconvertopenEuler22。03LTSx8664。qcow2openEuler22。03LTSx8664。rawSnapshot和BaseAMI的创建 首先使用awscli提供的工具,将RAW镜像上传至AWSS3bucket中。awss3cpopenEuler22。03LTSx8664。raws3:{BUCKETNAME} 创建vmimportpolicy和rolepolicy。catEOFtrustpolicy。json{Version:20121017,Statement:〔{Effect:Allow,Principal:{Service:vmie。amazonaws。com},Action:sts:AssumeRole,Condition:{StringEquals:{sts:Externalid:vmimport}}}〕}EOFawsiamcreaterolerolenamevmimportassumerolepolicydocumentfile:trustpolicy。jsoncatEOFrolepolicy。json{Version:20121017,Statement:〔{Effect:Allow,Action:〔s3:GetBucketLocation,s3:GetObject,s3:ListBucket〕,Resource:〔arn:aws:s3:::{BUCKETNAME},arn:aws:s3:::{BUCKETNAME}〕},{Effect:Allow,Action:〔s3:GetBucketLocation,s3:GetObject,s3:ListBucket,s3:PutObject,s3:GetBucketAcl〕,Resource:〔arn:aws:s3:::{BUCKETNAME},arn:aws:s3:::{BUCKETNAME}〕},{Effect:Allow,Action:〔ec2:ModifySnapshotAttribute,ec2:CopySnapshot,ec2:RegisterImage,ec2:Describe〕,Resource:}〕}EOFawsiamputrolepolicyrolenamevmimportpolicynamevmimportpolicydocumentfile:rolepolicy。json 创建importsnapshot任务,将存储在S3bucket的RAW镜像创建为Snapshot。awsec2importsnapshotdescriptionopenEulerRAWimageimporttaskdiskcontainerFormatRAW,UserBucket{S3Bucket{BUCKETNAME},S3KeyopenEuler22。03LTSx8664。raw} 等待几分钟后,通过importtaskID获取导入成功后的SnapshotID。awsec2describeimportsnapshottasksimporttaskids{IMPORTTASTID} 使用此Snapshot创建不含cloudinit机制的BaseAMI镜像。awsec2registerimagenameDEVopenEuler22。03LTSx8664BASEdescriptionDEVopenEulerimage,donotuseforproduction!rootdevicenamedevxvdaarchitecturex8664enasupportvirtualizationtypehvmblockdevicemappingsDeviceNamedevxvda,Ebs{SnapshotId{SNAPSHOTID}} 至此,我们获得了BaseAMIID。使用Packer创建包含Cloudinit机制的AMI镜像 首先创建Packer的配置文件,注意修改配置文件中的为刚刚获取的BaseAMIID。{variables:{version:{{envOPENEULERVERSION}},build:{{envAWSIMAGEBUILDNUMBER}},arch:{{envOPENEULERARCH}}},builders:〔{type:amazonebs,name:amazonebshvmx8664,region:apnortheast1,amiregions:〔apnortheast1〕,sourceami:BASEAMIID,instancetype:t3a。micro,sshusername:root,sshpassword:openEuler1234;,aminame:openEuler{{userversion}}x8664hvm{{userbuild}},enasupport:true}〕,provisioners:〔{type:shell,environmentvars:〔VERSION{{userversion}},ARCH{{userarch}}〕,script:。installcloudinit。sh}〕} 新建脚本文件installcloudinit。sh,用来执行安装cloudinit和其他配置的指令。!binbashseteyumyupdateyumyinstallcloudinitcloudutilsgrowpartgdiskyumyinstallvimtarmakezipgzipwgetgittmuxconntracktoolssocatiptablesserviceshtopdisableApparmorechoGRUBCMDLINELINUXDEFAULTapparmor0etcdefaultgrubUpdategrubconfigif〔〔(unamem)x8664〕〕;thengrub2mkconfigobootgrub2grub。cfgelif〔〔(unamem)arm64〕〕;thengrub2mkconfigobootefiEFIopenEulergrub。cfgfi 最后使用以下指令使用packer构建AMI镜像。packerbuildPACKERCONFIG。json构建ARM架构的AMI镜像 理论上构建ARM架构的AMI镜像的整体流程与x8664架构的流程几乎一致,但是在实际操作过程中遇到了使用BaseAMI镜像启动服务器后找不到网卡设备而无法ssh连接到服务器的情况。 在使用串口连接到服务器上进行调试后发现,ARM架构的openEuler系统的内核中没有预装AWSENA网卡驱动,所以无法访问网络连接。 后续openEuler会为ARM架构的内核增添ENA驱动支持,在此之前可使用编译ENA驱动内核模块并导入的方式,作为一个临时的解决办法,感兴趣的朋友可以参考一下。 此办法只能作为一个临时的解决方法,不建议用作生产环境中。 首先在本地运行一个用来编译内核模块的openEuleraarch64虚拟机,安装gcc,make,git,vim内核头文件等编译需要的工具,克隆ENA驱动的源码到本地并编译。yumyinstallmakegitgccvimkerneldevel(unamer)gitclonegitclonehttps:github。comamznamzndrivers。gitcdamzndriverskernellinuxenamakej2 编写这篇文章时,在编译的过程中会遇到这个报错:rootamzndriverskernellinuxenaenaethtool。c:1218:19:error:initializationof‘int()(structnetdevice,structethtoolcoalesce,structkernelethtoolcoalesce,structnetlinkextack)’fromincompatiblepointertype‘int()(structnetdevice,structethtoolcoalesce)’〔Werrorincompatiblepointertypes〕1218。getcoalesceenagetcoalesce,compilationterminatedduetoWfatalerrors。 一个比较直接的解决办法是编辑enaethtool。c,在12181221行,为这几个函数指针添加(void)强制的指针类型转换。 编译后会生成ena。ko内核模块文件,可用modinfoena。ko查看该模块的信息。modinfoena。kofilename:rootamzndriverskernellinuxenaena。koversion:2。8。0glicense:GPLdescription:ElasticNetworkAdapter(ENA)author:Amazon。com,Inc。oritsaffiliates。。。。。。 在调整硬盘分区时,挂载分区,复制此内核模块文件到挂载的分区的目录中并编辑modprobe配置文件,在每次开机启动时都加载这个内核模块。假设将分区挂载到了mnt目录下面sudomountdevnbd0p2mnt这里将内核模块复制到了root目录下面sudocp。ena。komntrootsudobashcechoinstallenainsmodrootena。komntetcmodprobe。dena。confsudobashcechoenamntetcmodulesload。dena。confsudosyncsudoumountmnt 重启系统后,可以使用lsmod查看已加载的内核模块,或使用dmesg查看内核日志,可以看到ENA驱动被加载的记录。sudolsmodModuleSizeUsedbyena1474560。。。。。。dmesggrepena:〔94。814488〕ena:loadingoutoftreemoduletaintskernel。〔94。814896〕ena:moduleverificationfailed:signatureandorrequiredkeymissingtaintingkernel 目前openEuler社区已修复了ARM架构的内核不包含ENA网卡驱动的问题,会在后续的内核更新中获取到包含ENA驱动的内核。更多信息可在此PR中获取到:https:gitee。comopeneulerkernelpulls104已构建的AMI镜像使用 在AWSEC2实例的控制台页面,使用构建的AMI镜像创建一个EC2虚拟机,设定网络安全组、SSH密钥、磁盘大小、用户数据等配置。 在本篇文章中,设定的EBS磁盘大小为30G,在用户数据中填写了安装RKE2的脚本:!binbashechoStartcustomuserdatayumupdatecurlsfLhttps:get。rke2。ioinstall。shchmodx。install。shsudoINSTALLRKE2METHODtar。install。shsudosystemctlenablerke2serversudosystemctlstartrke2serverechoUserdatafinishedsuccessfully 实例启动后,cloudinit机制会自动创建用户名为openeuler的账号并设定仅使用sshkey登录,同时root账号的ssh登录也会被禁止。磁盘的root分区会自动扩容到我们设定的EBS磁盘大小,用户数据中填写的脚本也将被自动执行。 查看cloudinit输出的日志,其中包括用户数据的执行结果:tailfvarlogcloudinitoutput。logIsthisok〔yN〕:Operationaborted。〔INFO〕findingreleaseforchannelstable〔INFO〕usingv1。24。4rke2r1asrelease〔INFO〕downloadingchecksumsathttps:github。comrancherrke2releasesdownloadv1。24。4rke2r1sha256sumamd64。txt〔INFO〕downloadingtarballathttps:github。comrancherrke2releasesdownloadv1。24。4rke2r1rke2。linuxamd64。tar。gz〔INFO〕verifyingtarball〔INFO〕unpackingtarballfiletousrlocalCreatedsymlinketcsystemdsystemmultiuser。target。wantsrke2server。serviceusrlocallibsystemdsystemrke2server。service。UserdatafinishedsuccessfullyCloudinitv。21。4finishedatWed,21Sep202206:56:300000。DatasourceDataSourceEc2Local。Up130。47seconds 验证分区自动扩容至总容量为设定的EBS的大小:lsblkNAMEMAJ:MINRMSIZEROTYPEMOUNTPOINTSnvme0n1259:0030G0disknvme0n1p1259:102G0partbootnvme0n1p2259:2028G0part 验证RKE2安装成功,所有pods均正常启动:sudovarlibrancherrke2binkubectlkubeconfigetcrancherrke2rke2。yamlgetnodesNAMESTATUSROLESAGEVERSIONip1723121213。apnortheast1。compute。internalReadycontrolplane,etcd,master7m58sv1。24。4rke2r1sudovarlibrancherrke2binkubectlkubeconfigetcrancherrke2rke2。yamlgetpodsANAMESPACENAMEREADYSTATUSRESTARTSAGEkubesystemcloudcontrollermanagerip1723121213。apnortheast1。compute。internal11Running014mkubesystemetcdip1723121213。apnortheast1。compute。internal11Running014mkubesystemhelminstallrke2canall5rnl01Completed014mkubesystemhelminstallrke2corednsjckq701Completed014mkubesystemhelminstallrke2ingressnginxdxcsc01Completed014mkubesystemhelminstallrke2metricsserverkgjdf01Completed014mkubesystemkubeapiserverip1723121213。apnortheast1。compute。internal11Running014mkubesystemkubecontrollermanagerip1723121213。apnortheast1。compute。internal11Running014mkubesystemkubeproxyip1723121213。apnortheast1。compute。internal11Running014mkubesystemkubeschedulerip1723121213。apnortheast1。compute。internal11Running014mkubesystemrke2canalng2sw22Running013mkubesystemrke2corednsrke2coredns76cb76d66nklrw11Running013mkubesystemrke2corednsrke2corednsautoscaler58867f8fc5mpgd711Running013mkubesystemrke2ingressnginxcontrollerfhpbd11Running012mkubesystemrke2metricsserver6979d95f952lrp811Running013m AboutSUSERancher Rancher是一个开源的企业级Kubernetes管理平台,实现了Kubernetes集群在混合云本地数据中心的集中部署与管理。Rancher一向因操作体验的直观、极简备受用户青睐,被Forrester评为2020年多云容器开发平台领导厂商以及2018年全球容器管理平台领导厂商,被Gartner评为2017年全球最酷的云基础设施供应商。 目前Rancher在全球拥有超过三亿的核心镜像下载量,并拥有包括中国联通、中国平安、中国人寿、上汽集团、三星、施耐德电气、西门子、育碧游戏、LINE、WWK保险集团、澳电讯公司、德国铁路、厦门航空、新东方等全球著名企业在内的共40000家企业客户。 2020年12月,SUSE完成收购RancherLabs,Rancher成为了SUSE创新无处不在(InnovateEverywhere)企业愿景的关键组成部分。SUSE和Rancher共同为客户提供了无与伦比的自由和所向披靡的创新能力,通过混合云IT基础架构、云原生转型和IT运维解决方案,简化、现代化并加速企业数字化转型,推动创新无处不在。 当前,SUSE及Rancher在中国大陆及港澳台地区的业务,均由数硕软件(北京)有限公司承载。SUSE在国内拥有优秀的研发团队、技术支持团队和销售团队,将结合Rancher领先的云原生技术,为中国的企业客户提供更加及时和可信赖的技术支撑及服务保障。