18.3.4 环境变量、参数化与凭据管理
环境变量、参数化与凭据管理是流水线“输入—控制—授权”的核心。建议明确作用域:全局(pipeline)、阶段(stage)、步骤(step),并通过统一命名与最小权限原则控制敏感信息的传播与日志暴露。
环境变量作用域与示例#
Jenkinsfile 中常见三类作用域变量,注意覆盖顺序:步骤级 > 阶段级 > 全局。
// Jenkinsfile
pipeline {
agent any
environment { // 全局变量
APP_NAME = "demo-web"
REGISTRY = "registry.example.com"
}
stages {
stage('Build') {
environment { // 阶段变量覆盖
BUILD_TYPE = "release"
}
steps {
sh 'echo "APP=$APP_NAME REG=$REGISTRY TYPE=$BUILD_TYPE"'
withEnv(["TAG=${env.BUILD_NUMBER}"]) { // 步骤级临时变量
sh 'echo "IMAGE=${REGISTRY}/${APP_NAME}:${TAG}"'
}
}
}
}
}
预期效果:控制台输出中可见 APP/REG/TYPE/IMAGE,步骤级 TAG 仅在 withEnv 内有效。
参数化构建与校验#
参数化构建用于多环境与多版本发布入口。建议启用白名单校验,并对高危操作增加确认参数。
// Jenkinsfile
pipeline {
agent any
parameters {
choice(name: 'ENV', choices: ['dev', 'test', 'prod'], description: '发布环境')
string(name: 'VERSION', defaultValue: '1.0.0', description: '发布版本')
booleanParam(name: 'CONFIRM_PROD', defaultValue: false, description: '确认生产发布')
}
stages {
stage('Validate') {
steps {
script {
def allowed = ['dev','test','prod']
if (!allowed.contains(params.ENV)) {
error "ENV非法:${params.ENV}"
}
if (params.ENV == 'prod' && !params.CONFIRM_PROD) {
error "生产发布必须确认 CONFIRM_PROD=true"
}
}
}
}
stage('Show') {
steps {
sh "echo ENV=${params.ENV} VERSION=${params.VERSION}"
}
}
}
}
凭据管理与注入(withCredentials)#
使用 Credentials Binding 插件,将凭据限制在步骤内,避免长时间驻留。
安装/启用插件(Jenkins CLI 示例)
# 需要已配置JENKINS_URL与API Token
java -jar jenkins-cli.jar -s http://jenkins.example.com/ \
-auth admin:APITOKEN install-plugin credentials-binding -restart
Jenkinsfile 使用示例
// Jenkinsfile
pipeline {
agent any
stages {
stage('Pull Code') {
steps {
withCredentials([usernamePassword(
credentialsId: 'git-cred',
usernameVariable: 'GIT_USER',
passwordVariable: 'GIT_PASS'
)]) {
sh '''
set -e
git clone https://${GIT_USER}:${GIT_PASS}@git.example.com/repo/demo.git
'''
}
}
}
stage('Deploy') {
steps {
withCredentials([string(credentialsId: 'kubeconfig', variable: 'KUBECONFIG_DATA')]) {
sh '''
set -e
echo "$KUBECONFIG_DATA" > /tmp/kubeconfig
export KUBECONFIG=/tmp/kubeconfig
kubectl get ns
'''
}
}
}
}
}
命令解释
- withCredentials:仅在闭包内注入环境变量,退出后自动清理。
- credentialsId:在 Jenkins 凭据管理器中创建的 ID。
- usernameVariable/passwordVariable:绑定为环境变量。
参数 + 环境 + 凭据综合示例#
pipeline {
agent any
parameters {
choice(name: 'ENV', choices: ['test','prod'], description: '环境')
string(name: 'IMAGE_TAG', defaultValue: 'latest', description: '镜像标签')
}
environment {
APP_NAME = "api-service"
REGISTRY = "registry.example.com"
}
stages {
stage('Validate') {
steps {
script {
if (params.ENV == 'prod' && params.IMAGE_TAG == 'latest') {
error "生产环境禁止使用latest标签"
}
}
}
}
stage('Push Image') {
steps {
withCredentials([usernamePassword(
credentialsId: 'harbor-cred',
usernameVariable: 'H_USER',
passwordVariable: 'H_PASS'
)]) {
sh '''
set -e
echo "$H_PASS" | docker login -u "$H_USER" --password-stdin registry.example.com
docker tag ${APP_NAME}:${IMAGE_TAG} ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}
docker push ${REGISTRY}/${APP_NAME}:${IMAGE_TAG}
'''
}
}
}
}
}
常见排错#
- 凭据变量为空
- 现象:/bin/sh: H_USER: unbound variable
- 排查:确认credentialsId是否正确、凭据作用域是否授权到当前 Job。 - 参数不生效
- 现象:params.ENV为空
- 排查:流水线未“参数化构建”,检查是否重新运行并选择参数。 - 日志泄漏
- 现象:控制台输出明文密码
- 排查:确保使用withCredentials,避免echo $PASS,启用 Mask Passwords。
练习#
- 创建一个参数化流水线,限制 prod 只能发布 v1.* 版本。
- 使用
withEnv实现仅在某个阶段临时设置JAVA_HOME。 - 绑定 SSH 私钥凭据,执行
ssh -i远程执行hostname。