全部課程
發(fā)布時(shí)間: 2021-11-09 16:50:11
環(huán)境變量 env,相信每個(gè)運(yùn)維工程師都耳熟能詳并能在 linux 環(huán)境下嫻熟應(yīng)用,但在 k8s集群環(huán)境中,靈活應(yīng)用環(huán)境變量并不是一件很容易的事情,需要考慮的東西遠(yuǎn)比 linux 環(huán)境下多。
用得好,可以維持發(fā)布、監(jiān)控和日志中心等運(yùn)維平臺(tái)的統(tǒng)一規(guī)范與邏輯,降低k8s 集群管理成本,否則將增加運(yùn)維難度,同時(shí)給故障診斷帶來(lái)不必要的干擾。
一、靜態(tài)環(huán)境變量
1、顯式定義
可以直接在 Dockerfile 中定義環(huán)境變量,語(yǔ)法為 ENV,比如我們?yōu)榱嗽O(shè)定容器時(shí)區(qū),往往會(huì)在鏡像 Dockerfile 里面設(shè)定“ENV TZ=Asia/Shanghai”,或者預(yù)先指定一個(gè)環(huán)境變量用于后續(xù)處理,比如在鏡像里指定一個(gè)JVM 的預(yù)置運(yùn)行參數(shù):
ENV JVM_OPTS="-Xms1024m -Xmx1024m -Xmn386m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -Xss256k"
2、隱式包含
除了顯式定義環(huán)境變量,也可以在鏡像里從其它文件引入。比如 tomcat 的官方鏡像,tomcat 的啟動(dòng)腳本為 catalina.sh,catalina.sh 里面會(huì)去調(diào)用 setenv.sh,這個(gè)里面可以定義環(huán)境變量。
二、動(dòng)態(tài)環(huán)境變量
靜態(tài)環(huán)境變量由于缺乏靈活性,往往不能滿(mǎn)足實(shí)際工作中的運(yùn)維需求,應(yīng)用較多的是動(dòng)態(tài)環(huán)境變量。需要注意的是:動(dòng)態(tài)環(huán)境變量的語(yǔ)義不能與靜態(tài)的發(fā)生沖突,比如我們?cè)? Dockerfile 中定義一個(gè)環(huán)境變量 APP_NAME,它的意思是微服務(wù)名稱(chēng),后面可以覆蓋其內(nèi)容,但不能改變它的含義。下面基于運(yùn)維場(chǎng)景,列舉兩種對(duì)于 k8s 動(dòng)態(tài)環(huán)境變量的典型應(yīng)用:
1、在微服務(wù)部署中的應(yīng)用
通過(guò)發(fā)布平臺(tái)結(jié)合helm等工具注入環(huán)境變量,前面提到的環(huán)境變量JVM_OPTS,針對(duì)同一個(gè)微服務(wù),不同環(huán)境往往需要配置不同的內(nèi)存容量,比如測(cè)試環(huán)境配置為512M,生產(chǎn)為2G。如何利用環(huán)境變量來(lái)統(tǒng)一配置邏輯呢?處理過(guò)程如下:
以 Jenkins pipeline 為例,其定義是一種 groove 腳本語(yǔ)言,可以直接在里面用 def 語(yǔ)法定義變量(或者基于用戶(hù)下拉框選項(xiàng)等),然后用 helm set 的方式注入到 k8s deployment,實(shí)現(xiàn)多環(huán)境配置邏輯統(tǒng)一。以下為部分配置片段:
1)、Jenkins流水線(xiàn)配置多分支
2)、helm模板注入
3)、啟動(dòng)腳本應(yīng)用
在 docker-entrypoint.sh 啟動(dòng)腳本中正式應(yīng)用前面的環(huán)境變量:
2、在微服務(wù)日志中的應(yīng)用
在應(yīng)用日志處理過(guò)程中,往往需要知道一些k8s元數(shù)據(jù),比如 pod 所在命名空間等,這種情況顯然無(wú)法使用靜態(tài)環(huán)境變量來(lái)處理,也是需要在pod啟動(dòng)的時(shí)候動(dòng)態(tài)注入,helm模板如下:
三、基于 configmap 的環(huán)境變量
《k8s concepts》中關(guān)于configmap的定義如下:A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume。
顯然,這里的意思是我們可以使用 configmap 的數(shù)據(jù),將其作為環(huán)境變量。在實(shí)際運(yùn)維過(guò)程中,如何使用呢?可以通過(guò) configMapKeyRef 引用 configmap 的 key 值,將其注入到 env 中,也可以直接掛載基于configmap的配置文件,將其封裝為動(dòng)態(tài)環(huán)境變量。比如,我們有一個(gè)log4j2的configmap,里面是項(xiàng)目組基于log4j2日志框架的配置,在helm模板中掛載如下:
后面也是類(lèi)似之前的處理,把這個(gè) mount 到的文件作為環(huán)境變量引入到啟動(dòng)腳本。一般來(lái)說(shuō),項(xiàng)目組的日志框架和格式定型后,很少會(huì)再有變化,如此處理,開(kāi)發(fā)人員不再需要專(zhuān)門(mén)維護(hù) log4j2 配置文件。需要注意的是:一般微服務(wù)架構(gòu)都有自己的配置中心,比如nacos 或者 apollo 等,業(yè)務(wù)配置信息建議一定要放到配置中心里面去,不要放進(jìn)configmap。
四、小結(jié)
合理使用k8s環(huán)境變量不僅有利于統(tǒng)一運(yùn)維邏輯,降低復(fù)雜性,而且可以較大限度復(fù)用已有規(guī)則規(guī)范,做到極簡(jiǎn)化配置。