用Docker彈性部署自己的服務
很久不看docker的東西了,之前瞭解的一些基本命令都忘得差不多了,適逢工作需要,再來複習鞏固下。今天想完成的是:藉助docker不部署下自己的服務。
環境準備
都說“巧婦難為無米之炊”,所以還是需要先準備下的。
OS:Ubuntu 16.04, 2G記憶體
docker:1.13.2
coding language: golang (gin web framework)
編碼
將服務跑起來,是我們要完成的第一個步驟,而且是最重要的一個步驟。所以這一步需要仔細除錯,為了方便,我就寫的簡單點。
- app.go
package main import ( "os" "log" "github.com/gin-gonic/gin" "net/http" "time" ) func GetHostName() string { hostname, err := os.Hostname() if err != nil { log.Fatal(err) } return hostname } func GetCurrentTime() string { timer := time.Now() return timer.String() } func startGinApp() { app := gin.Default() app.GET("/ping", func(context *gin.Context) { context.JSON(http.StatusOK, gin.H{ "message": "當前為您服務的主機為:" + GetHostName(), }) }) app.GET("/", func(context *gin.Context) { context.JSON(http.StatusOK, gin.H{ "message": "當前時間為:" + GetCurrentTime(), }) }) app.Run(":8080") } func main() { startGinApp() }
- 把服務跑起來
go run app.go
- curl一下看看服務是否正確跑起來了
➜gin curl http://localhost:8080 {"message":"當前時間為:2018-10-14 11:31:23.016121853 +0800 CST m=+0.254631109"}% ➜gin curl http://localhost:8080/ping {"message":"當前為您服務的主機為:BiaodeMacBook-Pro.local"}% ➜gin
製作Makefile
經過剛才的測試,程式碼可以正確跑起來了。但是要做到“一次編碼,到處執行”,還是需要在構建階段下點心思的,為了更好的維護,藉助Makefile來規範構建過程,是比較合適的方法。
- Makefile
# 這個是註釋 # 開頭可以宣告一大堆變數名 BUILD_NAME ?= httpserver COMPILER ?= go BUILD ?= build # 上方留一個空格,區分變數區和構建區 all: build test deploy clean build: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(COMPILER) $(BUILD) -o $(BUILD_NAME) test: echo "test over." deploy: echo "deploy over." clean: echo "clean over." .PHONY: build test deploy clean
- 構建服務
➜gin ls Makefile app.go ➜gin make all go build -o httpserver echo "test over." test over. echo "deploy over." deploy over. echo "clean over." clean over. ➜gin ls Makefileapp.gohttpserver ➜gin ./httpserver & [1] 6450 ➜gin [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env:export GIN_MODE=release - using code:gin.SetMode(gin.ReleaseMode) [GIN-debug] GET/ping--> main.startGinApp.func1 (3 handlers) [GIN-debug] GET/--> main.startGinApp.func2 (3 handlers) [GIN-debug] Listening and serving HTTP on :8080 ➜gin curl http://localhost:8080/ping [GIN] 2018/10/14 - 11:50:23 | 200 |214.161µs |::1 | GET/ping {"message":"當前為您服務的主機為:BiaodeMacBook-Pro.local"}% ➜gin
好了基本沒什麼問題,然後就可以通過scp命令將檔案拷貝到linux伺服器上了。
製作Dockerfile
由於golang構建出來的是二進位制可執行程式,所以製作Dockerfile很簡單。
- Dockerfile
FROM ubuntu:latest MAINTAINER guopu [email protected] WORKDIR /app EXPOSE 8080 ADD . /app CMD ["./httpserver"]
- 構建自己的映象
root@Server218 /h/d/g/d/httpserver# docker images REPOSITORYTAGIMAGE IDCREATEDSIZE ginserverlatest6277a0180f4f19 hours ago101 MB flaskindockerlatest170c6c0a41db22 hours ago131 MB python2.7-slim14dad3ead5f44 days ago120 MB docker/compose1.23.0-rc2dc59a0b5e9815 days ago45.6 MB ubuntulatestcd6d8154f1e15 weeks ago84.1 MB root@Server218 /h/d/g/d/httpserver# docker build -t httpserver . Sending build context to Docker daemon 17.07 MB Step 1/6 : FROM ubuntu:latest ---> cd6d8154f1e1 Step 2/6 : MAINTAINER guopu [email protected] ---> Running in 7106748df3ad ---> 0ae808029537 Removing intermediate container 7106748df3ad Step 3/6 : WORKDIR /app ---> 7278bf9659e7 Removing intermediate container f7fdc76b19a8 Step 4/6 : EXPOSE 8080 ---> Running in bedfabcb4b16 ---> edf4c123f72f Removing intermediate container bedfabcb4b16 Step 5/6 : ADD . /app ---> 36390e554a2f Removing intermediate container b14cce9da53e Step 6/6 : CMD ./httpserver ---> Running in 6682c8364717 ---> b490fef8a9ca Removing intermediate container 6682c8364717 Successfully built b490fef8a9ca root@Server218 /h/d/g/d/httpserver# docker images REPOSITORYTAGIMAGE IDCREATEDSIZE httpserverlatestb490fef8a9ca4 seconds ago101 MB ginserverlatest6277a0180f4f19 hours ago101 MB flaskindockerlatest170c6c0a41db22 hours ago131 MB python2.7-slim14dad3ead5f44 days ago120 MB docker/compose1.23.0-rc2dc59a0b5e9815 days ago45.6 MB ubuntulatestcd6d8154f1e15 weeks ago84.1 MB root@Server218 /h/d/g/d/httpserver#
- 讓服務在docker中跑起來
root@Server218 /h/d/g/d/httpserver# docker run -d-p 8000:8080 httpserver ebb1926206cdaf16eae9f4e13d5a7e70dd695da91463b438f77e45c6f65d3323 root@Server218 /h/d/g/d/httpserver# docker ps CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES ebb1926206cdhttpserver"./httpserver"4 seconds agoUp 3 seconds0.0.0.0:8000->8080/tcpnostalgic_wright root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ping {"message":"當前為您服務的主機為:ebb1926206cd"}~ root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ {"message":"當前時間為:2018-10-14 04:14:29.116207751 +0000 UTC"}~root@Server218 /h/d/g/d/httpserver#
至此,看起來服務已經成功在伺服器環境下的docker中運行了。
彈性服務
一個容器跑一個服務,有些服務訪問峰差很大的場景,就需要做下彈性適配,於是需要用一下docker swarm服務。這個在linux環境下需要進行安裝。具體可以參考官網連結:ofollow,noindex">https://github.com/docker/compose/releases
其執行以來一個YAML配置檔案,具體細節不多說,上手吧。
- docker-compose.yml
version: "3" services: web: image: httpserver:latest deploy: replicas: 5 resources: limits: cpus: "0.1" memory: 50M restart_policy: condition: on-faliure ports: - "8000:8080" networks: - webnet networks: webnet:
- 初始化swarm
root@Server218 /h/d/g/d/httpserver# docker swarm init Swarm initialized: current node (atiuy6c8k1qcig5w3br1bwf0n) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-5e0sj0glbwl5w5rqytyqokeg91n7piwdyw9ik598x0poiz5s20-do445zhrdr5io93lplov42c2y \ 172.31.237.68:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. root@Server218 /h/d/g/d/httpserver#
- 釋出服務到swarm中
root@Server218 /h/d/g/d/httpserver# docker stack deploy -c docker-compose.yml httpserver Creating service httpserver_web root@Server218 /h/d/g/d/httpserver# root@Server218 /h/d/g/d/httpserver# root@Server218 /h/d/g/d/httpserver# root@Server218 /h/d/g/d/httpserver# docker stack ps httpserver IDNAMEIMAGENODEDESIRED STATECURRENT STATEERRORPORTS kvpvwptlj44chttpserver_web.1httpserver:latestServer218RunningRunning 14 seconds ago 6549g79dz5izhttpserver_web.2httpserver:latestServer218RunningRunning 14 seconds ago xkz42mnetmwshttpserver_web.3httpserver:latestServer218RunningRunning 14 seconds ago rpziwzmpogn2httpserver_web.4httpserver:latestServer218RunningRunning 14 seconds ago y2kfe8bp09ldhttpserver_web.5httpserver:latestServer218RunningRunning 6 seconds ago root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ping {"message":"當前為您服務的主機為:a5419e3d3f9c"}~ root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ping {"message":"當前為您服務的主機為:f636819bd9c4"}~ root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ping {"message":"當前為您服務的主機為:97a6e3c9a064"}~ root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ping {"message":"當前為您服務的主機為:7f1b28e14970"}~ root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ping {"message":"當前為您服務的主機為:0ce251661188"}~ root@Server218 /h/d/g/d/httpserver# curl http://localhost:8000/ping {"message":"當前為您服務的主機為:a5419e3d3f9c"}~ root@Server218 /h/d/g/d/httpserver#
-
例項彈性變化
具體的操作只需要修改
docker-compose.yml
中的replicas的數量即可。然後重新使用:
docker stack deploy -c docker-compose.yml httpserver
釋出就可以了,可以看出swarm管理下的例項會進行自動的負載均衡。
- 關停服務
root@Server218 /h/d/g/d/httpserver# docker stack ls NAMESERVICES httpserver1 root@Server218 /h/d/g/d/httpserver# docker stack rm httpserver Removing service httpserver_web Removing network httpserver_webnet root@Server218 /h/d/g/d/httpserver# docker stack ls NAMESERVICES root@Server218 /h/d/g/d/httpserver#
- 關掉swarm
root@Server218 /h/d/g/d/httpserver# docker swarm leave --force Node left the swarm. root@Server218 /h/d/g/d/httpserver#
總結
最後,回頭看看這個目錄。
root@Server218 /h/d/g/d/httpserver# ls -al total 16688 drwxr-xr-x 2 root root4096 Oct 14 12:20 ./ drwxr-xr-x 5 root root4096 Oct 14 12:00 ../ -rw-r--r-- 1 root root121 Oct 14 12:11 Dockerfile -rw-r--r-- 1 root root362 Oct 14 12:01 Makefile -rw-r--r-- 1 root root682 Oct 14 12:01 app.go -rw-r--r-- 1 root root385 Oct 14 12:27 docker-compose.yml -rwxr-xr-x 1 root root 17063672 Oct 14 12:03 httpserver* root@Server218 /h/d/g/d/httpserver#
基本上,在docker中彈性部署自己的服務就結束了,基本上也能滿足需要。