K8s的所有操作基本都是通过调用kube-apiserver这个组件进行的,可以通过kubectl命令行工具或者编程API来,同时也REST API供外部系统远程访问。本文将介绍这几种方式来访问或操作K8S资源对象。

Kubectl命令行

kubectl作为客户端CLI工具,可以让用户通过命令行的方式对Kubernetes集群进行操作。

kubectl命令格式

kubectl命令格式为

kubectl [command] [TYPE] [NAME] [flags]
  • command子命令用于表示要对K8S集群中资源对象进行的操作,常见command命令有create、delete、describe、get、apply等;
  • TYPE表示command命令要操作的资源对象,如pod、service、job等,并且支持单复数与简写,如pod、pods与po等价,都可以用于表示pod对象,kubectl可以操作的所有K8S资源对象及其缩写如下

ef045eaf5c59bf0cdf9003ea829e5d59.png
  • NAME表示资源对象的名称。如果不指定名称,则系统将command操作施加在该TYPE的所有对象上,例如kubectl get pods将返回所有的Pod的信息;
  • flags:command命令的可选参数,例如使用“-f”指定yaml配置文件进行创建或删除操作。

一个kubectl命令可以同是最多个资源对象进行操作,多通过个TYPE和NAME的组合表示来表示多个对象,例如 * 获取多个同TYPE不同NAME的对象

kubectl get pods pod1 pod2
  • 获取多个不同TYPE的对象
kubectl get pod/pod1 rc/rc1
  • 同时应用多个yaml文件,操作资源对象
kubectl get pod -f pod1.yaml -f pod2.yaml
kubectl create -f pod1.yaml -f rc1.yaml -f service1.yaml

kubectl命令输出格式

kubectl 命令可以通过-o参数指定命令执行结果的输出的格式

kubectl [command] [TYPE] [NAME] -o=<output_format>

常见可选输出格式如下

  • -o=custom-columns=<spec> 根据自定义列名进行输出,以逗号分隔
  • -o=custom-colimns-file=<filename> 从文件中获取自定义列名进行输出
  • -o=json 以JSON格式显示结果
  • -o=jsonpath=<template> 输出jsonpath表达式定义的字段信息
  • -o=jsonpath-file=<filename> 输出jsonpath表达式定义的字段信息,来源于文件
  • -o=name 仅输出资源对象的名称
  • -o=wide 输出额外信息。对于Pod,将输出Pod所在的Node名
  • -o=yaml 以yaml格式显示结果

可以通过.metadata变量来引用默认输出结果的schema对象。

例如用自定义列名显示结果

kubectl get pod <pod-name> -o=custom-columns=NAME:.metadata.name,RSRC:.metadata.resourceVersion

另外可以通过--sort-by指定结果排序方式,如获取所有pod信息,并根据名称排序

kubectl get pods --sort-by=.metadata.name

常见操作

  • 根据配置文件创建资源:根据下列配置文件创建pod与service

[my-deployment.yaml]

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: web
  replicas: 2
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: web
        image: registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine
        ports:
        - containerPort: 8080

[service.yaml]

apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  ports:
  - port: 80 # 服务端口
    protocol: TCP
    targetPort: 8080 # 容器端口
  selector:
    app: web # 标签选择器,这里的app=web正是我们刚才建立app
kubectl create -f my-deployment.yaml -f my-service.yaml

创建<directory>目录下所有.yaml、.yml、.json文件的定义资源;

kubectl create -f <directory>
  • 查看资源对象:command子命令为get,如查看pod列表并展示额外信息
kubectl get Pods -o wide

查看service列表

kubectl get service
  • 描述资源对象:描述资源对象的command子命令describe,如查看节点信息
kubectl describe nodes <node-name>

或查看某个replicationcontrollers管理的所有pod信息

kubectl describe pods <rc-name>
  • 删除资源对象:command子命令是describe,如删除所有pod
kubectl delete pods --all

或如删除my-deployment.yaml文件定义的所有pod

kubectl delete -f my-deployment.yaml

或删除所有包含某个label的Pod:

kubectl delete pod -l name=<label-name>
  • 在容器中执行命令:command子命令为exec,命令的格式为
kubectl exec <pod-name> -c <container-name> <command to execuete>

如果省略container-name,则默认在该pod中的的第一个容器中执行命令。

例如登陆容器的终端

kubectl exec -ti <pod-name> -c <container-name> /bin/bash
  • 查看容器日志:command子命令为logs,命令格式
kubectl logs -f <pod-name> -c <container-name>

编程API使用

K8S提供了Java,Go与Python语言的编程API,本文以Java为例,其他语言的API使用方式可以参考官方文档。

引用依赖

<dependency>
     <groupId>io.kubernetes</groupId>
     <artifactId>client-java</artifactId>
     <version>7.0.0</version>
     <scope>compile</scope>
 </dependency>

安装配置文件与证书

为了保证整个k8s集群的安全性,k8s提供了多种认证方式来验证访问者身份的的合法性:比如客户端证书、静态token、静态密码文件、ServiceAccountTokens等。这里使用的时客户端证书认证即TLS双向认证。

从你的K8S安装目录下把这几个文件copy到你的项目目录下

4296e82cdcf6d6dc2d46cf5d5f22046c.png

然后打开config文件,重新配置本地的ca.crt(CA证书)、ca.key(TLS 证书)与client.crt(TLS Key)这三个文件的位置。也可以把这三个文件的内容进行Base64编码后copy到这个位置,并把这几个位置的key加上后缀-data,如certificate-authority-data,这样就不用维护这么多文件了。

cf50148b866c1a2d70727b05f3bfb644.png

然后既可以根据config文件的path去创建一个客户端对象了,示例如下。 当然,如果你的应用程序运行在K8S集群中,可以不指定配置文件,在客户端创建时会去获取当前集群的配置文件。

获取pod

通过config创建一个client对象,并置为默认ApiClient,然后创建一个CoreV1Api对象,就可以用它获取全部pod对象。

import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class TestClient {
    public static void main(String[] args) throws ApiException, IOException, ApiException {

        String kubeConfigPath = "/${your path}/config";
        //加载config,创建client
        ApiClient client = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();
        //设置默认client
        Configuration.setDefaultApiClient(client);
        //创建一个api
        CoreV1Api api = new CoreV1Api();
        //打印所有的pod
        V1PodList list = api.listPodForAllNamespaces(null,null,null,null,null,null,null,
        null,null);
        for (V1Pod item : list.getItems()) {
            System.out.println(item);
        }
    }
}

创建job

先根据docker镜像名称创建一个container对象,然后据此创建PodSpec对象(pod的配置),再创建V1JobSpec对象(job配置),再创建一个V1Job对象,最后用创建一个BatchV1Api对象来启动job。

import io.kubernetes.client.ApiException;
import io.kubernetes.client.apis.BatchV1Api;
import io.kubernetes.client.models.*;
import java.util.Collections;

public class TestJob {
    public static void main(String[] args) {
        V1Job v1Job = new V1Job();
        V1ObjectMeta v1ObjectMeta = new V1ObjectMeta();
        v1ObjectMeta.setNamespace("test_namespace");
        v1ObjectMeta.setName("test-job");
        v1Job.setMetadata(v1ObjectMeta);

        V1PodSpec podSpec = new V1PodSpec();
        V1Container container = new V1Container();
        container.setImage("your_image");
        podSpec.setContainers(Collections.singletonList(container));
        podSpec.restartPolicy("OnFailure");
        V1PodTemplateSpec podTemplateSpec = new V1PodTemplateSpec();
        podTemplateSpec.setSpec(podSpec);

        V1JobSpec v1JobSpec = new V1JobSpec();
        // 设置超时时间为两小时,超时后该job被置为Failed
        v1JobSpec.setActiveDeadlineSeconds(7200L);
        // 任务执行完( 无论Completeh还是Failed)100秒后,该job就会被删除
        v1JobSpec.setTtlSecondsAfterFinished(100);
        v1JobSpec.setTemplate(podTemplateSpec);
        // 启动失败最多重启3次,3次后就会被标记为Failed,该设置优先级低于setTtlSecondsAfterFinished
        v1JobSpec.backoffLimit(3);
        v1Job.setSpec(v1JobSpec);

        BatchV1Api batchV1Api = new BatchV1Api();
        try {
            batchV1Api.createNamespacedJob("test_namespace", v1Job, true, null, null);
        } catch (ApiException e) {
            e.printStackTrace();
        }
    }
}

REST API

通过REST API访问货操作K8S资源对象有两种方式,

使用 kubectl 代理

运行下面kubectl 命令, 将充当一个反向代理, 负责处理 apiserver 的定位和认证,用户可通过curl, wget, 或者浏览器在8081的端口访问 API。

kubectl proxy --port=8081 &

如通过下列请求来可以获取集群信息

 curl http://localhost:8081/api/

0329c4001132c410873fc6c88474f063.png

不使用 kubectl 代理

如果不使用kubectl代理则需要传递一个认证token给apiserver,例如通过下列命令一样可以获取集群信息。

APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d 't')
curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

REST API列表

/api
/api/v1
/apis
/apis/
/apis/admissionregistration.k8s.io
/apis/admissionregistration.k8s.io/v1beta1
/apis/apiextensions.k8s.io
/apis/apiextensions.k8s.io/v1beta1
/apis/apiregistration.k8s.io
/apis/apiregistration.k8s.io/v1
/apis/apiregistration.k8s.io/v1beta1
/apis/apps
/apis/apps/v1
/apis/apps/v1beta1
/apis/apps/v1beta2
/apis/authentication.k8s.io
/apis/authentication.k8s.io/v1
/apis/authentication.k8s.io/v1beta1
/apis/authorization.k8s.io
/apis/authorization.k8s.io/v1
/apis/authorization.k8s.io/v1beta1
/apis/autoscaling
/apis/autoscaling/v1
/apis/autoscaling/v2beta1
/apis/autoscaling/v2beta2
/apis/batch
/apis/batch/v1
/apis/batch/v1beta1
/apis/certificates.k8s.io
/apis/certificates.k8s.io/v1beta1
/apis/coordination.k8s.io
/apis/coordination.k8s.io/v1beta1
/apis/events.k8s.io
/apis/events.k8s.io/v1beta1
/apis/extensions
/apis/extensions/v1beta1
/apis/networking.k8s.io
/apis/networking.k8s.io/v1
/apis/policy
/apis/policy/v1beta1
/apis/rbac.authorization.k8s.io
/apis/rbac.authorization.k8s.io/v1
/apis/rbac.authorization.k8s.io/v1beta1
/apis/scheduling.k8s.io
/apis/scheduling.k8s.io/v1beta1
/apis/storage.k8s.io
/apis/storage.k8s.io/v1
/apis/storage.k8s.io/v1beta1
/healthz
/healthz/autoregister-completion
/healthz/etcd
/healthz/log
/healthz/ping
/healthz/poststarthook/apiservice-openapi-controller
/healthz/poststarthook/apiservice-registration-controller
/healthz/poststarthook/apiservice-status-available-controller
/healthz/poststarthook/bootstrap-controller
/healthz/poststarthook/ca-registration
/healthz/poststarthook/generic-apiserver-start-informers
/healthz/poststarthook/kube-apiserver-autoregistration
/healthz/poststarthook/rbac/bootstrap-roles
/healthz/poststarthook/scheduling/bootstrap-system-priority-classes
/healthz/poststarthook/start-apiextensions-controllers
/healthz/poststarthook/start-apiextensions-informers
/healthz/poststarthook/start-kube-aggregator-informers
/healthz/poststarthook/start-kube-apiserver-admission-initializer
/logs
/metrics
/openapi/v2
/swagger-2.0.0.json
/swagger-2.0.0.pb-v1
/swagger-2.0.0.pb-v1.gz
/swagger.json
/swaggerapi
/version

其中最常用的是/api/v1的API,具体如下

a436e756e16b0c21322553329cb03518.png

例如,通过如下请求可以获取default命名空间中所有的pod的信息

curl http://localhost:8081/api/v1/namespaces/default/pods

总结

本文介绍了三种K8S操作资源对象的方式,它们各有各的使用场景。kubectl命令行工具适合运维人员使用,编程API与REST API适合开发者使用,REST API也可以给远程用户使用。实际可以根据需要进行选择。

Logo

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

更多推荐