是否有关于在 go-client 某处构建k8s 作业的文档?特别是我正在尝试将工作 yaml 转换为代码,并且在我的一生中找不到说明字段如何转换的参考文档
问问题
949 次
2 回答
1
k8s.io/api
是 Kubernetes 的一个包,它kubectl
和其他组件使用它来实现 Kubernetes API
。在这个包中,有一个实现Job
API 的结构体,您可以使用它来将 Job 清单转换为 Go 结构体。
我认为这段代码可以提供帮助:
package main
import (
"fmt"
"io/ioutil"
"os"
"gopkg.in/yaml.v2"
v1 "k8s.io/api/batch/v1"
)
func main() {
file, err := os.Open("/path/to/job.yaml")
if err != nil {
panic(err)
}
b, err := ioutil.ReadAll(file)
if err != nil {
panic(err)
}
job := &v1.Job{}
err = yaml.Unmarshal(b, job)
if err != nil {
panic(err)
}
fmt.Println(job)
}
于 2020-06-11T05:23:37.387 回答
0
将 YAML 转换为 Golang 可能很困难,并且经常缺少带有示例的文档。
我编写了一个名为naml的工具,它能够将任何 Kubernetes YAML 转换为原始 Go。它很方便,因为它使用您运行它的 Kubernetes 版本,并且使用最新版本的 Kubernetes 代码库编译。
如果您想创建一个 Job,并查看该 Job 的有效 Go,它看起来像这样。beeps
使用容器映像创建作业boops
[nova@emma ~]$ kubectl create job beeps --image boops
job.batch/beeps created
[nova@emma ~]$
Naml 将通过设计输出一个工作程序,但您也将获得您正在寻找的输出。
[nova@emma naml]$ kubectl get job beeps -o yaml | naml codify
// Copyright © 2021 Kris Nóva <kris@nivenly.com>
//
// 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 main
import (
"context"
"fmt"
"os"
"github.com/hexops/valast"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"github.com/kris-nova/naml"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
)
// Version is the current release of your application.
var Version string = "0.0.1"
func main() {
// Load the application into the NAML registery
// Note: naml.Register() can be used multiple times.
naml.Register(NewApp("App", "Application autogenerated from NAML v0.3.1"))
// Run the generic naml command line program with
// the application loaded.
err := naml.RunCommandLine()
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
}
// App is a very important grown up business application.
type App struct {
metav1.ObjectMeta
description string
objects []runtime.Object
// ----------------------------------
// Add your configuration fields here
// ----------------------------------
}
// NewApp will create a new instance of App.
//
// See https://github.com/naml-examples for more examples.
//
// This is where you pass in fields to your application (similar to Values.yaml)
// Example: func NewApp(name string, example string, something int) *App
func NewApp(name, description string) *App {
return &App{
description: description,
ObjectMeta: metav1.ObjectMeta{
Name: name,
ResourceVersion: Version,
},
// ----------------------------------
// Add your configuration fields here
// ----------------------------------
}
}
func (a *App) Install(client *kubernetes.Clientset) error {
var err error
beepsJob := &batchv1.Job{
TypeMeta: metav1.TypeMeta{
Kind: "Job",
APIVersion: "batch/batchv1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "beeps",
Namespace: "default",
UID: types.UID("650e4f36-3316-4506-bbe0-1e34c13742cf"),
ResourceVersion: "3231200",
Generation: 1,
Labels: map[string]string{
"controller-uid": "650e4f36-3316-4506-bbe0-1e34c13742cf",
"job-name": "beeps",
},
},
Spec: batchv1.JobSpec{
Parallelism: valast.Addr(int32(1)).(*int32),
Completions: valast.Addr(int32(1)).(*int32),
BackoffLimit: valast.Addr(int32(6)).(*int32),
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{
"controller-uid": "650e4f36-3316-4506-bbe0-1e34c13742cf",
}},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{
"controller-uid": "650e4f36-3316-4506-bbe0-1e34c13742cf",
"job-name": "beeps",
}},
Spec: corev1.PodSpec{
Containers: []corev1.Container{corev1.Container{
Name: "beeps",
Image: "boops",
TerminationMessagePath: "/dev/termination-log",
TerminationMessagePolicy: corev1.TerminationMessagePolicy("File"),
ImagePullPolicy: corev1.PullPolicy("Always"),
}},
RestartPolicy: corev1.RestartPolicy("Never"),
TerminationGracePeriodSeconds: valast.Addr(int64(30)).(*int64),
DNSPolicy: corev1.DNSPolicy("ClusterFirst"),
SecurityContext: &corev1.PodSecurityContext{},
SchedulerName: "default-scheduler",
},
},
CompletionMode: valast.Addr(batchv1.CompletionMode("NonIndexed")).(*batchv1.CompletionMode),
Suspend: valast.Addr(false).(*bool),
},
}
a.objects = append(a.objects, beepsJob)
if client != nil {
_, err = client.BatchV1().Jobs("default").Create(context.TODO(), beepsJob, metav1.CreateOptions{})
if err != nil {
return err
}
}
return err
}
func (a *App) Uninstall(client *kubernetes.Clientset) error {
var err error
if client != nil {
err = client.BatchV1().Jobs("default").Delete(context.TODO(), "beeps", metav1.DeleteOptions{})
if err != nil {
return err
}
}
return err
}
func (a *App) Description() string {
return a.description
}
func (a *App) Meta() *metav1.ObjectMeta {
return &a.ObjectMeta
}
func (a *App) Objects() []runtime.Object {
return a.objects
}
于 2021-10-22T01:08:35.320 回答