简介
如果想要实现更加自动化智能化的 操作,,或者需要自已写一套k8s管理平台,,那么就需要二次开发了,k8s官方支持多语言的lib,如下图
在日常运维中用到的kubectl 其实也是调的api运行的
官网还提供了api文档面,给供查询,因为涉及到的api实在太多了,全部记住是不太实现的,有个文档就便于辅助了
文档页地址: kubernetes.io/docs/refere…
使用
因为博主平时使用golang写工具比较多一点,这里以golang为例
官方也给提供了一个例子 地址: github.com/kubernetes/…
客户端集成
在使用go api时有两个认证方式,一种是集群里认证,一种是集群外认证,这里以集群外证书方式进行认证
如果不改变以下代码,,需要将认证文件config 放到 用户目录的.kube下,,就是集群初始化生成的文件
var kubeconfig *string
if home := homedir.HomeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else {
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
}
flag.Parse()
如果想将config放到 指定路径,,则需要在第5行 "" 写入绝对路径
生成客户端配置
接下来使用kubenetes 创建clientset对象
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
panic(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
clientset对象包含了所有资源,也是所有资源的入口
构建deployment资源对象
拿到一个默认命名空间的 deployment对象
deploymentsClient := clientset.AppsV1().Deployments(apiv1.NamespaceDefault)
使用此对象可以进行 deployment控制器的增删改查
创建
根据deployment资源类型,定义基中meta数据以及spec内容
此例部署一个nginx
deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "demo-deployment",
},
Spec: appsv1.DeploymentSpec{
Replicas: int32Ptr(2),
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"app": "demo",
},
},
Template: apiv1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app": "demo",
},
},
Spec: apiv1.PodSpec{
Containers: []apiv1.Container{
{
Name: "web",
Image: "nginx:1.12",
Ports: []apiv1.ContainerPort{
{
Name: "http",
Protocol: apiv1.ProtocolTCP,
ContainerPort: 80,
},
},
},
},
},
},
},
}
// Create Deployment
fmt.Println("Creating deployment...")
result, err := deploymentsClient.Create(context.TODO(), deployment, metav1.CreateOptions{})
if err != nil {
panic(err)
}
fmt.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName())
更新
这里更新了nginx 的镜像为nginx:1.13
这里可以看到一个prompt()的函数,主要是为了将每个动作作分隔,,有这个函数,每执行 更新,查看,删除都需要 手动敲一下 键盘
// Update Deployment
prompt()
fmt.Println("Updating deployment...")
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
result, getErr := deploymentsClient.Get(context.TODO(), "demo-deployment", metav1.GetOptions{})
if getErr != nil {
panic(fmt.Errorf("Failed to get latest version of Deployment: %v", getErr))
}
result.Spec.Replicas = int32Ptr(1) // reduce replica count
result.Spec.Template.Spec.Containers[0].Image = "nginx:1.13" // change nginx version
_, updateErr := deploymentsClient.Update(context.TODO(), result, metav1.UpdateOptions{})
return updateErr
})
if retryErr != nil {
panic(fmt.Errorf("Update failed: %v", retryErr))
}
fmt.Println("Updated deployment...")
查看
从切片中将资源遍历到d身上,然后打印pod名称,和复本个数
// List Deployments
prompt()
fmt.Printf("Listing deployments in namespace %q:\n", apiv1.NamespaceDefault)
list, err := deploymentsClient.List(context.TODO(), metav1.ListOptions{})
if err != nil {
panic(err)
}
for _, d := range list.Items {
fmt.Printf(" * %s (%d replicas)\n", d.Name, *d.Spec.Replicas)
}
删除
指定deployment名称(demo-deployment) 删除
prompt()
fmt.Println("Deleting deployment...")
deletePolicy := metav1.DeletePropagationForeground
if err := deploymentsClient.Delete(context.TODO(), "demo-deployment", metav1.DeleteOptions{
PropagationPolicy: &deletePolicy,
}); err != nil {
panic(err)
}
fmt.Println("Deleted deployment.")
全部运行之后截图如下:
list资源例子
node
查看node列表
nodes,_ := clientset.CoreV1().Nodes().List(context.TODO(),metav1.ListOptions{})
for i, node := range nodes.Items {
fmt.Printf("[%d] %s\n", i, node.GetName())
}
services
查看service列表
services,_ := clientset.CoreV1().Services("").List(context.TODO(),metav1.ListOptions{})
for i, svc := range services.Items {
fmt.Printf("[%d] %s\n", i, svc.GetName())
}
大部分资源在CoreV1下,还有一些在ExtensionsV1beta1下,还有AppsV1下,使用clientset. 提示相关
上面查看的都是默认namespace的列表,想要查看有namespace下的 资源列表,在前面加个遍历既可
namespace
查看namespace列表
namespaces,_ := clientset.CoreV1().Namespaces().List(context.TODO(),metav1.ListOptions{})
for i,namespace := range namespaces.Items {
fmt.Printf("[%d] %s\n", i, namespace.GetName())
}
总结
官方出来的sdk用起来还是蛮顺的,如果只是实现一些查看或者删除功能,会比较简单,但是如果要更新或者创建,便会涉及很多的知识点,这其中包括要对 相应控制器的了解
在每一次动作中都有context.TODO() 这样一个参数,,这是用于控制该线程的(超时控制),,如果是TODO那就什么也不干,就是不干涉,以服务提供者为准