1 Star 0 Fork 0

zhuchance / kubernetes

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cleaner.go 7.22 KB
一键复制 编辑 原始数据 按行查看 历史
WanLinghao 提交于 2018-01-15 10:31 . fix some log param error
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Package cleaner implements an automated cleaner that does garbage collection
// on CSRs that meet specific criteria. With automated CSR requests and
// automated approvals, the volume of CSRs only increases over time, at a rapid
// rate if the certificate duration is short.
package cleaner
import (
"crypto/x509"
"encoding/pem"
"fmt"
"time"
"github.com/golang/glog"
capi "k8s.io/api/certificates/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
certificatesinformers "k8s.io/client-go/informers/certificates/v1beta1"
csrclient "k8s.io/client-go/kubernetes/typed/certificates/v1beta1"
certificateslisters "k8s.io/client-go/listers/certificates/v1beta1"
)
const (
// The interval to list all CSRs and check each one against the criteria to
// automatically clean it up.
pollingInterval = 1 * time.Hour
// The time periods after which these different CSR statuses should be
// cleaned up.
approvedExpiration = 1 * time.Hour
deniedExpiration = 1 * time.Hour
pendingExpiration = 24 * time.Hour
)
// CSRCleanerController is a controller that garbage collects old certificate
// signing requests (CSRs). Since there are mechanisms that automatically
// create CSRs, and mechanisms that automatically approve CSRs, in order to
// prevent a build up of CSRs over time, it is necessary to GC them. CSRs will
// be removed if they meet one of the following criteria: the CSR is Approved
// with a certificate and is old enough to be past the GC issued deadline, the
// CSR is denied and is old enough to be past the GC denied deadline, the CSR
// is Pending and is old enough to be past the GC pending deadline, the CSR is
// approved with a certificate and the certificate is expired.
type CSRCleanerController struct {
csrClient csrclient.CertificateSigningRequestInterface
csrLister certificateslisters.CertificateSigningRequestLister
}
// NewCSRCleanerController creates a new CSRCleanerController.
func NewCSRCleanerController(
csrClient csrclient.CertificateSigningRequestInterface,
csrInformer certificatesinformers.CertificateSigningRequestInformer,
) *CSRCleanerController {
return &CSRCleanerController{
csrClient: csrClient,
csrLister: csrInformer.Lister(),
}
}
// Run the main goroutine responsible for watching and syncing jobs.
func (ccc *CSRCleanerController) Run(workers int, stopCh <-chan struct{}) {
defer utilruntime.HandleCrash()
glog.Infof("Starting CSR cleaner controller")
defer glog.Infof("Shutting down CSR cleaner controller")
for i := 0; i < workers; i++ {
go wait.Until(ccc.worker, pollingInterval, stopCh)
}
<-stopCh
}
// worker runs a thread that dequeues CSRs, handles them, and marks them done.
func (ccc *CSRCleanerController) worker() {
csrs, err := ccc.csrLister.List(labels.Everything())
if err != nil {
glog.Errorf("Unable to list CSRs: %v", err)
return
}
for _, csr := range csrs {
if err := ccc.handle(csr); err != nil {
glog.Errorf("Error while attempting to clean CSR %q: %v", csr.Name, err)
}
}
}
func (ccc *CSRCleanerController) handle(csr *capi.CertificateSigningRequest) error {
isIssuedExpired, err := isIssuedExpired(csr)
if err != nil {
return err
}
if isIssuedPastDeadline(csr) || isDeniedPastDeadline(csr) || isPendingPastDeadline(csr) || isIssuedExpired {
if err := ccc.csrClient.Delete(csr.Name, nil); err != nil {
return fmt.Errorf("unable to delete CSR %q: %v", csr.Name, err)
}
}
return nil
}
// isIssuedExpired checks if the CSR has been issued a certificate and if the
// expiration of the certificate (the NotAfter value) has passed.
func isIssuedExpired(csr *capi.CertificateSigningRequest) (bool, error) {
for _, c := range csr.Status.Conditions {
isExpired, err := isExpired(csr)
if err != nil {
return false, err
}
if c.Type == capi.CertificateApproved && isIssued(csr) && isExpired {
glog.Infof("Cleaning CSR %q as the associated certificate is expired.", csr.Name)
return true, nil
}
}
return false, nil
}
// isPendingPastDeadline checks if the certificate has a Pending status and the
// creation time of the CSR is passed the deadline that pending requests are
// maintained for.
func isPendingPastDeadline(csr *capi.CertificateSigningRequest) bool {
// If there are no Conditions on the status, the CSR will appear via
// `kubectl` as `Pending`.
if len(csr.Status.Conditions) == 0 && isOlderThan(csr.CreationTimestamp, pendingExpiration) {
glog.Infof("Cleaning CSR %q as it is more than %v old and unhandled.", csr.Name, pendingExpiration)
return true
}
return false
}
// isDeniedPastDeadline checks if the certificate has a Denied status and the
// creation time of the CSR is passed the deadline that denied requests are
// maintained for.
func isDeniedPastDeadline(csr *capi.CertificateSigningRequest) bool {
for _, c := range csr.Status.Conditions {
if c.Type == capi.CertificateDenied && isOlderThan(c.LastUpdateTime, deniedExpiration) {
glog.Infof("Cleaning CSR %q as it is more than %v old and denied.", csr.Name, deniedExpiration)
return true
}
}
return false
}
// isIssuedPastDeadline checks if the certificate has an Issued status and the
// creation time of the CSR is passed the deadline that issued requests are
// maintained for.
func isIssuedPastDeadline(csr *capi.CertificateSigningRequest) bool {
for _, c := range csr.Status.Conditions {
if c.Type == capi.CertificateApproved && isIssued(csr) && isOlderThan(c.LastUpdateTime, approvedExpiration) {
glog.Infof("Cleaning CSR %q as it is more than %v old and approved.", csr.Name, approvedExpiration)
return true
}
}
return false
}
// isOlderThan checks that t is a non-zero time after time.Now() + d.
func isOlderThan(t metav1.Time, d time.Duration) bool {
return !t.IsZero() && t.Sub(time.Now()) < -1*d
}
// isIssued checks if the CSR has `Issued` status. There is no explicit
// 'Issued' status. Implicitly, if there is a certificate associated with the
// CSR, the CSR statuses that are visible via `kubectl` will include 'Issued'.
func isIssued(csr *capi.CertificateSigningRequest) bool {
return csr.Status.Certificate != nil
}
// isExpired checks if the CSR has a certificate and the date in the `NotAfter`
// field has gone by.
func isExpired(csr *capi.CertificateSigningRequest) (bool, error) {
if csr.Status.Certificate == nil {
return false, nil
}
block, _ := pem.Decode(csr.Status.Certificate)
if block == nil {
return false, fmt.Errorf("expected the certificate associated with the CSR to be PEM encoded")
}
certs, err := x509.ParseCertificates(block.Bytes)
if err != nil {
return false, fmt.Errorf("unable to parse certificate data: %v", err)
}
return time.Now().After(certs[0].NotAfter), nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/meoom/kubernetes.git
git@gitee.com:meoom/kubernetes.git
meoom
kubernetes
kubernetes
v1.10.0

搜索帮助

344bd9b3 5694891 D2dac590 5694891