RFO SIG之openEuler AWS AMI 制作詳解
正文
本篇將主要介紹 openEuler AWS AMI 鏡像制作的詳細過程。
通過創(chuàng)建 AWS AMI 鏡像可將 openEuler 與 AWS 云服務(wù)相結(jié)合,支持云環(huán)境中標準的 ssh key注入、分區(qū)擴容、用戶數(shù)據(jù)執(zhí)行等功能,并使用 cloud-init 機制實現(xiàn)自動啟動 Rancher RKE2 集群。今后,openEuler Cloud Images 的工作也將成為 RFO SIG 的一部分,逐步擴展支持更多的云平臺。
調(diào)整硬盤分區(qū)大小
openEuler 官方提供的 qcow2 格式的鏡像為一個總磁盤大小為 40G 的虛擬機鏡像,在 qemu 中啟動虛擬機,查看分區(qū)情況。
可以看到磁盤含有兩個分區(qū),其中 2G 為 boot 分區(qū),38G 為 root 分區(qū)。
使用 Net Based Disk (NBD) 將 qcow2 鏡像的分區(qū)加載到 Linux 系統(tǒng)中,之后使用 resize2fs 壓縮 ext4 文件系統(tǒng)的體積,并使用分區(qū)調(diào)整工具 fdisk 調(diào)整分區(qū)的大小。
# 加載 NBD 內(nèi)核模塊 $ sudo modprobe nbd max_part=3 # 加載 qcow2 鏡像中的分區(qū)至系統(tǒng) sudo qemu-nbd -c "/dev/nbd0" "openEuler-22.03-LTS-x86_64.qcow2" $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT nbd0 43:0 0 40G 0 disk |-nbd0p1 43:1 0 2G 0 part |-nbd0p2 43:2 0 38G 0 part # 調(diào)整 ext4 文件系統(tǒng)大小至6G $ sudo resize2fs /dev/nbd0p2 6G # 使用fdisk調(diào)整分區(qū)大小至6G $ sudo fdisk /dev/nbd0 Welcome to fdisk (util-linux 2.34). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help): d Partition number (1,2, default 2): 2 Partition 2 has been deleted. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (2-4, default 2): 2 First sector (4194304-83886079, default 4194304): Last sector, +/-sectors or +/-size{K,M,G,T,P} (4194304-83886079, default 83886079): +6G Created a new partition 2 of type 'Linux' and of size 6 GiB. Partition 2 contains a ext4 signature. Do you want to remove the signature? [Y]es/[N]o: N Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks. # 從系統(tǒng)中卸載 qcow2 鏡像的分區(qū) $ sudo qemu-nbd -d /dev/nbd0
之后使用 qemu-img 將 qcow2 鏡像縮小至8G,并轉(zhuǎn)換為 RAW 格式。
$ qemu-img resize openEuler-22.03-LTS-x86_64.qcow2 --shrink 8G $ qemu-img convert openEuler-22.03-LTS-x86_64.qcow2 openEuler-22.03-LTS-x86_64.raw
Snapshot 和 Base AMI 的創(chuàng)建
首先使用 awscli 提供的工具,將 RAW 鏡像上傳至 AWS S3 bucket 中。
$ aws s3 cp openEuler-22.03-LTS-x86_64.raw s3://${BUCKET_NAME}/
創(chuàng)建 vmimport policy 和 role policy。
$ cat << EOF > trust-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "vmie.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals":{ "sts:Externalid": "vmimport" } } } ] } EOF $ aws iam create-role --role-name vmimport --assume-role-policy-document file://trust-policy.json $ cat << EOF > role-policy.json { "Version":"2012-10-17", "Statement":[ { "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::${BUCKET_NAME}", "arn:aws:s3:::${BUCKET_NAME}/*" ] }, { "Effect": "Allow", "Action": [ "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:PutObject", "s3:GetBucketAcl" ], "Resource": [ "arn:aws:s3:::${BUCKET_NAME}", "arn:aws:s3:::${BUCKET_NAME}/*" ] }, { "Effect": "Allow", "Action": [ "ec2:ModifySnapshotAttribute", "ec2:CopySnapshot", "ec2:RegisterImage", "ec2:Describe*" ], "Resource": "*" } ] } EOF $ aws iam put-role-policy --role-name vmimport --policy-name vmimport --policy-document file://role-policy.json
創(chuàng)建 import-snapshot 任務(wù),將存儲在 S3 bucket 的 RAW 鏡像創(chuàng)建為 Snapshot。
$ aws ec2 import-snapshot \ --description "openEuler RAW image import task" \ --disk-container \ "Format=RAW,UserBucket={S3Bucket=${BUCKET_NAME},S3Key=openEuler-22.03-LTS-x86_64.raw}"
等待幾分鐘后,通過 import task ID 獲取導(dǎo)入成功后的 Snapshot ID。
$ aws ec2 describe-import-snapshot-tasks \ --import-task-ids ${IMPORT_TAST_ID}
使用此 Snapshot 創(chuàng)建不含 cloud init 機制的 Base AMI 鏡像。
$ aws ec2 register-image \ --name "DEV-openEuler-22.03-LTS-x86_64-BASE" \ --description "DEV openEuler image, do not use for production!" \ --root-device-name /dev/xvda \ --architecture x86_64 \ --ena-support \ --virtualization-type hvm \ --block-device-mappings \ DeviceName=/dev/xvda,Ebs={SnapshotId=${SNAPSHOT_ID}}
至此,我們獲得了 Base AMI ID。
使用 Packer 創(chuàng)建包含 Cloud init 機制的 AMI 鏡像
首先創(chuàng)建 Packer 的配置文件,注意修改配置文件中的 <BASE_AMI_ID> 為剛剛獲取的 Base AMI ID。
{ "variables": { "version": "{{env `OPENEULER_VERSION`}}", "build": "{{env `AWS_IMAGE_BUILD_NUMBER`}}", "arch": "{{env `OPENEULER_ARCH`}}" }, "builders": [ { "type": "amazon-ebs", "name": "amazon-ebs-hvm-x86_64", "region": "ap-northeast-1", "ami_regions": [ "ap-northeast-1" ], "source_ami": "<BASE_AMI_ID>", "instance_type": "t3a.micro", "ssh_username": "root", "ssh_password": "openEuler12#$", "ami_name": "openEuler-{{user `version`}}-x86_64-hvm-{{user `build`}}", "ena_support": "true" } ], "provisioners": [ { "type": "shell", "environment_vars": [ "VERSION={{user `version`}}", "ARCH={{user `arch`}}" ], "script": "./install-cloudinit.sh" } ] }
新建腳本文件 install-cloudinit.sh,用來執(zhí)行安裝 cloud init 和其他配置的指令。
#!/bin/bash set -e yum -y update yum -y install cloud-init cloud-utils-growpart gdisk yum -y install vim tar make zip gzip wget git tmux \ conntrack-tools socat iptables-services htop # disable Apparmor echo "GRUB_CMDLINE_LINUX_DEFAULT=\"apparmor=0\"" >> /etc/default/grub # Update grub config if [[ "$(uname -m)" == "x86_64" ]]; then grub2-mkconfig -o /boot/grub2/grub.cfg elif [[ "$(uname -m)" == "arm64" ]]; then grub2-mkconfig -o /boot/efi/EFI/openEuler/grub.cfg fi
最后使用以下指令使用 packer 構(gòu)建 AMI 鏡像。
$ packer build <PACKER_CONFIG.json>
構(gòu)建 ARM 架構(gòu)的 AMI 鏡像
理論上構(gòu)建 ARM 架構(gòu)的 AMI 鏡像的整體流程與 x86_64 架構(gòu)的流程幾乎一致,但是在實際操作過程中遇到了使用 Base AMI 鏡像啟動服務(wù)器后找不到網(wǎng)卡設(shè)備而無法 ssh 連接到服務(wù)器的情況。
在使用串口連接到服務(wù)器上進行調(diào)試后發(fā)現(xiàn),ARM 架構(gòu)的 openEuler 系統(tǒng)的內(nèi)核中沒有預(yù)裝 AWS ENA 網(wǎng)卡驅(qū)動,所以無法訪問網(wǎng)絡(luò)連接。
后續(xù) openEuler 會為 ARM 架構(gòu)的內(nèi)核增添 ENA 驅(qū)動支持,在此之前可使用編譯 ENA 驅(qū)動內(nèi)核模塊并導(dǎo)入的方式,作為一個臨時的解決辦法,感興趣的朋友可以參考一下。
此辦法只能作為一個臨時的解決方法,不建議用作生產(chǎn)環(huán)境中。
首先在本地運行一個用來編譯內(nèi)核模塊的 openEuler aarch64 虛擬機,安裝 gcc,make,git,vim 內(nèi)核頭文件等編譯需要的工具,克隆 ENA 驅(qū)動的源碼到本地并編譯。
$ yum -y install make git gcc vim kernel-devel-$(uname -r) $ git clone git clone https://github.com/amzn/amzn-drivers.git $ cd amzn-drivers/kernel/linux/ena/ $ make -j2
編寫這篇文章時,在編譯的過程中會遇到這個報錯:
/root/amzn-drivers/kernel/linux/ena/ena_ethtool.c:1218:19: error: initialization of ‘int (*)(struct net_device *, struct ethtool_coalesce *, struct kernel_ethtool_coalesce *, struct netlink_ext_ack *)' from incompatible pointer type ‘int (*)(struct net_device *, struct ethtool_coalesce *)' [-Werror=incompatible-pointer-types] 1218 | .get_coalesce = ena_get_coalesce, | ^~~~~~~~~~~~~~~~ compilation terminated due to -Wfatal-errors.
一個比較直接的解決辦法是編輯 ena_ethtool.c,在 1218-1221 行,為這幾個函數(shù)指針添加 (void*) 強制的指針類型轉(zhuǎn)換。
編譯后會生成 ena.ko 內(nèi)核模塊文件,可用 modinfo ena.ko 查看該模塊的信息。
$ modinfo ena.ko filename: /root/amzn-drivers/kernel/linux/ena/ena.ko version: 2.8.0g license: GPL description: Elastic Network Adapter (ENA) author: Amazon.com, Inc. or its affiliates ......
在調(diào)整硬盤分區(qū)時,掛載分區(qū),復(fù)制此內(nèi)核模塊文件到掛載的分區(qū)的目錄中并編輯 modprobe 配置文件,在每次開機啟動時都加載這個內(nèi)核模塊。
# 假設(shè)將分區(qū)掛載到了 /mnt 目錄下面 $ sudo mount /dev/nbd0p2 /mnt # 這里將內(nèi)核模塊復(fù)制到了 /root 目錄下面 $ sudo cp ./ena.ko /mnt/root/ $ sudo bash -c ' echo "install ena insmod /root/ena.ko" >> /mnt/etc/modprobe.d/ena.conf ' $ sudo bash -c ' echo "ena" >> mnt/etc/modules-load.d/ena.conf ' $ sudo sync && sudo umount /mnt
重啟系統(tǒng)后,可以使用 lsmod 查看已加載的內(nèi)核模塊,或使用 dmesg 查看內(nèi)核日志,可以看到 ENA 驅(qū)動被加載的記錄。
$ sudo lsmod Module Size Used by ena 147456 0 ...... $ dmesg | grep ena: [ 94.814488] ena: loading out-of-tree module taints kernel. [ 94.814896] ena: module verification failed: signature and/or required key missing - tainting kernel
目前 openEuler 社區(qū)已修復(fù)了 ARM 架構(gòu)的內(nèi)核不包含 ENA 網(wǎng)卡驅(qū)動的問題,會在后續(xù)的內(nèi)核更新中獲取到包含 ENA 驅(qū)動的內(nèi)核。更多信息可在此PR中獲取到:gitee.com/openeuler/k…
已構(gòu)建的 AMI 鏡像使用
在 AWS EC2 實例的控制臺頁面,使用構(gòu)建的 AMI 鏡像創(chuàng)建一個 EC2 虛擬機,設(shè)定網(wǎng)絡(luò)安全組、SSH 密鑰、磁盤大小、用戶數(shù)據(jù)等配置。
在本篇文章中,設(shè)定的 EBS 磁盤大小為 30G,在用戶數(shù)據(jù)中填寫了安裝 RKE2 的腳本:
#!/bin/bash echo "-------- Start custom user data ----------" yum update curl -sfL https://get.rke2.io > install.sh chmod +x ./install.sh sudo INSTALL_RKE2_METHOD=tar ./install.sh sudo systemctl enable rke2-server sudo systemctl start rke2-server echo "-------- User data finished successfully -----------"
實例啟動后,cloud init 機制會自動創(chuàng)建用戶名為 openeuler 的賬號并設(shè)定僅使用 ssh key 登錄,同時 root 賬號的 ssh 登錄也會被禁止。磁盤的 root 分區(qū)會自動擴容到我們設(shè)定的 EBS 磁盤大小,用戶數(shù)據(jù)中填寫的腳本也將被自動執(zhí)行。
查看 cloud init 輸出的日志,其中包括用戶數(shù)據(jù)的執(zhí)行結(jié)果:
$ tail -f /var/log/cloud-init-output.log Is this ok [y/N]: Operation aborted. [INFO] finding release for channel stable [INFO] using v1.24.4+rke2r1 as release [INFO] downloading checksums at https://github.com/rancher/rke2/releases/download/v1.24.4+rke2r1/sha256sum-amd64.txt [INFO] downloading tarball at https://github.com/rancher/rke2/releases/download/v1.24.4+rke2r1/rke2.linux-amd64.tar.gz [INFO] verifying tarball [INFO] unpacking tarball file to /usr/local Created symlink /etc/systemd/system/multi-user.target.wants/rke2-server.service → /usr/local/lib/systemd/system/rke2-server.service. -------- User data finished successfully ----------- Cloud-init v. 21.4 finished at Wed, 21 Sep 2022 06:56:30 +0000. Datasource DataSourceEc2Local. Up 130.47 seconds
驗證分區(qū)自動擴容至總?cè)萘繛樵O(shè)定的 EBS 的大?。?/p>
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS nvme0n1 259:0 0 30G 0 disk ├─nvme0n1p1 259:1 0 2G 0 part /boot └─nvme0n1p2 259:2 0 28G 0 part /
驗證 RKE2 安裝成功,所有 pods 均正常啟動:
$ sudo /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get nodes NAME STATUS ROLES AGE VERSION ip-172-31-21-213.ap-northeast-1.compute.internal Ready control-plane,etcd,master 7m58s v1.24.4+rke2r1 $ sudo /var/lib/rancher/rke2/bin/kubectl --kubeconfig /etc/rancher/rke2/rke2.yaml get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system cloud-controller-manager-ip-172-31-21-213.ap-northeast-1.compute.internal 1/1 Running 0 14m kube-system etcd-ip-172-31-21-213.ap-northeast-1.compute.internal 1/1 Running 0 14m kube-system helm-install-rke2-canal-l5rnl 0/1 Completed 0 14m kube-system helm-install-rke2-coredns-jckq7 0/1 Completed 0 14m kube-system helm-install-rke2-ingress-nginx-dxcsc 0/1 Completed 0 14m kube-system helm-install-rke2-metrics-server-kgjdf 0/1 Completed 0 14m kube-system kube-apiserver-ip-172-31-21-213.ap-northeast-1.compute.internal 1/1 Running 0 14m kube-system kube-controller-manager-ip-172-31-21-213.ap-northeast-1.compute.internal 1/1 Running 0 14m kube-system kube-proxy-ip-172-31-21-213.ap-northeast-1.compute.internal 1/1 Running 0 14m kube-system kube-scheduler-ip-172-31-21-213.ap-northeast-1.compute.internal 1/1 Running 0 14m kube-system rke2-canal-ng2sw 2/2 Running 0 13m kube-system rke2-coredns-rke2-coredns-76cb76d66-nklrw 1/1 Running 0 13m kube-system rke2-coredns-rke2-coredns-autoscaler-58867f8fc5-mpgd7 1/1 Running 0 13m kube-system rke2-ingress-nginx-controller-fhpbd 1/1 Running 0 12m kube-system rke2-metrics-server-6979d95f95-2lrp8 1/1 Running 0 13m
About SUSE Rancher
Rancher是一個開源的企業(yè)級Kubernetes管理平臺,實現(xiàn)了Kubernetes集群在混合云+本地數(shù)據(jù)中心的集中部署與管理。Rancher一向因操作體驗的直觀、極簡備受用戶青睞,被Forrester評為“2020年多云容器開發(fā)平臺領(lǐng)導(dǎo)廠商”以及“2018年全球容器管理平臺領(lǐng)導(dǎo)廠商”,被Gartner評為“2017年全球最酷的云基礎(chǔ)設(shè)施供應(yīng)商”。
目前Rancher在全球擁有超過三億的核心鏡像下載量,并擁有包括中國聯(lián)通、中國平安、中國人壽、上汽集團、三星、施耐德電氣、西門子、育碧游戲、LINE、WWK保險集團、澳電訊公司、德國鐵路、廈門航空、新東方等全球著名企業(yè)在內(nèi)的共40000家企業(yè)客戶。
2020年12月,SUSE完成收購RancherLabs,Rancher成為了SUSE “創(chuàng)新無處不在(Innovate Everywhere)”企業(yè)愿景的關(guān)鍵組成部分。SUSE和Rancher共同為客戶提供了無與倫比的自由和所向披靡的創(chuàng)新能力,通過混合云IT基礎(chǔ)架構(gòu)、云原生轉(zhuǎn)型和IT運維解決方案,簡化、現(xiàn)代化并加速企業(yè)數(shù)字化轉(zhuǎn)型,推動創(chuàng)新無處不在。
當前,SUSE及Rancher在中國大陸及港澳臺地區(qū)的業(yè)務(wù),均由數(shù)碩軟件(北京)有限公司承載。SUSE在國內(nèi)擁有優(yōu)秀的研發(fā)團隊、技術(shù)支持團隊和銷售團隊,將結(jié)合Rancher領(lǐng)先的云原生技術(shù),為中國的企業(yè)客戶提供更加及時和可信賴的技術(shù)支撐及服務(wù)保障。
以上就是RFO SIG之openEuler AWS AMI 制作詳解的詳細內(nèi)容,更多關(guān)于openEuler AWS AMI 制作的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Kubernetes應(yīng)用服務(wù)質(zhì)量管理詳解
這篇文章主要為大家介紹了Kubernetes應(yīng)用服務(wù)質(zhì)量管理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11K8s學(xué)習(xí)之Pod的定義及詳細資源調(diào)用案例
Kubernetes將所有內(nèi)容抽象為資源,通過操作資源管理集群,核心單元是Pod,通過控制器管理Pod,資源管理分為命令式對象管理、命令式對象配置和聲明式對象配置,各有適用場景,需要的朋友可以參考下2024-09-09