AKS containerd运行时容器化Windows构建代理无法启动问题
AKS Windows自托管构建代理containerd运行时故障排查方案
问题描述
在AKS集群上托管私有Azure DevOps Windows构建代理,使用的Dockerfile、start.ps1启动脚本均来自微软官方《在Docker中运行自托管代理》文档,容器部署完成后出现运行错误:
初步怀疑故障与官方配置和containerd运行时的兼容性问题相关。
环境信息
- AKS版本:1.23.5
- 容器运行时:containerd
原部署YAML配置
kind: Deployment metadata: name: azdevops-win-deployment namespace: build-agent labels: app: azdevops-win-agent spec: replicas: 2 selector: matchLabels: app: azdevops-win-agent template: metadata: labels: app: azdevops-win-agent spec: containers: - name: az-win-build-agent image: "xxxxx-acr/amie_win1:latest" imagePullPolicy: Always resources: requests: memory: "1Gi" cpu: "0.5" limits: memory: "3Gi" cpu: "2" env: - name: AZP_URL valueFrom: secretKeyRef: name: azdevops key: AZP_URL - name: AZP_TOKEN valueFrom: secretKeyRef: name: azdevops key: AZP_TOKEN - name: AZP_POOL value: amie_win1 nodeSelector: kubernetes.io/os: windows tolerations: - key: "os" operator: "Equal" value: "win" effect: "NoSchedule"
排查思路与修复方案
- 第一步:校验Windows容器与节点版本匹配性
containerd运行时下Windows容器不支持跨版本兼容(Docker EE时代的Hyper-V隔离版本适配逻辑在containerd下不生效),必须保证构建镜像使用的Windows基础镜像版本(如ltsc2019、ltsc2022)与AKS Windows节点的主机OS版本完全一致,版本不匹配会直接导致容器启动失败、进程无响应。可通过kubectl get nodes -o wide查看节点OS版本,重新构建对应版本的代理镜像即可解决该类问题。 - 第二步:修正官方start.ps1脚本的containerd适配问题
官方旧版脚本是基于Docker运行时编写的,在containerd环境下需要修改三处逻辑:- 删除所有调用
docker.exe、读取C:\ProgramData\Docker\路径下容器ID文件的逻辑,containerd不会在容器内部暴露Docker相关二进制、也不会挂载Docker的容器元数据目录 - 替换脚本中依赖Docker注入环境变量获取容器名、工作目录的逻辑,直接使用
$env:COMPUTERNAME作为代理注册名,写死代理工作目录为固定路径(如C:\azp) - 调整代理启动逻辑,不要用
Start-Process后台启动代理进程后执行Wait,改为直接调用.\bin\Agent.Listener.exe run前台执行,避免PID 1进程退出后containerd判定容器运行结束直接重启
- 删除所有调用
- 第三步:修复Deployment配置的兼容问题
原配置存在两处明确的containerd适配问题:- 缺少Windows容器运行账号声明:在容器配置段添加
runAsUserName: "ContainerAdministrator",containerd下Windows容器默认账号权限不足,会导致代理解压、服务注册步骤失败 - 污点容忍配置错误:AKS Windows节点默认污点为
node.kubernetes.io/os=windows:NoSchedule,原配置中os=win的容忍规则与实际污点不匹配,会导致Pod调度异常,替换为对应默认污点的容忍规则即可 - 补充显式工作目录声明:在容器配置段添加
workingDir: "C:/azp",避免containerd下默认工作目录路径异常导致脚本找不到执行文件
- 缺少Windows容器运行账号声明:在容器配置段添加
- 第四步:定向日志排查
- 执行
kubectl describe pod <pod名> -n build-agent查看事件流,确认故障属于调度失败、镜像拉取失败还是容器启动后异常退出 - 如果容器启动后闪退,执行
kubectl logs <pod名> -n build-agent查看start.ps1执行输出,重点定位权限拒绝、路径不存在、网络连接失败类报错 - 如果无有效日志,临时将容器启动命令改为
powershell.exe -Command "Start-Sleep 3600",进入容器手动执行start.ps1复现问题,定位具体失败点
- 执行
内容的提问来源于stack exchange,提问作者Nikhil Rajan
相关产品推荐
相关产品推荐

