拓展閱讀:宜信開源|詳解PaaS平臺LAIN的功能和架構node
宜信開源|一個實例解析PaaS平臺LAIN的9大殺手級功能python
本節包含三種場景下安裝LAIN集羣git
三者都須要從 GitHub 獲取已經發布的 LAIN 版本源代碼: https://github.com/laincloud/lain/releasesgithub
下載源碼後在目標機器上解壓便可。golang
tar xf lain-VERSION.tar.gz
1)環境依賴web
2)初始化docker
啓動並初始化第一個節點json
cd lain-VERSION vagrant up --provision
啓動耗時取決於 vagrant box 下載時間, 啓動完成後 vagrant 會自動 執行bootstrap進行初始化, 初始化須要至少20分鐘,取決於網絡速度。 初始化過程爲集羣默認配置vip=192.168.77.201bootstrap
若是出現如下錯誤:centos
Vagrant was unable to mount VirtualBox shared folders. This is usually because the filesystem "vboxsf" is not available. This filesystem is made available via the VirtualBox Guest Additions and kernel module. Please verify that these guest additions are properly installed in the guest. This is not a bug in Vagrant and is usually caused by a faulty Vagrant box. For context, the command attempted was: mount -t vboxsf -o uid=1000,gid=1000 vagrant /vagrant The error output from the command was: /sbin/mount.vboxsf: mounting failed with the error: No such device
這個錯誤是由於宿主機的 Virtual Box 的 Guest Additions 與 laincloud/centos-lain box 已安裝的 Guest Additions 版本不一致引發的,致使沒法建立 /vagrant 這個同步 目錄。請修改工程根目錄下的 Vagrantfile,禁止宿主機強行安裝新版本的 Guest Additions, 即添加以下配置:
config.vbguest.auto_update = false
3)添加更多節點
vagrant up node2 # 待 node2 啓動後 [vagrant@node1 ~]$ cd /vagrant [vagrant@node1 ~]$ sudo lainctl node add -p playbooks node2:192.168.77.22 # root 密碼爲 vagrant
4)同理能夠如此添加 node3
1)環境依賴
2)初始化
第一個節點
cd lain-VERSION # 選擇一個同網段的未被使用的 IP 地址做爲 VIP sudo ./bootstrap -r docker.io/laincloud --vip={{ vip }}
國內用戶建議經過 -m 參數使用 aliyun 的加速器下載鏡像,使用方式爲
sudo ./bootstrap -m https://l2ohopf9.mirror.aliyuncs.com \ -r docker.io/laincloud --vip=192.168.77.201
添加更多節點
# 須要輸入 root 密碼 sudo lainctl node add -p playbooks {{ hostname }}:{{ ip }}
1)環境依賴
3) 初始化
第一個節點
cd lain-VERSION # 若是 VPC 不對數據包進行來源 IP 限制(如青雲) sudo ./bootstrap -r docker.io/laincloud # 若是 VPC 限制了數據包的來源 IP(如阿里雲) sudo ./bootstrap -r docker.io/laincloud --ipip
添加更多節點
# 須要輸入 root 密碼 sudo lainctl node add -p playbooks {{ hostname }}:{{ ip }}
LAIN Console 組件是 LAIN 集羣的控制檯,配置域名解析後便可在瀏覽器訪問 http://console.lain.local
echo "IP/VIP console.lain.local" >> /etc/hosts
add-node ssh-copy-id 失敗
若是出現 ssh-copy-id 失敗,可能須要把 node1:/root/.ssh/lain.pub
內容放到 node2:/root/.ssh/authorized_keys
裏,新增一行。固然緣由多是多樣的,最有可能就是 lain-02 的 /root/.ssh
目錄或者目錄中的文件權限不對
開發 LAIN 應用時,須要安裝 LAIN 客戶端。LAIN 客戶端依賴於:
只要支持 docker 和 python 的系統,就可使用 LAIN 客戶端,好比 Linux 和 macOS。
如下均假設 LAIN 集羣的 domain 爲 lain.local,對於其餘 domain,將下文中的 lain.local 替換便可。
1)安裝
請參考 https://docs.docker.com/engine/installation/ 安裝 docker >= 1.12。
2)配置
Insecure Registries
安裝好以後,請參考 https://docs.docker.com/registry/insecure/ 將 registry.lain.local
添加進 docker daemon 的 insecure-registries
選項。
例如,在 Linux 上,以下的 /etc/docker/daemon.json
表示將 registry.lain.local
加入了 insecure-registries
:
{ "insecure-registries" : ["registry.lain.local"] }
macOS 上的 insecure registries 配置以下圖所示:
配置 insecure-registries
是由於 LAIN 集羣的鏡像倉庫只提供了 HTTP 服務,沒有提供 HTTPS 服務。
pip install lain-cli
推薦使用 virtualenv 安裝這個 python 包,即:
pip install virtualenv # 安裝 virtualenv virtualenv lain # lain 是虛擬環境的名字,也能夠取其餘名字 source lain/bin/activate # 激活 lain 虛擬環境 pip install lain-cli deactivate # 退出 lain 虛擬環境
之後須要使用 lain-cli 的時候,用 source ${lain-virtualenv-path}/bin/activate
激活 lain 虛擬環境; 不使用 lain-cli 的時候,用 deactivate
退出 lain 虛擬環境
安裝好以後,須要配置 lain-cli,讓 lain-cli 知道 LAIN 集羣的 Domain 等信息:
lain config show # 顯示當前配置 lain config save-global private_docker_registry registry.lain.local # 配置 docker 私有倉庫 lain config save local domain lain.local # 保存 lain.local 集羣,並取名爲 local
假如 LAIN 集羣開啓了 sso 驗證(默認未開啓),請配置 sso:
lain config save local sso_url https://sso.lain.local
若是 LAIN 集羣不能在公網上解析(好比本地啓動的集羣),請配置 /etc/hosts。
若是啓動集羣時,使用了 vip
模式,即便用了 /vagrant/bootstrap -r docker.io/laincloud --vip=192.168.77.201
啓動,請執行:
echo "192.168.77.201 registry.lain.local console.lain.local entry.lain.local lvault.lain.local ipaddr-client.lain.local ipaddr-service.lain.local ipaddr-client.ipaddr-resource.resource.lain.local" >> /etc/hosts
192.168.77.201
是啓動集羣時的 vip 參數
若是啓動集羣時,沒有使用 vip
模式,即便用了 /vagrant/bootstrap -r docker.io/laincloud
啓動,請執行:
echo "192.168.77.21 registry.lain.local console.lain.local entry.lain.local lvault.lain.local ipaddr-client.lain.local ipaddr-service.lain.local ipaddr-client.ipaddr-resource.resource.lain.local" >> /etc/hosts
192.168.77.21
是集羣的主節點的 IP,即啓動集羣的節點的 IP。
本節會演示如何基於 LAIN 集羣建立一個 LAIN 應用,它提供 HTTP 服務,當用戶訪問 /
時,返回 Hello, LAIN.
。
LAIN 是基於 docker 的 PaaS 系統,建議先了解下 docker 的基本概念:
package main import ( "net/http" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Hello, LAIN.")) }) http.ListenAndServe(":8080", nil) }
代碼的邏輯爲:
0.0.0.0:8080
端口/
的 HTTP 請求時,返回 Hello, LAIN.
lain.yaml
是 LAIN 應用的配置文件,以下例所示:
appname: hello-world # 應用名,在集羣內惟一,由小寫字母、數字和 `-` 組成,且開頭不能爲數字,不能有連續的 `-` build: # 描述如何構建 hello-world:build-${git-committer-date}-${git-commit-hash} 鏡像 base: golang:1.8 # 基礎鏡像,相似於 Dockerfile 裏的 FROM script: - go build -o hello-world # 編譯指令,相似於 Dockerfile 裏的 RUN,WORKDIR 爲 /lain/app proc.web: # 定義一個 proc,名字爲 web type: web # proc 類型爲 web(LAIN 會爲 web 類型的 proc 配置 ${appname}.${LAIN-domain} 的域名,對外提供 HTTP 服務) cmd: /lain/app/hello-world # 由於 WORKDIR 爲 /lain/app,因此編譯好的程序在 /lain/app 目錄下 port: 8080 # hello-world 監聽的端口
由於咱們須要提供 HTTP 服務,因此定義一個 web
類型的 proc,LAIN 集羣會爲 web 類型的 proc 自動分配 ${appname}.${LAIN-domain} 的域名。
proc.type 爲 web
時,其名字也必須爲 web,即一個 app 只能有一個 web 類型的 proc,且其名字爲 web。
laincloud/hello-world@basic 的完整代碼在這裏:https://github.com/laincloud/hello-world/tree/basic
[vagrant@lain ~]$ cd ${hello-world-project} # 進入工程目錄 [vagrant@lain hello-world]$ lain build # 構建 hello-world:build-${git-committer-date}-${git-commit-hash} 鏡像,生成編譯結果 >>> Building meta and release images ... >>> found shared prepare image at remote and local, sync ... >>> generating dockerfile to /Users/bibaijin/Projects/go/src/github.com/laincloud/hello-world/Dockerfile >>> building image hello-world:build-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 ... Sending build context to Docker daemon 6.656 kB Step 1/4 : FROM registry.lain.local/hello-world:prepare-0-1494908044 ---> 7406706a7f21 Step 2/4 : COPY . /lain/app/ ---> 45f6215362ad Removing intermediate container 41e822d3b086 Step 3/4 : WORKDIR /lain/app/ ---> 75c0f3094b6e Removing intermediate container 24065cf1d7de Step 4/4 : RUN ( go build -o hello-world ) ---> Running in 43cefd489608 ---> 644f596f83c8 Removing intermediate container 43cefd489608 Successfully built 644f596f83c8 >>> build succeeded: hello-world:build-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 >>> tag hello-world:build-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 as hello-world:release-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 >>> generating dockerfile to /Users/bibaijin/Projects/go/src/github.com/laincloud/hello-world/Dockerfile >>> building image hello-world:meta-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 ... Sending build context to Docker daemon 6.656 kB Step 1/2 : FROM scratch ---> Step 2/2 : COPY lain.yaml /lain.yaml ---> cfdb9c518f0d Removing intermediate container ab94a3603b8a Successfully built cfdb9c518f0d >>> build succeeded: hello-world:meta-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 >>> Done lain build. [vagrant@lain hello-world]$ lain run web # 在本地運行 >>> run proc hello-world.web.web with image hello-world:release-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 59f7fe4b1a7c6214361ecd5e06b19023ab7e02058888aa625749028af7b92954 >>> container name: hello-world.web.web >>> port mapping: >>> 8080/tcp -> 0.0.0.0:32769
lain build
以前進行 git commit
docker ps
時,能夠看到:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 59f7fe4b1a7c hello-world:release-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 "/lain/app/hello-w..." 27 seconds ago Up 31 seconds 0.0.0.0:32769->8080/tcp hello-world.web.web
上面的輸出表示 lain 經過 docker 把 hello-world.web.web 容器裏的 8080 端口映射到了主機的 32769,因此,能夠在主機上訪問:
[vagrant@lain hello-world]$ curl http://localhost:32769 Hello, LAIN.
獲得了預期的結果。
從上一小節能夠看到,本地運行沒有問題,如今能夠部署到 LAIN 集羣了:
[vagrant@lain ~]$ cd ${hello-world-project} # 進入工程目錄 [vagrant@lain hello-world]$ lain build # 構建 hello-world:build-${git-committer-date}-${git-commit-hash} 鏡像,生成編譯結果 [vagrant@lain hello-world]$ lain tag local # 相似於 docker tag,爲 hello-world:(meta/release)-${git-committer-date}-${git-commit-hash} 鏡像添加倉庫前綴 >>> Taging meta and relese image ... >>> tag hello-world:meta-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 as registry.lain.local/hello-world:meta-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 >>> tag hello-world:release-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 as registry.lain.local/hello-world:release-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 >>> Done lain tag. [vagrant@lain hello-world]$ lain push local # 相似於 docker push,將鏡像推送到 LAIN 集羣 >>> Pushing meta and release images ... >>> pushing image registry.lain.local/hello-world:meta-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 ... The push refers to a repository [registry.lain.local/hello-world] 1a4886bd9611: Layer already exists meta-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005: digest: sha256:daed70190af5fa980d6963fd3a6350591708c1568e180fe85e7eb6cfdd12d998 size: 524 >>> pushing image registry.lain.local/hello-world:release-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 ... The push refers to a repository [registry.lain.local/hello-world] 1a2245680fe1: Layer already exists dfe083dd50ba: Layer already exists edac683c8e67: Layer already exists 0372f18510d4: Layer already exists c0b53d6ac422: Layer already exists bcf20a0a17f3: Layer already exists 9d039e60afe3: Layer already exists a172d29265f3: Layer already exists e6562eb04a92: Layer already exists 596280599f68: Layer already exists 5d6cbe0dbcf9: Layer already exists release-1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005: digest: sha256:1cea69b6ed882fcc16f1f5661b3830a8b3f20263264c51d0610b8ec09e72a439 size: 2626 >>> Done lain push. [vagrant@lain hello-world]$ lain deploy local # 將應用部署到 LAIN 集羣 >>> Begin deploy app hello-world to local ... upgrading... Done. >>> app hello-world deploy operation: >>> last version: 1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 >>> this version: 1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005 >>> if shit happened, rollback your app by: >>> lain deploy -v 1496631978-a46ef7afcbbc18c1c1248bcbb84fa770d0758005
lain tag
爲鏡像添加倉庫前綴,以後才能進行 lain push
release
鏡像包含了編譯成果,未來會以這個鏡像爲基礎運行容器meta
鏡像包含 lain.yaml
文件,用於 LAIN 集羣解析,用戶不須要關心lain deploy local
以後可使用 lain ps local
查詢部署結果。此時,能夠經過如下命令訪問 hello-world
:
[vagrant@lain hello-world]$ curl -H "Host: hello-world.lain.local" http://192.168.77.201 Hello, LAIN.
或者能夠先更改 /etc/hosts
文件,而後直接使用域名訪問:
[vagrant@lain hello-world]$ echo "192.168.77.201 hello-world.lain.local" >> /etc/hosts [vagrant@lain hello-world]$ curl http://hello-world.lain.local Hello, LAIN.
上面的 192.168.77.201
是本地 LAIN 集羣的虛擬 IP,沒有以 vip
方式啓動,請使用 192.168.77.21
獲得了 Hello, LAIN.
的響應,符合咱們的預期。