iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
DevOps

AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑系列 第 24

Day 24 連進 private subnet 的 EC2 instance & container

  • 分享至 

  • xImage
  •  

昨天把 EC2 instance 搬進 private subnet,如果要 debug 要怎麼連進去呢?今天介紹兩種連進 EC2 instance、一種直接進 container 的方式~

透過跳板機連線

最傳統(?)的方式是在 public subnet 開一台跳板機。連進跳板機後,從跳板機用 private IP address 連到 private subnet 的 EC2 instance。

我們有一台非 terraform 管理、用來當作 Gitlab runner 以及 MySQL server 的 EC2 instance 放在 public subnet,它就可以當作跳板機使用。

這個做法要注意 EC2 instance 的 security group 要打開從 VPC 網段連 SSH 的 inbound rule,以及要把 ssh 連線用的 key pair 放進跳板機。

透過 EC2 Instance Connect Endpoint 連線

用跳板機連線得多開一台機器,AWS 在今年六月推出一個新功能:EC2 Instance Connect Endpoint。這個功能可以讓我們不需要跳板機就能直接連進 private subnet 中的 EC2 instance!神奇吧~

這個功能不是所有 OS 都支援,可以參考文件看哪些 AMI 是有支援的。它是利用 IAM 權限來做 access control,要能夠用這個方式連 EC2 instance 必須要有相關的權限。另外,除非 endpoint 跟要連線的 EC2 在不同 AZ,不然沒有額外費用的!

建立 EC2 Instance Connect Endpoint

resource "aws_ec2_instance_connect_endpoint" "public_1a" {
  subnet_id = aws_subnet.public_1a.id
  security_group_ids = [aws_security_group.allow_ssh_from_my_ip.id]
}

可連線進 EC2 inst 的 IAM 權限

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EC2InstanceConnect",
            "Action": "ec2-instance-connect:OpenTunnel",
            "Effect": "Allow",
            "Resource": "arn:aws:ec2:[REGION]:[ACCOUNT_ID]:instance-connect-endpoint/[EC2_Instance_Connect_Endpoint_ID]",
            "Condition": {
                "NumericEquals": {
                    "ec2-instance-connect:remotePort": "22"
                },
                "IpAddress": {
                    "ec2-instance-connect:privateIpAddress": [
                        "172.16.0.0/16"
                    ]
                }
            }
        },
        {
            "Sid": "Describe",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceConnectEndpoints"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

所有 Condition 要符合才會能夠成功連上:

  • ec2-instance-connect:remotePort 指定 EC2 instance 上可以被連線的 port

  • ec2-instance-connect:privateIpAddress 指定可以被連線的 EC2 instance 的 private IP

幫 EC2 instance 加 security group

要讓要連線的 EC2 instance 擁有可以從自己 IP 連 SSH 的 security group。

Connect EC2 instance

$ ssh -i my-key-pair.pem ec2-user@i-0123456789example \
    -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id i-0123456789example'

要注意 tunnel 的 web socket 的最大 duration,參數是 --max-tunnel-duration ,預設值 3600 秒(最大值也是 3600 秒),超過這個時間 web socket 就會斷掉,所以連帶 ssh 也會斷掉,所以這個方式不適合長時間使用。

ECS Exec

ECS Exec 讓我們可以直接以 AWSCLI 進入 ECS task 的 container,不用連進 EC2 instance 再用 docker exec 進入 container。如果 EC2 instance 無法直接從 internet 連 SSH,前面還得再多加一層跳板機,總共要過三層才能到 container,用 ECS Exec 來 debug 會方便很多~

首先依照 官方文件 在自己電腦上安裝 AWSCLI 的 Session Manager plugin,Ubuntu 的安裝命令摘錄如下:

$ curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb"
$ sudo dpkg -i session-manager-plugin.deb

增加 SSM 權限到 ECS task 的 task role:

{
    "Statement": [
        {
            "Action": [
                "ssmmessages:CreateControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:OpenDataChannel"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ],
    "Version": "2012-10-17"
}

在用來連 container 的 IAM user 要加上 ecs:ExecuteCommandecs:DescribeTasks permission:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ECSExecuteCommand",
            "Effect": "Allow",
            "Action": [
                "ecs:ExecuteCommand",
                "ecs:DescribeTasks"
            ],
            "Resource": "*"
        }
    ]
}

最後修改 aws_ecs_service.service attribute enable_execute_command ,改成 true 。重新 deploy 一次 service,確認 task 的 td 是有 task role 的。

然後就可以用 awscli 進入 container 啦!

$ aws ecs execute-command --cluster <cluster-name> \
    --task <task-id> \
    --container <container-name> \
    --interactive \
    --command "/bin/bash"

上一篇
Day 23 把 EC2 instance 移到 private subnet
下一篇
Day 25 ECS Rolling Deployment 流程與 min/max 參數
系列文
AWS ECS + Gitlab + Laravel + Terraform 從入門到摔坑30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言