sigs.k8s.io controller-runtime系列之七 certwatcher分析

简介

之前介绍过sigs.k8s.io controller-runtime系列之六 webhook分析sigs.k8s.io controller-runtime-webhook
本文主要介绍pkg/certwatcher的源码分析。

目录结构

  1. certwatcher.go
    • CertWatcher结构体 监视证书和密钥文件的更改。当任何一个文件更改时,它调用读取和解析这两个函数,并使用新的证书。
    type CertWatcher struct {
    	sync.RWMutex
        
        // 解析后的证书文件内容
    	currentCert *tls.Certificate
    	watcher     *fsnotify.Watcher
        
        // 证书路径
    	certPath string
        // 证书key路径
    	keyPath  string
    }
    
    • New函数 通过给定的certPath和keyPath,创建一个新的证书监视器。
    func New(certPath, keyPath string) (*CertWatcher, error) {
    	var err error
        // 通过certPath和keyPath构造出CertWatcher对象的地址
    	cw := &CertWatcher{
    		certPath: certPath,
    		keyPath:  keyPath,
    	}
    
    	// 从文件读取证书文件
    	if err := cw.ReadCertificate(); err != nil {
    		return nil, err
    	}
        // 引用github.com/fsnotify/fsnotify构造的监视器,具体注意事项参考https://github.com/fsnotify/fsnotify的FAQ
    	cw.watcher, err = fsnotify.NewWatcher()
    	if err != nil {
    		return nil, err
    	}
    
    	return cw, nil
    }
    
    // ReadCertificate从磁盘读取证书和密钥文件,并对其进行解析,并更新观察程序上的当前证书。如果设置了回调,则用新证书调用。
    func (cw *CertWatcher) ReadCertificate() error {
    	cert, err := tls.LoadX509KeyPair(cw.certPath, cw.keyPath)
    	if err != nil {
    		return err
    	}
    
    	cw.Lock()
    	cw.currentCert = &cert
    	cw.Unlock()
    
    	log.Info("Updated current TLS certificate")
    
    	return nil
    }
    
    • Start函数 启动cerwatcher,监视certificate and key 文件
    func (cw *CertWatcher) Start(ctx context.Context) error {
    	files := []string{cw.certPath, cw.keyPath}
        // 添加到监视文件中
    	for _, f := range files {
    		if err := cw.watcher.Add(f); err != nil {
    			return err
    		}
    	}
        // 目前必须开启单独的goruntime监视,参考https://github.com/fsnotify/fsnotify的FAQ
    	go cw.Watch()
    
    	log.Info("Starting certificate watcher")
    
    	// Block until the context is done.
    	<-ctx.Done()
    
    	return cw.watcher.Close()
    }
    
    // 从监视器管道中读取事件,并及时响应
    func (cw *CertWatcher) Watch() {
    	for {
    		select {
    		case event, ok := <-cw.watcher.Events:
    			// 通道已关闭
    			if !ok {
    				return
    			}
                // 处理给定事件
    			cw.handleEvent(event)
    
    		case err, ok := <-cw.watcher.Errors:
    			// 通道已关闭
    			if !ok {
    				return
    			}
    
    			log.Error(err, "certificate watch error")
    		}
    	}
    }
    
    func (cw *CertWatcher) handleEvent(event fsnotify.Event) {
    	// 仅仅关心修改了file内容的event
    	if !(isWrite(event) || isRemove(event) || isCreate(event)) {
    		return
    	}
    
    	log.V(1).Info("certificate event", "event", event)
    
    	// 如果文件被移除,则重新添加到监视文件中
    	if isRemove(event) {
    		if err := cw.watcher.Add(event.Name); err != nil {
    			log.Error(err, "error re-watching file")
    		}
    	}
    
    	if err := cw.ReadCertificate(); err != nil {
    		log.Error(err, "error re-reading certificate")
    	}
    }
    
    // 判断是否写入事件
    func isWrite(event fsnotify.Event) bool {
    	return event.Op&fsnotify.Write == fsnotify.Write
    }
    
    // 判断是否创建事件
    func isCreate(event fsnotify.Event) bool {
    	return event.Op&fsnotify.Create == fsnotify.Create
    }
     
    // 判断是否移除事件
    func isRemove(event fsnotify.Event) bool {
    	return event.Op&fsnotify.Remove == fsnotify.Remove
    }
    
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值