2MB REST API 구축 -- 스크래치 이미지 에피소드 III
마지막 에피소드는 히트를 쳤습니다. 계속하기 전에 확인하십시오.
여기에서 간단한 Go REST API 프록시를 빌드하여 더 설명적이고 유용한 작업을 수행할 것입니다. 이것은 우리가 hello world 이상의 것을 할 수 있음을 보여주고 스크래치 이미지에 다른 종속성을 추가하는 방법을 보여줍니다.
REST API
이 프록시는
url
에서 리소스를 가져와 반환합니다. 이것은 원격 리소스를 캐싱하기 위한 일반적인 패턴입니다.예:
$ curl 'http://localhost:8080/?url=https%3A%2F%2Fwww.httpbin.org%2Fget' \
| jq .headers
{
"Accept-Encoding": "gzip",
"Host": "www.httpbin.org",
"User-Agent": "Go-http-client/1.1"
}
main.go
package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
url := r.FormValue("url")
if url == "" {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("\"url\" param is required"))
return
}
resp, err := http.Get(url)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Error fetching url [%s]: %s", url, err.Error())))
return
}
// stream the resp body to our HTTP response, w
writtenCount, err := io.Copy(w, resp.Body)
if err != nil || writtenCount == 0 {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte("Response was empty from url " + url))
return
}
})
if port := os.Getenv("PORT"); port != "" {
http.ListenAndServe(":"+port, nil)
} else {
log.Panic("PORT not set")
}
}
높은 수준에서
HandleFunc
쿼리 매개변수에서 http.Get(url)
를 호출하는 url
에 전달된 핸들러를 구현한 다음 url
의 본문을 클라이언트로 스트리밍합니다.마지막으로 우리는 환경에 의해 전달된
PORT
를 듣습니다.도커파일
FROM golang:stretch AS build
WORKDIR /build
RUN apt-get update && \
apt-get install -y xz-utils
ADD https://github.com/upx/upx/releases/download/v3.95/upx-3.95-amd64_linux.tar.xz /usr/local
RUN xz -d -c /usr/local/upx-3.95-amd64_linux.tar.xz | \
tar -xOf - upx-3.95-amd64_linux/upx > /bin/upx && \
chmod a+x /bin/upx
COPY . .
RUN GO111MODULE=off CGO_ENABLED=0 GOOS=linux \
go build -a -tags netgo -ldflags '-w -s' main.go && \
upx main
FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /build/main /main
WORKDIR /
CMD ["/main"]
다음은 몇 가지 새로운 개념을 보여줍니다.
-tags netgo
가 필요합니다. 빌드가 다른 동적 라이브러리로 끝나는 경우 C 도구 체인이 필요한 CGO_ENABLED=1 ... -extldflags "-static"
를 사용할 수 있습니다. upx
-- Ultimate Packer for Exes은 약 70%를 줄이는 데 사용됩니다http.Get()
호출 중) https 서버의 인증서를 인증할 수 있는 클라이언트 인증서 번들ca-certificates.crt
이 필요합니다.이미지 구축
docker build . -t go-http-proxy
docker images |grep go-http-proxy | awk '{print $7}'
2.16MB
100kb가 조금 넘지만 2MB도 나쁘지 않습니다! 이것은 우리가 사용했던 806MB 스트레치 이미지보다 99.5% 작습니다.
docker images |grep c0167164f9fa | awk '{print $7}'
806MB
실행 및 테스트
운영...
docker run -ePORT=8080 -p8080:8080 go-http-proxy
테스트...
curl 'http://localhost:8080/?url=https%3A%2F%2Fwww.httpbin.org%2Fget' | jq .headers
{
"Accept-Encoding": "gzip",
"Host": "www.httpbin.org",
"User-Agent": "Go-http-client/1.1"
}
안에 뭐가 들어있어
이 이미지에는 두 개의 레이어가 있습니다(
COPY
당 하나씩) -- 살펴보겠습니다.$ mkdir go-http-proxy && cd go-http-proxy
$ docker save go-http-proxy |tar -x
$ find . -iname layer.tar|xargs -n 1 tar -tf
main
etc/
etc/ssl/
etc/ssl/certs/
etc/ssl/certs/ca-certificates.crt
... 여전히 두 개의 파일만 있습니다.
다음 단계
이 시점에서 우리는 게임을 nodejs와 같은 스크립팅 언어로 레벨 업해야 합니다. 이 언어는 앱과 런타임 모두에서 훨씬 더 많은 종속성을 포함합니다.
➡️ 도커 이미지 축소에 대한 팁을 들어보겠습니다. 그리고 어떤 플랫폼이 처음부터 구축되기를 원하십니까?
Reference
이 문제에 관하여(2MB REST API 구축 -- 스크래치 이미지 에피소드 III), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tonymet/build-a-2mb-rest-api-scratch-images-episode-iii-1p9k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)