在集群中的特定容器上执行命令。从另一个容器

时间:2017-11-30 12:24:13

标签: api curl cron kubernetes

在kubernetes中我有一个容器X.我想运行一个cronjob,它在容器X中执行一个命令。

我有以下想法:

  1. 使用busybox容器运行cronjob,
  2. 从busybox容器中
  3. 执行一个脚本:

    1. 确定必须执行的pod名称,
    2. 运行curl,类似

       curl https://35.187.120.184/api/v1/namespaces/my_namespace/pods/my_pod_name/exec?command=my_sh_command&container=my_container_name&stdin=true&stdout=true&tty=true
      

      此处的动态值为:

      • my_namespace
      • my_pod_name
      • my_sh_command
      • my_container_name
  4. 我知道我应该使用令牌来访问kubernetes API,但我无法弄清楚如何在curl中获取/使用该令牌。

    是否可以使用curl和kubernetes API执行此操作?如果是,怎么样?

    我想做这个奇怪的事情是有原因的。我有一个编译的应用程序,它可识别CLI命令。我想运行一个特定的CLI命令,而不必通过Web服务器路由暴露CLI,随后可以通过k8s服务访问。

2 个答案:

答案 0 :(得分:1)

您的一般方法(在容器内调用Kubernetes API上的{pod}/exec端点)对我来说似乎完全有效。一般来说,我认为需要考虑两个方面:1)如何使用curl与Kubernetes API进行通信,以及2)如何从Pod中对API进行身份验证。

使用curl进行Kubernetes API访问

通常,Kubernetes API可以通过curl轻松调用。但是,exec端点是该规则的一个例外,因为API服务器将该端点上的连接升级为SPDY连接,curl不支持该连接(甚至还有discussion in the Kubernetes issue tracker关于那个话题)。出于这个原因,我建议使用kubectl(已经由@sfgroups建议)或使用其中一个客户端SDK(例如,GoPython)。

在Pod

中验证exec次来电

如果您正在使用Pod(或任何客户端SDK,甚至卷曲)中的kubectl,则需要对API服务器进行身份验证。为此,您的Pod需要与服务帐户相关联,并且需要授权该服务帐户调用/pods/{pod}/exec端点。这是如何工作的,在很大程度上取决于您的群集配置:

  1. 在许多群集配置中,默认情况下,您的Pod可能已与服务帐户关联(具有足够的授权)。在Pod中,您将在/var/run/secrets/kubernetes.io/serviceaccount目录中找到凭据。 kubectl和公共客户端SDK都会自动找到此目录,允许它们“正常工作”而无需任何其他配置。使用curl,您需要从该目录中的token文件中提取身份验证令牌,并在Authorization: Bearer <token>标头中使用它。

    如果您的Pod使用automountServiceAccountToken: false属性创建,则可能没有收到服务帐户令牌。

  2. 如果您的群集已配置为to use RBAC,则您的Pod可能仍与服务帐户相关联,但该帐户可能无权在其他Pod中执行命令。要授予访问权限,您可以创建自己的角色以授予所需权限,然后创建服务帐户和RoleBinding:

    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      namespace: default
      name: pod-exec
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    - apiGroups: [""]
      resources: ["pods/exec]
      verbs: ["create"]
    ---
    kind: ServiceAccount
    apiVersion: v1
    metadata:
      name: cron
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: cron   
    subjects:
    - kind: ServiceAccount
      name: cron
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: pod-exec
      apiGroup: rbac.authorization.k8s.io
    

    然后,使用PodSpec中的serviceAccountName: cron属性将您的cron runner pod与新创建的服务帐户相关联。

答案 1 :(得分:0)

我认为我们不能使用curl命令触发。另一个选择是在pod上安装kubectl并使用kubectl exec命令来运行脚本。

./kubectl exec <POD> -- <script>