k8s-nginx启动

1、代码结构

.
├── ingress-nginx               # k8s ingress-nginx源码
│ ├── build                     # 构建相关
│ ├── charts                    # helm打包编排
│ ├── cmd                       # 命令行,初始化等
│ ├── deploy                    # yaml构建相关支持
│ ├── hack                      # 构建底层相关支持
│ ├── image                     # 镜像构建相关支持
│ ├ ── kube-webhook-certgen     # webhook相关创建
│ ├── internal                  # 路由匹配等
│ ├ ── admisson/controller      # webhook配置安全检查
│ ├ ── ingress/annotations      # ingress支持的一大堆注解
│ ├ ── ingress/controller       # ingress控制器核心逻辑
│ ├ ── ingress/metric           # ingress支持的普罗米修斯等数据收集
│ ├ ── ingress/nginx            # nginx交互rest帮助
│ ├ ── ingress/watch            # nginx配置文件变更监听
│ ├── rootfs                    # nginx lua支持
│ └── test                      # 各种测试
...

nginx.tmpl

      balancer.init_worker()

balancer

 初始化backends,且设置定时任务定期更新,数据是存放在worker本地内存中

function _M.init_worker()
  -- when worker starts, sync non ExternalName backends without delay
  sync_backends()
  -- we call sync_backends_with_external_name in timer because for endpoints that require
  -- DNS resolution it needs to use socket which is not available in
  -- init_worker phase
  local ok, err = ngx.timer.at(0, sync_backends_with_external_name)
  if not ok then
    ngx.log(ngx.ERR, "failed to create timer: ", err)
  end

  ok, err = ngx.timer.every(BACKENDS_SYNC_INTERVAL, sync_backends)
  if not ok then
    ngx.log(ngx.ERR, "error when setting up timer.every for sync_backends: ", err)
  end
  ok, err = ngx.timer.every(BACKENDS_SYNC_INTERVAL, sync_backends_with_external_name)
  if not ok then
    ngx.log(ngx.ERR, "error when setting up timer.every for sync_backends_with_external_name: ",
            err)
  end
end
local backends_data = configuration.get_backends_data()
local configuration_data = ngx.shared.configuration_data
...

function _M.get_backends_data()
  return configuration_data:get("backends")
end

定时任务变更

depolyment变更

 cmd/nginx/main.go

初始化客户端、监控数据、web服务及
ngx := controller.NewNGINXController(conf, mc)

internal/ingress/controller/nginx.go

n.syncQueue = task.NewTaskQueue(n.syncIngress)
文件监听,回调更新配置等也在这里

internal/ingress/controller/controller.go 定时更新

retry := wait.Backoff{
        Steps:    15,
        Duration: 1 * time.Second,
        Factor:   0.8,
        Jitter:   0.1,
    }

    err := wait.ExponentialBackoff(retry, func() (bool, error) {
        err := n.configureDynamically(pcfg)
        if err == nil {
            klog.V(2).Infof("Dynamic reconfiguration succeeded.")
            return true, nil
        }

        klog.Warningf("Dynamic reconfiguration failed: %v", err)
        return false, err
    })

变更后nginx.go中从apiserver获取新值post请求到Lua

func configureBackends(rawBackends []*ingress.Backend) error {
    backends := make([]*ingress.Backend, len(rawBackends))

    for i, backend := range rawBackends {
        var service *apiv1.Service
        if backend.Service != nil {
            service = &apiv1.Service{Spec: backend.Service.Spec}
        }
        luaBackend := &ingress.Backend{
            Name:                 backend.Name,
            Port:                 backend.Port,
            SSLPassthrough:       backend.SSLPassthrough,
            SessionAffinity:      backend.SessionAffinity,
            UpstreamHashBy:       backend.UpstreamHashBy,
            LoadBalancing:        backend.LoadBalancing,
            Service:              service,
            NoServer:             backend.NoServer,
            TrafficShapingPolicy: backend.TrafficShapingPolicy,
            AlternativeBackends:  backend.AlternativeBackends,
        }

        var endpoints []ingress.Endpoint
        for _, endpoint := range backend.Endpoints {
            endpoints = append(endpoints, ingress.Endpoint{
                Address: endpoint.Address,
                Port:    endpoint.Port,
            })
        }

        luaBackend.Endpoints = endpoints
        backends[i] = luaBackend
    }

    statusCode, _, err := nginx.NewPostStatusRequest("/configuration/backends", "application/json", backends)
    if err != nil {
        return err
    }

    if statusCode != http.StatusCreated {
        return fmt.Errorf("unexpected error code: %d", statusCode)
    }

    return nil
}
原文地址:https://www.cnblogs.com/it-worker365/p/15417625.html