docker - Jenkins 的 K8s 插件:始终在一个 pod 内运行两个单独的容器
问题描述
我创建了一个Dockerfile(用于一个 Node JNLP slave,可以与Jenkins 的 Kubernetes 插件一起使用)。我从官方图片延伸而来jenkinsci/jnlp-slave
FROM jenkinsci/jnlp-slave
USER root
MAINTAINER Aryak Sengupta <aryak.sengupta@hyland.com>
LABEL Description="Image for NodeJS slave"
COPY cert.crt /usr/local/share/ca-certificates
RUN update-ca-certificates
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash \
&& apt-get install -y nodejs
ENTRYPOINT ["jenkins-slave"]
我将此图像保存在我的 Pod 模板中(在 K8s 插件配置中)。现在,当我尝试在这个slave上运行构建时,我发现 Pod 内部生成了两个容器(截图证明了这一点。)。
我的 Pod 模板如下所示:
现在如果我做一个简单的docker ps
,我发现有两个容器启动了(为什么?):
现在,在 Jenkins 的 Jenkins Job 配置中,无论我在构建步骤中添加什么,这些步骤都会在第一个容器中执行。
即使我Node
在我的内部使用官方容器PodTemplate
,结果仍然是一样的:
我试图在我的 Jenkins Job 中打印 Node 版本,输出是"Node not found"。另外,为了验证我的臀部,我在docker exec
我的第二个容器中做了一个并尝试打印Node
版本。在这种情况下,它工作得非常好。
这是我的构建步骤的样子:
因此,归结为,我有两个主要问题:
- 为什么当我启动 Jenkins 作业时会启动两个单独的容器(一个用于 JNLP,一个用于所有自定义更改)容器?
- 为什么我的作业在第一个未安装 Node 的容器上运行?如何
Node
使用此配置实现构建项目所需的行为?
我错过了什么?
PS - 如果问题在某些部分不清楚,请告诉我。
编辑:我知道这可以使用Pipeline
Jenkins 插件来完成,我可以在其中明确提及container
名称,但我需要从 Jenkins UI 执行此操作。有什么方法可以指定容器名称以及我已经这样做的从属名称:
解决方案
Jenkins kubernetes 插件将始终在为执行构建而创建的 pod 内创建一个 JNLP 从属容器。podTemplate 是您定义执行构建所需的其他容器的地方。
在这种情况下,您似乎希望将 Node 容器添加到您的 podTemplate。在您的构建中,您将在命名的 Node 容器内进行构建。
你不应该真正关心 Pod 在哪里运行。您需要做的就是确保添加一个包含所需资源的容器(如本例中的 Node)。您可以向 podTemplate 添加任意数量的容器。我有一些包含 10 个或更多容器的容器,用于 PMD、Maven、curl 等步骤。
我使用带有管道的 Jenkinsfile。
podTemplate(cloud: 'k8s-houston', label: 'api-hire-build',
containers: [
containerTemplate(name: 'maven', image: 'maven:3-jdk-8-alpine', ttyEnabled: true, command: 'cat'),
containerTemplate(name: 'pmd', image: 'stash.company.com:8443/pmd:pmd-bin-5.5.4', alwaysPullImage: false, ttyEnabled: true, command: 'cat')
],
volumes: [
persistentVolumeClaim(claimName: 'jenkins-pv-claim', mountPath: '/mvn/.m2nrepo')
]
)
{
node('api-hire-build') {
stage('Maven compile') {
container('maven') {
sh "mvn -Dmaven.repo.local=/mvn/.m2nrepo/repository clean compile"
}
}
stage('PMD SCA (docker)') {
container('pmd') {
sh 'run.sh pmd -d "$PWD"/src -f xml -reportfile "$PWD"/target/pmd.xml -failOnViolation false -rulesets java-basic,java-design,java-unusedcode -language java'
sh 'run.sh pmd -d "$PWD"/src -f html -reportfile "$PWD"/target/pmdreport.html -failOnViolation false -rulesets java-basic,java-design,java-unusedcode -language java'
sh 'run.sh cpd --files "$PWD"/src --minimum-tokens 100 --failOnViolation false --language java --format xml > "$PWD"/target/duplicate-code.xml'
}
archive 'target/duplicate-code.xml'
step([$class: 'PmdPublisher', pattern: 'target/pmd.xml'])
}
}
}
推荐阅读
- c# - 为什么 GetClassName 和 RealGetWindowClass 返回相同的值?
- python - 没有名为“matplotlib”的模块,除了它在那里,同一文件夹中的其他文件还可以,交互式 python 很好
- mysql - MySQL在插入触发器失败后创建外键约束
- amazon-web-services - 跟踪多个 AWS SQS 队列上的消息
- node.js - 当用户在对话框流中从另一个意图键入列表项时如何触发列表
- mysql - 查找未与另一个 id 关联的 id 的 SQL 查询
- android - 与第三方库的数据绑定
- docker - 构建docker镜像时如何修改`core_pattern`
- material-design - Material Design 风格图标如何基于文本节点子节点
- python - 为什么图像不会闪烁?