Tutorial Kubernetes - 1ere partie
Ce tutorial illustre comment démarrer avec Kubernetes (au minimum version 1.2) en mode pas à pas. Il est basé sur l'utilisation de Google Container Engine, mais peut facilement être suivi sur un autre environnement.
Initial configuration
create new project in Cloud Console (optional)
start Cloud Shell
configure Project environment variable
$ export PROJ="xtrav42kubnormal"
create work folder
$ mkdir mykubeapp
$ cd mykubeapp
Application creation
create source file
$ vi app.go
package main
import (
"fmt"
"net/http"
"os"
"time"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
currenttime:=time.Now().Local()
name,err:=os.Hostname()
if err !=nil {
panic(err)
}
fmt.Printf("server: %s received request from: %s\n",name,r.RemoteAddr)
fmt.Fprintf(w, "server: %s\n\n",name)
fmt.Fprintf(w, "request: %s %s\n",r.Host,r.URL.Path)
fmt.Fprintf(w, "Hello World from Go! current local time: %s\n", currenttime.Format("20060102 15:04:05"))
res:=dowork(30000)
fmt.Fprintf(w, "result: %d duration: %s\n",res,time.Since(currenttime))
}
func dowork(max int) int{
var k int
for i:=0; i<max; i++ {
for j:=0; j<max; j++ {
k=k+i*j;
}
}
return k
}
func main() {
http.HandleFunc("/", helloHandler)
fmt.Println("serving on port 8080")
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic("ListenAndServe: " + err.Error())
}
}
build application
$ go build
run application and test it from Cloud Shell with Web Preview (ctrl-c to stop the app)
$ ./mykubeapp
Docker image preparation
recompile app to be statically linked
$ CGO_ENABLED=0 go build -ldflags '-extldflags "-static"'
check the binary doesn't have any dynamic dependencies
$ ldd mykubeapp
not a dynamic executable
create simple Dockerfile
$ vi Dockerfile
FROM alpine
RUN apk add --no-cache bash
ADD mykubeapp /mykubeapp
CMD ["/mykubeapp"]
build Docker image
$ sudo docker build -t areg/mykubeapp:1 .
Sending build context to Docker daemon 7.596 MBStep 1 : FROM alpinelatest: Pulling from library/alpine31b45a1205be: Pull complete Digest: sha256:023c4a98e02ff523c38e830299bbe64f3a0c1cdde7dbd4ecacaf46986e264c94Status: Downloaded newer image for alpine:latest ---> 31b45a1205beStep 2 : RUN apk add --no-cache bash ---> Running in 7c510d0b6a7ffetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gzfetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz(1/5) Installing ncurses-terminfo-base (6.0-r7)(2/5) Installing ncurses-terminfo (6.0-r7)(3/5) Installing ncurses-libs (6.0-r7)(4/5) Installing readline (6.3.008-r4)(5/5) Installing bash (4.3.42-r3)Executing bash-4.3.42-r3.post-installExecuting busybox-1.24.2-r9.triggerOK: 13 MiB in 16 packages ---> 45680305244fRemoving intermediate container 7c510d0b6a7fStep 3 : ADD mykubeapp /mykubeapp ---> 44ea11cc5564Removing intermediate container bca9116980afStep 4 : CMD /mykubeapp ---> Running in 113da1f22c2f ---> 59dacfcbd8f8Removing intermediate container 113da1f22c2fSuccessfully built 59dacfcbd8f8
check image was successfully built
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEareg/mykubeapp 1 59dacfcbd8f8 About a minute ago 15.83 MBalpine latest 31b45a1205be 10 weeks ago 4.799 MB
test docker image locally using Web Preview
$ sudo docker run -p 8080:8080 areg/mykubeapp:1
serving on port 8080server: 419c0565b1a0 received request from: 172.18.0.1:39734^C
tag image to prepare it for Google Container Registry
$ sudo docker tag areg/mykubeapp:1 gcr.io/$PROJ/mykubeapp:1
check docker images
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEareg/mykubeapp 1 59dacfcbd8f8 25 minutes ago 15.83 MBgcr.io/xtrav42kubnormal/mykubeapp 1 59dacfcbd8f8 25 minutes ago 15.83 MBalpine latest 31b45a1205be 10 weeks ago 4.799 MB
push image to Google Container Registry
$ gcloud docker push gcr.io/$PROJ/mykubeapp:1
The push refers to a repository [gcr.io/xtrav42kubnormal/mykubeapp] (len: 1)59dacfcbd8f8: Pushed 44ea11cc5564: Pushed 45680305244f: Pushed 31b45a1205be: Image already exists 1: digest: sha256:10b59055e6c9e0f94f6576c4904bff00f76476baa960d1693a6ccdc3bc6ce326 size: 6088
Cluster creation on GKE
configure zone
$ gcloud config set compute/zone us-central1-a
create cluster with 3 machines of type n1-standard-1 (may take several minutes to complete)
$ gcloud container clusters create knormal --num-nodes 3 --machine-type n1-standard-1
Creating cluster knormal...done.Created [https://container.googleapis.com/v1/projects/xtrav42kubnormal/zones/us-central1-a/clusters/knormal].kubeconfig entry generated for knormal.NAME ZONE MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUSknormal us-central1-a 1.3.6 23.251.157.118 n1-standard-1 1.3.6 3 RUNNING
check created nodes
$ kubectl get nodes
NAME STATUS AGEgke-knormal-default-pool-3edb1986-gh00 Ready 12mgke-knormal-default-pool-3edb1986-xljo Ready 12mgke-knormal-default-pool-3edb1986-y90h Ready 12m
get credentials
$ gcloud container clusters get-credentials knormal
Application deployment as pods
create a simple 1 pod deployment with default settings
$ kubectl run mydeploy --image=gcr.io/$PROJ/mykubeapp:1 --port=8080
check created deployment
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEmydeploy 1 1 1 1 10s
check created pods
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODEmydeploy-2057093778-ns1mu 1/1 Running 0 6m 10.0.2.3 gke-knormal-default-pool-3edb1986-y90h
check pod logs
$ kubectl logs mydeploy-2057093778-ns1mu
serving on port 8080
create service to allow external traffic
$ kubectl expose deployment mydeploy --type="LoadBalancer"
service "mydeploy" exposed
check created service (external ip may take a while to show up)
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes 10.3.240.1 <none> 443/TCP 43mmydeploy 10.3.249.220 <pending> 8080/TCP 22s$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes 10.3.240.1 <none> 443/TCP 43mmydeploy 10.3.249.220 104.154.32.162 8080/TCP 1m
test access from external web browser using the service external IP http://104.154.32.162:8080
check pod logs
$ kubectl logs mydeploy-2057093778-ns1mu
serving on port 8080server: mydeploy-2057093778-ns1mu received request from: 10.128.0.2:64558server: mydeploy-2057093778-ns1mu received request from: 10.128.0.2:64558server: mydeploy-2057093778-ns1mu received request from: 10.128.0.2:64558server: mydeploy-2057093778-ns1mu received request from: 10.128.0.2:64558