今天在使用 Packer 建立 AWS EC2 AMI 的時候遇到鬼打牆的情況,跑 provisioner 的時候時常出現找不到 apt package,但有時又正常 …
#!/bin/bash
sudo apt update -y
sudo apt install -y chrony
正常的情況下 apt update 更新 repository 後就可以正常獲取 package,尤其 chrony 通常是在內建套件庫裡,但是卻很異常的找不到 chrony 套件 …
Reading package lists… Done
Building dependency tree
Reading state information… Done
Package chrony is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package ‘chrony’ has no installation candidate
花了一個下午才找到問題,其實問題不在於 apt 或 Packer 的問題,是因為 AWS EC2 的 cloud-init 執行時會將 apt default source 改掉 …
- 預設(Ubuntu 18.04):http://archive.ubuntu.com/ubuntu bionic InRelease
- Cloud-init 改過後變成:http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic InRelease
這個狀況並非每次都發生的原因是在於 EC2 cloud-init 和 Packer 哪一個先跑完 …
- cloud-init 先跑完的情況:
- apt default source 已經被改成 ap-northeast-1.ec2.archive.ubuntu.com
- Packer 執行的 apt update 就會以 AWS source 為主
- 安裝套件正常
- cloud-init 比 Packer 慢跑完的情況:
- Packer 執行的 apt update 以 Ubuntu 預設的 archive.ubuntu.com 為主
- cloud-init 更新完成,並且把 default source 改成 AWS source
- Packer 執行 apt install chrony 發現 AWS source 沒有執行 apt update 故找不到 package。
這個雷常出現在 Packer 或是 User Data 跑 apt / yum 會遇到這個問題,後來在「Option for builder to wait on cloud-init to complete」找到完美的解法,加上 cloud-init status –wait 先等 cloud-init 完成後再跑,在這個案例有幾個方法可以做:
- Packer 直接在 provisioners 的一開始先檢查 cloud-init 等他跑完
provisioners:
- type: shell
inline:
- /usr/bin/cloud-init status --wait
- 在執行 apt update 前先等 cloud-init 跑完
#!/bin/bash
# waiting cloud-init to update
/usr/bin/cloud-init status --wait
sudo apt update -y
sudo apt install -y chrony
人生就是不斷的踩雷 …