Makefile运行导出环境时出现问题

时间:2020-05-04 10:36:18

标签: linux shell kubernetes makefile gnu-make

我创建了一个Makefile,用于从固定路径中导出kubeconfig,例如:

myproj
 - .kube     //folder
     config    //file which contain the config
 - Makefile.  //same level as .kube folder

现在,当我从终端运行 时,它可以正常工作,这意味着如果我运行kubectl get ns,我将获得结果,这意味着它成功配置了

export KUBECONFIG=/Users/i33333/projects/app-test/v-app/.kube/config

我已经创建了如下的makefile目标

kube-cfg:
    export KUBECONFIG=$(PWD)/.kube/config

执行目标时,我会在终端中看到

export KUBECONFIG=/Users/i33333/projects/app-test/v-app/.kube/config

与手动操作完全相同,但是当我运行kubectl get ns

我遇到了错误:

error: no configuration has been provided, try setting KUBERNETES_MASTER environment variable

我不明白为什么它从生成文件运行时不能正常运行,而从终端手动运行时却可以正常运行?任何想法 我尝试更改并使用没有帮助的$(CURRDIR)

更新

我已经尝试过像建议的那样不起作用

KUBECONFIG=$(PWD)/.kube/config


kube-cfg:
    export $(KUBECONFIG)

更新2

如果我这样做

KUBECONFIG := $(PWD)/kube/config.yaml
tgt1:
    @export KUBECONFIG=$(KUBECONFIG) && kubectl get ns

运行生成文件tgt1:时我可以看到ns ,但是 如果现在我想从终端kubectl get ns运行它,我会收到相同的错误`错误:未提供配置,请尝试设置KUBERNETES_MASTER环境变量,我想从makefile配置它

2 个答案:

答案 0 :(得分:1)

问题在于makefile配方创建了新环境,该环境在完成配方后会被破坏。

如果要在调用make之后使用kubernetes工具,则在您的方案中更合适的工具是使用source命令。它适用于您当前的环境,该脚本在脚本中进行的所有更改均作为参数传递:

$ source setupenv.sh
$ kubectl get ns # should be no problem
$ make someting # even using kubectl inside make shouldn't be a problem

但是,如果要在make脚本中使用kubectl,请创建类似以下内容的

recipe :
      source setupenv.sh && kubectl get ns
# or 
recipe2 :
      export KUBECONFIG=$(PWD)/.kube/config && kubectl get ns

更新

我认为配置文件是一个脚本。因此,您应该准备shell脚本设置环境,例如setupenv.sh

#!/bin/bash
export KUBECONFIG=$(PWD)/.kube/config

答案 1 :(得分:1)

运行make时,配方将在make进程派生的shell中执行。同样,跨越多条代码的食谱,每行(除非通过换行符进行链接)也将获得自己的shell子进程。这实际上意味着,无论在这些shell中发生任何事情(shell变量赋值或导出),都不会影响make本身或其他配方行。

例如,您可以定义一个make变量(如在更新中所做的那样),然后可以在环境中为您要运行的任何命令(somecmd)设置该变量,例如:

some_target:
    export KUBECONFIG=$(KUBECONFIG); somecmd

或:

some_target:
    KUBECONFIG=$(KUBECONFIG) somecmd

在这种情况下,KUBECONFIG指的是一个make变量,就像上面定义的那样:

KUBECONFIG := $(PWD)/.kube/config

即像这样:

KUBECONFIG := $(PWD)/.kube/config

all: tgt1 tgt2

tgt1:
        @export KUBECONFIG=$(KUBECONFIG); echo "KUBECONFIG is $${KUBECONFIG}"

tgt2:
        @KUBECONFIG=$(KUBECONFIG) sh -c 'echo KUBECONFIG is $${KUBECONFIG}'

屈服:

$ make
KUBECONFIG is /tmp/.kube/config
KUBECONFIG is /tmp/.kube/config

因此,如果您在make完成之后仍在执行某些仍会持续的操作,则需要将其写出。例如。包装器,例如:

KUBECONFIG := $(PWD)/kube/config.yaml

.PHONY: call

# run callme.sh being the first prerequisite.
call: callme.sh
    ./$<

# creates and sets exec bit on rule target here being callme.sh
callme.sh:
    @echo -e '#!/bin/bash\nKUBECONFIG=$(KUBECONFIG) kubectl get ns' > $@
    chmod +x $@

这使您可以运行make并且目标call调用包装器……您还剩下一个包装器callme.sh,可以在make之后完成。