Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Commit db0d731

Browse files
committed
checkpoint: make run func generic
1 parent cb22058 commit db0d731

File tree

1 file changed

+59
-46
lines changed

1 file changed

+59
-46
lines changed

cmd/checkpoint/main.go

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,15 @@ const (
2424
kubeletAPIPodsURL = "http://127.0.0.1:10255/pods"
2525
ignorePath = "/srv/kubernetes/manifests"
2626
activePath = "/etc/kubernetes/manifests"
27-
manifestFilename = "apiserver.json"
2827
kubeconfigPath = "/etc/kubernetes/kubeconfig"
2928
secretsPath = "/etc/kubernetes/checkpoint-secrets"
29+
30+
tempAPIServer = "temp-apiserver"
31+
kubeAPIServer = "kube-apiserver"
3032
)
3133

3234
var (
33-
tempAPIServer = []byte("temp-apiserver")
34-
kubeAPIServer = []byte("kube-apiserver")
35-
activeManifest = filepath.Join(activePath, manifestFilename)
36-
checkpointManifest = filepath.Join(ignorePath, manifestFilename)
37-
secureAPIAddr = fmt.Sprintf("https://%s:%s", os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT_HTTPS"))
35+
secureAPIAddr = fmt.Sprintf("https://%s:%s", os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT_HTTPS"))
3836
)
3937

4038
var tempAPIServerManifest = v1.Pod{
@@ -44,48 +42,56 @@ var tempAPIServerManifest = v1.Pod{
4442
},
4543
ObjectMeta: v1.ObjectMeta{
4644
Name: "temp-apiserver",
47-
Namespace: "kube-system",
45+
Namespace: api.NamespaceSystem,
4846
},
4947
}
5048

49+
var tempPodSpecMap = map[string]v1.Pod{
50+
tempAPIServer: tempAPIServerManifest,
51+
}
52+
5153
func main() {
52-
glog.Info("begin apiserver checkpointing...")
53-
run()
54+
glog.Info("begin pods checkpointing...")
55+
run(kubeAPIServer, tempAPIServer, api.NamespaceSystem)
5456
}
5557

56-
func run() {
58+
func run(actualPodName, tempPodName, namespace string) {
5759
client := newAPIClient()
5860
for {
5961
var podList v1.PodList
6062
if err := json.Unmarshal(getPodsFromKubeletAPI(), &podList); err != nil {
6163
glog.Fatal(err)
6264
}
6365
switch {
64-
case bothAPIServersRunning(podList):
65-
glog.Info("both temp and kube apiserver running, removing temp apiserver")
66-
// Both the self-hosted API Server and the temp API Server are running.
67-
// Remove the temp API Server manifest from the config dir so that the
66+
case bothRunning(podList, actualPodName, tempPodName, namespace):
67+
glog.Infof("both temp %v and actual %v pods running, removing temp pod", actualPodName, tempPodName)
68+
// Both the temp and actual pods are running.
69+
// Remove the temp manifest from the config dir so that the
6870
// kubelet will stop it.
69-
if err := os.Remove(activeManifest); err != nil {
71+
if err := os.Remove(activeManifest(tempPodName)); err != nil {
7072
glog.Error(err)
7173
}
72-
case kubeSystemAPIServerRunning(podList, client):
73-
glog.Info("kube-apiserver found, creating temp-apiserver manifest")
74-
// The self-hosted API Server is running. Let's snapshot the pod,
74+
case isPodRunning(podList, client, actualPodName, namespace):
75+
glog.Infof("actual pod %v found, creating temp pod manifest", actualPodName)
76+
// The actual is running. Let's snapshot the pod,
7577
// clean it up a bit, and then save it to the ignore path for
7678
// later use.
77-
tempAPIServerManifest.Spec = parseAPIPodSpec(podList)
78-
convertSecretsToVolumeMounts(client, &tempAPIServerManifest)
79-
writeManifest(tempAPIServerManifest)
80-
glog.Infof("finished creating temp-apiserver manifest at %s\n", checkpointManifest)
79+
tempSpec, ok := tempPodSpecMap[tempPodName]
80+
if !ok {
81+
glog.Fatalf("cannot find pod spec for %v", tempPodName)
82+
}
83+
tempSpec.Spec = parseAPIPodSpec(podList, actualPodName, namespace)
84+
convertSecretsToVolumeMounts(client, &tempSpec)
85+
writeManifest(tempSpec, tempPodName)
86+
glog.Infof("finished creating temp pod %v manifest at %s\n", tempPodName, checkpointManifest(tempPodName))
8187

8288
default:
83-
glog.Info("no apiserver running, installing temp apiserver static manifest")
84-
b, err := ioutil.ReadFile(checkpointManifest)
89+
glog.Info("no actual pod running, installing temp pod static manifest")
90+
b, err := ioutil.ReadFile(checkpointManifest(tempPodName))
8591
if err != nil {
8692
glog.Error(err)
8793
} else {
88-
if err := ioutil.WriteFile(activeManifest, b, 0644); err != nil {
94+
if err := ioutil.WriteFile(activeManifest(tempPodName), b, 0644); err != nil {
8995
glog.Error(err)
9096
}
9197
}
@@ -115,36 +121,35 @@ func getPodsFromKubeletAPI() []byte {
115121
return pods
116122
}
117123

118-
func bothAPIServersRunning(pods v1.PodList) bool {
119-
var kubeAPISeen, tempAPISeen bool
124+
func bothRunning(pods v1.PodList, an, tn, ns string) bool {
125+
var actualPodSeen, tempPodSeen bool
120126
for _, p := range pods.Items {
121-
kubeAPISeen = kubeAPISeen || isKubeAPI(p)
122-
tempAPISeen = tempAPISeen || isTempAPI(p)
123-
if kubeAPISeen && tempAPISeen {
127+
actualPodSeen = actualPodSeen || isPod(p, an, ns)
128+
tempPodSeen = tempPodSeen || isPod(p, tn, ns)
129+
if actualPodSeen && tempPodSeen {
124130
return true
125131
}
126132
}
127133
return false
128134
}
129135

130-
func kubeSystemAPIServerRunning(pods v1.PodList, client clientset.Interface) bool {
136+
func isPodRunning(pods v1.PodList, client clientset.Interface, n, ns string) bool {
131137
for _, p := range pods.Items {
132-
if isKubeAPI(p) {
133-
// Make sure it's actually running. Sometimes we get that
134-
// pod manifest back, but the server is not actually running.
135-
_, err := client.Discovery().ServerVersion()
136-
return err == nil
138+
if isPod(p, n, ns) {
139+
if n == kubeAPIServer {
140+
// Make sure it's actually running. Sometimes we get that
141+
// pod manifest back, but the server is not actually running.
142+
_, err := client.Discovery().ServerVersion()
143+
return err == nil
144+
}
145+
return true
137146
}
138147
}
139148
return false
140149
}
141150

142-
func isKubeAPI(pod v1.Pod) bool {
143-
return strings.Contains(pod.Name, "kube-apiserver") && pod.Namespace == api.NamespaceSystem
144-
}
145-
146-
func isTempAPI(pod v1.Pod) bool {
147-
return strings.Contains(pod.Name, "temp-apiserver") && pod.Namespace == api.NamespaceSystem
151+
func isPod(pod v1.Pod, n, ns string) bool {
152+
return strings.Contains(pod.Name, n) && pod.Namespace == ns
148153
}
149154

150155
// cleanVolumes will sanitize the list of volumes and volume mounts
@@ -172,18 +177,18 @@ func cleanVolumes(p *v1.Pod) {
172177
// writeManifest will write the manifest to the ignore path.
173178
// It first writes the file to a temp file, and then atomically moves it into
174179
// the actual ignore path and correct file name.
175-
func writeManifest(manifest v1.Pod) {
180+
func writeManifest(manifest v1.Pod, name string) {
176181
m, err := json.Marshal(manifest)
177182
if err != nil {
178183
glog.Fatal(err)
179184
}
180-
writeAndAtomicCopy(m, checkpointManifest)
185+
writeAndAtomicCopy(m, checkpointManifest(name))
181186
}
182187

183-
func parseAPIPodSpec(podList v1.PodList) v1.PodSpec {
188+
func parseAPIPodSpec(podList v1.PodList, n, ns string) v1.PodSpec {
184189
var apiPod v1.Pod
185190
for _, p := range podList.Items {
186-
if isKubeAPI(p) {
191+
if isPod(p, n, ns) {
187192
apiPod = p
188193
break
189194
}
@@ -247,3 +252,11 @@ func writeAndAtomicCopy(data []byte, path string) {
247252
glog.Fatal(err)
248253
}
249254
}
255+
256+
func activeManifest(name string) string {
257+
return filepath.Join(activePath, name+".json")
258+
}
259+
260+
func checkpointManifest(name string) string {
261+
return filepath.Join(ignorePath, name+".json")
262+
}

0 commit comments

Comments
 (0)