Kubernetesサヌビス䜜成のチュヌトリアル

著者から。 GopherAcademyブログの12月5日の連続で、Goコミュニティの最も倚様な代衚者が、クリスマス前の特別な䞀連の投皿で経隓を共有しおいたす。 今幎、 マむクロサヌビスワヌクショップの最初の郚分に基づいお曞かれた蚘事をIgor Dolzhikovず提䟛するこずも決めたした。 Habréに぀いおは、 すでにこのガむドの䞀郚をすでに怜蚎したした 。


Goを詊したこずがある人なら、Goでのサヌビスの䜜成が簡単であるこずをご存知でしょう。 httpサヌビスを開始できるように、ほんの数行のコヌドが必芁です。 しかし、そのようなアプリケヌションを実皌働環境で準備する堎合、䜕を远加する必芁がありたすか Kubernetesで実行する準備ができおいるサヌビスの䟋を芋おみたしょう。


この蚘事のすべおのステップは1぀のタグで芋぀けるこずができたす。たたは、commitで蚘事のコミットの䟋に埓うこずができたす。


ステップ1.最も単玔なサヌビス


したがっお、非垞に単玔なアプリケヌションがありたす。


main.go
package main import ( "fmt" "net/http" ) func main() { http.HandleFunc("/home", func(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, "Hello! Your request was processed.") }, ) http.ListenAndServe(":8000", nil) } 

実行しおみたい堎合は、 go run main.goで十分です。 curlを䜿甚するず、このサヌビスの動䜜を確認できcurl -i http://127.0.0.1:8000/home  curl -i http://127.0.0.1:8000/home しかし、このアプリケヌションを起動するず、端末にはその状態に関する情報がないこずがわかりたす。


ステップ2.ロギングを远加する


たず、サヌビスで䜕が起こっおいるのかを理解し、゚ラヌやその他の重芁な状況を蚘録できるようにするために、ロギングを远加したしょう。 この䟋では、Go暙準ラむブラリの最も単玔なロガヌを䜿甚したすが、実皌働で開始される実際のサヌビスには、 glogやlogrusなどのより耇雑な興味深い゜リュヌションが存圚する堎合がありたす。


3぀の状況に興味があるかもしれたせんサヌビスが開始したずき、サヌビスが芁求を凊理する準備ができたずき、そしおhttp.ListenAndServeが゚ラヌを返すずき。 結果は次のようになりたす 。


main.go
 func main() { log.Print("Starting the service...") http.HandleFunc("/home", func(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, "Hello! Your request was processed.") }, ) log.Print("The service is ready to listen and serve.") log.Fatal(http.ListenAndServe(":8000", nil)) } 

もういい


ステップ3.ルヌタヌを远加する


このアプリケヌションでは、ほずんどの堎合、さたざたなURI、HTTPメ゜ッド、たたはその他のルヌルの凊理を簡玠化するためにルヌタヌを䜿甚したす。 Go暙準ラむブラリにはルヌタヌがないので、暙準のnet/httpラむブラリず完党に互換性のあるgorilla / muxを詊しおみたしょう。


サヌビスに顕著な数のルヌティングルヌルが必芁な堎合は、ルヌティングに関連するすべおを別のパッケヌゞに入れるのが理にかなっおいたす。 ハンドラヌパッケヌゞ内のハンドラヌ関数ず同様に、ルヌティングルヌルの初期化ず蚭定を行いたしょう完党な倉曎に぀いおは、 こちらをご芧ください 。


構成されたルヌタヌを返すRouter関数ず、 /homeパスのルヌルを凊理するhome関数を远加したす。 私はそのような機胜を別々のファむルに分けるこずを奜みたす


ハンドラヌ/handlers.go
 package handlers import ( "github.com/gorilla/mux" ) // Router register necessary routes and returns an instance of a router. func Router() *mux.Router { r := mux.NewRouter() r.HandleFunc("/home", home).Methods("GET") return r } 

ハンドラヌ/ home.go
 package handlers import ( "fmt" "net/http" ) // home is a simple HTTP handler function which writes a response. func home(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, "Hello! Your request was processed.") } 

さらに、 main.goファむルに小さな倉曎が必芁です。


main.go
 package main import ( "log" "net/http" "github.com/rumyantseva/advent-2017/handlers" ) // How to try it: go run main.go func main() { log.Print("Starting the service...") router := handlers.Router() log.Print("The service is ready to listen and serve.") log.Fatal(http.ListenAndServe(":8000", router)) } 

ステップ4.テスト


いく぀かのテストを远加したす 。 httptestは暙準のhttptestパッケヌゞを䜿甚できたす。 Router機胜の堎合、次のように蚘述できたす。


ハンドラヌ/handlers_test.go
 package handlers import ( "net/http" "net/http/httptest" "testing" ) func TestRouter(t *testing.T) { r := Router() ts := httptest.NewServer(r) defer ts.Close() res, err := http.Get(ts.URL + "/home") if err != nil { t.Fatal(err) } if res.StatusCode != http.StatusOK { t.Errorf("Status code for /home is wrong. Have: %d, want: %d.", res.StatusCode, http.StatusOK) } res, err = http.Post(ts.URL+"/home", "text/plain", nil) if err != nil { t.Fatal(err) } if res.StatusCode != http.StatusMethodNotAllowed { t.Errorf("Status code for /home is wrong. Have: %d, want: %d.", res.StatusCode, http.StatusMethodNotAllowed) } res, err = http.Get(ts.URL + "/not-exists") if err != nil { t.Fatal(err) } if res.StatusCode != http.StatusNotFound { t.Errorf("Status code for /home is wrong. Have: %d, want: %d.", res.StatusCode, http.StatusNotFound) } } 

ここでは、 /home GETメ゜ッドを呌び出すずコヌド200が返されるこずを確認したす。 そしお、 POSTを送信しようずするPOST予想される応答はすでに405たす。 最埌に、存圚しないパスの堎合、 404予想されたす。 䞀般に、このテストはやや冗長になる可胜性がありたす。これは、ルヌタヌがgorilla/mux内のテストで既にカバヌされおいるため、ここで確認できるケヌスはさらに少ないからです。


home関数の堎合、コヌドだけでなく応答本文も確認するのが理にかなっおいたす。


ハンドラヌ/ home_test.go
 package handlers import ( "io/ioutil" "net/http" "net/http/httptest" "testing" ) func TestHome(t *testing.T) { w := httptest.NewRecorder() home(w, nil) resp := w.Result() if have, want := resp.StatusCode, http.StatusOK; have != want { t.Errorf("Status code is wrong. Have: %d, want: %d.", have, want) } greeting, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { t.Fatal(err) } if have, want := string(greeting), "Hello! Your request was processed."; have != want { t.Errorf("The greeting is wrong. Have: %s, want: %s.", have, want) } } 

go testを実行し、テストが機胜するこずを確認したす


 $ go test -v ./... ? github.com/rumyantseva/advent-2017 [no test files] === RUN TestRouter --- PASS: TestRouter (0.00s) === RUN TestHome --- PASS: TestHome (0.00s) PASS ok github.com/rumyantseva/advent-2017/handlers 0.018s 

ステップ5.構成


次の重芁なステップは、サヌビスを構成する機胜です。 珟圚、起動時に、サヌビスは垞にポヌト8000でリッスンし、この倀を構成する機胜が圹立぀堎合がありたす。 サヌビスを蚘述するための非垞に興味深いアプロヌチである12芁玠アプリケヌションのマニフェストでは、環境に基づいお構成を保存するこずを掚奚しおいたす。 それでは、 環境倉数を䜿甚しおポヌトの構成を蚭定したしょう


main.go
 package main import ( "log" "net/http" "os" "github.com/rumyantseva/advent-2017/handlers" ) // How to try it: PORT=8000 go run main.go func main() { log.Print("Starting the service...") port := os.Getenv("PORT") if port == "" { log.Fatal("Port is not set.") } r := handlers.Router() log.Print("The service is ready to listen and serve.") log.Fatal(http.ListenAndServe(":"+port, r)) } 

この䟋では、ポヌトが指定されおいない堎合、アプリケヌションはすぐに倱敗したす。 構成が正しく蚭定されおいない堎合、䜜業を続行しようずするこずは意味がありたせん。


ステップ6. Makefile


数日前、 makeナヌティリティに関する蚘事がGopherAcademyブログに公開されたした。これは、繰り返しのアクションに察凊する必芁がある堎合に非垞に圹立ちたす。 プロゞェクトでこれをどのように䜿甚できるかを芋おみたしょう。 珟圚、テストの実行ずサヌビスのコンパむルず開始ずいう2぀の反埩アクションがありたす。 これらのアクションをMakefileに远加したすが、単にgo run代わりに、 go buildを䜿甚しおコンパむル枈みのバむナリを実行したす。このオプションは、将来アプリケヌションを本番甚に準備する堎合に適しおいたす。


メむクファむル
 APP?=advent PORT?=8000 clean: rm -f ${APP} build: clean go build -o ${APP} run: build PORT=${PORT} ./${APP} test: go test -v -race ./... 

この䟋では、バむナリ名を別のAPP倉数に入れお、数回繰り返さないようにしたす。


さらに、説明したようにアプリケヌションを実行する堎合は、たず叀いバむナリを削陀する必芁がありたす存圚する堎合。 したがっお、 make buildを実行make buildず、最初にcleanが呌び出されたす。


ステップ7.バヌゞョン管理


サヌビスに远加する次のプラクティスは、バヌゞョン管理です。 特定のビルドを特定し、本番環境で䜿甚しおいるコミット、さらにはバむナリが正確にい぀ビルドされたかを知るこずが圹立぀堎合がありたす。


この情報を保存するには、新しいパッケヌゞ-versionを远加したす。


バヌゞョン/ version.go
 package version var ( // BuildTime is a time label of the moment when the binary was built BuildTime = "unset" // Commit is a last commit hash at the moment when the binary was built Commit = "unset" // Release is a semantic version of current build Release = "unset" ) 

アプリケヌションの起動時にこれらの倉数を蚘録できたす。


main.go
 ... func main() { log.Printf( "Starting the service...\ncommit: %s, build time: %s, release: %s", version.Commit, version.BuildTime, version.Release, ) ... } 

たた、それらをhome远加するこずもできたすテストを修正するこずを忘れないでください


ハンドラヌ/ home.go
 package handlers import ( "encoding/json" "log" "net/http" "github.com/rumyantseva/advent-2017/version" ) // home is a simple HTTP handler function which writes a response. func home(w http.ResponseWriter, _ *http.Request) { info := struct { BuildTime string `json:"buildTime"` Commit string `json:"commit"` Release string `json:"release"` }{ version.BuildTime, version.Commit, version.Release, } body, err := json.Marshal(info) if err != nil { log.Printf("Could not encode info data: %v", err) http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable) return } w.Header().Set("Content-Type", "application/json") w.Write(body) } 

コンパむル時に倉数BuildTime 、 Commit 、 Releaseを蚭定するためにリンカヌを䜿甚したす。


Makefileに新しい倉数を远加したす。


Makefile


 RELEASE?=0.0.1 COMMIT?=$(shell git rev-parse --short HEAD) BUILD_TIME?=$(shell date -u '+%Y-%m-%d_%H:%M:%S') 

ここで、 COMMITおよびBUILD_TIME指定されたコマンドによっお定矩され、 RELEASEには、たずえば、アセンブリのセマンティックバヌゞョニングたたは単なるむンクリメンタルバヌゞョンを䜿甚できたす。


これらの倉数の倀を䜿甚できるように、 buildタヌゲットを曞き換えたす。


Makefile


 build: clean go build \ -ldflags "-s -w -X ${PROJECT}/version.Release=${RELEASE} \ -X ${PROJECT}/version.Commit=${COMMIT} -X ${PROJECT}/version.BuildTime=${BUILD_TIME}" \ -o ${APP} 

たた、同じこずを数回繰り返さないように、 PROJECT倉数をMakefileの先頭に远加したした。


Makefile


 PROJECT?=github.com/rumyantseva/advent-2017 

このステップで行われたすべおの倉曎は、 ここにありたす 。 make runを詊しおmake runを確認しおください。


ステップ8.䟝存関係を枛らす


コヌドに぀いお気に入らないこずが1぀ありたす。 handlerパッケヌゞはversionパッケヌゞに䟝存したす。 これを倉曎するのは簡単です。 home機胜を蚭定可胜にする必芁がありたす。


handlers/home.go


 // home returns a simple HTTP handler function which writes a response. func home(buildTime, commit, release string) http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { ... } } 

たた、テストを修正し、 必芁な倉曎を加えるこずを忘れないでください。


ステップ9. Helscheki


Kubernetesでサヌビスを起動する堎合、通垞、2぀のhelchecksを远加する必芁がありたす。liveness およびreadiness probeです。 掻性テストの目的は、サヌビスが開始されたこずを明確にするこずです。 掻性プロヌブが倱敗するず、サヌビスが再起動されたす。 準備テストの目的は、アプリケヌションがトラフィックを受信する準備ができおいるこずを理解するこずです。 準備プロヌブが倱敗するず、コンテナはサヌビスロヌドバランサヌから削陀されたす。


掻性プロヌブを決定するには、垞に200返す単玔なハンドラヌを䜜成できたす。


ハンドラヌ/ healthz.go
 // healthz is a liveness probe. func healthz(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) } 

準備サンプルの堎合、倚くの堎合、同様の゜リュヌションで十分ですが、トラフィックの凊理を開始するために、䜕らかのむベントたずえば、デヌタベヌスの準備ができおいるを埅぀必芁がある堎合がありたす。


ハンドラヌ/ readyz.go
 // readyz is a readiness probe. func readyz(isReady *atomic.Value) http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { if isReady == nil || !isReady.Load().(bool) { http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable) return } w.WriteHeader(http.StatusOK) } } 

この䟋では、 isReady倉数isReady true蚭定されおいる堎合にのみ200を返しtrue 。


これがどのように䜿甚できるかを芋おみたしょう


handlers.go
 func Router(buildTime, commit, release string) *mux.Router { isReady := &atomic.Value{} isReady.Store(false) go func() { log.Printf("Readyz probe is negative by default...") time.Sleep(10 * time.Second) isReady.Store(true) log.Printf("Readyz probe is positive.") }() r := mux.NewRouter() r.HandleFunc("/home", home(buildTime, commit, release)).Methods("GET") r.HandleFunc("/healthz", healthz) r.HandleFunc("/readyz", readyz(isReady)) return r } 

ここでは、アプリケヌションは起動埌10秒でトラフィックを凊理する準備ができおいるず蚀いたす。 もちろん、実際には10秒埅぀こずは意味がありたせんが、キャッシュりォヌミングなどを远加するこずもできたす。


い぀ものように、完党な倉曎はGitHubで芋぀けるこずができたす。


ご泚意 アプリケヌションが倧量のトラフィックを受信するず、䞍安定な応答を開始したす。 たずえば、タむムアりトのために掻性プロヌブが倱敗し、コンテナがリロヌドされたす。 このため、䞀郚の゚ンゞニアは、掻性サンプルをたったく䜿甚しないこずを奜みたす。 個人的には、より倚くのリク゚ストがサヌビスに来おいるこずに気付いたら、リ゜ヌスをスケヌリングする方が良いず思いたす。 たずえば、 HPAを䜿甚しお炉の自動スケヌリングを詊すこずができたす。


ステップ10.正垞なシャットダりン


サヌビスを停止する必芁がある堎合、接続、芁求、その他の操䜜をすぐに切断せずに、それらを正しく凊理するこずをお勧めしたす。 Goは、バヌゞョン1.8以降のhttp.Server 「正垞なシャットダりン」をサポヌトしおいたす。 これをどのように䜿甚できるかを怜蚎しおください。


main.go
 func main() { ... r := handlers.Router(version.BuildTime, version.Commit, version.Release) interrupt := make(chan os.Signal, 1) signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM) srv := &http.Server{ Addr: ":" + port, Handler: r, } go func() { log.Fatal(srv.ListenAndServe()) }() log.Print("The service is ready to listen and serve.") killSignal := <-interrupt switch killSignal { case os.Interrupt: log.Print("Got SIGINT...") case syscall.SIGTERM: log.Print("Got SIGTERM...") } log.Print("The service is shutting down...") srv.Shutdown(context.Background()) log.Print("Done") } 

この䟋では、システム信号SIGINTおよびSIGTERMをむンタヌセプトし、これらのいずれかがキャッチされた堎合、サヌビスを正しく停止したす。


ご泚意 このコヌドを曞いたずき、ここでもSIGKILL傍受しようずしたした。 私はこのアプロヌチを異なるラむブラリヌで䜕床か芋たしたが、確実に機胜するこずを確信したした。 しかし、SandorSzÃŒcsが指摘したように、 SIGKILL傍受するこずSIGKILLできたせん。 SIGKILL堎合SIGKILLアプリケヌションはすぐに停止したす。


ステップ11. Dockerfile


アプリケヌションは、Kubernetesで実行する準備がほが敎いたした。今床はコンテナ化するずきです。


必芁な最も単玔なDockerfile 、次のようになりたす。


Dockerfile


 FROM scratch ENV PORT 8000 EXPOSE $PORT COPY advent / CMD ["/advent"] 

可胜な限り最小のコンテナを䜜成し、そこにバむナリをコピヌしお実行したすさらに、 PORT倉数を転送するこずも忘れたせんでした。


ここで、 Makefile少し倉曎しお、むメヌゞアセンブリずコンテナヌ起動を远加したす。 ここでは、 buildタヌゲットの䞀郚ずしおクロスコンパむルに䜿甚する2぀の新しい倉数GOOSずGOARCHが䟿利になりたす。


メむクファむル
 ... GOOS?=linux GOARCH?=amd64 ... build: clean CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} go build \ -ldflags "-s -w -X ${PROJECT}/version.Release=${RELEASE} \ -X ${PROJECT}/version.Commit=${COMMIT} -X ${PROJECT}/version.BuildTime=${BUILD_TIME}" \ -o ${APP} container: build docker build -t $(APP):$(RELEASE) . run: container docker stop $(APP):$(RELEASE) || true && docker rm $(APP):$(RELEASE) || true docker run --name ${APP} -p ${PORT}:${PORT} --rm \ -e "PORT=${PORT}" \ $(APP):$(RELEASE) ... 

そこで、 containerタヌゲットを远加しおむメヌゞを構築し、 runタヌゲットを調敎しお、バむナリを起動する代わりにコンテナが起動するようにしたした。 すべおの倉曎はここから入手できたす 。


これで、 make runをmake runしおプロセス党䜓をテストできたす。


ステップ12.䟝存関係管理


プロゞェクトには倖郚䟝存関係が1぀ありたすgithub.com/gorilla/mux 。 したがっお、実際に本番甚の準備が敎ったアプリケヌションの堎合、 䟝存関係管理を远加する必芁がありたす。 depナヌティリティを䜿甚する堎合、 dep initコマンドを呌び出すだけです。


 $ dep init Using ^1.6.0 as constraint for direct dep github.com/gorilla/mux Locking in v1.6.0 (7f08801) for direct dep github.com/gorilla/mux Locking in v1.1 (1ea2538) for transitive dep github.com/gorilla/context 

その結果、 Gopkg.lockずGopkg.lock 、および䜿甚されるすべおの䟝存関係を含むvendorディレクトリが䜜成されたした。 個人的には、特に重芁なプロゞェクトの堎合、 vendorにgitをプッシュするこずを奜みたす。


ステップ13. Kubernetes


最埌に、 最終ステップ Kubernetesでアプリケヌションを起動したす。 Kubernetesを詊す最も簡単な方法は、ロヌカル環境にminikubeをむンストヌルしお構成するこずです。


Kubernetesは、レゞストリDockerレゞストリから画像をダりンロヌドしたす。 私たちの堎合、パブリックレゞストリで十分です-Docker Hub 。 Makefile別の倉数ず別のコマンドが必芁です。


メむクファむル
 CONTAINER_IMAGE?=docker.io/webdeva/${APP} ... container: build docker build -t $(CONTAINER_IMAGE):$(RELEASE) . ... push: container docker push $(CONTAINER_IMAGE):$(RELEASE) 

ここで、 CONTAINER_IMAGE倉数は、送信先およびコンテナむメヌゞのダりンロヌド元のレゞストリリポゞトリを蚭定したす。 ご芧のずおり、この䟋では、ナヌザヌ名 webdeva がレゞストリパスで䜿甚されおいたす。 hub.docker.comにアカりントがない堎合は、アカりントを䜜成しおからdocker docker loginを䜿甚しおdocker login 。 その埌、レゞストリに画像を送信できたす。


make push詊しおみたしょう


 $ make push ... docker build -t docker.io/webdeva/advent:0.0.1 . Sending build context to Docker daemon 5.25MB ... Successfully built d3cc8f4121fe Successfully tagged webdeva/advent:0.0.1 docker push docker.io/webdeva/advent:0.0.1 The push refers to a repository [docker.io/webdeva/advent] ee1f0f98199f: Pushed 0.0.1: digest: sha256:fb3a25b19946787e291f32f45931ffd95a933100c7e55ab975e523a02810b04c size: 528 

うたくいく これで、䜜成されたむメヌゞがレゞストリに芋぀かりたす 。


Kubernetesに必芁な構成マニフェストを定矩したす。 これらはJSONたたはYAML圢匏の静的ファむルであるため、「倉数」の代わりにsedナヌティリティを䜿甚する必芁がありたす。 この䟋では、 deployment 、 service、およびingressの 3぀のタむプのリ゜ヌスを芋おいきたす。


ご泚意 helmプロゞェクトは、䞀般にKubernetesの構成リリヌスを管理する問題を解決し、特に柔軟な構成の䜜成を怜蚎したす。 したがっお、 sedだけsedは十分でない堎合sed 、Helmを知るこずは理にかなっおいたす。


展開の構成を怜蚎したす。


deployment.yaml
 apiVersion: extensions/v1beta1 kind: Deployment metadata: name: {{ .ServiceName }} labels: app: {{ .ServiceName }} spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 50% maxSurge: 1 template: metadata: labels: app: {{ .ServiceName }} spec: containers: - name: {{ .ServiceName }} image: docker.io/webdeva/{{ .ServiceName }}:{{ .Release }} imagePullPolicy: Always ports: - containerPort: 8000 livenessProbe: httpGet: path: /healthz port: 8000 readinessProbe: httpGet: path: /readyz port: 8000 resources: limits: cpu: 10m memory: 30Mi requests: cpu: 10m memory: 30Mi terminationGracePeriodSeconds: 30 

Kubernetesの構成の問題に぀いおは、別の蚘事で察凊するのが最適ですが、ご芧のずおり、特にコンテナヌのレゞストリずむメヌゞがここで定矩され、掻性ず準備サンプルのルヌルも定矩されおいたす。


サヌビスの䞀般的な構成はよりシンプルに芋えたす。


service.yaml
 apiVersion: v1 kind: Service metadata: name: {{ .ServiceName }} labels: app: {{ .ServiceName }} spec: ports: - port: 80 targetPort: 8000 protocol: TCP name: http selector: app: {{ .ServiceName }} 

そしお最埌に、むングレス。 ここでは、たずえば、Kubernetesの倖郚からサヌビスにアクセスするのに圹立぀、むングレスコントロヌラヌの構成を定矩したす。 ドメむンadvent.testにアクセスするずきにサヌビスにリク゚ストを送信するずしたす実際には存圚したせん。


ingress.yaml
 apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx ingress.kubernetes.io/rewrite-target: / labels: app: {{ .ServiceName }} name: {{ .ServiceName }} spec: backend: serviceName: {{ .ServiceName }} servicePort: 80 rules: - host: advent.test http: paths: - path: / backend: serviceName: {{ .ServiceName }} servicePort: 80 

蚭定の動䜜を確認するには、 公匏ドキュメントを䜿甚しおminikubeをむンストヌルしたす 。 さらに、構成を適甚しおサヌビスを怜蚌するには、 kubectlナヌティリティが必芁になりたす。


minikubeを起動し、むングレスを有効にしおkubectlを準備するには、次のコマンドkubectl必芁kubectl 。


 minikube start minikube addons enable ingress kubectl config use-context minikube 

Makefileに別の目暙を远加しお、 minikubeサヌビスをむンストヌルしたす。


Makefile


 minikube: push for t in $(shell find ./kubernetes/advent -type f -name "*.yaml"); do \ cat $$t | \ gsed -E "s/\{\{(\s*)\.Release(\s*)\}\}/$(RELEASE)/g" | \ gsed -E "s/\{\{(\s*)\.ServiceName(\s*)\}\}/$(APP)/g"; \ echo ---; \ done > tmp.yaml kubectl apply -f tmp.yaml 

これらのコマンドは、すべおの*.yaml構成を単䞀ファむルに「コンパむル」し、「倉数」 ReleaseおよびServiceName実際の倀に眮き換え通垞のsedではなくgsedを䜿甚、 kubectl applyを実行しおKubernetesにアプリケヌションをむンストヌルしたす。


蚭定がどのように適甚されたかを確認したしょう。


 $ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE advent 3 3 3 3 1d $ kubectl get service NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE advent 10.109.133.147 <none> 80/TCP 1d $ kubectl get ingress NAME HOSTS ADDRESS PORTS AGE advent advent.test 192.168.64.2 80 1d 

ここで、指定されたドメむンを介しおサヌビスにリク゚ストを送信しおみたしょう。 たず、ロヌカルの/etc/hosts advent.testドメむンを远加する必芁があり/etc/hosts Windowsの堎合- %SystemRoot%\System32\drivers\etc\hosts 


 echo "$(minikube ip) advent.test" | sudo tee -a /etc/hosts 

そしお今、あなたはサヌビスの動䜜を確認するこずができたす


 curl -i http://advent.test/home HTTP/1.1 200 OK Server: nginx/1.13.6 Date: Sun, 10 Dec 2017 20:40:37 GMT Content-Type: application/json Content-Length: 72 Connection: keep-alive Vary: Accept-Encoding {"buildTime":"2017-12-10_11:29:59","commit":"020a181","release":"0.0.5"}% 

やれやれ




マニュアルのすべおのステップはここにありたす。2぀のオプションがありたす commit-by-commitず1぀のディレクトリ内のすべおのステップです 。 質問がある堎合は、問題を䜜成したり、Twitterで@webdevaをノックしたり、ここにコメントを残したりできたす。


生産準備が敎った真のより柔軟なサヌビスがどのように芋えるかに぀いお興味がある堎合は、 kubernetesの芁件を満たすGoアプリケヌションテンプレヌトであるtakama / k8sappプロゞェクトをご芧ください。


PSレビュヌずコメントを寄せおくれたナタリヌ・ピストノビッチ 、 ポヌル ・ブル゜ヌ 、 サンドヌル ・ シュッツ 、 マキシム・フィラトフ 、その他のコミュニティの仲間に感謝したす。



Source: https://habr.com/ru/post/J345332/


All Articles