GitHub Action连接EC2失败排查及正确实现方法咨询
问题:GitHub Action无法正确连接EC2实例
我配置了如下GitHub Action流程:
--- name: build and push image to aws ecr on: push: branches: [ main ] jobs: build-and-push: name: Build and push to ecr runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 ... deploy: needs: build-and-push name: deploy runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Login ec2 env: PRIVATE_KEY: ${{ secrets.EC2_SSH_KEY }} HOSTNAME: ${{ secrets.HOST_DNS }} USER_NAME: ${{ secrets.USER_NAME }} run: | echo "$PRIVATE_KEY" > private_key && chmod 600 private_key ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} ls touch helloworld.txt
Action执行后,我怀疑没成功连接EC2实例——因为刚创建的EC2是空的,但执行结果列出了我的项目文件:
Run echo "$PRIVATE_KEY" > private_key && chmod 600 private_key Pseudo-terminal will not be allocated because stdin is not a terminal. Warning: Permanently added '***,18.181.220.91' (ECDSA) to the list of known hosts. Dockerfile README.md docker-compose.yml nest-cli.json package-lock.json package.json private_key src test tsconfig.build.json tsconfig.json
我本地连接EC2的命令是:ssh -i "home-key.pem" ec2-user@ec2-18-181-220-91.ap-northeast-1.compute.amazonaws.com,想知道怎么通过GitHub Action正确实现EC2连接?
解决方案
你的问题核心是:SSH命令执行后只是短暂登录EC2就退出了,后面的ls和touch命令其实是在GitHub的Runner虚拟机上执行的,不是EC2实例内。要在EC2上执行命令,需要把要运行的指令通过SSH一次性传递过去,或者用更可靠的SSH Action工具。
方法1:直接通过SSH命令传递要执行的指令
修改run里的SSH命令,把要在EC2上执行的命令放在SSH的后面,用单引号包裹:
run: | echo "$PRIVATE_KEY" > private_key && chmod 600 private_key ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} ' ls touch helloworld.txt '
这样所有包裹在单引号里的命令都会在EC2实例内执行,而不是回到Runner上。
方法2:使用成熟的SSH Action工具
推荐用appleboy/ssh-action,这个Action专门处理GitHub Action里的SSH连接,配置更简洁,也更容易调试:
steps: - uses: actions/checkout@v2 - name: Deploy to EC2 uses: appleboy/ssh-action@v1.0.3 with: host: ${{ secrets.HOST_DNS }} username: ${{ secrets.USER_NAME }} key: ${{ secrets.EC2_SSH_KEY }} script: | ls touch helloworld.txt
这个Action会自动处理密钥权限、主机校验等问题,执行结果里的输出就是EC2内的内容。
验证连接是否成功的小技巧
可以在EC2上执行一个能产生唯一标识的命令,比如打印EC2的主机名:
# 用方法1的话 ssh -o StrictHostKeyChecking=no -i private_key ${USER_NAME}@${HOSTNAME} 'hostname' # 用方法2的话 script: | hostname
如果输出是EC2的主机名(类似ip-172-31-xx-xx.ap-northeast-1.compute.internal),就说明连接成功了。
内容的提问来源于stack exchange,提问作者Đoàn Đức Bảo
相关产品推荐
相关产品推荐

