client-go代码在集群内部署使用
创建目录并初始化项目

#创建目录
mkdir client-go-examples
cd client-go-examples
#初始化项目
go mod init incluster
mkdir incluster
cd incluster
#创建文件
touch main.go

main.go内容

//client-go链接apiSeriver
//获取依赖
//go get k8s.io/client-go@v0.19.16
//go get k8s.io/apimachinery@v0.19.16
package main

import (
	"context"
	"log"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
)

func main() {
	//初始化config InClusterConfig函数取得认证所需的token和ca.crt文件
	config, err := rest.InClusterConfig()
	if err != nil {
		log.Fatal(err)
	}
	//通过client初始化clientset 通过clientset可以实现各种资源的CRUD操作
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatal(err)
	}

	for {
		//通过clientset来列出特定命名空间里的所有pod
		pods, err := clientset.CoreV1().Pods("default").List(context.TODO(), metav1.ListOptions{})
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("There are %d pods in the cluster\n", len(pods.Items))
		for i, pod := range pods.Items {
			log.Printf("%d -> %s/%s", i+1, pod.Namespace, pod.Name)
		}
		<-time.Tick(5 * time.Second)
	}
}

下载k8s对应版本的client-go依赖版本,本机安装的是19.16

#获取依赖
go get k8s.io/client-go@v0.19.16
go get k8s.io/apimachinery@v0.19.16
#更新依赖
go mod tidy

使用dockerfile生成镜像

#构建
go build -o app ./main.go
#dockerfile内容
FROM busybox
COPY ./app /app
ENTRYPOINT /app
#dockerfile生成镜像
docker build -t in-cluster:v1 .
#因为是集群环境 需要把镜像推送到本地私有仓库,一遍其他node节点获取镜像
docker tag in-cluster:v1 192.168.140.135:5000/in-cluster:v1
docker push 192.168.140.135:5000/in-cluster
#创建ClusterRoleBinding,为了能列出所有pod需要给default Service Account View权限--clusterrole=view  就是k8s里边已经存在的 叫做view 的 clusterrole资源把它绑定到default命名空间下的名为default的 serviceaccount
kubectl create clusterrolebinding default-view --clusterrole=view --serviceaccount=default:default
#启动pod测试
kubectl run -i in-cluster --image=192.168.140.135:5000/in-cluster:v1

集群外部署client-go
外部部署需要获取到kubeconfig来实现认证
认证所需crt文件存储在kubeconfig内
默认地址:/root/.kube/config
注意:只有master有此配置文件 在master会执行成功 要想在node执行 需要把/root/.kube/config 复制到node上 或者在程序里指定kubeconfig位置

#在上边的go项目中创建目录
mkdir outcluster
#创建文件
touch main.go

代码:

//client-go在k8s集群外部链接apiSeriver
//获取依赖
//go get k8s.io/client-go@v0.19.16
//go get k8s.io/apimachinery@v0.19.16
package main

import (
	"context"
	"log"
	"path/filepath"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
)

func main() {
	//获取kubeconfig路径
	homePath := homedir.HomeDir()
	if homePath == "" {
		log.Fatal("failed to get the home directory")
	}
	log.Printf("kubeconfig路径:%s", homePath)
	//拼接kubeconfig地址
	kubeconfig := filepath.Join(homePath, ".kube", "config")
	log.Printf("kubeconfig地址:%s", kubeconfig)
	//通过kubeconfig初始化config BuildConfigFromFlags函数两个参数 分别是masterUrl和kubeconfigPath 这里我们这给了第二个参数,因为kubeConfig中已经包含了API service的连接信息BuildConfigFromFlags会根据配置来初始化config对象
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
	if err != nil {
		log.Fatal(err)
	}

	//通过client初始化clientset 通过clientset可以实现各种资源的CRUD操作
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatal(err)
	}

	for {
		//通过clientset来列出特定命名空间里的所有pod
		pods, err := clientset.CoreV1().Pods("default").List(context.TODO(), metav1.ListOptions{})
		if err != nil {
			log.Fatal(err)
		}
		log.Printf("There are %d pods in the cluster\n", len(pods.Items))
		for i, pod := range pods.Items {
			log.Printf("%d -> %s/%s", i+1, pod.Namespace, pod.Name)
		}
		<-time.Tick(5 * time.Second)
	}
}

#编译
go build -o outCluster
#运行
./outCluster

client-go操作deployment
代码

//client-go在k8s集群外部链接apiSeriver  创建deployment
//获取依赖
//go get k8s.io/client-go@v0.19.16
//go get k8s.io/apimachinery@v0.19.16
package main

import (
	"context"
	"log"
	"path/filepath"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"

	appsv1 "k8s.io/api/apps/v1"
	corev1 "k8s.io/api/core/v1"
	v1 "k8s.io/client-go/kubernetes/typed/apps/v1"
	"k8s.io/client-go/util/retry"
)

func main() {
	//获取kubeconfig路径
	homePath := homedir.HomeDir()
	if homePath == "" {
		log.Fatal("failed to get the home directory")
	}

	log.Printf("kubeconfig路径:%s", homePath)
	//拼接kubeconfig地址
	kubeconfig := filepath.Join(homePath, ".kube", "config")
	log.Printf("kubeconfig地址:%s", kubeconfig)
	//通过kubeconfig初始化config BuildConfigFromFlags函数两个参数 分别是masterUrl和kubeconfigPath 这里我们这给了第二个参数,因为kubeConfig中已经包含了API service的连接信息BuildConfigFromFlags会根据配置来初始化config对象
	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
	if err != nil {
		log.Fatal(err)
	}

	//通过client初始化clientset 通过clientset可以实现各种资源的CRUD操作
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		log.Fatal(err)
	}
	//取得dbClient 这是个接口类型 可以对deployment进行crud操作
	dpClient := clientset.AppsV1().Deployments(corev1.NamespaceDefault)
	log.Printf("create Deployment")
	if err := createDeployment(dpClient); err != nil {
		log.Fatal(err)
	}

	<-time.Tick(1 * time.Minute)

	log.Println("update Deployment")
	if err := updateDeployment(dpClient); err != nil {
		log.Fatal(err)
	}

	<-time.Tick(1 * time.Minute)

	log.Println("delete Deployment")
	if err := deleteDeployment(dpClient); err != nil {
		log.Fatal(err)
	}

	<-time.Tick(1 * time.Minute)
	log.Println("end")
}

/**
创建deployment
*/
func createDeployment(dpClient v1.DeploymentInterface) error {
	replicas := int32(3)
	//deployment配置
	newDp := &appsv1.Deployment{
		ObjectMeta: metav1.ObjectMeta{
			Name: "nginx-deploy",
		},
		Spec: appsv1.DeploymentSpec{
			Replicas: &replicas,
			Selector: &metav1.LabelSelector{
				MatchLabels: map[string]string{
					"app": "nginx",
				},
			},
			Template: corev1.PodTemplateSpec{
				ObjectMeta: metav1.ObjectMeta{
					Labels: map[string]string{
						"app": "nginx",
					},
				},
				Spec: corev1.PodSpec{
					Containers: []corev1.Container{
						{
							Name:  "nginx",
							Image: "nginx:1.14",
							Ports: []corev1.ContainerPort{
								{
									Name:          "http",
									Protocol:      corev1.ProtocolTCP,
									ContainerPort: 80,
								},
							},
						},
					},
				},
			},
		},
	}
	//创建deployment
	_, err := dpClient.Create(context.TODO(), newDp, metav1.CreateOptions{})
	return err
}

/**
更新deployment
*/
func updateDeployment(dpClient v1.DeploymentInterface) error {
	//获取nginx-deploy对象
	dp, err := dpClient.Get(context.TODO(), "nginx-deploy", metav1.GetOptions{})
	if err != nil {
		return err
	}
	//修改镜像
	dp.Spec.Template.Spec.Containers[0].Image = "nginx:1.16"
	//RetryOnConflict函数 提供重试机制 更新失败 会重试
	return retry.RetryOnConflict(
		retry.DefaultRetry, func() error {
			//更新deployment
			_, err := dpClient.Update(context.TODO(), dp, metav1.UpdateOptions{})
			return err
		},
	)
}

/**
删除deployment
*/
func deleteDeployment(dpClient v1.DeploymentInterface) error {
	deletePolicy := metav1.DeletePropagationForeground
	return dpClient.Delete(
		context.TODO(), "nginx-deploy", metav1.DeleteOptions{
			PropagationPolicy: &deletePolicy,
		})
}

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐