目錄
- 正文
- 調整硬盤分區大小
- Snapshot 和 Base AMI 的創建
- 使用 Packer 創建包含 Cloud init 機制的 AMI 鏡像
- 構建 ARM 架構的 AMI 鏡像
- 已構建的 AMI 鏡像使用
- About SUSE Rancher
正文
本篇將主要介紹 openEuler AWS AMI 鏡像制作的詳細過程。
通過創建 AWS AMI 鏡像可將 openEuler 與 AWS 云服務相結合,支持云環境中標準的 ssh key注入、分區擴容、用戶數據執行等功能,并使用 cloud-init 機制實現自動啟動 Rancher RKE2 集群。今后,openEuler Cloud Images 的工作也將成為 RFO SIG 的一部分,逐步擴展支持更多的云平臺。
調整硬盤分區大小
openEuler 官方提供的 qcow2 格式的鏡像為一個總磁盤大小為 40G 的虛擬機鏡像,在 qemu 中啟動虛擬機,查看分區情況。
可以看到磁盤含有兩個分區,其中 2G 為 boot 分區,38G 為 root 分區。
使用 Net Based Disk (NBD) 將 qcow2 鏡像的分區加載到 Linux 系統中,之后使用 resize2fs 壓縮 ext4 文件系統的體積,并使用分區調整工具 fdisk 調整分區的大小。
# 加載 NBD 內核模塊 $ sudo modprobe nbd max_part=3 # 加載 qcow2 鏡像中的分區至系統 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 # 調整 ext4 文件系統大小至6G $ sudo resize2fs /dev/nbd0p2 6G # 使用fdisk調整分區大小至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. # 從系統中卸載 qcow2 鏡像的分區 $ sudo qemu-nbd -d /dev/nbd0
之后使用 qemu-img 將 qcow2 鏡像縮小至8G,并轉換為 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 的創建
首先使用 awscli 提供的工具,將 RAW 鏡像上傳至 AWS S3 bucket 中。
$ aws s3 cp openEuler-22.03-LTS-x86_64.raw s3://${BUCKET_NAME}/
創建 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
創建 import-snapshot 任務,將存儲在 S3 bucket 的 RAW 鏡像創建為 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 獲取導入成功后的 Snapshot ID。
$ aws ec2 describe-import-snapshot-tasks \ --import-task-ids ${IMPORT_TAST_ID}
使用此 Snapshot 創建不含 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 創建包含 Cloud init 機制的 AMI 鏡像
首先創建 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,用來執行安裝 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 構建 AMI 鏡像。
$ packer build <PACKER_CONFIG.json>
構建 ARM 架構的 AMI 鏡像
理論上構建 ARM 架構的 AMI 鏡像的整體流程與 x86_64 架構的流程幾乎一致,但是在實際操作過程中遇到了使用 Base AMI 鏡像啟動服務器后找不到網卡設備而無法 ssh 連接到服務器的情況。
在使用串口連接到服務器上進行調試后發現,ARM 架構的 openEuler 系統的內核中沒有預裝 AWS ENA 網卡驅動,所以無法訪問網絡連接。
后續 openEuler 會為 ARM 架構的內核增添 ENA 驅動支持,在此之前可使用編譯 ENA 驅動內核模塊并導入的方式,作為一個臨時的解決辦法,感興趣的朋友可以參考一下。
此辦法只能作為一個臨時的解決方法,不建議用作生產環境中。
首先在本地運行一個用來編譯內核模塊的 openEuler aarch64 虛擬機,安裝 gcc,make,git,vim 內核頭文件等編譯需要的工具,克隆 ENA 驅動的源碼到本地并編譯。
$ 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 行,為這幾個函數指針添加 (void*) 強制的指針類型轉換。
編譯后會生成 ena.ko 內核模塊文件,可用 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 ......
在調整硬盤分區時,掛載分區,復制此內核模塊文件到掛載的分區的目錄中并編輯 modprobe 配置文件,在每次開機啟動時都加載這個內核模塊。
# 假設將分區掛載到了 /mnt 目錄下面 $ sudo mount /dev/nbd0p2 /mnt # 這里將內核模塊復制到了 /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
重啟系統后,可以使用 lsmod 查看已加載的內核模塊,或使用 dmesg 查看內核日志,可以看到 ENA 驅動被加載的記錄。
$ 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 社區已修復了 ARM 架構的內核不包含 ENA 網卡驅動的問題,會在后續的內核更新中獲取到包含 ENA 驅動的內核。更多信息可在此PR中獲取到:gitee.com/openeuler/k…
已構建的 AMI 鏡像使用
在 AWS EC2 實例的控制臺頁面,使用構建的 AMI 鏡像創建一個 EC2 虛擬機,設定網絡安全組、SSH 密鑰、磁盤大小、用戶數據等配置。
在本篇文章中,設定的 EBS 磁盤大小為 30G,在用戶數據中填寫了安裝 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 機制會自動創建用戶名為 openeuler 的賬號并設定僅使用 ssh key 登錄,同時 root 賬號的 ssh 登錄也會被禁止。磁盤的 root 分區會自動擴容到我們設定的 EBS 磁盤大小,用戶數據中填寫的腳本也將被自動執行。
查看 cloud init 輸出的日志,其中包括用戶數據的執行結果:
$ 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
驗證分區自動擴容至總容量為設定的 EBS 的大小:
$ 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是一個開源的企業級Kubernetes管理平臺,實現了Kubernetes集群在混合云+本地數據中心的集中部署與管理。Rancher一向因操作體驗的直觀、極簡備受用戶青睞,被Forrester評為“2020年多云容器開發平臺領導廠商”以及“2018年全球容器管理平臺領導廠商”,被Gartner評為“2017年全球最酷的云基礎設施供應商”。
目前Rancher在全球擁有超過三億的核心鏡像下載量,并擁有包括中國聯通、中國平安、中國人壽、上汽集團、三星、施耐德電氣、西門子、育碧游戲、LINE、WWK保險集團、澳電訊公司、德國鐵路、廈門航空、新東方等全球著名企業在內的共40000家企業客戶。
2020年12月,SUSE完成收購RancherLabs,Rancher成為了SUSE “創新無處不在(Innovate Everywhere)”企業愿景的關鍵組成部分。SUSE和Rancher共同為客戶提供了無與倫比的自由和所向披靡的創新能力,通過混合云IT基礎架構、云原生轉型和IT運維解決方案,簡化、現代化并加速企業數字化轉型,推動創新無處不在。
當前,SUSE及Rancher在中國大陸及港澳臺地區的業務,均由數碩軟件(北京)有限公司承載。SUSE在國內擁有優秀的研發團隊、技術支持團隊和銷售團隊,將結合Rancher領先的云原生技術,為中國的企業客戶提供更加及時和可信賴的技術支撐及服務保障。
以上就是RFO SIG之openEuler AWS AMI 制作詳解的詳細內容,更多關于openEuler AWS AMI 制作的資料請關注其它相關文章!