本篇來介紹 Hashicorp 旗下其中一個產品叫 Packer,其實在 Hashicorp 旗下有很多其他雲端工具都非常好用,如果大家有興趣都可以上官網參考看看。而 Packer 是用來產生各大雲平台映像檔的工具,平行產生 AWS, GCP, Docker 或 DigitalOcean … 等等眾多雲平台之映像檔對 Packer 來說相當容易,詳細可以參考這邊,也就是說透過 Packer 來統一管理各大雲平台的映像檔,用 JSON 檔案進行版本控制。假設您有需求要管理工程團隊所使用的 Image,你絕對不能錯過 Packer。Packer 不是用來取代像是 Ansible 或是 Chef 等軟體,而是讓開發者更方便整合 Ansible .. 等第三方工具,快速安裝好系統環境。
影片教學
如果不想看底下文字介紹,可以直接參考 Youtube 影片: 如果您對 Drone 整合 Docker 有興趣,可以直接參考線上課程- 一天學會 DEVOPS 自動化流程 $1800
自動建立 AWS AMI 映像檔
不多說直接拿實際例子來實做看看,假設我們有個需求,就是需要產生一個 AMI 裡面已經內建包含了 Docker 服務,該如何來實現呢?底下是 Packer 所撰寫的 JSON 檔案,底下範例可以直接在這邊找到{ "variables": { "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}", "ssh_bastion_host": "", "ssh_bastion_port": "22", "ssh_bastion_username": "", "ssh_bastion_private_key_file": "", "region": "ap-southeast-1" }, "builders": [{ "type": "amazon-ebs", "access_key": "{{user `aws_access_key`}}", "secret_key": "{{user `aws_secret_key`}}", "region": "{{user `region`}}", "source_ami_filter": { "filters": { "virtualization-type": "hvm", "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*", "root-device-type": "ebs" }, "owners": ["099720109477"], "most_recent": true }, "instance_type": "t2.micro", "ssh_username": "ubuntu", "ami_name": "ggz-docker-image-{{isotime | clean_ami_name}}", "tags": { "Name": "ggz", "Environment": "production" }, "communicator": "ssh", "ssh_bastion_host": "{{user `ssh_bastion_host`}}", "ssh_bastion_port": "{{user `ssh_bastion_port`}}", "ssh_bastion_username": "{{user `ssh_bastion_username`}}", "ssh_bastion_private_key_file": "{{user `ssh_bastion_private_key_file`}}" }], "provisioners": [{ "type": "file", "source": "{{template_dir}}/welcome.txt", "destination": "/home/ubuntu/" }, { "type": "shell", "script": "{{template_dir}}/docker.sh", "execute_command": "echo 'ubuntu' | sudo -S sh -c '{{ .Vars }} {{ .Path }}'" } ] }第一部分
variables
讓開發者可以定義變數,可以讀取系統環境變數,第二部分 builders
就是用來定義要產生不同平台的 Image,像是 GCP 或 AWS,可以看到是傳入一個 Array 值,上面的例子就是要產生 AWS AMI,所以設定 "type": "amazon-ebs"
,第三部分 provisioners
,就是來寫 script,映像檔預設可能會有一些檔案,或者是預設安裝一些工具,看到 type 可以是 file
、shell
等等,也就是說 provisioners
可以讓開發者安裝套件,更新 Kernel,建立使用者,或者是安裝下載 application source code。這對於部署來說是一個非常棒的工具。
執行 Packer
完成上述 JSON 檔案後,就可以透過 Packer 來產生 AWS AMI 了$ packer build -var-file=config/mcs.json mcs.json amazon-ebs output will be in this color. ==> amazon-ebs: Prevalidating AMI Name: ggz-docker-image-2018-07-29T06-11-12Z amazon-ebs: Found Image ID: ami-1c6627f6 ==> amazon-ebs: Creating temporary keypair: packer_5b5d5a80-c1e2-e266-e0b8-bc7c6e63dba3 ==> amazon-ebs: Creating temporary security group for this instance: packer_5b5d5a82-5d1f-c702-18f4-992ac37e885a ==> amazon-ebs: Authorizing access to port 22 from 0.0.0.0/0 in the temporary security group... ==> amazon-ebs: Launching a source AWS instance... ==> amazon-ebs: Adding tags to source instance amazon-ebs: Adding tag: "Name": "Packer Builder" amazon-ebs: Instance ID: i-0d12e2a9e6f00a410 ==> amazon-ebs: Waiting for instance (i-0d12e2a9e6f00a410) to become ready...透過
-var-file
將隱秘資訊寫到檔案內,像是 AWS Secret Key 等等。
整合 Drone CI/CD
上一個步驟可以透過指令方式完成映像檔,本章節會教大家如何跟 Drone 整合,這邊可以直接使用 drone-packer 套件,使用文件也已經放到 drone plugin 首頁了。使用方式非常簡單,請參考底下範例:pipeline: packer: image: appleboy/drone-packer pull: true secrets: [ aws_access_key_id, aws_secret_access_key ] template: ggz.json actions: - validate - build when: branch: master其中 template 請輸入 json 檔案路徑,actions 目前只有支援
validate
跟 build
,我建議兩者都寫,先驗證 json 檔案是否寫錯,再執行 build。另外我們可以看到
"variables": { "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}", "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}" },其中
aws_access_key
是讀取系統環境變數 AWS_ACCESS_KEY_ID
,所以可以透過 drone secret
將變數設定上去
$ drone secret add \ -repository go-ggz/packer \ -image appleboy/drone-packer \ -event push \ -name aws_access_key_id \ -value xxxxxx請注意記得將敏感資訊綁定在
-image
身上,避免被偷走。上面的範例,可以直接參考 go-ggz/packer。