封尘网

让学习成为一种习惯!

Go程序跑在Docker中并使用health check示例

Go是一种静态类型,编译后可以在各种系统环境中运行,对于高性能分布式系统领域而言,Go语言无疑比大多数其它语言有着更高的开发效率。

现在微服务的流行,让Go程序跑起来更方便。本次记录参照Go基础教程的示例实现。让Go程序跑在Docker容器中,并使用docker Health check健康检查功能。


项目main.go代码:
package main

import (
    "flag"
    "fmt"
    "log"
    "net/http"
)

func homehandler(w http.ResponseWriter, r *http.Request) {
    log.Println("http request.")
    fmt.Fprintln(w, "Golang Web server is running. ")

}

func pinger(port string) error {
    resp, err := http.Get("http://localhost:" + port)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    if resp.StatusCode != 200 {
        return fmt.Errorf("server is not return 200 stauts code.")
    }
    return nil

}

func main() {
    var port string
    var ping bool
    flag.StringVar(&port, "port", "8000", "server port")
    flag.StringVar(&port, "p", "8000", "server port")
    flag.BoolVar(&ping, "ping", false, "check server live")
    flag.Parse()

    //检查状态
    if ping {
        if err := pinger(port); err != nil {
            log.Printf("ping server error: %v\n", err)
        }
        return
    }
    http.HandleFunc("/", homehandler)
    log.Println("http server run on " + port + " port")
    log.Fatal(http.ListenAndServe(":"+port, nil))
}
Dockerfile文件内容:
FROM plugins/base:multiarch
add helloworld /bin/
EXPOSE 8000
HEALTHCHECK --start-period=5s --interval=30s --timeout=30s --retries=3 \
  CMD ["/bin/helloworld", "-ping"]
  ENTRYPOINT ["/bin/helloworld"]
打包程序Makefile文件内容:
build_linux_amd64:
    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -v -a -o release/linux/amd64/helloworld

build_linux_i386:
    CGO_ENABLED=0 GOOS=linux GOARCH=i386 go build -v -a -o release/linux/i386/helloworld

docker:
    docker build -t helloworld .

打包GO程序,因为系统使用64位的所以选择编译:

[root@docker-ce test]# make build_linux_amd64 Makefile

使用基础镜像,因为够小可以事先拉下来:

docker build \
--label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \
--file docker/Dockerfile.linux.multiarch \
--tag plugins/base:multiarch .
打包成Docker镜像
[root@docker-ce test]# make docker Makefile
docker build -t helloworld .
Sending build context to Docker daemon  6.674MB
Step 1/5 : FROM plugins/base:multiarch
 ---> 92bf59f52f26
Step 2/5 : add release/linux/amd64/helloworld /bin/
 ---> d9db90fb34d9
Step 3/5 : EXPOSE 8080
 ---> Running in 34bf95cf6370
Removing intermediate container 34bf95cf6370
 ---> 0946fe4e1006
Step 4/5 : HEALTHCHECK --start-period=5s --interval=30s --timeout=30s --retries=3   CMD ["/bin/helloworld", "-ping"]
 ---> Running in 06d32d4e7b9c
Removing intermediate container 06d32d4e7b9c
 ---> ecdd5067e9ae
Step 5/5 : ENTRYPOINT ["/bin/helloworld"]
 ---> Running in 5c232e917e21
Removing intermediate container 5c232e917e21
 ---> 232ac0d24f85
Successfully built 232ac0d24f85
Successfully tagged helloworld:latest
make: Nothing to be done for `Makefile'.

打包后的镜像大小,其它就是Go程序大小差不多了。

[root@docker-ce test]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
helloworld          latest              232ac0d24f85        2 minutes ago       6.96MB
plugins/base        multiarch           92bf59f52f26        About an hour ago   293kB

启动容器查看效果,通过当前的控制台查看效果:

[root@docker-ce test]# docker run -p 3000:8000 helloworld
2019/06/26 09:05:10 http server run on 8000 port

查看启动后的容器,刚才开始程序(health: starting)

[root@docker-ce ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                            PORTS                              NAMES
639169df414c        hello               "/bin/helloworld"   7 seconds ago       Up 5 seconds (health: starting)   8080/tcp, 0.0.0.0:4000->8000/tcp   nifty_jones

过30秒左右就可以看到效果了,使用JSON格式化容易看。

[root@docker-ce ~]# docker inspect --format '{{json .State.Health}}' 639169df414c | python -m json.tool
{
    "FailingStreak": 0,
    "Log": [
        {
            "End": "2019-06-26T14:13:04.613608178+08:00",
            "ExitCode": 0,
            "Output": "",
            "Start": "2019-06-26T14:12:59.50654346+08:00"
        }
    ],
    "Status": "healthy"
}

访问Docker主机的Ip加端口即可看到效果:

curl http://localhost:3000