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 }