1. 采集并删除pvc
go.mod
module cronserver
go 1.13
require (
/imdario/mergo v0.3.8 // indirect
/spf13/pflag v1.0.5
/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
k8s.io/api v0.0.0-20200214081623-ecbd4af0fc33
k8s.io/apimachinery v0.17.3
k8s.io/client-go v11.0.0+incompatible
k8s.io/klog v1.0.0
k8s.io/utils v0.0.0-20200229041039-0a110f9eb7ab // indirect
)
replace k8s.io/client-go => k8s.io/client-go v0.0.0-20200214082307-e38a84523341
client.go
package main
import (
"context"
"time"
"fmt"
"/spf13/pflag"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog"
clientset "k8s.io/client-go/kubernetes"
)
// GetPersistentVolumeClaims 方法将会从 Kuberenetes 自动获取到 PersistentVolumeClaims 服务对象
func GetPersistentVolumeClaims(name string) *v1.PersistentVolumeClaim {
_, kubeClient := loadKubernetesClientsForDelPersistentVolumeClaims()
PersistentVolumeClaims, err := kubeClient.CoreV1().PersistentVolumeClaims("").Get(context.TODO(),name,metav1.GetOptions{})
if err != nil {
klog.Errorf("Error getting PersistentVolumeClaims %v", err)
}
return PersistentVolumeClaims
}
// ListersistentVolumeClaims 方法将会从Kuberenetes自动获取到 PersistentVolumeClaims 服务对象
func ListPersistentVolumeClaims() *v1.PersistentVolumeClaimList {
_, kubeClient := loadKubernetesClientsForDelPersistentVolumeClaims()
PersistentVolumeClaims, err := kubeClient.CoreV1().PersistentVolumeClaims("").List(context.TODO(),metav1.ListOptions{})
if err != nil {
klog.Errorf("Error getting PersistentVolumeClaims %v", err)
}
return PersistentVolumeClaims
}
// DelPersistentVolumeClaims 方法将会从Kuberenetes自动删除 PersistentVolumeClaims 服务对象
func DelPersistentVolumeClaims(pvc v1.PersistentVolumeClaim) {
_, kubeClient := loadKubernetesClientsForDelPersistentVolumeClaims()
pvcname := pvc.GetName()
namespace := pvc.GetNamespace()
pvcstatusPhase := string(pvc.Status.Phase)
pvcCreationTime := pvc.GetCreationTimestamp()
age := int(time.Since(pvcCreationTime.Time).Seconds())
//pvc.Labels[PVC_WAIT_KEY] = PVC_WAIT_GC_VALUE
//pvc.Labels[PVC_DELETE_TIME] = time.Now().In(unitv1alpha1.GetCstZone()).Format(layout: "2006-01-02 15:04:05.999999999")
//fmt.Println(pvc.Labels)
// 删除条件pvc STATUS is "Released" and age 大于72小时
if pvcstatusPhase == "Pending" {
if age > 20 {
err := kubeClient.CoreV1().PersistentVolumeClaims(namespace).Delete(context.TODO(),pvcname,&metav1.DeleteOptions{})
if err != nil {
klog.Errorf("Delete pvc error: %v", err)
}
}
}
}
func loadKubernetesClientsForDelPersistentVolumeClaims() (*restclient.Config, *clientset.Clientset) {
klog.Infof("starting getting PersistentVolumeClaims")
kubeconfig := pflag.Lookup("kubefile").Value.String()
// uses the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(err.Error())
}
kubeClient, errClient := clientset.NewForConfig(config)
if errClient != nil {
klog.Errorf("Error received creating client %v", errClient)
}
return config, kubeClient
}
func main() {
pflag.String("kubefile", "/Users/jamesjiang/.kube/config", "Kube file to load")
pflag.String("timetoexec", "800", "Seconds to execute in a single period")
pflag.String("option", "backupBinaryLog", "Function options")
pflag.Parse()
option := pflag.Lookup("option").Value.String()
if option == "DelPersistentVolumeClaims" {
fmt.Println("【DelpersistentVolumeClaims】")
PersistentVolumeClaims := ListPersistentVolumeClaims()
for _, pvc := range PersistentVolumeClaims.Items {
DelPersistentVolumeClaims(pvc)
}
}
}
测试
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
cron-pv-claim Pending manual 6m30s
pvc Bound pv 512M RWX shared 62d
task-pv-claim Bound task-pv-volume 10Gi RWO manual 40h
$ go build .
$ ./cronserver --kubefile /root/.kube/config --option DelPersistentVolumeClaims
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc Bound pv 512M RWX shared 62d
task-pv-claim Bound task-pv-volume 10Gi RWO manual 40h
2. 通过label标签筛选删除pvc
(pod、pv也通用)
go.mode
module hello
go 1.13
require (
/imdario/mergo v0.3.8 // indirect
/spf13/pflag v1.0.5
/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect
/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
k8s.io/api v0.0.0-20200214081623-ecbd4af0fc33
k8s.io/apimachinery v0.17.3
k8s.io/client-go v11.0.0+incompatible
k8s.io/klog v1.0.0
k8s.io/utils v0.0.0-20200229041039-0a110f9eb7ab // indirect
)
replace k8s.io/client-go => k8s.io/client-go v0.0.0-20200214082307-e38a84523341
client.go
package main
import (
"context"
// "time"
"fmt"
"/spf13/pflag"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
restclient "k8s.io/client-go/rest"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/klog"
clientset "k8s.io/client-go/kubernetes"
)
// GetPersistentVolumeClaims 方法将会从 Kuberenetes 自动获取到 PersistentVolumeClaims 服务对象
func GetPersistentVolumeClaims(name string) *v1.PersistentVolumeClaim {
_, kubeClient := loadKubernetesClientsForDelPersistentVolumeClaims()
PersistentVolumeClaims, err := kubeClient.CoreV1().PersistentVolumeClaims("").Get(context.TODO(),name,metav1.GetOptions{})
if err != nil {
klog.Errorf("Error getting PersistentVolumeClaims %v", err)
}
return PersistentVolumeClaims
}
// ListersistentVolumeClaims 方法将会从Kuberenetes自动获取到 PersistentVolumeClaims 服务对象
func ListPersistentVolumeClaims() *v1.PersistentVolumeClaimList {
_, kubeClient := loadKubernetesClientsForDelPersistentVolumeClaims()
PersistentVolumeClaims, err := kubeClient.CoreV1().PersistentVolumeClaims("").List(context.TODO(),metav1.ListOptions{})
if err != nil {
klog.Errorf("Error getting PersistentVolumeClaims %v", err)
}
return PersistentVolumeClaims
}
// ListNamespace 方法将会从Kuberenetes自动获取到 Namespace 服务对象
func ListNamespaces() *v1.NamespaceList {
_, kubeClient := loadKubernetesClientsForDelPersistentVolumeClaims()
Namespaces, err := kubeClient.CoreV1().Namespaces().List(context.TODO(),metav1.ListOptions{})
if err != nil {
klog.Errorf("Error getting Namespaces %v", err)
}
return Namespaces
}
// DelPersistentVolumeClaims 方法将会从Kuberenetes自动删除 PersistentVolumeClaims 服务对象
func DelLabelPersistentVolumeClaims(namespace string) {
var (
PVC_WAIT_GC_VALUE = "PVC_WAIT_GC_VALUE"
PVC_DELETE_TIME = "295200s"
)
_, kubeClient := loadKubernetesClientsForDelPersistentVolumeClaims()
labelPvc := labels.SelectorFromSet(labels.Set(map[string]string{"PVC_WAIT_KEY": PVC_WAIT_GC_VALUE, "PVC_DELETE_TIME": PVC_DELETE_TIME}))
listPvcOptions := metav1.ListOptions{
LabelSelector: labelPvc.String(),
}
PersistentVolumeClaims, err := kubeClient.CoreV1().PersistentVolumeClaims(namespace).List(context.TODO(), listPvcOptions)
for _, PersistentVolumeClaim := range PersistentVolumeClaims.Items {
fmt.Printf("Start to delete pvc %s in %s namespace! \n", PersistentVolumeClaim.ObjectMeta.Name, namespace)
}
err = kubeClient.CoreV1().PersistentVolumeClaims(namespace).DeleteCollection(context.TODO(), &metav1.DeleteOptions{}, listPvcOptions)
if err != nil {
klog.Errorf("Drop pvc labels err %v",err)
}
}
func loadKubernetesClientsForDelPersistentVolumeClaims() (*restclient.Config, *clientset.Clientset) {
klog.Infof("starting getting PersistentVolumeClaims")
kubeconfig := pflag.Lookup("kubefile").Value.String()
// uses the current context in kubeconfig
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(err.Error())
}
kubeClient, errClient := clientset.NewForConfig(config)
if errClient != nil {
klog.Errorf("Error received creating client %v", errClient)
}
return config, kubeClient
}
func main() {
pflag.String("kubefile", "/Users/jamesjiang/.kube/config", "Kube file to load")
pflag.String("timetoexec", "800", "Seconds to execute in a single period")
pflag.String("option", "backupBinaryLog", "Function options")
pflag.Parse()
option := pflag.Lookup("option").Value.String()
if option == "DelLabelPersistentVolumeClaims" {
fmt.Println("【DelpersistentVolumeClaims】")
Namespaces := ListNamespaces()
for _, namespace := range Namespaces.Items {
namespace := namespace.ObjectMeta.Name
DelLabelPersistentVolumeClaims(namespace)
}
}
}
go build .
测试
创建一个pvc,labels分别为PVC_WAIT_KEY: PVC_WAIT_GC_VALUE
和PVC_DELETE_TIME: 295200s
pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: backup-pv-claim
labels:
PVC_WAIT_KEY: PVC_WAIT_GC_VALUE
PVC_DELETE_TIME: 295200s
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
$ kubectl apply -f pvc.yaml
persistentvolumeclaim/backup-pv-claim created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
backup-pv-claim Pending manual 4s
$ ./cronserver --option DelLabelPersistentVolumeClaims --kubefile /root/.kube/config
【DelpersistentVolumeClaims】
I1130 22:59:55.328428 60651 client.go:76] starting getting PersistentVolumeClaims
I1130 22:59:55.403363 60651 client.go:76] starting getting PersistentVolumeClaims
Start to delete pvc backup-pv-claim in default namespace! //删除pvc日志
I1130 22:59:55.512610 60651 client.go:76] starting getting PersistentVolumeClaims