minikube程式碼分析與Go語言 - 1

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

[TOC]

閑言

最近需要看Kubernetes(簡寫為k8s)和docker相關的技術資料,順帶學一下Go語言。

嘗試了通過minikube部署遇到鏡像下載和網路設定等等各種問題。
雖然k8s很火熱,但是資料其實很少,並且國內熱衷於在其上做整合或者重新造輪子,對於這些用Go實現的工具內部分析討論不多。

所以趁著最近有點時間,邊看minikube源碼邊讀 《The Go Programming Language》,將minikube的架構、主要流程和實現做一個分析,Go語言應該也能夠學以致用,同時附帶一下k8sdocker相關知識,以及八卦。

紙上得來終覺淺絕知此事要躬行
項目 版本
go v1.8.3
minikube v0.20.0
kubectl v1.7.0

Go語言簡介

Go是一門開源的程式設計語言,致力於開發簡單、可靠和高效的軟體。

Go語言始於2007年9月Google的三個工程師Robert Griesemer, Rob Pike, Ken Thompson,2009年11月正式宣布。

Go項目包括語言、工具和標準庫,以及一切從簡的理念。

作為較新的高層語言,Go有其後發優勢:它包含了垃圾收集、包管理系統、函數式代碼,語義範圍,系統調用介面和基於UTF-8的常量字串。

但是Go僅僅有相對較少的特性並且不太可能添加更多功能支援。
比如說Go沒有隱式數字轉換,沒有構造和解構函式,沒有操作符重載,沒有預設參數,沒有繼承,沒有泛型,沒有異常,沒有宏,沒有函數標註,也沒有執行緒區域儲存。

Go語言本身成熟且穩定,並且保證向下相容。

安裝最新的Go

https://golang.org/doc/install

# 刪除系統已經安裝的golangsudo apt remove golang-go# 下載最新版本wget https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz# 解壓到/usr/local/go下sudo tar -C /usr/local -zxvf go1.8.3.linux-amd64.tar.gz# 把go/bin加入到使用者PATH環境變數,或是系統範圍 /etc/profileecho "PATH=$PATH:/usr/local/go/bin" >> $HOME/.profile

查看安裝的Go版本:

$ source ~/.profile $ go versiongo version go1.8.3 linux/amd64

0 - Go語言設計體系

graph TDCSP[CSP, Hoare, 1978]-->SqueakSqueak[Squeak, Cardelli & Pike, 1985]-->NewsqueakNewsqueak[Newsqueak, Pike, 1989]-->AlefAlef[Alef, Winterbottom, 1992]-->GoALGOL-60[ALGOL 60, Bakus etal., 1960]-->PascalPascal[Pascal, Wirth, 1970]-->Modula-2Modula-2[Modula-2, Wirth, 1980]-->OberonOberon[Oberon, Wirth & Gutknecht, 1986]-->Oberon-2Oberon-->Object-OberonObject-Oberon[Object Oberon, Mossenbock, Templ & Griesemer, 1990]-->Oberon-2Oberon-2[Oberon-2, Wirth & Mossenbock, 11991]-->GoALGOL-60-->C[C, Ritchie, 1972]C-->Go[Go, Griesemer, Pike & Thompson, 2009]

參考材料:

  • 電腦科學經典論文

1 - 基礎結構

  • go run 可以直接運行go代碼檔案

  • go build 編譯代碼

  • go fmt 協助格式化代碼

++helloworld.go++ (列印字串)

// Go代碼按包組織,類似其它語言的模組或庫// 當前Go有100多個包,涵蓋了輸入輸出,排序,文本處理等基本任務package main // main包表示這是可執行檔而不是庫代碼import "fmt" // fmt包負責處理格式化輸入輸出// 函式宣告是func關鍵字func main() { // { 必須要跟代碼在同一行,不能單獨一行    fmt.Println("Hello,世界!") // 預設不用寫分號,Go會自動加上} // Go預設採用UTF-8編碼,相容多種語言

++echo.go++ (回顯命令參數)

package mainimport ( // 匯入多個包的常用形式    "fmt"    "os")func main() {    var sep = ""  // Go不允許聲明沒有用到的變數    // range關鍵字,數組切分跟Python類似,無需括弧    for _, arg := range os.Args[1:] { // := 是聲明變數的簡寫        sep += arg + " " // 支援逆波蘭運算式,僅支援i++形式,不支援++i    }    fmt.Println(sep)}

++dup.go++ (統計重複行數)

package mainimport ( // 匯入多個包的常用形式    "bufio"    "fmt"    "os")func main() {    counts := make(map[string]int) // 內建函數make建立一個新的map類型變數    if len(os.Args) > 1 {        for _, file := range os.Args[1:] { // 如果有參數則作為檔案開啟            f, err := os.Open(file)            if err != nil { // 錯誤值                fmt.Fprintf(os.Stderr, "dup: %v\n", err)                continue            } else {                countLines(f, counts)                f.Close()            }        }    } else {        countLines(os.Stdin, counts)    }    for line, num := range counts {        if num > 1 { // 不需要`(`,但`{`還是要有            fmt.Printf("> %d\t'%s'\n", num, line) // 與C語言的printf類似        }    }}// 聲明函數參數的形式,counts是參考型別func countLines(f *os.File, counts map[string]int) {    for input := bufio.NewScanner(f); input.Scan(); { // for可以替代while        counts[input.Text()]++    }}

++gif.go++ (產生gif動態圖)

package main// 示範Go的標準映像包import (    "image"    "image/color" // 引用包的最後一部分,如color.White    "image/gif"    "io"    "math"    "math/rand"    "os")// 一種緊湊的方式聲明複合類型,詳見第四部分var palette = []color.Color{color.White, color.Black} // slice// 聲明常量,相當於給一些值起個名字const ( // 常量只能是數字、字串或bool值    white = 0 // first color in palette    black = 1 // next color in palette)func main() {    lissajous(os.Stdout)}func lissajous(out io.Writer) {    const (        cycles  = 5     // number of complete x oscillator revolutions        res     = 0.001 // angular resolution        size    = 100   // image canvas covers [-size..+size]        nframes = 64    // number of animation frames        delay   = 8     // delay between frames in 10ms units    )    freq := rand.Float64() * 3.0        // relative frequency of y oscillator    anim := gif.GIF{LoopCount: nframes} // struct    phase := 0.0                        // phase difference    for i := 0; i < nframes; i++ {        rect := image.Rect(0, 0, 2*size+1, 2*size+1)        img := image.NewPaletted(rect, palette)        for t := 0.0; t < cycles*2*math.Pi; t += res {            x := math.Sin(t)            y := math.Sin(t*freq + phase)            img.SetColorIndex(size+int(x*size+.5), size+int(y*size+.5), black)        }        phase += .1        anim.Delay = append(anim.Delay, delay)        anim.Image = append(anim.Image, img)    }    gif.EncodeAll(out, &anim)}

++fetch.go++ (並行擷取URL內容)

package main // main包表示這是可執行檔而不是庫代碼import (    "fmt"    "io"    "io/ioutil"    "net/http"    "os"    "time")func main() { // main函數運行運行於一個goroutine內    start := time.Now()    ch := make(chan string) // channel是在goroutine間訊息通訊的機制    for _, url := range os.Args[1:] {        go fetch(url, ch) // goroutine是並存執行的函數,go語句建立goroutine    }    for range os.Args[1:] {        fmt.Println(<-ch) // 訊息傳遞是阻塞式的    }    fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds())}func fetch(url string, ch chan<- string) {    start := time.Now()    resp, err := http.Get(url)    if err != nil {        ch <- fmt.Sprint(err)        return    }    nb, err := io.Copy(ioutil.Discard, resp.Body)    resp.Body.Close()    if err != nil {        ch <- fmt.Sprintf("while reading %s: %v\n", url, err)        return    }    secs := time.Since(start).Seconds()    ch <- fmt.Sprintf("%.2fs, %7d, %s", secs, nb, url)}

++server.go++ (Web伺服器樣本)

package mainimport (    "fmt"    "log"    "net/http"    "sync")var mu sync.Mutexvar count intfunc main() {    http.HandleFunc("/", handler)    http.HandleFunc("/counter", counter)    log.Fatal(http.ListenAndServe("localhost:8000", nil))}func handler(w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "%s %s %s\n", r.Method, r.URL, r.Proto)    for k, v := range r.Header {        fmt.Fprintf(w, "Header[%s] = %q\n", k, v)    }    fmt.Fprintf(w, "Host = %q\n", r.Host)    fmt.Fprintf(w, "RemoteAddr = %q\n", r.RemoteAddr)    if err := r.ParseForm(); err != nil {        log.Print(err)    }    for k, v := range r.Form {        fmt.Fprintf(w, "Form[%q] = %q\n", k, v)    }    mu.Lock()    count++    mu.Unlock()    fmt.Fprintf(w, "URL.path = %q\n", r.URL.Path)}func counter(w http.ResponseWriter, r *http.Request) {    mu.Lock()    fmt.Fprintf(w, "Count: %d\n", count)    mu.Unlock()}
  • switch語句與C語言類似,但沒有fall through特性(有fallthrough語句)

  • 命名類型,類似C語言的結構體

  • 指標,類似C語言,支援*&操作符,但不支援指標運算

  • 方法是命名類型裡的函數函數,與C++的類函數相似

  • 介面是聲明了相同方法的抽象類別型

  • go doc http.file可以查看包的協助資訊

  • 注釋支援/* ... *///兩種方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.