From af38aac11ae421bef787ff0618b6a53f9b19f854 Mon Sep 17 00:00:00 2001 From: joohwan Date: Tue, 19 Dec 2023 15:01:50 +0800 Subject: [PATCH] Site updated: 2023-12-19 15:01:50 --- 2023/02/28/web/go/piwriw-blog/index.html | 6 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 6 +- .../index.html" | 6 +- .../\346\225\264\345\220\210JWT/index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 4 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 6 +- .../Git \350\247\204\350\214\203/index.html" | 4 +- .../index.html" | 6 +- .../index.html" | 6 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../K8s\346\265\205\345\255\246/index.html" | 4 +- 2023/09/16/cloud/Harbor/index.html | 4 +- .../Bash\345\205\245\351\227\250/index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 6 +- .../Go-panic\344\270\216recover/index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../02/cloud/k8s/K8s-DNS-CoreDNS/index.html | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../index.html" | 4 +- .../K8s-\350\212\202\347\202\271/index.html" | 313 ++++++++++++++++ .../K8s-\345\256\271\345\231\250/index.html" | 333 ++++++++++++++++++ .../K8s-\345\257\271\350\261\241/index.html" | 276 +++++++++++++++ about/index.html | 9 +- archives/2023/02/index.html | 9 +- archives/2023/03/index.html | 9 +- archives/2023/03/page/2/index.html | 9 +- archives/2023/06/index.html | 9 +- archives/2023/07/index.html | 9 +- archives/2023/08/index.html | 9 +- archives/2023/09/index.html | 9 +- archives/2023/10/index.html | 9 +- archives/2023/10/page/2/index.html | 9 +- archives/2023/11/index.html | 9 +- archives/2023/11/page/2/index.html | 172 +++++++++ archives/2023/12/index.html | 172 +++++++++ archives/2023/index.html | 9 +- archives/2023/page/2/index.html | 9 +- archives/2023/page/3/index.html | 9 +- archives/2023/page/4/index.html | 9 +- archives/2023/page/5/index.html | 9 +- archives/2023/page/6/index.html | 9 +- archives/2023/page/7/index.html | 9 +- archives/index.html | 9 +- archives/page/2/index.html | 9 +- archives/page/3/index.html | 9 +- archives/page/4/index.html | 9 +- archives/page/5/index.html | 9 +- archives/page/6/index.html | 9 +- archives/page/7/index.html | 9 +- categories/basic/go/index.html | 9 +- categories/basic/index.html | 9 +- .../\351\235\242\350\257\225/index.html" | 9 +- categories/cloud/Harbor/index.html | 9 +- categories/cloud/docker/index.html | 9 +- categories/cloud/index.html | 9 +- categories/cloud/k8s/index.html | 9 +- categories/cloud/k8s/page/2/index.html | 9 +- categories/cloud/k8s/page/3/index.html | 9 +- categories/cloud/kubeedge/index.html | 9 +- categories/cloud/page/2/index.html | 9 +- categories/cloud/page/3/index.html | 9 +- categories/cloud/page/4/index.html | 172 +++++++++ categories/index.html | 7 +- categories/tools/bash/index.html | 9 +- categories/tools/chrome/index.html | 9 +- categories/tools/git/index.html | 9 +- categories/tools/homebrew/index.html | 9 +- categories/tools/index.html | 9 +- categories/tools/redis/index.html | 9 +- categories/web/index.html | 9 +- categories/web/page/2/index.html | 9 +- categories/web/page/3/index.html | 9 +- .../index.html" | 9 +- index.html | 111 +++--- link/index.html | 9 +- messageboard/index.html | 7 +- page/2/index.html | 76 ++-- page/3/index.html | 72 ++-- page/4/index.html | 194 +++------- page/5/index.html | 196 ++++++++--- page/6/index.html | 124 +++---- page/7/index.html | 81 ++++- search.xml | 229 ++++++++---- tags/Gin/index.html | 9 +- tags/Harbor/index.html | 9 +- .../index.html" | 9 +- tags/client-go/index.html | 9 +- tags/cloud/index.html | 9 +- tags/cloud/page/2/index.html | 9 +- tags/cloud/page/3/index.html | 9 +- tags/cookies/index.html | 9 +- tags/go/index.html | 9 +- tags/go/page/2/index.html | 9 +- tags/go/page/3/index.html | 9 +- tags/go/page/4/index.html | 9 +- tags/index.html | 7 +- tags/jwt/index.html | 9 +- tags/k8s/index.html | 9 +- tags/k8s/page/2/index.html | 9 +- tags/k8s/page/3/index.html | 9 +- tags/k8s/page/4/index.html | 172 +++++++++ tags/kubeedge/index.html | 9 +- tags/session/index.html | 9 +- tags/sql/index.html | 9 +- tags/sqlx/index.html | 9 +- tags/swagger/index.html | 9 +- tags/tools/index.html | 9 +- tags/validation/index.html | 9 +- tags/viper/index.html | 9 +- tags/web/index.html | 9 +- tags/web/page/2/index.html | 9 +- tags/web/page/3/index.html | 9 +- tags/zap/index.html | 9 +- .../index.html" | 9 +- .../index.html" | 9 +- .../index.html" | 9 +- .../index.html" | 9 +- .../index.html" | 9 +- .../index.html" | 9 +- .../index.html" | 9 +- "tags/\351\235\242\350\257\225/index.html" | 9 +- 165 files changed, 2805 insertions(+), 957 deletions(-) create mode 100644 "2023/11/14/cloud/k8s/K8s-\350\212\202\347\202\271/index.html" create mode 100644 "2023/12/01/cloud/k8s/K8s-\345\256\271\345\231\250/index.html" create mode 100644 "2023/12/02/cloud/k8s/K8s-\345\257\271\350\261\241/index.html" create mode 100644 archives/2023/11/page/2/index.html create mode 100644 archives/2023/12/index.html create mode 100644 categories/cloud/page/4/index.html create mode 100644 tags/k8s/page/4/index.html diff --git a/2023/02/28/web/go/piwriw-blog/index.html b/2023/02/28/web/go/piwriw-blog/index.html index 964c50ffa..93652cae0 100644 --- a/2023/02/28/web/go/piwriw-blog/index.html +++ b/2023/02/28/web/go/piwriw-blog/index.html @@ -162,7 +162,7 @@ } } detectApple() - })(window)

piwriw_blog

Piwriw Blog

+ })(window)

piwriw_blog

Piwriw Blog

@@ -289,7 +289,7 @@

Vue

作者

Piwriw

-

@Email:piwriw@163.com

+

@Email:piwriw@163.com

前端使用了 wejectchan的ginblog 并作出修改

鸣谢

打赏
  • alipay
    alipay

评论

AI协同子项目-Sedna

Kubeedge - 6:AI协同子项目-Sedna

什么是 Sedna

Kubeedge-边缘计算

why I write the series of kubeedge

-
文章作者: Piwriw.
文章链接: http://example.com/2023/03/01/cloud/Kubeedge-边缘计算/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
打赏
  • alipay
    alipay

评论
打赏
  • alipay
    alipay

评论

Linux部署Go

Linux部署Go

bash一键部署

bash地址

+ })(window)

Linux部署Go

Linux部署Go

bash一键部署

bash地址

下载

# 安装wget命令
yum install -y wget
# 在 ~ 下创建 go 文件夹,并进入 go 文件夹
mkdir ~/go && cd ~/go
# 下载的 go 压缩包
wget https://studygolang.com/dl/golang/go1.17.linux-amd64.tar.gz

解压

tar -C /usr/local -zxvf go1.17.0.linux-amd64.tar.gz
@@ -180,7 +180,7 @@

  • 运行项目:go run main.go
  • -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/03/02/web/go/Linux部署Go/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    整合zap日志

    数据库(MySql)篇

    连接数据库

    	db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/DB_TEST")
    // 测试连接
    db.Ping()
    // 使用 defer 释放连接
    defer db.Close()
    ```
    ## insert 插入数据
    ```java
    db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/DB_TEST")
    db.Ping()
    defer db.Close()

    if err != nil {
    fmt.Println("数据库连接失败!")
    }

    _, err := db.Query("INSERT INTO user VALUES(1, 'test')")
    if err != nil {
    fmt.Println(err.Error())
    }

    + })(window)

    整合zap日志

    数据库(MySql)篇

    连接数据库

    	db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/DB_TEST")
    // 测试连接
    db.Ping()
    // 使用 defer 释放连接
    defer db.Close()
    ```
    ## insert 插入数据
    ```java
    db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/DB_TEST")
    db.Ping()
    defer db.Close()

    if err != nil {
    fmt.Println("数据库连接失败!")
    }

    _, err := db.Query("INSERT INTO user VALUES(1, 'test')")
    if err != nil {
    fmt.Println(err.Error())
    }

    select 查询所有数据

    db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/DB_TEST")
    db.Ping()
    defer db.Close()

    if err != nil {
    fmt.Println("数据库连接失败!")
    log.Fatalln(err)
    }

    result, err2 := db.Query("SELECT * FROM user")
    if err2 != nil {
    log.Fatal(err2)
    }

    for result.Next() {

    var id int
    var name string

    err = result.Scan(&id, &name)

    if err != nil {
    panic(err)
    }

    fmt.Printf("Id: %d, Name: %s\n", id, name)
    }

    where 条件查询

    result, err := db.Query("SELECT * FROM user WHERE id = ?", mid)
    @@ -173,7 +173,7 @@

    delete 删除

       sql := "DELETE FROM user WHERE id = 1"
    res, err := db.Exec(sql)
    // 获取删除的行数(收到sql影响的行数)
    affectedRows, err := res.RowsAffected()

    update 修改数据

       sql := "update user set name = ? WHERE id = ?"
    res, err2 := db.Exec(sql, "Yuzhou1su", 2)
    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/03/02/web/go/数据库篇/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    整合JWT

    整合JWT

    What is JWT

      + })(window)

      整合JWT

      整合JWT

      What is JWT

      • JWT 是 JSON Web Token 的缩写,是为了在⽹络应⽤环境间传递声明⽽执⾏的⼀种基于JSON的开放标准((RFC 7519)。JWT 本身没有定义任何技术实现,它只是定义了⼀种基于 Token 的会话管理的规则,涵盖 Token 需要包含的标准内容和 Token 的⽣成过程,特别适⽤于分布式站点的单点登录(SSO)场景
      • 一段JWT Token 由”.”切割成头部、负载、签名三部分
      @@ -199,7 +199,7 @@

      GenTokenWithRefreshToken 生成RefreshToken


      // GenTokenWithRefreshToken : 生成Access token 和 RefreshToken
      func GenTokenWithRefreshToken(userID int64) (acToken, reToken string, err error) {
      c := MyClaims{
      userID,
      "username",
      jwt.StandardClaims{
      ExpiresAt: time.Now().Add(TokenExpireTime).Unix(), //签发日期
      Issuer: "Piwirw", //签发人
      },
      }
      // 加密并获得编码Token
      acToken, err = jwt.NewWithClaims(jwt.SigningMethodES256, c).SignedString(mySecret)

      // refresh token 不需要存储子自定义数据
      reToken, err = jwt.NewWithClaims(jwt.SigningMethodES256, jwt.StandardClaims{
      ExpiresAt: time.Now().Add(time.Second * 30).Unix(), // 过期时间
      Issuer: "Piwriw", //签发人
      }).SignedString(mySecret)
      // 使用自定secret签名并获得完整后的Token
      return
      }

      // ParseToken2 : 解析Access Token
      func ParseToken2(tokenString string)(claims *MyClaims,err error) {
      // 解析tokenn
      var token *jwt.Token
      claims=new(MyClaims)
      token,err=jwt.ParseWithClaims(tokenString,claims, func(token *jwt.Token) (i interface{}, err error) {
      // 直接使用标准的Claim则可以直接使用Parse方法
      //token, err := jwt.Parse(tokenString, func(token *jwt.Token) (i interface{}, err error) {
      return mySecret, nil
      })
      if err != nil {
      return
      }
      if !token.Valid {
      err=errors.New("Invalid token")
      }
      return
      }

      RefreshToken 刷新token


      // RefreshToken : 刷新RefreshToken
      func RefreshToken(acToken, reToken string) (newToken, newReToken string, err error) {
      // refresh token is invalid returnn
      _,err=jwt.Parse(reToken,func(token *jwt.Token) (i interface{}, err error) {
      // 直接使用标准的Claim则可以直接使用Parse方法
      //token, err := jwt.Parse(tokenString, func(token *jwt.Token) (i interface{}, err error) {
      return mySecret, nil
      })
      if err!=nil{
      return
      }
      // 从 older access token 解析出claims
      var claims MyClaims
      _,err=jwt.ParseWithClaims(acToken,&claims,func(token *jwt.Token) (i interface{}, err error) {
      // 直接使用标准的Claim则可以直接使用Parse方法
      //token, err := jwt.Parse(tokenString, func(token *jwt.Token) (i interface{}, err error) {
      return mySecret, nil
      })
      v,_:=err.(*jwt.ValidationError)
      // 当access token is 过期错误并且 refresh token 没有过期 ->>>create a new access token
      if v.Errors==jwt.ValidationErrorExpired{
      return GenTokenWithRefreshToken(claims.UserID)
      }
      return
      }

      ParseToken 解析Access Token


      // ParseToken2 : 解析Access Token
      func ParseToken2(tokenString string)(claims *MyClaims,err error) {
      // 解析tokenn
      var token *jwt.Token
      claims=new(MyClaims)
      token,err=jwt.ParseWithClaims(tokenString,claims, func(token *jwt.Token) (i interface{}, err error) {
      // 直接使用标准的Claim则可以直接使用Parse方法
      //token, err := jwt.Parse(tokenString, func(token *jwt.Token) (i interface{}, err error) {
      return mySecret, nil
      })
      if err != nil {
      return
      }
      if !token.Valid {
      err=errors.New("Invalid token")
      }
      return
      }
      -
      文章作者: Piwriw.
      文章链接: http://example.com/2023/03/02/web/go/整合JWT/
      版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
      打赏
      • alipay
        alipay

      评论
      打赏
      • alipay
        alipay

      评论

    整合Swagger

    整合Swagger

    What is Swagger

    整合sql和sqlx

    整合sql和sqlx

    What is sqlx

    整合validation库

    整合validation库

    Background

      + })(window)

      整合validation库

      整合validation库

      Background

      • 利用validation库进行对参数校验,减少业务逻辑的手动校验

      Get validation

        @@ -500,7 +500,7 @@

        All Examle Code

        package controller

        import (

        "fmt"
        "github.com/gin-gonic/gin/binding"
        "github.com/go-playground/locales/en"
        "github.com/go-playground/locales/zh"
        ut "github.com/go-playground/universal-translator"
        "github.com/go-playground/validator/v10"
        enTranslations "github.com/go-playground/validator/v10/translations/en"
        zhTranslations "github.com/go-playground/validator/v10/translations/zh"
        "reflect"
        "strings"
        )

        // 定义一个全局翻译器T
        var trans ut.Translator

        // InitTrans 初始化翻译器
        func InitTrans(locale string) (err error) {
        // 修改gin框架中的Validator引擎属性,实现自定制
        if v, ok := binding.Validator.Engine().(*validator.Validate); ok {

        // 注册一个获取json tag的自定义方法
        v.RegisterTagNameFunc(func(fld reflect.StructField) string {
        name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
        if name == "-" {
        return ""
        }
        return name
        })
        // 给SignUpParam注册自定义校验方法
        v.RegisterStructValidation(SignUpParamStructLevelValidation,models.ParamSignUp{})

        zhT := zh.New() // 中文翻译器
        enT := en.New() // 英文翻译器

        // 第一个参数是备用(fallback)的语言环境
        // 后面的参数是应该支持的语言环境(支持多个)
        // uni := ut.New(zhT, zhT) 也是可以的
        uni := ut.New(enT, zhT, enT)

        // locale 通常取决于 http 请求头的 'Accept-Language'
        var ok bool
        // 也可以使用 uni.FindTranslator(...) 传入多个locale进行查找
        trans, ok = uni.GetTranslator(locale)
        if !ok {
        return fmt.Errorf("uni.GetTranslator(%s) failed", locale)
        }

        // 注册翻译器
        switch locale {
        case "en":
        err = enTranslations.RegisterDefaultTranslations(v, trans)
        case "zh":
        err = zhTranslations.RegisterDefaultTranslations(v, trans)
        default:
        err = enTranslations.RegisterDefaultTranslations(v, trans)
        }
        return
        }
        return
        }
        // removeTopStruct: 去除提示信息中的结构体名称
        func removeTopStruct(fields map[string]string) map[string]string {
        res := map[string]string{}
        for field, err := range fields {
        res[field[strings.Index(field, ".")+1:]] = err
        }
        return res
        }

        // SignUpParamStructLevelValidation 自定义SignUpParam结构体校验函数
        func SignUpParamStructLevelValidation(sl validator.StructLevel) {
        su := sl.Current().Interface().(models.ParamSignUp)

        if su.Password != su.RePassword {
        // 输出错误提示信息,最后一个参数就是传递的param
        sl.ReportError(su.RePassword, "re_password", "RePassword", "eqfield", "password")
        }
        }
        -
      文章作者: Piwriw.
      文章链接: http://example.com/2023/03/02/web/go/整合validation库/
      版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
      打赏
      • alipay
        alipay

      评论
      打赏
      • alipay
        alipay

      评论

    整合zap日志

    整合zap日志

    To Get zap

    go get go.uber.org/zap

    + })(window)

    整合zap日志

    整合zap日志

    To Get zap

    go get go.uber.org/zap

    Fast Use

    全局loggger

    logger, _ := zap.NewProduction()
    defer logger.Sync() // 将 buffer 中的日志写到文件中
    logger.Info("this is a test log")

    Zap.S 和 Zap.L

    zap.SugarLogger

    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    整合热加载

    整合热加载

    热加载 和 热部署

    整合管理配置 - viper

    整合管理配置 - viper

    自定义业务状态码

    自定义业务状态码

    业务状态码和HTTP状态码

    整合限流策略

    整合限流策略

    限流

    部署安装KubeEdge

    Kubeedge - 2: 部署安装KubeEdge

    KubeEdge 部署环境

    部署安装EdgeMesh

    Kubeedge - 3: 部署安装EdgeMesh

    什么是EdgeMesh

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/03/05/cloud/Kubeedge - 3: 部署安装EdgeMesh/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    玩转 Device twin

    Kubeedge - 4: 玩转 Device twin

    什么是 Device twin

    Device twin

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/03/12/cloud/Kubeedge - 4: 玩转 Device twin/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    玩转 Router

    Kubeedge - 5: 玩转 Router

    什么是 Router

    Gin中session和cookies

    Gin中session和cookies

    session

    什么是session

    Gin中间件

    Gin中间件

    内置中间件

    K8s如何支持公网访问

    K8s如何支持公网访问

    因为k8s默认启动支持内网ip,下面是三种 让k8s支持公网访问的模式

    + })(window)

    K8s如何支持公网访问

    K8s如何支持公网访问

    因为k8s默认启动支持内网ip,下面是三种 让k8s支持公网访问的模式

    keadm init添加参数

    # 未实践
    kubeadm init --apiserver-advertise-address= 内网ip --apiserver-cert-extra-sans 公网ip --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.19.4 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16

    重新生成apiserver证书

      @@ -207,7 +207,7 @@

      整合上述可:

      func InitK8sClient() error {
      var err error
      switch setting.Conf.K8sConfig.AuthModel {
      case "token":
      err = ClientWithToken()
      case "config":
      err = ClientWithConfig()
      default:
      return errors.New("目前只支持 token | config")
      }
      if err!=nil{
      return err
      }
      return nil
      }
      func ClientWithConfig() error {
      kubeconifg := ".kube/config"
      flag.Parse()

      // use the current context in kubeconfig
      config, err := clientcmd.BuildConfigFromFlags("", kubeconifg)
      if err != nil {
      return err
      }

      // create the clientset
      clientSet, err = kubernetes.NewForConfig(config)
      if err != nil {
      return err
      }

      configLoader, err := cf.NewKubeConfigLoaderFromYAMLFile(kubeconifg, false)

      configuration, err := configLoader.LoadAndSet()

      ctx = context.Background()
      //ctx = context.WithValue(ctx, client.ContextAPIKey, client.APIKey{Key: "Bearer " + string(token), Prefix: ""})
      clientAPI = client.NewAPIClient(configuration)
      return nil
      }

      func ClientWithToken() error {
      token, err := ioutil.ReadFile(setting.Conf.K8sConfig.TokenPath)
      if err != nil {
      return err
      }

      config := &rest.Config{
      Host: fmt.Sprintf("https://%s:6443", setting.Conf.K8sConfig.Host),
      BearerToken: string(token),
      TLSClientConfig: rest.TLSClientConfig{
      Insecure: true, // 设置为true时 不需要CA
      CAData: []byte(""),
      },
      }
      clientSet2, err := kubernetes.NewForConfig(config)
      clientSet = clientSet2
      if err != nil {
      return err
      }
      configuration := &client.Configuration{
      BasePath: fmt.Sprintf("https://%s:6443", setting.Conf.K8sConfig.Host),
      DefaultHeader: map[string]string{
      "Authorization": fmt.Sprintf("Bearer %s", string(token)),
      },
      HTTPClient: &http.Client{
      Transport: &http.Transport{
      TLSClientConfig: &tls.Config{
      InsecureSkipVerify: true,
      },
      },
      },
      }
      clientAPI = client.NewAPIClient(configuration)
      return nil
      }
      -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/06/10/cloud/K8s如何支持公网访问/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    微服务之注册中心

    微服务之注册中心

    什么是注册中心

    注册中心的作用一句话概括就是存放和调度服务,实现服务和注册中心,服务和服务之间的相互通信

    + })(window)

    微服务之注册中心

    微服务之注册中心

    什么是注册中心

    注册中心的作用一句话概括就是存放和调度服务,实现服务和注册中心,服务和服务之间的相互通信

    常见的几种注册中心

    @@ -217,7 +217,7 @@

    文章作者: Piwriw.
    文章链接: http://example.com/2023/06/18/web/go/微服务之注册中心/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    微服务之配置中心

    微服务之配置中心

    为什么需要配置中心

      + })(window)

      微服务之配置中心

      打赏
      • alipay
        alipay

      评论
    打赏
    • alipay
      alipay

    评论

    微服务之配置中心

    负载均衡

    什么是负载均衡

    负载均衡是将网络流量分发到多个后台服务的一种机制。通过负载均衡的流量分发,降低了单台服务器的负载,减少了应用的响应时间

    + })(window)

    微服务之配置中心

    负载均衡

    什么是负载均衡

    负载均衡是将网络流量分发到多个后台服务的一种机制。通过负载均衡的流量分发,降低了单台服务器的负载,减少了应用的响应时间

    20230618122934

    负载均衡类型

    集中式Load balance

    集中式LB方案,如下图。首先,服务的消费方和提供方不直接耦合,而是在服务消费者和服务提供者之间有一个独立的LB(LB通常是专门的硬件设备如F5,或者基于软件如LVS,HAproxy等实现)。

    20230618144003

    @@ -197,7 +197,7 @@

    最小连接数法

    前面我们费尽心思来实现服务消费者请求次数分配的均衡,我们知道这样做是没错的,可以为后端的多台服务器平均分配工作量,最大程度地提高服务器的利用率,但是,实际上,请求次数的均衡并不代表负载的均衡。因此我们需要介绍最小连接数法,最小连接数法比较灵活和智能,由于后台服务器的配置不尽相同,对请求的处理有快有慢,它正是根据后端服务器当前的连接情况,动态的选取其中当前积压连接数最少的一台服务器来处理当前请求,尽可能的提高后台服务器利用率,将负载合理的分流到每一台服务器。

    GRPC与负载均衡

    配置grpc中的负载均衡


    import (
    "fmt"
    "github.com/hashicorp/consul/api"
    "go.uber.org/zap"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    "shop_api/user-web/global"
    "shop_api/user-web/proto"
    )

    // InitSrvConn 配置了负载均衡的grpc client
    func InitSrvConn() error {
    consulInfo := global.AppConf.Consul
    userConn, err := grpc.Dial(fmt.Sprintf("consul://%s:%d/%s?wait=14s", consulInfo.IP, consulInfo.Port, global.AppConf.System.Name),
    grpc.WithTransportCredentials(insecure.NewCredentials()),
    grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"`))
    if err != nil {
    zap.S().Errorw("[InitSrvConn] 连接 【用户服务失败】", "msg", err.Error())
    return err
    }
    global.UserSrvClient = proto.NewUserClient(userConn)
    return nil
    }
    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/06/19/web/go/负载均衡/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    Git 规范

    Git 规范

    为什么需要git规范

    遵循 Git Commit 规范可以提高团队协作效率和代码库的可维护性。 通过明确的 Commit 类型和格式,开发者能够更轻松地理解每个提交所带来的更改,并能够快速回溯和回滚代码。 建议团队在项目中制定统一的 Git Commit 规范,并通过培训和代码审查来确保规范的遵循

    + })(window)

    Git 规范

    Git 规范

    为什么需要git规范

    遵循 Git Commit 规范可以提高团队协作效率和代码库的可维护性。 通过明确的 Commit 类型和格式,开发者能够更轻松地理解每个提交所带来的更改,并能够快速回溯和回滚代码。 建议团队在项目中制定统一的 Git Commit 规范,并通过培训和代码审查来确保规范的遵循

    git规范

    1. 约定式():
    2. git commit 合并
    3. @@ -223,7 +223,7 @@

      持续集成 -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/06/23/tools/Git 规范/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    优雅退出注销服务

    优雅退出注销服务

    为什么需要优雅注销服务

    当往服务中心注册了服务之后,由于调试,可能会重复注册同一个服务。当时之前服务由于健康检查,并不会立即退出注销,这就会多线多个“重复的服务”

    + })(window)

    优雅退出注销服务

    优雅退出注销服务

    为什么需要优雅注销服务

    当往服务中心注册了服务之后,由于调试,可能会重复注册同一个服务。当时之前服务由于健康检查,并不会立即退出注销,这就会多线多个“重复的服务”

    整合优雅退出服务

    package consul

    import (
    "fmt"

    "github.com/hashicorp/consul/api"
    )
    // register.go 工具
    type Registry struct {
    Host string
    Port int
    }

    type RegistryClient interface {
    Register(address string, port int, name string, tags []string, id string) error
    DeRegister(serviceId string) error
    }

    func NewRegistryClient(host string, port int) RegistryClient {
    return &Registry{
    Host: host,
    Port: port,
    }
    }

    func (r *Registry) Register(address string, port int, name string, tags []string, id string) error {
    cfg := api.DefaultConfig()
    cfg.Address = fmt.Sprintf("%s:%d", r.Host, r.Port)

    client, err := api.NewClient(cfg)
    if err != nil {
    panic(err)
    }
    //生成对应的检查对象
    check := &api.AgentServiceCheck{
    // GRPC: fmt.Sprintf("%s:%d", global.AppConf.Grpc.IP, global.AppConf.Grpc.Port),
    HTTP: fmt.Sprintf("http://%s:%d/health", address, port),
    Timeout: "5s",
    Interval: "5s",
    DeregisterCriticalServiceAfter: "10s",
    }

    //生成注册对象
    registration := new(api.AgentServiceRegistration)
    registration.Name = name
    registration.ID = id
    registration.Port = port
    registration.Tags = tags
    registration.Address = address
    registration.Check = check

    err = client.Agent().ServiceRegister(registration)
    if err != nil {
    panic(err)
    }
    return nil
    }

    func (r *Registry) DeRegister(serviceId string) error {
    cfg := api.DefaultConfig()
    cfg.Address = fmt.Sprintf("%s:%d", r.Host, r.Port)

    client, err := api.NewClient(cfg)
    if err != nil {
    return err
    }
    err = client.Agent().ServiceDeregister(serviceId)
    return err
    }

    package main

    import (
    "fmt"
    "github.com/nacos-group/nacos-sdk-go/inner/uuid"
    "go.uber.org/zap"
    "os"
    "os/signal"
    "shop_api/good-web/global"
    "shop_api/good-web/initialize"
    "shop_api/good-web/utils/register/consul"
    "syscall"
    )
    // main.go 优雅退出
    func main() {
    router := initialize.Routers()

    registerClient := consul.NewRegistryClient(global.AppConf.Consul.IP, global.AppConf.Consul.Port)
    // 生成UUID
    u, err := uuid.NewV4()
    if err != nil {
    panic("failed new uuid:" + err.Error())
    }
    serverId := u.String()
    err = registerClient.Register(global.AppConf.System.Host, global.AppConf.System.Port,
    global.AppConf.System.Name, global.AppConf.System.Tags, serverId)
    if err != nil {
    panic(err.Error())
    }
    zap.S().Infof("启动服务器,端口:%d", global.AppConf.System.Port)
    // gin会卡住现场
    go func() {
    if err := router.Run(fmt.Sprintf("%s:%d", global.AppConf.System.Host, global.AppConf.System.Port)); err != nil {
    zap.S().Panic(err)
    }
    }()

    //接收终止信号
    quit := make(chan os.Signal)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit
    // 注销服务
    if err = registerClient.DeRegister(serverId); err != nil {
    zap.S().Info("注销失败")
    }
    zap.S().Info("注销成功")
    }

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/06/23/web/go/优雅退出注销服务/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    Go-日志库Zap

    Go-日志库Zap

    什么是zap

    Go-内存对齐

    内存对齐

    什么是内存对齐

    面试八股文-计算机网络篇

    面试八股文-计算机网络篇

    OSI七层模型和TCP/IP四层协议概述

    OSI七层模型协议

    20230703141100

    + })(window)

    面试八股文-计算机网络篇

    面试八股文-计算机网络篇

    OSI七层模型和TCP/IP四层协议概述

    OSI七层模型协议

    20230703141100

    帧结构

    20230703141556

    各层级之间的作用

    网络层:

    关键协议:IP协议、ICMP协议

    @@ -581,7 +581,7 @@

    VPN(虚拟专用网)

    VPN的隧道协议主要有三种,PPTP、L2TP和IPSec,其中PPTP和L2TP协议工作在OSI模型的第二层,又称为二层隧道协议;IPSec是第三层隧道协议。
    按VPN的应用分类:
    (1)Access VPN(远程接入VPN):客户端到网关,使用公网作为骨干网在设备之间传输VPN数据流量;
    (2)Intranet VPN(内联网VPN):网关到网关,通过公司的网络架构连接来自同公司的资源;
    (3)Extranet VPN(外联网VPN):与合作伙伴企业网构成Extranet,将一个公司与另一个公司的资源进行连接。

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/07/04/basic/meeting/面试八股文-计算机网络篇/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    常见的分布式服务发现和服务注册方案

    常见的分布式服务发现和服务注册方案

    + })(window)

    常见的分布式服务发现和服务注册方案

    常见的分布式服务发现和服务注册方案

    @@ -267,7 +267,7 @@

    etcd

    et

    etcd 采用 Go 语言编写,它具有出色的跨平台支持,很小的二进制文件和强大的社区。 etcd 机器之间的通信通过 Raft 算法处理。

    Eureka

    Eureka是 Netflix 开发的服务发现框架,本身是一个基于 REST 的服务,主要用于定位运行在 AWS 域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。. SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。. [1] Eureka包含两个组件:Eureka Server和Eureka Client。. Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/07/18/web/go/常见的分布式服务发现和服务注册方案/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    常见的分布式锁解决方案

    常见的分布式锁解决方案

      + })(window)

      常见的分布式锁解决方案

      打赏
      • alipay
        alipay

      评论
    打赏
    • alipay
      alipay

    评论

    Docker配置远程访问

    Docker配置远程访问

    暴力修改

    这种就很简单暴力,直接修改/lib/systemd/system/docker.service文件,注释掉默认的 ExecStart 并添加新的 ExecStart 配置:

    + })(window)

    Docker配置远程访问

    Docker配置远程访问

    暴力修改

    这种就很简单暴力,直接修改/lib/systemd/system/docker.service文件,注释掉默认的 ExecStart 并添加新的 ExecStart 配置:

    Feature
    # ExecStart=/usr/bin/dockerd -H fd://
    ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

    然后重启 docker.service:

    @@ -194,7 +194,7 @@

    文章作者: Piwriw.
    文章链接: http://example.com/2023/08/16/cloud/Docker-开启远程Cli/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw

    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s浅学

    k8s

    1、安装(v.1.17.1,docker-cri)

    1.1 env.bash

    #!/bin/bash

    # 在 master 节点和 worker 节点都要执行

    # 卸载旧版本
    yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine

    # 安装并启动 docker(cri)
    yum install -y docker-ce-19.03.5 docker-ce-cli-19.03.5 containerd.io
    systemctl enable docker
    systemctl start docker

    # 关闭 防火墙
    systemctl stop firewalld
    systemctl disable firewalld

    # 关闭 SeLinux
    setenforce 0
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

    # 关闭 swap
    swapoff -a
    yes | cp /etc/fstab /etc/fstab_bak
    cat /etc/fstab_bak |grep -v swap > /etc/fstab

    # 修改 /etc/sysctl.conf
    # 如果有配置,则修改
    sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf
    sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf
    sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf
    # 可能没有,追加
    echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
    echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
    echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
    # 执行命令以应用
    sysctl -p

    docker version
    + })(window)

    K8s浅学

    k8s

    1、安装(v.1.17.1,docker-cri)

    1.1 env.bash

    #!/bin/bash

    # 在 master 节点和 worker 节点都要执行

    # 卸载旧版本
    yum remove docker \
    docker-client \
    docker-client-latest \
    docker-common \
    docker-latest \
    docker-latest-logrotate \
    docker-logrotate \
    docker-engine

    # 安装并启动 docker(cri)
    yum install -y docker-ce-19.03.5 docker-ce-cli-19.03.5 containerd.io
    systemctl enable docker
    systemctl start docker

    # 关闭 防火墙
    systemctl stop firewalld
    systemctl disable firewalld

    # 关闭 SeLinux
    setenforce 0
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

    # 关闭 swap
    swapoff -a
    yes | cp /etc/fstab /etc/fstab_bak
    cat /etc/fstab_bak |grep -v swap > /etc/fstab

    # 修改 /etc/sysctl.conf
    # 如果有配置,则修改
    sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf
    sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf
    sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf
    # 可能没有,追加
    echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
    echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
    echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
    # 执行命令以应用
    sysctl -p

    docker version

    1.2 k8ssetup.bash

    1.2.1 k8ssetup.yaml

    apiVersion: kubeadm.k8s.io/v1beta2
    kind: ClusterConfiguration
    kubernetesVersion: v1.17.1
    controlPlaneEndpoint: "apiserver.k8s.com:6443"
    networking:
    serviceSubnet: "10.96.0.0/16"
    podSubnet: "10.11.10.0/16"
    dnsDomain: "cluster.local
    @@ -438,7 +438,7 @@

    api list
  • kubernetes教程
  • -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/08/16/cloud/K8s浅学/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!
    目录
    1. 1. k8s
  • 1、安装(v.1.17.1,docker-cri)
    1. 1. 1.1 env.bash
    2. 2. 1.2 k8ssetup.bash
      1. 2.1. 1.2.1 k8ssetup.yaml
      2. 2.2. 1.2.2 k8s run setup(single-host Kubernetes cluster)
  • 2、资源管理
    1. 1. 2.1Pod
      1. 1.1. 2.1.1创建容器
      2. 1.2. 2.1.2查看容器
      3. 1.3. 2.1.3查看容器日志
      4. 1.4. 2.1.4向pod发送请求
  • 3、标签管理
    1. 1. 3.1pod
    2. 2. 3.2node
      1. 2.1. 指定调度到特定节点(nodeselector)
    3. 3. 3.3命名空间(namespace)
      1. 3.1. 创建ns
  • 4、控制器
    1. 1. 4.1探针
      1. 1.1. 4.1.1存活探针
        1. 1.1.1. 基于Http的存活探针
      2. 1.2. 4.1.2就绪探针
    2. 2. 4.2 ReplicationController
      1. 2.1. 4.2.1将pod移入或移出ReplicationController的作用域
      2. 2.2. 4.2.2修改pod 模版
      3. 2.3. 4.2.3删除RC
    3. 3. 4.3 ReplicaSet(RC进化版,更优秀)
    4. 4. 4.4 Job
      1. 4.1. 4.4.1顺序运行job pod
      2. 4.2. 4.4.2并行运行job pod
      3. 4.3. 4.4.3job的缩放
      4. 4.4. 4.4.4限制job pod完成任务时间
      5. 4.5. job定期运行(Crodjob)
  • 5.Service
    1. 0.1. 5.1 如何在一个已有的pod,访问service
  • 1. 5.2配置每次请求来自于同一个pod
  • 2. 5.3 同一个服务暴露多个端口
  • 3. 5.4服务发现
  • 4. 5.5服务对外暴露
    1. 4.1. 5.5.1使用NodePort类型的服务
    2. 4.2. 5.5.2使用负载均衡器
  • 6.k8s的卷
    1. 1. 6.1emptyDir卷
    2. 2. 6.2hostPath卷
    3. 3. 6.3持久卷
  • 7.ConfigMap和Secret
    1. 1. 7.1向容器传递命令行参数
      1. 1.1. 7.1.1Docker中的命令和参数
        1. 1.1.1. Dockerfile中的ENTRYOINT和CMD
        2. 1.1.2. shell和exec形式的区别
      2. 1.2. 7.1.2k8s中覆盖命令和参数
    2. 2. 7.2在容器定义中指定环境变量
    3. 3. 7.3ConfigMap
      1. 3.1. 7.3.1创建cm
      2. 3.2. 7.3.2cm设置环境变量
      3. 3.3. 7.3.3 cm在pod中作为文件使用
    4. 4. 7.4Secret
      1. 4.1. 7.4.1在Docker
      2. 4.2. 7.4.2基本身份认证
  • 8.从应用访问Pod元数据以及其他资源
    1. 1. 8.1Downward API传递元数据
    2. 2. 8.2K8s 的REST API
  • 9.Deployment
    1. 1. 9.1滚动升级
    2. 2. 9.2回滚升级
    3. 3. 9.3暂停滚动升级
  • 10.k8s的架构
    1. 1. 10.1控制面的组件
    2. 2. 10.2工作节点上运行的组件
    3. 3. 10.3附加组件
  • 11.认证方式
    1. 1.
      1. 1.1. 创建serviceAccount
  • 12.污点
  • 13.其他一些资料
  • 最新文章
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!
    目录
    1. 1. k8s
  • 1、安装(v.1.17.1,docker-cri)
    1. 1. 1.1 env.bash
    2. 2. 1.2 k8ssetup.bash
      1. 2.1. 1.2.1 k8ssetup.yaml
      2. 2.2. 1.2.2 k8s run setup(single-host Kubernetes cluster)
  • 2、资源管理
    1. 1. 2.1Pod
      1. 1.1. 2.1.1创建容器
      2. 1.2. 2.1.2查看容器
      3. 1.3. 2.1.3查看容器日志
      4. 1.4. 2.1.4向pod发送请求
  • 3、标签管理
    1. 1. 3.1pod
    2. 2. 3.2node
      1. 2.1. 指定调度到特定节点(nodeselector)
    3. 3. 3.3命名空间(namespace)
      1. 3.1. 创建ns
  • 4、控制器
    1. 1. 4.1探针
      1. 1.1. 4.1.1存活探针
        1. 1.1.1. 基于Http的存活探针
      2. 1.2. 4.1.2就绪探针
    2. 2. 4.2 ReplicationController
      1. 2.1. 4.2.1将pod移入或移出ReplicationController的作用域
      2. 2.2. 4.2.2修改pod 模版
      3. 2.3. 4.2.3删除RC
    3. 3. 4.3 ReplicaSet(RC进化版,更优秀)
    4. 4. 4.4 Job
      1. 4.1. 4.4.1顺序运行job pod
      2. 4.2. 4.4.2并行运行job pod
      3. 4.3. 4.4.3job的缩放
      4. 4.4. 4.4.4限制job pod完成任务时间
      5. 4.5. job定期运行(Crodjob)
  • 5.Service
    1. 0.1. 5.1 如何在一个已有的pod,访问service
  • 1. 5.2配置每次请求来自于同一个pod
  • 2. 5.3 同一个服务暴露多个端口
  • 3. 5.4服务发现
  • 4. 5.5服务对外暴露
    1. 4.1. 5.5.1使用NodePort类型的服务
    2. 4.2. 5.5.2使用负载均衡器
  • 6.k8s的卷
    1. 1. 6.1emptyDir卷
    2. 2. 6.2hostPath卷
    3. 3. 6.3持久卷
  • 7.ConfigMap和Secret
    1. 1. 7.1向容器传递命令行参数
      1. 1.1. 7.1.1Docker中的命令和参数
        1. 1.1.1. Dockerfile中的ENTRYOINT和CMD
        2. 1.1.2. shell和exec形式的区别
      2. 1.2. 7.1.2k8s中覆盖命令和参数
    2. 2. 7.2在容器定义中指定环境变量
    3. 3. 7.3ConfigMap
      1. 3.1. 7.3.1创建cm
      2. 3.2. 7.3.2cm设置环境变量
      3. 3.3. 7.3.3 cm在pod中作为文件使用
    4. 4. 7.4Secret
      1. 4.1. 7.4.1在Docker
      2. 4.2. 7.4.2基本身份认证
  • 8.从应用访问Pod元数据以及其他资源
    1. 1. 8.1Downward API传递元数据
    2. 2. 8.2K8s 的REST API
  • 9.Deployment
    1. 1. 9.1滚动升级
    2. 2. 9.2回滚升级
    3. 3. 9.3暂停滚动升级
  • 10.k8s的架构
    1. 1. 10.1控制面的组件
    2. 2. 10.2工作节点上运行的组件
    3. 3. 10.3附加组件
  • 11.认证方式
    1. 1.
      1. 1.1. 创建serviceAccount
  • 12.污点
  • 13.其他一些资料
  • 最新文章

    Harbor

    Harbor

    什么是Harbor

    Harbor 是一个开源的企业级容器镜像注册中心,用于管理和存储 Docker 镜像以及其他容器化应用的相关资源。它允许团队或组织在内部搭建自己的容器镜像仓库,以便更好地控制镜像的分发、访问和安全性。

    + })(window)

    Harbor

    Harbor

    什么是Harbor

    Harbor 是一个开源的企业级容器镜像注册中心,用于管理和存储 Docker 镜像以及其他容器化应用的相关资源。它允许团队或组织在内部搭建自己的容器镜像仓库,以便更好地控制镜像的分发、访问和安全性。

    Harbor的安装

    安装最小配置

    最低建议配置:

    文章作者: Piwriw.
    文章链接: http://example.com/2023/09/16/cloud/Harbor/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    Bash入门

    Bash入门

    什么是bash

    Bash 是 Unix 系统和 Linux 系统的一种 Shell(命令行环境),是目前绝大多数 Linux 发行版的默认 Shell

    + })(window)

    Bash入门

    Bash入门

    什么是bash

    Bash 是 Unix 系统和 Linux 系统的一种 Shell(命令行环境),是目前绝大多数 Linux 发行版的默认 Shell

    什么是shell

    学习 Bash,首先需要理解 Shell 是什么。Shell 这个单词的原意是“外壳”,跟 kernel(内核)相对应,比喻内核外面的一层,即用户跟内核交互的对话界面。

    首先,Shell 是一个程序,提供一个与用户对话的环境。这个环境只有一个命令提示符,让用户从键盘输入命令,所以又称为命令行环境(command line interface,简写为 CLI)。Shell 接收到用户输入的命令,将命令送入操作系统执行,并将结果返回给用户。

    @@ -490,7 +490,7 @@

    数组Set命令

    # 执行脚本时,如果遇到不存在的变量,Bash 默认忽略它。
    set -u

    # 默认情况下,脚本执行后,只输出运行结果,没有其他内容。如果多个命令连续执行,它们的运行结果就会连续输出
    set -x

    #上面这些写法多少有些麻烦,容易疏忽。set -e从根本上解决了这个问题,它使得脚本只要发生错误,就终止执行
    set -e

    # -e 在有|情况下不生效 用来解决这种情况,只要一个子命令失败,整个管道命令就失败,脚本就会终止执行
    set -o pipefail

    set -n:等同于set -o noexec,不运行命令,只检查语法是否正确。
    set -f:等同于set -o noglob,表示不对通配符进行文件名扩展。
    set -v:等同于set -o verbose,表示打印 Shell 接收到的每一行输入。
    set -o noclobber:防止使用重定向运算符>覆盖已经存在的文件

    Bash 的错误处理

    # 写法一
    command || { echo "command failed"; exit 1; }

    # 写法二
    if ! command; then echo "command failed"; exit 1; fi

    # 写法三
    command
    if [ "$?" -ne 0 ]; then echo "command failed"; exit 1; fi
    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/09/16/tools/Bash入门/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!
    打赏
    • alipay
      alipay

    评论

    部署K8s(脚本版本)

    部署K8s(脚本版本)

    文件位置:https://github.com/Piwriw/k8s_base/tree/master/k8s-setup

    + })(window)

    部署K8s(脚本版本)

    部署K8s(脚本版本)

    文件位置:https://github.com/Piwriw/k8s_base/tree/master/k8s-setup

    分发文件(push-file.sh)

    #!/bin/bash
    set -e
    # 源文件路径
    source_file="../k8s-setup"

    # 目标主机列表
    target_hosts=(
    "root@10.10.103.79:/root"
    "root@10.10.103.80:/root"
    "root@10.10.103.81:/root"
    )

    # 循环迭代目标主机列表,并使用 scp 命令将文件复制到每个主机
    for target_host in "${target_hosts[@]}"; do
    scp -r "$source_file" "$target_host"
    done

    部署包括docker(set-up.sh)

    ⚠️注意修改

    # 需要修改
    kubeadm join 10.10.101.158:6443 --token m6ygdj.wrlffvuvofffj2c5 --discovery-token-ca-cert-hash

    # 执行bash 传入hostname 参数 会自动设置本机hostname
    bash set-up.sh $homename
    #!/bin/bash
    set -e
    # 需要传递harbor hostname:ip h
    hostname="$1"
    initYum(){
    yum install -y wget
    mkdir /etc/yum.repos.d/bak && mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
    wget -O /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
    yum clean all && yum makecache
    }
    setHostname(){
    hostnamectl set-hostname $hostname
    echo "`ip -4 addr show scope global | awk '/inet/ {print $2; exit}' | cut -d '/' -f1` $hostname" >> /etc/hosts
    /etc/init.d/network restart
    }
    setupdocker(){

    curl -k -fsSL https://get.docker.com -o get-docker.sh
    sh get-docker.sh --version 20.10
    systemctl start docker
    systemctl enable docker
    touch /etc/docker/daemon.json
    echo '{ "exec-opts": ["native.cgroupdriver=systemd"] }' > /etc/docker/daemon.json
    systemctl restart docker
    }
    setupK8s(){
    bash ./k8s-setup.sh
    # 不使用可能会出现 sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables
    modprobe br_netfilter
    yum install -y kubeadm-1.20.4 kubelet-1.20.4 kubectl-1.20.4
    systemctl start kubelet
    systemctl enable kubelet
    # 需要修改
    kubeadm join 10.10.101.158:6443 --token m6ygdj.wrlffvuvofffj2c5 --discovery-token-ca-cert-hash sha256:fb74344fe281551bf7c32e1959a1d5a5439a8fa8a5ee209adb4eab0a568b8990
    }

    if [ -z "$hostname" ]; then
    echo "没有提供参数 需要hostname"
    exit 1 # 退出脚本,并返回非零退出状态
    fi

    initYum
    setHostname
    setupdocker
    setupK8s
    -

    k8s-prepare(k8s-setup.sh)

    #k8s-setup.sh
    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
    setenforce 0

    systemctl stop firewalld
    systemctl disable firewalld
    setenforce 0
    sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
    swapoff -a
    sed -i 's/.*swap.*/#&/' /etc/fstab

    cat > /etc/sysctl.d/k8s.conf <<EOF
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF

    echo "1" > /proc/sys/net/ipv4/ip_forward
    文章作者: Piwriw.
    文章链接: http://example.com/2023/09/22/cloud/部署K8s(脚本版本)/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    只关闭chrome深色模式

    只关闭chrome深色模式

    背景

    chrome会自动根据系统的深浅色模式,进行匹配。

    + })(window)

    只关闭chrome深色模式

    只关闭chrome深色模式

    背景

    chrome会自动根据系统的深浅色模式,进行匹配。

    单独关闭chrome深色模式

    # 单独关闭
    defaults write com.google.Chrome NSRequiresAquaSystemAppearance -bool YES
    # 重启chrome 生效

    # 开启深色模式
    defaults write com.google.Chrome NSRequiresAquaSystemAppearance -bool NO
    # 重启chrome 生效

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/09/23/tools/只关闭chrome深色模式/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    版本控制工具-Git

    版本控制工具-Git

    什么是git

    Git是一个版本控制工具,在编程中用于进行管理代码

    + })(window)

    版本控制工具-Git

    版本控制工具-Git

    什么是git

    Git是一个版本控制工具,在编程中用于进行管理代码

    安装Git

    Git安装

    # 一些常见安装罗列

    # mac安装
    brew install git

    # Windows 安装
    https://git-scm.com/download/win

    # linux 安装
    yum install -y git
    @@ -175,7 +175,7 @@

    4.因为忽略了第一步(在这可以只设置当前的)

    git config user.name 'yourname' && git config  user.email 'youremail@163.com' &&ssh-add ~/.ssh/yourid_rsa

    #example:
    git config user.name 'piwriw' && git config user.email 'piwriw@163.com' &&ssh-add ~/.ssh/piwriw
    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/09/26/tools/版本控制工具-Git/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    Go-网络编程

    Go的网络编程

    TCP

    什么是TCP

    TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网际协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一样传输,会存在黏包问题。

    + })(window)

    Go-网络编程

    Go的网络编程

    TCP

    什么是TCP

    TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网际协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一样传输,会存在黏包问题。

    TCP的工作流程

    服务端:

    1. 监听端口
    2. @@ -203,7 +203,7 @@

      -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/03/basic/go/Go的网络编程/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    Go 的panic与recover

    Go 的panic与recover

    panic和recover调用时机

    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    Go-深入理解GMP

    深入理解GMP

    为什么需要调度器

      + })(window)

      Go-深入理解GMP

      打赏
      • alipay
        alipay

      评论
    打赏
    • alipay
      alipay

    评论

    homebrew安装redis(Mac)

    homebrew安装redis(Mac)

    已经确保安装好brew

    # 安装redis
    brew install redis

    # 启动redis
    #方式一:使用brew帮助我们启动软件
    brew services start redis
    #方式二
    redis-server /usr/local/etc/redis.conf
    #方式三 redis-server

    + })(window)

    homebrew安装redis(Mac)

    homebrew安装redis(Mac)

    已经确保安装好brew

    # 安装redis
    brew install redis

    # 启动redis
    #方式一:使用brew帮助我们启动软件
    brew services start redis
    #方式二
    redis-server /usr/local/etc/redis.conf
    #方式三 redis-server

    配置文件安装位置

    • Homebrew安装的软件会默认在/usr/local/Cellar/路径下
    • @@ -172,7 +172,7 @@

      Redis可视化工具推荐

      AnotherRedisDesktopManager

      2023-10 目前已经获得27K :star:

      -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/06/tools/homebrew安装redis(Mac)/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    深入理解GO的GC

    深入理解GO的GC

    Gov1.3之前的标记清除法(mark and sweep)

      + })(window)

      深入理解GO的GC

      深入理解GO的GC

      Gov1.3之前的标记清除法(mark and sweep)

      1. 进行STW暂停

      2. 把所有的程序可达对象标记

        @@ -243,7 +243,7 @@

        场景4:一个栈对象删除引用,成为另一个堆对象的下游

        -
      文章作者: Piwriw.
      文章链接: http://example.com/2023/10/07/basic/go/深入理解GO的GC/
      版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
      打赏
      • alipay
        alipay

      评论
      打赏
      • alipay
        alipay

      评论

    K8s批量获取大量数据资源解决方案

    K8s批量获取大量数据资源解决方案

    背景

    当使用kubelet已经无法获取到资源的级别,比如万级别

    + })(window)

    K8s批量获取大量数据资源解决方案

    K8s批量获取大量数据资源解决方案

    背景

    当使用kubelet已经无法获取到资源的级别,比如万级别

    可以先直接采用client-go,去获取,这会更快,因为当我们使用kubelet get nodes|wc -l计算的时候,要先打印到出来再遍历

    :star:最后最大数据可以采用NewSharedInformerFactory来获取,使用informer,former 提供了基于事件通知的只读缓存机制,可以注册资源变化的回调函数,并可以极大减少 API 的调用。

    官方exampleURL

    代码实例

    package main

    import (
    "flag"
    "fmt"
    "k8s.io/apimachinery/pkg/labels"
    "k8s.io/client-go/informers"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/cache"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
    "path/filepath"
    "time"
    )

    func GetClientOutside() (*kubernetes.Clientset, error) {
    // 支持以 Pod 形式或者在宿主机上运行代码的形式获取 kubeconfig 配置
    var kubeconfig *string
    if home := homedir.HomeDir(); home != "" {
    kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
    } else {
    kubeconfig = flag.String("kubeconfig", "./kube/config", "absolute path to the kubeconfig file")
    }
    flag.Parse()

    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
    if err != nil {
    return nil, err

    }
    clientSet, err := kubernetes.NewForConfig(config)
    if err != nil {
    return nil, err
    }

    return clientSet, nil
    }

    func main() {
    start := time.Now()

    // 在这里执行您的代码或函数

    clientset, err := GetClientOutside()
    if err != nil {
    fmt.Println(err)
    return
    }
    //var timeout int64
    //timeout = 6000
    // 创建本地缓存
    informerFactory := informers.NewSharedInformerFactory(clientset, 0)
    nodeInformer := informerFactory.Core().V1().Nodes().Informer()
    nodeLister := informerFactory.Core().V1().Nodes().Lister()

    // 启动本地缓存的同步
    stopCh := make(chan struct{})
    defer close(stopCh)
    informerFactory.Start(stopCh)
    cache.WaitForCacheSync(stopCh, nodeInformer.HasSynced)

    // 在这里执行您的代码或函数,可以从缓存中获取资源对象

    // 示例:从缓存中获取所有 Pod 资源对象并打印它们的名称
    nodes, _ := nodeLister.List(labels.Everything())
    fmt.Printf("集群节点数%d\n", len(nodes))
    //for _, node := range nodes {
    // fmt.Println(node.Name)
    // for _, statu := range node.Status.Conditions {
    // if statu.Status == corev1.ConditionTrue && statu.Type == corev1.NodeReady {
    // fmt.Println(node.Name)
    // }
    // }
    //}

    //items, err := clientset.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{Limit: 5000, ResourceVersion: "0", TimeoutSeconds: &timeout})
    //for _, item := range items.Items {
    // for _, statu := range item.Status.Conditions {
    // if statu.Status == corev1.ConditionTrue && statu.Type == corev1.NodeReady {
    // fmt.Println(item.Name)
    // }
    // }
    //}
    //if err != nil {
    // fmt.Println(err)
    // return
    //}
    //fmt.Println(len(items.Items))

    elapsed := time.Since(start)
    fmt.Printf("代码执行时间:%s\n", elapsed)
    }
    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/08/cloud/K8s批量获取大量数据资源解决方案/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-通过URL访问模式

    K8s-通过URL访问模式

    背景

    大多情况下,一般操作K8s资源都会使用SDK模式,比如client-go

    + })(window)

    K8s-通过URL访问模式

    K8s-通过URL访问模式

    背景

    大多情况下,一般操作K8s资源都会使用SDK模式,比如client-go

    但是其实还支持原生的URL访问模式

    几种模式

    kubectl

    # 启动代理程序
    kubectl proxy --port=8080 &

    # 查看 http 模式
    curl http://localhost:8080/api/ '{"versions": ["v1"]}'

    @@ -193,7 +193,7 @@

    示例代码

    package main

    import (
    "crypto/tls"
    "fmt"
    "io"
    "net/http"
    )

    func main() {
    // 忽略严重ssl
    client := &http.Client{Transport: &http.Transport{
    TLSClientConfig: &tls.Config{
    InsecureSkipVerify: true,
    },
    }}
    targetUrl := "https://10.10.102.96:6443/api/v1/namespaces/default/services"

    req, _ := http.NewRequest("GET", targetUrl, nil)

    req.Header.Add("Authorization", "Bearer xxx")

    response, err := client.Do(req)
    if err != nil {
    fmt.Println(err)
    return
    }
    s, err := io.ReadAll(response.Body)
    if err != nil {
    fmt.Println(err)
    return
    }
    sprintf := fmt.Sprintf("%s", s)
    fmt.Println(sprintf)
    }
    -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/09/cloud/K8s-通过URL访问模式/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-编译Kubemark

    编译Kubemark

    背景

    Kubemark是k8s虚拟化节点的工具,用于测试。

    + })(window)

    K8s-编译Kubemark

    编译Kubemark

    背景

    Kubemark是k8s虚拟化节点的工具,用于测试。

    目前找不到现成可用Kubamark镜像,所以自行编译。

    安装

    # gcc 环境准备
    yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
    yum -y install wget httpd-tools vim
    yum -y install glibc-static.x86_64
    yum -y install binutils
    @@ -185,7 +185,7 @@

    安装问题 rpc error: code = Unimplemented desc = unknown service runtime.v1alpha2.ImageService


    cat > /etc/containerd/config.toml <<EOF
    [plugins."io.containerd.grpc.v1.cri"]
    systemd_cgroup = true
    EOF

    systemctl restart containerd

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/13/cloud/k8s/编译Kubemark/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    解读Kubeadm源码

    解读Kubeadm源码

    kubeadm init过程

    官网教程:https://kubernetes.io/zh-cn/docs/reference/setup-tools/kubeadm/kubeadm-init/

    + })(window)

    解读Kubeadm源码

    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/23/cloud/k8s/解读Kubeadm源码/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    Homebrew共存arm和X86(Mac)

    Homebrew共存arm和X86

    背景

    部分包支持arm,部分支持x86,主要是x86和arm的包的位置不一样

    + })(window)

    Homebrew共存arm和X86(Mac)

    Homebrew共存arm和X86

    背景

    部分包支持arm,部分支持x86,主要是x86和arm的包的位置不一样

    arm安装

    # 切换到/opt目录
    cd /opt
    # 创建homebrew目录
    sudo mkdir homebrew
    # 修改目录所属用户
    sudo chown -R $(whoami) /opt/homebrew
    # 安装Arm版Homebrew
    curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew

    x86 安装

    arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    @@ -181,7 +181,7 @@

    如何查看当前brew的版本

    # 查看brew架构
    brew config
    >
    HOMEBREW_VERSION: 4.1.17
    ORIGIN: https://mirrors.ustc.edu.cn/brew.git
    HEAD: 35746e0a6ba6c3c5cfe56d99f79d9ec9f52ee15f
    Last commit: 2 days ago
    Core tap origin: https://github.com/Homebrew/homebrew-core
    Core tap HEAD: cfa52a1f3d877a726b6006f4413000b3437c2709
    Core tap last commit: 4 hours ago
    Core tap branch: master
    Core tap JSON: 24 Oct 09:20 UTC
    HOMEBREW_PREFIX: /usr/local
    HOMEBREW_API_DOMAIN: https://mirrors.ustc.edu.cn/homebrew-bottles/api
    HOMEBREW_BOTTLE_DOMAIN: https://mirrors.ustc.edu.cn/homebrew-bottles/bottles
    HOMEBREW_CASK_OPTS: []
    HOMEBREW_MAKE_JOBS: 8
    HOMEBREW_NO_AUTO_UPDATE: set
    Homebrew Ruby: 2.6.10 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
    CPU: octa-core 64-bit westmere
    Clang: 14.0.0 build 1400
    Git: 2.37.1 => /Library/Developer/CommandLineTools/usr/bin/git
    Curl: 8.1.2 => /usr/bin/curl
    macOS: 12.6.8-x86_64
    CLT: 14.2.0.0.1.1668646533
    Xcode: N/A
    Rosetta 2: true

    abrew
    >
    HOMEBREW_VERSION: >=2.5.0 (shallow or no git repository)
    ORIGIN: (none)
    HEAD: (none)
    Last commit: never
    Core tap JSON: 24 Oct 09:20 UTC
    HOMEBREW_PREFIX: /opt/homebrew
    HOMEBREW_API_DOMAIN: https://mirrors.ustc.edu.cn/homebrew-bottles/api
    HOMEBREW_BOTTLE_DOMAIN: https://mirrors.ustc.edu.cn/homebrew-bottles/bottles
    HOMEBREW_CASK_OPTS: []
    HOMEBREW_MAKE_JOBS: 8
    HOMEBREW_NO_AUTO_UPDATE: set
    Homebrew Ruby: 2.6.10 => /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
    CPU: octa-core 64-bit arm_firestorm_icestorm
    Clang: 14.0.0 build 1400
    Git: 2.37.1 => /Library/Developer/CommandLineTools/usr/bin/git
    Curl: 8.1.2 => /usr/bin/curl
    macOS: 12.6.8-arm64
    CLT: 14.2.0.0.1.1668646533
    Xcode: N/A
    Rosetta 2: false

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/24/tools/Homebrew共存arm和X86/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-Service端点切片和服务拓扑

    K8s-Service端点切片和服务拓扑

    背景

    Service背后指向了一组Endpoint列表,当集群规范增大时,kube-proxy负载迅速上升,同时Service对Endpoint的CRUD操作成本是上升。

    + })(window)

    K8s-Service端点切片和服务拓扑

    K8s-Service端点切片和服务拓扑

    背景

    Service背后指向了一组Endpoint列表,当集群规范增大时,kube-proxy负载迅速上升,同时Service对Endpoint的CRUD操作成本是上升。

    所以在K8s 1.16引入了端点切片(Endpoint Slices)机制,包括一个新的EndpointSlice资源对象和新的EndpointSlice控制器。

    在K8s 1.17进入beta阶段,其原理是对Endpoint进行分片管理,实现降低Master和Node之间的网络传输数据量和提供整体性能。

    默认:EndpointSlice控制器创建Endpoint为100,需要修改需要设置kube-controller-manager –max- endpoint-per-slice设置,但是最大上限不能超过1000

    @@ -179,7 +179,7 @@

    服务拓扑(Service Topology)

    服务拓扑机制从Kubernetes 1.17版本开始引入,目前为Alpha阶段, 目标是实现基于Node拓扑的流量路由,例如将发送到某个服务的流量优 先路由到与客户端相同Node的Endpoint上,或者路由到与客户端相同 Zone的那些Node的Endpoint上

    在默认情况下,发送到一个Service的流量会被均匀转发到每个后端 Endpoint,但无法根据更复杂的拓扑信息设置复杂的路由策略。服务拓 扑机制的引入就是为了实现基于Node拓扑的服务路由,允许Service创建 者根据来源Node和目标Node的标签来定义流量路由策略

    服务拓扑机制需要通过设置kube-apiserver和kube-proxy服务的启动 参数–feature-gates=”ServiceTopology=true,EndpointSlice=true”进行启用 (需要同时启用EndpointSlice功能),然后就可以在Service资源对象上 通过定义topologyKeys字段来控制到Service的流量路由了

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/25/cloud/k8s/K8s-Service端点切片和服务拓扑/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-Pod的扩容

    K8s-Pod的扩容

    背景

    在实际生产系统中,我们经常会遇到某个服务需要扩容的场景,也 可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的 场景。此时可以利用Deployment/RC的Scale机制来完成这些工作。

    + })(window)

    K8s-Pod的扩容

    K8s-Pod的扩容

    背景

    在实际生产系统中,我们经常会遇到某个服务需要扩容的场景,也 可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的 场景。此时可以利用Deployment/RC的Scale机制来完成这些工作。

    手动扩容

    1. 通过kubectl scale deployment $nginx-deploymenr --replicas 5
    2. 本质上是通过修改replicas 实现的
    3. @@ -174,7 +174,7 @@

      期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]
      -
      apiVersion: autoscaling/v2
      kind: HorizontalPodAutoscaler
      metadata:
      name: php-apache
      spec:
      # 指向的副本控制器
      scaleTargetRef:
      apiVersion: apps/v1
      kind: Deployment
      name: php-apache
      # 最小
      minReplicas: 1
      # 最大拓展
      maxReplicas: 10
      #Pod指标
      metrics:
      - type: Resource
      resource:
      name: cpu
      target:
      # 百分比类型
      type: Utilization
      averageUtilization: 50
      - type: Resource
      resource:
      name: memory
      target:
      # 绝对值类型
      type: AverageValue
      averageValue: 100M

    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/26/cloud/k8s/K8s-Pod的扩容/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-Service的负载均衡机制

    K8s-Service的负载均衡机制

    Service对象通过关联转发到PodI实现负载均衡,每个Node的kube-proxy负责实现。

    + })(window)

    K8s-Service的负载均衡机制

    K8s-Service的负载均衡机制

    Service对象通过关联转发到PodI实现负载均衡,每个Node的kube-proxy负责实现。

    kube-proxy的代理模式

    通过启动参数–proxy-mode设 置

    userspace模式(x)

    用户空间模式,由kube-proxy完成的代理模式,效率低,不再推荐

    iptables模式

    kube-proxy通过设置Linux Kernel的iptables规则, 实现从Service到后端Endpoint列表的负载分发规则,效率很高。但是, 如果某个后端Endpoint在转发时不可用,此次客户端请求就会得到失败 的响应,相对于userspace模式来说更不可靠。

    @@ -180,7 +180,7 @@

    kernelspace模式

    Windows Server上的代理模式。

    会话保持机制

    Service支持通过设置sessionAffinity实现基于客户端IP的会话保持机制,即首次将某个客户端来源IP发起的请求转发到后端的某个Pod上, 之后从相同的客户端IP发起的请求都将被转发到相同的后端Pod上,配 置参数为service.spec.sessionAffinity

    -
    apiVersion: v1
    kind: Service
    metadata:
    name: sessionService
    spec:
    # 设置
    sessionAffinity: ClientIP
    # 会话保持时间
    sessionAffinityConfig:
    clientIP:
    timeoutSeconds: 10800
    selector:
    app: sessionService
    ports:
    - protocol: TCP
    port: 80
    targetPort: 8080
    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/26/cloud/k8s/K8s-Service的负载均衡机制/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-Service的服务发现机制

    K8s-Service的服务发现机制

    服务发现机制主要是K8s集群如何获取后端服务的访问地址。

    + })(window)

    K8s-Service的服务发现机制

    K8s-Service的服务发现机制

    服务发现机制主要是K8s集群如何获取后端服务的访问地址。

    K8s主要提供了俩种模式,环境变量方式和DNS方式

    环境变量

    apiVersion: v1
    kind: Service
    metadata:
    name: kubia
    spec:
    selector:
    app: kubia-service
    ports:
    - protocol: TCP
    port: 8080
    targetPort: 8080
    @@ -183,7 +183,7 @@

    <_portname>.<_protocol>...svc.

    会多一条:_http._tcp.webapp.default.svc.cluster.local

    -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/10/27/cloud/k8s/K8s-Service的服务发现机制/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-三大核心数据结构

    K8s-三大核心数据结构

    构成

    K8s-使用swagger-ui可视化K8s API文档

    使用swagger-ui可视化K8s API文档

    背景

    需要进行K8s API开发的时候,不方便查看

    + })(window)

    K8s-使用swagger-ui可视化K8s API文档

    使用swagger-ui可视化K8s API文档

    背景

    需要进行K8s API开发的时候,不方便查看

    具体实现

    # 启动代理
    kubectl proxy --port=8080

    # 获取到swagger.json
    curl localhost:8080/openapi/v2 > k8s-swagger.json

    # docker启动swagger
    docker run \
    --rm \
    -d \
    -p 8087:8080 \
    -e SWAGGER_JSON=/k8s-swagger.json \
    -v $(pwd)/k8s-swagger.json:/k8s-swagger.json \
    swaggerapi/swagger-ui


    # 通过http://ip:8087
    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/01/cloud/k8s/K8s-使用swagger-ui可视化K8s API文档/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-集群安装认证

    K8s-集群安装认证

    API Server认证

    三大K8s API访问模式:

    + })(window)

    K8s-集群安装认证

    K8s-集群安装认证

    API Server认证

    三大K8s API访问模式:

    1. 以Service Account方式访问K8s的内部服务进程
    2. 以匿名方式访问的进程
    3. @@ -197,7 +197,7 @@

      OpenID Connect Token第三方认证

      Kubernetes也支持使用OpenID Connect协议(简称OIDC)进行身份 认证。OIDC协议是基于OAuth 2.0协议的身份认证标准协议,在OAuth 2.0上构建了一个身份层,OIDC的登录过程与OAuth相比,最主要的扩 展就是提供了ID Token,这是一个JWT格式的加密Token。API Server本 身与OIDC Server(即Identity Provider)没有太多交互,用户(主要是 kubectl用户)通过OIDC Server得到一个合法的ID Token,并作为命令行 参数(或者kubectl的配置文件)传递给API Server,API Server则通过验 证该Token是否合法及是否有效来确定用户的身份。虽然在OIDC Server 中可以做到用户的权限管理,但Kubernetes并不使用OIDC Server的权限 管理,因为它有自己完善的BRAC权限管理体系

      Authenticating Proxy

      在这种方式下,将API Server配置为从HTTP Header(例如XRemote-User字段)对用户进行识别。这需要与Authenticating Proxy程序 一同工作,由Authenticating Proxy设置HTTP Header的值。

      Service Account

      Service Account也是一种账号,但它并不是给Kubernetes集群的用户 (系统管理员、运维人员、租户用户等)用的,而是给运行在Pod里的 进程用的,它为Pod里的进程提供了必要的身份证明。

      -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/01/cloud/k8s/K8s-集群安装认证/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-CNI网络模型

    K8s-CNI网络模型

    背景

    跨主机容器间的网络互通已经成为基本要求,更 高的要求包括容器固定IP地址、一个容器多个IP地址、多个子网隔离、 ACL控制策略、与SDN集成等。所以提出了Container Network Interface(CNI)

    + })(window)

    K8s-CNI网络模型

    K8s-CNI网络模型

    背景

    跨主机容器间的网络互通已经成为基本要求,更 高的要求包括容器固定IP地址、一个容器多个IP地址、多个子网隔离、 ACL控制策略、与SDN集成等。所以提出了Container Network Interface(CNI)

    CNM网络模型

    主要组件功能:

      @@ -299,7 +299,7 @@

      Versi
    • CNI_PATH:可执行文件的查找路径,可以设置多个

    错误返回码说明

    -
    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/02/cloud/k8s/K8s-CNI网络模型/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-DNS-CoreDNS

    K8s-DNS-CoreDNS

    修改Node上的kubelet的DNS启动参数

    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-存储系统

    K8s-存储系统

    Config Map

    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: game-demo
    data:
    # 类属性键;每一个键都映射到一个简单的值
    player_initial_lives: "3"
    ui_properties_file_name: "user-interface.properties"

    # 类文件键
    game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
    user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    ---
    apiVersion: v1
    kind: Pod
    metadata:
    name: cm-test-app
    spec:
    containers:
    - name: cm-test-app
    image: kubeguide/tomcat-app:v1
    ports:
    - containerPort: 8080
    volumeMounts:
    # 挂载的容器目录
    - mountPath: /configfiles
    name: serverxml
    volumes:
    # volume的名字
    - name: serverxml
    configMap:
    #cm 的name
    name: game-demo
    items:
    # cm的 key
    - key: game.properties
    # 容器内文件名字
    path: containergame.properties
    # cm的 key
    - key: user-interface.properties
    # 容器内文件名字
    path: user-xxx.properties
    + })(window)

    K8s-存储系统

    K8s-存储系统

    Config Map

    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: game-demo
    data:
    # 类属性键;每一个键都映射到一个简单的值
    player_initial_lives: "3"
    ui_properties_file_name: "user-interface.properties"

    # 类文件键
    game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
    user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    ---
    apiVersion: v1
    kind: Pod
    metadata:
    name: cm-test-app
    spec:
    containers:
    - name: cm-test-app
    image: kubeguide/tomcat-app:v1
    ports:
    - containerPort: 8080
    volumeMounts:
    # 挂载的容器目录
    - mountPath: /configfiles
    name: serverxml
    volumes:
    # volume的名字
    - name: serverxml
    configMap:
    #cm 的name
    name: game-demo
    items:
    # cm的 key
    - key: game.properties
    # 容器内文件名字
    path: containergame.properties
    # cm的 key
    - key: user-interface.properties
    # 容器内文件名字
    path: user-xxx.properties

    ​ ConfigMap中的配置内容如果是UTF-8编码的字符,则将被系统认 为是文本文件。如果是其他字符,则系统将以二进制数据格式进行保存 (设置为binaryData字段)

    Node本地存储卷

    Kubernetes管理的Node本地存储卷(Volume)的类型如下。

    @@ -298,7 +298,7 @@

    CS
  • 与kubelet通信的辅助sidecar容器的node-driver-register,主要功能是将存储驱动注册到kubelet中
  • CSI Driver存储驱动容器,,由第三方存储提供商提供,主要功 能是接收kubelet的调用,需要实现一系列与Node相关的CSI接口,例如 NodePublishVolume接口(用于将Volume挂载到容器内的目标路径)、 NodeUnpublishVolume接口(用于从容器中卸载Volume),等等。node-driver-registrar容器与kubelet通过Node主机一个hostPath目录下 的unix socket进行通信。CSI Driver容器与kubelet通过Node主机另一个 hostPath目录下的unix socket进行通信,同时需要将kubelet的工作目录 (默认为/var/lib/kubelet)挂载给CSI Driver容器,用于为Pod进行 Volume的管理操作(包括mount、umount等)
  • -

    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/02/cloud/k8s/K8s-存储系统/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-核心数据结构-scheme资源注册表

    K8s-核心数据结构-scheme资源注册表

    所有的K8s资源类型都会注册到Scheme资源注册表中,有如下的特点:

    + })(window)

    K8s-核心数据结构-scheme资源注册表

    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-client-go:源码结构

    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/08/cloud/k8s/K8s-client-go:源码结构/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-常见API Server响应说明

    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/08/cloud/k8s/K8s-常见API Server响应说明/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!

    K8s-Client-go:四种客户端

    K8s-Client-go:四种客户端

    概述

    ClientSet、DynamicClient、DiscoveryClient. —> RESTClient —> kubeconfig

    + })(window)

    K8s-Client-go:四种客户端

    K8s-Client-go:四种客户端

    概述

    ClientSet、DynamicClient、DiscoveryClient. —> RESTClient —> kubeconfig

    其实,前面三种都是依赖于 RESTClient

    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/11/cloud/k8s/K8s-Client-go:四种客户端/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-client-go:WorkQueue工作队列

    K8s-client-go:WorkQueue工作队列

    WorkQueue队列与普通的FIFO队列,添加了标记和去重功能。有如下特性:

    + })(window)

    K8s-client-go:WorkQueue工作队列

    K8s-client-go:WorkQueue工作队列

    WorkQueue队列与普通的FIFO队列,添加了标记和去重功能。有如下特性:

    1. 有序:按照顺序处理元素
    2. 去重:相同元素同一时间不会被重复处理
    3. @@ -208,7 +208,7 @@

      exp := r.failures[item]
      r.failures[item] = r.failures[item] + 1

      // The backoff is capped such that 'calculated' value never overflows.
      backoff := float64(r.baseDelay.Nanoseconds()) * math.Pow(2, float64(exp))
      if backoff > math.MaxInt64 {
      return r.maxDelay
      }

      calculated := time.Duration(backoff)
      if calculated > r.maxDelay {
      return r.maxDelay
      }

      return calculated

      计数器算法

      计数器算法就是限制一段时间内允许通过的元素数量。但是WorkQueue添加了fastslow速率

      -
      func (r *ItemFastSlowRateLimiter) When(item interface{}) time.Duration {
      r.failuresLock.Lock()
      defer r.failuresLock.Unlock()

      r.failures[item] = r.failures[item] + 1

      if r.failures[item] <= r.maxFastAttempts {
      return r.fastDelay
      }

      return r.slowDelay
      }

    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/11/cloud/k8s/K8s-client-goWorkQueue工作队列/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    打赏
    • alipay
      alipay

    评论

    K8s-节点

    K8s-节点

    K8s的node(节点)是一个工作机器。每个节点都是归属master组件管理。

    +

    节点的状态

      +
    • Addresses
    • +
    • Conditions
    • +
    • Capacity and Allocatable
    • +
    • Info
    • +
    +

    Addresses

      +
    • HostName: 在节点命令行界面上执行 hostname 命令所获得的值。启动 kubelet 时,可以通过参数 --hostname-override 覆盖
    • +
    • ExternalIP:通常是节点的外部IP(可以从集群外访问的内网IP地址;上面的例子中,此字段为空)
    • +
    • InternalIP:通常是从节点内部可以访问的 IP 地址
    • +
    +

    Conditions

    Conditions 描述了节点的状态。

    +

    Condition的例子有:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Node Condition描述
    OutOfDisk如果节点上的空白磁盘空间不够,不能够再添加新的节点时,该字段为 True,其他情况为 False
    Ready如果节点是健康的且已经就绪可以接受新的 Pod。则节点Ready字段为 TrueFalse表明了该节点不健康,不能够接受新的 Pod。
    MemoryPressure如果节点内存紧张,则该字段为 True,否则为False
    PIDPressure如果节点上进程过多,则该字段为 True,否则为 False
    DiskPressure如果节点磁盘空间紧张,则该字段为 True,否则为 False
    NetworkUnvailable如果节点的网络配置有问题,则该字段为 True,否则为 False
    +

    如果 Ready 类型Condition 的 status 持续为 Unkown 或者 False 超过 pod-eviction-timeoutkube-controller-manager (opens new window)的参数)所指定的时间,节点控制器(node controller)将对该节点上的所有 Pod 执行删除的调度动作

    +

    默认的 pod-eviction-timeout 时间是 5 分钟。某些情况下(例如,节点网络故障),apiserver 不能够与节点上的 kubelet 通信,删除 Pod 的指令不能下达到该节点的 kubelet 上,直到 apiserver 与节点的通信重新建立,指令才下达到节点。这意味着,虽然对 Pod 执行了删除的调度指令,但是这些Pod 可能仍然在失联的节点上运行

    +

    在 kubernetes v1.5 以前,节点控制器将从 apiserver 强制删除这些失联节点上的 Pod。在 v1.5 及以后的版本中,节点控制器将不会强制删除这些 Pod,直到已经确认他们已经停止运行为止。您可能会发现失联节点上的 Pod 仍然在运行(在该节点上执行 docker ps 命令可查看容器的运行状态),然而 apiserver 中,他们的状态已经变为 Terminating 或者 Unknown。如果 Kubernetes 不能通过 cloud-controller-manager 判断失联节点是否已经永久从集群中移除(例如,在虚拟机或物理机上自己部署 Kubernetes 的情况),集群管理员需要手工(通过 kubectl delete node your-node-name 命令)删除 apiserver 中的节点对象。此时,Kubernetes 将删除该节点上的所有 Pod

    +

    在 Kubernetes v1.12 中,TaintNodesByCondition 特性进入 beta 阶段,此时 node lifecycle controller 将自动创建该 Condition 对应的 污点。相应地,调度器在选择合适的节点时,不再关注节点的 Condition,而是检查节点的污点和 Pod 的容忍。

    +

    Capacity and Allocatable(容量和可分配量)

    容量和可分配量(Capacity and Allocatable)描述了节点上的可用资源的情况:

    +
      +
    • CPU
    • +
    • 内存
    • +
    • 该节点可调度的最大 pod 数量
    • +
    +

    Capacity 中的字段表示节点上的资源总数,Allocatable 中的字段表示该节点上可分配给普通 Pod 的资源总数。

    +

    参考 reserve compute resources (opens new window)可以了解更多关于容量和可分配量的内容

    +

    节点管理

    节点控制器

      +
    • 节点控制器,在注册节点的时候分配CIDR地址块

      +
    • +
    • 通过cloud-controller-manager 检查节点的虚拟机是否可用

      +
    • +
    • 节点控制器会监控节点的监控状态。节点控制器将节点API对象的 NodeStatus Condition 取值从 NodeReady 更新为 Unknown;然后在等待 pod-eviction-timeout 时间后,将节点上的所有 Pod 从节点驱逐

      +
      +

      默认40秒未收到心跳,修改 NodeStatus Condition 为 Unknown

      +

      默认 pod-eviction-timeout 为 5分钟

      +

      节点控制器每隔 --node-monitor-period 秒检查一次节点的状态

      +
      +
    • +
    +

    大多数情况下,节点控制器限制了驱逐 Pod 的速率为 --node-eviction-rate (默认值是0.1)每秒,即节点控制器每 10 秒驱逐 1 个 Pod。

    +

    当节点所在的高可用区出现故障时,节点控制器驱逐 Pod 的方式将不一样。节点控制器驱逐Pod前,将检查高可用区里故障节点的百分比(NodeReady Condition 的值为 UnknownFalse):

    +
      +
    • 如果故障节点的比例不低于--unhealthy-zone-threshold(默认为 0.55),则降低驱逐 Pod 的速率
        +
      • 如果集群规模较小(少于等于 --large-cluster-size-threshold 个节点,默认值为 50),则停止驱逐 Pod
      • +
      • 如果集群规模大于 --large-cluster-size-threshold 个节点,则驱逐 Pod 的速率降低到 --secondary-node-eviction-rate (默认值为 0.01)每秒
      • +
      +
    • +
    +

    节点自注册(Self-Registration)

    如果 kubelet 的启动参数 --register-node为 true(默认为 true),kubelet 会尝试将自己注册到 API Server。kubelet自行注册时,将使用如下选项:

    +
      +
    • --kubeconfig:向 apiserver 进行认证时所用身份信息的路径
    • +
    • --cloud-provider:向云供应商读取节点自身元数据
    • +
    • --register-node:自动向 API Server 注册节点
    • +
    • --register-with-taints:注册节点时,为节点添加污点(逗号分隔,格式为 =:
    • +
    • --node-ip:节点的 IP 地址
    • +
    • --node-labels:注册节点时,为节点添加标签
    • +
    • --node-status-update-frequency:向 master 节点发送心跳信息的时间间
    • +
    +

    手动管理节点

    集群管理员可以创建和修改节点API对象。

    +

    如果管理员想要手工创建节点API对象,可以将 kubelet 的启动参数 --register-node 设置为 false。

    +

    管理员可以修改节点API对象(不管是否设置了 --register-node 参数)。可以修改的内容有:

    +
      +
    • 增加/减少标签
    • +
    • 标记节点为不可调度(unschedulable)
    • +
    +

    节点的标签与 Pod 上的节点选择器(node selector)配合,可以控制调度方式,例如,限定 Pod 只能在某一组节点上运行。请参考 将容器组调度到指定的节点

    +

    执行如下命令可将节点标记为不可调度(unschedulable),此时将阻止新的 Pod 被调度到该节点上,但是不影响任何已经在该节点上运行的 Pod。这在准备重启节点之前非常有用。

    +
    kubectl cordon $NODENAME
    文章作者: Piwriw.
    文章链接: http://example.com/2023/11/14/cloud/k8s/K8s-节点/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    \ No newline at end of file diff --git "a/2023/12/01/cloud/k8s/K8s-\345\256\271\345\231\250/index.html" "b/2023/12/01/cloud/k8s/K8s-\345\256\271\345\231\250/index.html" new file mode 100644 index 000000000..b1ded0e45 --- /dev/null +++ "b/2023/12/01/cloud/k8s/K8s-\345\256\271\345\231\250/index.html" @@ -0,0 +1,333 @@ +K8s-容器 | Piwriw + + + + + + + + + + + + + +

    K8s-容器

    K8s-容器

    镜像

    在 Kubernetes 的 Pod 中使用容器镜像之前,您必须将其推送到一个镜像仓库(或者使用仓库中已经有的容器镜像)。在 Kubernetes 的 Pod 定义中定义容器时,必须指定容器所使用的镜像,容器中的 image 字段支持与 docker 命令一样的语法,包括私有镜像仓库和标签。

    +

    例如:my-registry.example.com:5000/example/web-example:v1.0.1 由如下几个部分组成:

    +

    my-registry.example.com:5000/example/web-example:v1.0.1

    +
      +
    • my-registry.example.com:registry 地址
    • +
    • 5000:registry 端口
    • +
    • example:repository 名字
    • +
    • web-example:image 名字
    • +
    • v1.0.1:image 标签
    • +
    +

    如果您使用 hub.dokcer.com Registry 中的镜像,可以省略 registry 地址和 registry 端口。例如:nginx:latesteipwork/kuboard

    +

    更新镜像

    更新策略

    Kubernetes中,默认的镜像抓取策略是 IfNotPresent,使用此策略,kubelet在发现本机有镜像的情况下,不会向镜像仓库抓取镜像

    +

    如果期望每次启动 Pod 时,都强制从镜像仓库抓取镜像

    +
      +
    • 设置 container 中的 imagePullPolicyAlways
    • +
    • 省略 imagePullPolicy 字段,并使用 :latest tag 的镜像
    • +
    • 省略 imagePullPolicy 字段和镜像的 tag
    • +
    • 激活 AlwaysPullImages (opens new window)管理控制器
    • +
    +

    更新过程:

    +
      +
    • imagePullPolicy: IfNotPresent 仅在节点上没有该镜像时,从镜像仓库抓取

      +
    • +
    • imagePullPolicy: Always 每次启动 Pod 时,从镜像仓库抓取

      +
    • +
    • imagePullPolicy 未填写,镜像 tag 为 :latest 或者未填写,则同 Always 每次启动 Pod 时,从镜像仓库抓取

      +
    • +
    • imagePullPolicy 未填写,镜像 tag 已填写但不是 :latest,则同 IfNotPresent 仅在节点上没有该镜像时,从镜像仓库抓取

      +
    • +
    • imagePullPolicy: Never,Kubernetes 假设本地存在该镜像,并且不会尝试从镜像仓库抓取镜像

      +
    • +
    +

    使用私有仓库中的docker镜像

    因为企业以下需求通常会有自建仓库的需求:

    +
      +
    • 限制 docker 镜像的分发范围,例如:只允许在内网分发,或者只允许被授权的用户获取 docker 镜像
    • +
    • 提高推送 docker 镜像以及抓取 docker 镜像时的网络传输速度
    • +
    +

    一个镜像仓库需要以下的要求:

    +

    ⚠️需要支持HTTPS

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    参数名称参数值备注
    registry地址my-registry.example.com推荐使用域名,也可以是 ip 地址
    registry端口5000必须支持 HTTPS
    registry用户名myusername
    registry密码mypassowrd
    repository名字example
    image名字web-example
    image标签v1.0.1
    +

    Harbor的部署

    +

    容器的环境变量

    容器的信息

    在容器中执行 hostname 命令或者在libc 中执行 gethostname (opens new window)函调用,获得的是容器所在 Pod 的名字。

    +

    Pod 的名字,以及 Pod 所在名称空间可以通过 downward API (opens new window)注入到容器的环境变量里。

    +

    用户也可以为容器自定义环境变量,请参考 使用ConfigMap配置您的应用程序

    +

    集群的信息

    在容器创建时,集群中所有的 Service 的连接信息将以环境变量的形式注入到容器中。例如,已创建了一个名为 Foo 的 Service,此时再创建任何容器时,该容器将包含如下环境变量:
    FOO_SERVICE_HOST=<Service的ClusterIP>
    FOO_SERVICE_PORT=<Service的端口>
    + +

    Runtime Class

    可以通过 RuntimeClass,使不同的 Pod 使用不同的容器引擎,以在性能和安全之间取得平衡。例如,如果某些工作负载需要非常高的信息安全保证,您可能想要将其 Pod 运行在那种使用硬件虚拟化的容器引擎上;同时,将其他的 Pod 运行在另外一种容器引擎上,以获得更高的性能。K8s-Runtime Class

    +

    容器生命周期

      +
    • PostStart

      +

      此钩子函数在容器创建后将立刻执行。但是,并不能保证该钩子函数在容器的 ENTRYPOINT 之前执行。该钩子函数没有输入参数。

      +
    • +
    • PreStop

      +

      此钩子函数在容器被 terminate(终止)之前执行,例如:

      +
        +
      • 通过接口调用删除容器所在 Pod
      • +
      • 某些管理事件的发生:健康检查失败、资源紧缺等
      • +
      +

      如果容器已经被关闭或者进入了 completed 状态,preStop 钩子函数的调用将失败。该函数的执行是同步的,即,kubernetes 将在该函数完成执行之后才删除容器。该钩子函数没有输入参数

      +
    • +
    +

    Hook handler的实现

    容器只要实现并注册 hook handler 便可以使用钩子函数。Kubernetes 中,容器可以实现两种类型的 hook handler:

    +
      +
    • Exec - 在容器的名称空进和 cgroups 中执行一个指定的命令,例如 pre-stop.sh。该命令所消耗的 CPU、内存等资源,将计入容器可以使用的资源限制。
    • +
    • HTTP - 向容器的指定端口发送一个 HTTP 请求
    • +
    +

    Hook handler的执行

    当容器的生命周期事件发生时,Kubernetes 在容器中执行该钩子函数注册的 handler。

    +

    对于 Pod 而言,hook handler 的调用是同步的。即,如果是 PostStart hook,容器的 ENTRYPOINT 和 hook 是同时出发的,然而如果 hook 执行的时间过长或者挂起了,容器将不能进入到 Running 状态。

    +

    PreStop hook 的行为与此相似。如果 hook 在执行过程中挂起了,Pod phase 将停留在 Terminating 的状态,并且在 terminationGracePeriodSeconds 超时之后,Pod被删除。如果 PostStart 或者 PreStop hook 执行失败,则 Kubernetes 将 kill(杀掉)该容器。

    +

    用户应该使其 hook handler 越轻量级越好。例如,对于长时间运行的任务,在停止容器前,调用 PreStop 钩子函数,以保存当时的计算状态和数据

    +

    定义postStart和preStop处理程序

    apiVersion: v1
    kind: Pod
    metadata:
    name: lifecycle-demo
    spec:
    containers:
    - name: lifecycle-demo-container
    image: nginx
    lifecycle:
    postStart:
    exec:
    command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
    preStop:
    exec:
    command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]

    + +
    文章作者: Piwriw.
    文章链接: http://example.com/2023/12/01/cloud/k8s/K8s-容器/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    \ No newline at end of file diff --git "a/2023/12/02/cloud/k8s/K8s-\345\257\271\350\261\241/index.html" "b/2023/12/02/cloud/k8s/K8s-\345\257\271\350\261\241/index.html" new file mode 100644 index 000000000..51c0707fc --- /dev/null +++ "b/2023/12/02/cloud/k8s/K8s-\345\257\271\350\261\241/index.html" @@ -0,0 +1,276 @@ +K8s-对象 | Piwriw + + + + + + + + + + + + + +

    K8s-对象

    K8s-对象

    对象的spec和status

      +
    • spec:操作员所期望的状态
    • +
    • status:实际上集群中的状态
    • +
    +

    必填字段

    在上述的 .yaml 文件中,如下字段是必须填写的:

    +
      +
    • apiVersion 用来创建对象时所使用的Kubernetes API版本
    • +
    • kind 被创建对象的类型
    • +
    • metadata 用于唯一确定该对象的元数据:包括 namenamespace,如果 namespace 为空,则默认值为 default
    • +
    • spec 描述您对该对象的期望状态
    • +
    +

    名称

    Kubernetes REST API 中,所有的对象都是通过 nameUID 唯一性确定。

    +

    Names

    可以通过 namespace + name 唯一性地确定一个 RESTFUL 对象,例如:

    +
    /api/v1/namespaces/{namespace}/pods/{name}
    + +

    同一个名称空间下,同一个类型的对象,可以通过 name 唯一性确定。如果删除该对象之后,可以再重新创建一个同名对象。

    +

    下面是三种广泛使用的资源名称的限制类型:

    +

    DNS Subdomain Names

    绝大部分资源类型的名称必须符合 DNS subdomain 命名规则 RFC 1123 (opens new window),具体如下:

    +
      +
    • 最长不超过 253个字符
    • +
    • 必须由小写字母、数字、减号 -、小数点 . 组成
    • +
    • 由字母开始
    • +
    • 由字母结束
    • +
    +

    DNS Label Names

    部分类型的资源要求其名称符合 DNS Label 的命名规则 RFC 1123 (opens new window),具体如下:

    +
      +
    • 最长不超过 63个字符
    • +
    • 必须由小写字母、数字、减号 -、小数点 . 组成
    • +
    • 由字母开始
    • +
    • 由字母结束
    • +
    +

    Path Segment Names

    部分类型的资源要求其名称可以被编码到路径中。换句话说,名称中不能包含 .../%

    +

    UIDs

    UID 是由 Kubernetes 系统生成的,唯一标识某个 Kubernetes 对象的字符串。

    +

    Kubernetes集群中,每创建一个对象,都有一个唯一的 UID。用于区分多次创建的同名对象(如前所述,按照名字删除对象后,重新再创建同名对象时,两次创建的对象 name 相同,但是 UID 不同。)

    +

    Kubernetes 中的 UID 是全局唯一的标识符(UUIDs,符合规范 ISO/IEC 9834-8 以及 ITU-T X.667)

    +

    名称(命名)空间

    可以通过 set-context 命令改变当前 kubectl 上下文 的名称空间,后续所有命令都默认在此名称空间下执行。

    +
    kubectl config set-context --current --namespace=<您的名称空间>
    # 验证结果
    kubectl config view --minify | grep namespace:
    + +

    名称空间与DNS

    当您创建一个 Service 时,Kubernetes 为其创建一个对应的 DNS 条目。该 DNS 记录的格式为 <service-name>.<namespace-name>.svc.cluster.local,也就是说,如果在容器中只使用 <service-name>,其DNS将解析到同名称空间下的 Service。这个特点在多环境的情况下非常有用,例如将开发环境、测试环境、生产环境部署在不同的名称空间下,应用程序只需要使用 <service-name> 即可进行服务发现,无需为不同的环境修改配置。如果您想跨名称空间访问服务,则必须使用完整的域名(fully qualified domain name,FQDN

    +

    并非所有对象都在名称空间里

    大部分的 Kubernetes 对象(例如,Pod、Service、Deployment、StatefulSet等)都必须在名称空间里。但是某些更低层级的对象,是不在任何名称空间中的,例如 nodespersistentVolumesstorageClass

    +
    # 在名称空间里
    kubectl api-resources --namespaced=true

    # 不在名称空间里
    kubectl api-resources --namespaced=false
    + +

    使用命名空间共享集群

    Kubernetes 安装成功后,默认有初始化了三个名称空间:

    +
      +
    • default 默认名称空间,如果 Kubernetes 对象中不定义 metadata.namespace 字段,该对象将放在此名称空间下
    • +
    • kube-system Kubernetes系统创建的对象放在此名称空间下
    • +
    • kube-public 此名称空间自动在安装集群是自动创建,并且所有用户都是可以读取的(即使是那些未登录的用户)。主要是为集群预留的,例如,某些情况下,某些Kubernetes对象应该被所有集群用户看到。
    • +
    +

    命名空间拥有Resource Quota 和 resource limit range:

    +
      +
    • Resource quota 汇总了名称空间中使用的资源总量,并指定了集群管理员定义该名称空间最多可以使用的资源量
    • +
    • Limit range 定义了名称空间中某种具体的资源类型的最大、最小值
    • +
    +

    注解annotation

    注解(annotation)可以用来向 Kubernetes 对象的 metadata.annotations 字段添加任意的信息。Kubernetes 的客户端或者自动化工具可以存取这些信息以实现其自定义的逻辑

    +

    Example:

    +
    apiVersion: v1
    kind: Pod
    metadata:
    name: annotations-demo
    annotations:
    imageregistry: "https://hub.docker.com/"
    spec:
    containers:
    - name: nginx
    image: nginx:1.7.9
    ports:
    - containerPort: 80
    + +

    字段选择器

    字段选择器(Field Selector)可以用来基于的一个或多个字段的取值来选取一组Kubernetes对象。下面有一些示例性的字段选择器:

    +
    # 下面的 kubectl 命令选择了所有字段 status.phase 的取值为 Running 的 Pod:
    不一样。所有的对象类型都支持的两个字段是 metadata.name 和 metadata.namespace
    kubectl get pods --field-selector status.phase=Running
    + + + +
    文章作者: Piwriw.
    文章链接: http://example.com/2023/12/02/cloud/k8s/K8s-对象/
    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Piwriw
    打赏
    • alipay
      alipay

    评论
    \ No newline at end of file diff --git a/about/index.html b/about/index.html index 83ec487f7..c49d4b516 100644 --- a/about/index.html +++ b/about/index.html @@ -162,7 +162,7 @@ } } detectApple() - })(window)
    \ No newline at end of file diff --git a/archives/2023/12/index.html b/archives/2023/12/index.html new file mode 100644 index 000000000..c99421c57 --- /dev/null +++ b/archives/2023/12/index.html @@ -0,0 +1,172 @@ +十二月 2023 | Piwriw + + + + + + + + + + +
    文章总览 - 2
    2023
    K8s-对象
    K8s-对象
    K8s-容器
    K8s-容器
    \ No newline at end of file diff --git a/archives/2023/index.html b/archives/2023/index.html index c6b5ccd6e..f58231863 100644 --- a/archives/2023/index.html +++ b/archives/2023/index.html @@ -56,7 +56,7 @@ isHome: false, isHighlightShrink: false, isToc: false, - postUpdate: '2023-11-12 16:16:56' + postUpdate: '2023-12-19 15:01:49' }
    \ No newline at end of file diff --git a/categories/index.html b/categories/index.html index a406c613d..c3aa23930 100644 --- a/categories/index.html +++ b/categories/index.html @@ -162,15 +162,16 @@ } } detectApple() - })(window)
    avatar
    Piwriw.
    该知道的都知道,不知道的慢慢了解
    Follow Me
    公告
    Please try your best!
    最新文章
    + })(window)
    \ No newline at end of file diff --git a/tags/kubeedge/index.html b/tags/kubeedge/index.html index 063fd1e7c..667de9a67 100644 --- a/tags/kubeedge/index.html +++ b/tags/kubeedge/index.html @@ -56,7 +56,7 @@ isHome: false, isHighlightShrink: false, isToc: false, - postUpdate: '2023-11-12 16:16:56' + postUpdate: '2023-12-19 15:01:49' }