在上一篇中已介紹了 Kolla 的源代碼目錄結構和各個目錄中源代碼的基本做用,如今開始深刻到各個目錄,介紹目錄中的具體內容。每一個人分析代碼的思路和方法不一樣,會選擇從不一樣的目錄開始。在這裏,我選擇從 tools
目錄開始,從高層瞭解 Kolla 組件間的關係、編譯依賴,命令行工具等,而後再次按照依賴來逐個組件分析。linux
tools
目錄的文件樹以下:git
. ├── build-all-docker-images ├── build-docker-image ├── cleanup-containers ├── cleanup-images ├── genenv ├── init-runonce ├── kolla ├── pre-commit-hook ├── update-build-links ├── validate-all-json.sh ├── validate-all-maintainer.sh ├── validate-all-yaml.sh ├── validate-json.py ├── validate-maintainer.sh └── validate-yaml.py
這些文件都是腳本文件,核心的文件爲:build-* genenv kolla 。(這裏使用了 vi 來查看,並使用了 set nu,所以會帶上行號,使用一些支持列模式的編輯器可很簡單地去掉行號;由於文件版本不一樣的話,內容和行號不相同,僅供參考)docker
build-* 負責處理 Dockerfile ,編譯 doker 鏡像。有兩個 Shell 腳本文件:json
build-docker-imagecentos
編譯一個組件的 docker 鏡像。這個腳本的用法可以使用 build-docker-image -h
查看。數組
這裏涉及了一點隱含的 Shell 技巧。 Kolla 中各個 docker 鏡像定義的目錄中,都有一個 build 文件用來編譯當前的 docker 鏡像。這些 build 文件其實都是一個連接,指向 build-docker-image
腳本。當調用 build 文件,會把 build 文件路徑做爲 $0
參數,因此 build-docker-image
腳本的 IMGDIR
變量爲指向 build 文件所在的鏡像目錄(即 docker 鏡像定義目錄,經過 dirname $0
得到),所以 build-docker-image
腳本能夠編譯當前 docker 鏡像。安全
腳本中首先定義了一系列編譯使用到的變量,並設置了默認值,改變這些值時應參考默認值:bash
3 TOPDIR=$(git rev-parse --show-toplevel) 4 IMGDIR="$(cd "$(dirname "$0")" && pwd)" 5 6 RELEASE_NAMESPACE=kollaglue 7 NAMESPACE=kollaglue 8 PREFIX=centos-rdo- 9 TAG=$(git rev-parse --short HEAD) 10 RELEASE_TAG=kilo
而後,定義了一個 usage 函數,用來打印幫助內容(略)。網絡
而後,在正式執行前,先檢查是否有編譯配置文件,若是有,執行這些文件:編輯器
29 [ -f $TOPDIR/.buildconf ] && . $TOPDIR/.buildconf 30 [ -f $IMGDIR/.buildconf ] && . $IMGDIR/.buildconf
而後,會有一段常規的命令後參數處理腳本,讀取參數並轉換(略)。而後,根據參數,對鏡像命名
97 IMAGE="${PREFIX}${IMGDIR##*/}" 98 FULLIMAGE="${NAMESPACE}/${IMAGE}${TAG:+:${TAG}}"
IMAGE
是鏡像的名字,用編譯時前綴PREFIX
和鏡像在的目錄IMGDIR
(只保留路徑中最後一個'/'後的部分)來命名,如 centos-rdo-keystone
。 FULLIMAGE
是鏡像的全名,是在 docker-registry 中的名字,並當 TAG
變量不爲空時,在IMAGE
後面加上一個版本標籤,如 kollaglue/centos-rdo-keystone:kilo
。
而後,建立編譯時的臨時目錄,把鏡像目錄內容拷貝到臨時目錄,使用 sed 修改掉 Dockerfile 中定義的 %%KOLLA_NAMESPACE%%
%%KOLLA_PREFIX%%
%%KOLLA_TAG%%
等值,而後使用 docker build
編譯。因爲全部的編譯使用同一個 TEMPDIR
,所以不能同時編譯多個 docker 鏡像!
112 TMPDIR=$(mktemp -d /tmp/kolla-build.XXXXXXXXXX) 113 cp -aL $IMGDIR/* $TMPDIR 114 # Use an extension for in-place editing for portability, as GNU and BSD 115 # versions of sed behave differently otherwise 116 sed -i.bak "s/%%KOLLA_NAMESPACE%%/${NAMESPACE}/g" $TMPDIR/Dockerfile 117 sed -i.bak "s/%%KOLLA_PREFIX%%/${PREFIX}/g" $TMPDIR/Dockerfile 118 sed -i.bak "s/%%KOLLA_TAG%%/${PARENT_TAG}/g" $TMPDIR/Dockerfile 119 120 if ! docker build ${BUILDFLAGS} -t "$FULLIMAGE" $TMPDIR; then 121 echo "ERROR: failed to build $FULLIMAGE" 122 exit 1 123 fi 124 rm -rf $TMPDIR
最後,若是使用了push選項,會把鏡像push到docker倉庫,此時使用到 FULLIMAGE
變量。
128 if [ "$PUSH" = 1 ]; then 129 if ! docker push "$FULLIMAGE"; then 130 echo "ERROR: failed to push $FULLIMAGE" 131 exit 1 132 fi 133 134 echo "Pushed: $FULLIMAGE" 135 fi
build-all-docker-images
編譯全部組件的 docker 鏡像。這個腳本的用法經過 build-all-docker-image -h
得到。
這個腳本是對 build-docker-image
的進一步封裝,從而能支持一次性編譯全部的 docker 鏡像。須要注意的是,這個腳本註明了要使用 bash 4 和 gawk。因爲部分的 Linux distribution 裏面沒有包含這些軟件,須要本身安裝(裏面只用了一句 gawk 啊!!!不明白爲何不直接用awk,或者用which檢查哪一個awk兼容軟件可用)。
1 #!/usr/bin/env bash 2 # Depends on bash 4 and gawk
在 Ubuntu 14.04 Desktop裏面,就缺乏了 gawk,經過apt安裝:
sudo apt-get install -y --force-yes gawk
首先,定義了3個用於變量的目錄變量。 TOPDIR
是 Kolla 根目錄,這裏用了 git 來進行判斷,也可經過 dirname 來獲取; WORKDIR
是編譯時的臨時目錄; DOCKERDIR
是編譯全部 docker 鏡像的臨時目錄。Kolla 根目錄的全部內容 copy 到 WORKDIR
中。
4 TOPDIR=$(git rev-parse --show-toplevel) 5 # Work in a temp dir so that developers can continue working while a build is 6 # in progress 7 WORKDIR=$(mktemp -d /tmp/kolla-workdir.XXXXXXXXXX) 8 # Remove $WORKDIR otherwise $TOPDIR is copied *inside* of it 9 rm -rf $WORKDIR 10 cp -aL "$TOPDIR" $WORKDIR 11 DOCKERDIR="$WORKDIR/docker"
而後,定義了3個數組變量。 dependency
保存了各個 docker 鏡像依賴關係; img_dirs
保存 docker 鏡像的目錄; status
保存 docker 鏡像的編譯狀態。
13 declare -A dependency 14 declare -A img_dirs 15 declare -A status而後,是一系列函數的定義:
info
打印普通訊息
success
打印成功信息
warn
打印警告
set_defaults
設置 PREFIX
和 NAMESPACE
等參數默認值
has_changed
經過 git 檢查是否有文件的改變。參數爲 image
,所在的目錄爲 ${img_dirs[$image]#$WORKDIR/}
經過 git diff 檢查是否有改變。
requires_build
檢查鏡像是否須要進行編譯
build_image
編譯鏡像。調用鏡像目錄中的 build 腳本(即 build-docker-image
腳本),進行編譯。
init_image
初始化鏡像編譯配置。調用 set_defaults
,運行鏡像目錄的buildconf
文件,經過 gawk
檢查鏡像所依賴的鏡像(就是這個地方使用了 gawk ),並處理鏡像的名字
69 function init_image { 70 local img_dir=$1 71 72 set_defaults 73 [ -f $WORKDIR/.buildconf ] && . $WORKDIR/.buildconf 74 [ -f $img_dir/.buildconf ] && . $img_dir/.buildconf 75 [ -n "$FORCE_NAMESPACE" ] && NAMESPACE=$FORCE_NAMESPACE 76 77 local image="${NAMESPACE:+${NAMESPACE}/}${PREFIX}${img_dir##*/}" 78 local base_image=$(cat $img_dir/Dockerfile | gawk 'match($0, /^\s*FROM\s+(\S+)/, matches) {print matches[1]}' ) 79 base_image=${base_image//%%KOLLA_NAMESPACE%%/$NAMESPACE} 80 base_image=${base_image//%%KOLLA_PREFIX%%/$PREFIX} 81 base_image=${base_image//:%%KOLLA_TAG%%/} 82 83 img_dirs[$image]=$img_dir 84 dependency[$image]=$base_image 85 86 # Restore defaults to minimize risk of side effects 87 set_defaults 88 }
79-81行替換掉 %%KOLLA_NAMESPACE%%
%%KOLLA_PREFIX%%
:%%KOLLA_TAG%%
等標記,而後記錄到數組 img_dirs
和 dependency
裏面。
process_image
處理鏡像。函數先根據 ${dependency[$image]}
遞歸地調用process-image
處理其基礎鏡像,而後調用 requires_build
檢查 $image
是否須要從新編譯,須要編譯時用 build-image
進行編譯,最後更新 status
中的狀態爲 up-to-date
print_summary
打印編譯總結。把 status
中的狀態信息打印出來。
interrupted
中斷處理函數。在中斷編譯時,會刪除 $WORKDIR
。
usage
和參數處理
顯示幫助信息,處理腳本運行參數。
其它
處理邏輯。找到 $DOCKERDIR
裏面的全部 Dockerfile,而後執行 init_image
初始化編譯配置,而後使用 process_image
處理鏡像編譯。
175 # Do a first pass to find images to build and their dependencies 176 for dockerfile in $(find $DOCKERDIR -name Dockerfile); do 177 init_image $(dirname $dockerfile) 178 done 179 180 # Process all images 181 for image in "${!img_dirs[@]}"; do 182 process_image $image 183 done 184 185 print_summary 186 rm -rf $WORKDIR
生成 Kolla 所須要的環境變量。
genenv 最終生成 2 個環境變量文件 ./openrc
和 ./compose/openstack.env
。
openrc
OpenStack的訪問文件,用於各類 client 訪問 OpenStack API。
128 export OS_AUTH_URL="http://${KEYSTONE_PUBLIC_SERVICE_HOST}:5000/v2.0" 129 export OS_USERNAME=$ADMIN_TENANT_NAME 130 export OS_PASSWORD=$ADMIN_USER_PASSWORD 131 export OS_TENANT_NAME=$ADMIN_TENANT_NAME
openstack.env
Kolla 全部 docker 鏡像在啓動時須要的配置文件。從鏡像啓動一個容器時,須要讀取這個文件的內容,並初始化各個服務(在編譯鏡像時,各類 OpenStack 服務尚未配置,只是安裝在鏡像中而已)。
Kolla 輔助工具腳本。這個腳本可經過 kolla -h
查詢用法。
腳本里面定義了一系列的函數:
process
經過 docker-compose
啓動 docker 容器。
process_all
啓動一整個OpenStack所須要的容器,單個容器經過 process
啓動
check_selinux
檢查 selinux 狀態
pre_start
調用 check_selinux,並 source openrc,若是 openrc 文件不存在,那麼須要經過 genenv 生成
post_start
等待 OpenStack 服務啓動完畢
usage
幫助函數
使用這個腳本可啓動一個測試環境。
cleanup-*
清理環境
init-runonce
初始化 OpenStack 配置,下載鏡像、增長安全組、創建初始網絡、更新配額設置等
pre-commit-hook
Git 提交前的鉤子腳本,會調用 validate*
腳本進行處理
update-build-links
更新 docker 鏡像定義目錄的 build 文件連接
validate*
檢查各個文件是否有效