By 和風信使 ( @taichunmin )
Create Droplet
→One-click Apps
→Docker 1.x.x on 14.04
Ubuntu Server 14.04 LTS (HVM)
→自己安裝 Docker
如果你用 DigitalOcean 的
Docker 1.x.x on 14.04
就可以跳過啦。
- 請大家完成到可成功測試 Docker
sudo service docker start
sudo docker run hello-world
- 先開一個基礎的容器
# 開啟一個基礎的 ubuntu:14.04 指令
sudo docker run -ti ubuntu:14.04 /bin/bash
- 按照安裝教學安裝一次
- 將指令改成 non-interactive (不須互動,自動安裝)
- 再把指令複製到 Dockerfile
sudo apt-get update
sudo apt-get upgrade
- non-interactive
apt-get update -qq
apt-get upgrade -y
- Git
- Node.js
- 純文字編輯器 (Text Editor)
- 英文語系 (English locales)
sudo apt-get install git
- non-interactive
apt-get install -y git
sudo apt-get install nodejs npm
# 由於 git-it 預設使用 node 執行,故須 link
sudo ln -s /usr/bin/nodejs /usr/bin/node
- non-interactive
apt-get install -y nodejs npm
ln -s /usr/bin/nodejs /usr/bin/node
sudo apt-get install vim nano
- non-interactive
apt-get install -y vim nano
sudo npm install -g git-it
- non-interactive
npm install -g git-it
FROM ubuntu:14.04
RUN apt-get update -qq
RUN apt-get upgrade -y
RUN apt-get install -y git nodejs npm vim nano
RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN npm install -g git-it
- Docker 官方範例 https://goo.gl/edqX2W
# ... 略
RUN apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:git-it' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
請注意 Docker Compose 的版本。
curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
參考網址
version: '2'
services:
client:
build: client/
ports:
- "22"
YML 的縮行很重要
- 可自由指定數量
sudo docker-compose up -d
sudo docker-compose scale client=5
如果開的機器 RAM 較小,則建議手動新增 swap 以供 Docker 使用。
docker-compose ps
Name Ports
--------------------------------------------------------------------
gititcoursedocker_client_1 0.0.0.0:32794->22/tcp
scoreboard 0.0.0.0:22000->22/tcp, 0.0.0.0:80->80/tcp
在 Dockerfile 加上
RUN chage -d 0 root
- 使用 SSH 進入 client
- 登入後立即要求更改 root 密碼
- 輸入
git-it
後進入選題選單
- 顯示 client 的 SSH PORT
- 顯示哪個 client 還沒有人使用
- 顯示學員的名字
- 顯示學員的解題數
- 使用網頁公開資料
# Dockerfile
LABEL role="git-it-client"
curl http://host/containers/json?filters={"label":["role=git-it-client"]}
- docker ps 範例
docker ps --filter "label=role=git-it-client" --format '"{{.ID}}":{{.Ports}}'
- 查詢登入密碼是否已被更改
OWNED=`[ "never" = "$(chage -l root | grep 'Password expires' | sed -r 's/^[^:]+: //')" ] && echo '1' || echo '0'`
- client 定期 (cron) 回報給 scoreboard
git-it 的題目會要求幫 git 設定使用者的名字和 GitHub 的帳號,所以直接抓 git 的 user.name
和 user.username
就好了。
NAME=`git config --global user.name || hostname`
GITHUB=`git config --global user.username || echo ''`
git-it 會把解題數存放在 ~/.config/git-it/completed.json
COMPLETED=`test -r /root/.config/git-it/completed.json && cat /root/.config/git-it/completed.json || echo []`
sudo apt-get install curl
- non-interactive
apt-get install -y curl
#!/bin/bash
COMPLETED=`test -r /root/.config/git-it/completed.json && cat /root/.config/git-it/completed.json || echo []`
MID=`hostname`
NAME=`git config --global user.name || hostname`
GITHUB=`git config --global user.username || echo ''`
OWNED=`[ "never" = "$(chage -l root | grep 'Password expires' | sed -r 's/^[^:]+: //')" ] && echo '1' || echo '0'`
curl \
--data-urlencode "completed=${COMPLETED}" \
--data-urlencode "mid=${MID}" \
--data-urlencode "name=${NAME}" \
--data-urlencode "github=${GITHUB}" \
--data-urlencode "owned=${OWNED}" \
http://scoreboard/completed/update
每分鐘回報 client 的資料給 scoreboard,以 root 身份執行。
* * * * * root /usr/bin/scoreboard-reporter.sh >> /dev/null 2>&1
RUN apt-get -y install rsyslog
ADD crontab /etc/crontab
ADD client-start.sh /usr/bin/client-start.sh
ADD scoreboard-reporter.sh /usr/bin/scoreboard-reporter.sh
RUN chmod +x /usr/bin/client-start.sh
RUN chmod +x /usr/bin/scoreboard-reporter.sh
RUN touch /var/log/cron.log
由於我們需要執行的程式已經超過一個了,為了避免 Dockerfile 的 CMD 指令太過複雜,所以我們要開新 client 要執行的指令都寫在 client-start.sh
#!/bin/sh
# client-start.sh
sleep 5
rsyslogd
cron
/usr/sbin/sshd # 刪掉 -D 參數
/usr/bin/scoreboard-reporter.sh # 開機時先回報一次
tail -F /var/log/syslog /var/log/cron.log
# 要把舊的刪除,因為只有最後一個 CMD 有效
CMD /usr/bin/client-start.sh
- 請參考 https://github.com/taichunmin/git-it-course-docker/tree/master/client
- client 完成到可以回報資料給 scoreboard
version: '2'
services:
scoreboard:
# build: scoreboard/
image: taichunmin/git-it-course-docker:scoreboard
ports:
- "80:80"
- "22000:22"
container_name: scoreboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- port 80 是網頁伺服器
- port 22 是 SSH,為了方便就固定對應到 22000
- 設定了
container_name
可以避免誤開多台 - 設定
volumes
可以讓 scoreboard 存取 Remote API
利用 Volumes
version: '2'
services:
scoreboard:
# 省略
volumes:
- /var/run/docker.sock:/var/run/docker.sock
version: '2'
services:
client:
build: client/
ports:
- "22"
links:
- scoreboard
depends_on:
- scoreboard
- 讓 docker-compose 自動對應 port 22 出來
- LINK 到 scoreboard,讓 client 可以回報資料
depends_on
讓 docker-compose 確保有 scoreboard