こんにちは。SCSKのふくちーぬです。今回は、EC2(Amazon Linux 2023)にDockerをインストールする方法をご紹介します。
本手順は、閉域網環境を対象としてますが、もちろんインターネットゲートウェイまたはNatゲートウェイがあるパブリック環境に対しても有効なものとなります。
アーキテクチャー
- インターネットゲートウェイ、NATゲートウェイが存在しない閉域網ネットワーク(プライベート環境)とする。
- Systems Managerの管理下にするために、EC2はマネージドインスタンスとする。また、OSはAmazon Linux 2023を利用します。
- 運用者は、セッションマネージャーを利用してEC2に接続します。
- Run Commandを利用して、マネージドインスタンスに対してDockerインストールコマンドを実行します。
S3にRun Commandの実行ログを出力します。
完成したCloudFormationテンプレート
以下のテンプレートをデプロイしてください。
AWSTemplateFormatVersion: 2010-09-09 Description: CFN template EC2 Parameters: ResourceName: Type: String AMIId: Type: String Resources: # ------------------------------------------------------------# # S3 # ------------------------------------------------------------# S3BucketFor: Type: AWS::S3::Bucket DeletionPolicy: Delete Properties: BucketName: !Sub ${ResourceName}-s3-bucket AccessControl: Private PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true # ------------------------------------------------------------# # VPC # ------------------------------------------------------------# VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/16 EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${ResourceName}-VPC # ------------------------------------------------------------# # Private Subnet # ------------------------------------------------------------# PrivateSubnet1a: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.1.0/24 AvailabilityZone: ap-northeast-1a MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1a PrivateSubnet1c: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC CidrBlock: 10.0.11.0/24 AvailabilityZone: ap-northeast-1c MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub ${ResourceName}-subnet-Private-1c # ------------------------------------------------------------# # Route Table and Routes # ------------------------------------------------------------# PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: PrivateRouteTable PrivateSubnet1aAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1a RouteTableId: !Ref PrivateRouteTable PrivateSubnet1cAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1c RouteTableId: !Ref PrivateRouteTable # ------------------------------------------------------------# # VPC Endpoint # ------------------------------------------------------------# ssmEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssm SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ec2messagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ec2messages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true ssmmessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .ssmmessages SubnetIds: - !Ref PrivateSubnet1a - !Ref PrivateSubnet1c VpcId: !Ref VPC VpcEndpointType: Interface SecurityGroupIds: - !Ref VPCeSecurityGroup PrivateDnsEnabled: true S3VpcEndpoint: Type: AWS::EC2::VPCEndpoint Properties: ServiceName: !Join - '' - - com.amazonaws. - !Ref 'AWS::Region' - .s3 VpcId: !Ref VPC VpcEndpointType: Gateway RouteTableIds: - !Ref PrivateRouteTable # ------------------------------------------------------------# # Security Group # ------------------------------------------------------------# SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: For EC2 VpcId: !Ref VPC VPCeSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VPC GroupDescription: For VPCEndpoint SecurityGroupIngress: - SourceSecurityGroupId: !Ref SecurityGroup IpProtocol: tcp FromPort: 443 ToPort: 443 # ------------------------------------------------------------# # IAM Role and Instance Profile # ------------------------------------------------------------# SSMRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ${ResourceName}-ec2-role AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/AmazonS3FullAccess InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref SSMRole # ------------------------------------------------------------# # EC2 Instance # ------------------------------------------------------------# EC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: t2.micro ImageId: !Ref AMIId SubnetId: !Ref PrivateSubnet1a IamInstanceProfile: !Ref InstanceProfile SecurityGroupIds: - !Ref SecurityGroup Tags: - Key: Name Value: !Sub ${ResourceName}-ec2
Dockerのインストール
セッションマネージャーを利用してEC2に接続
セッションマネージャーを利用して、EC2に接続します。「接続」を押下します。
下記のコマンドを実行して、Dockerがインストールされていないことを確認します。
docker --version
Run Commandの実行
Systems Managerのコンソールのペインから、Run Commandを選択します。「Run Command」を押下します。
Dockerをインストールするためのコマンドである”AWS-ConfigureDocker”を検索ボックスに入れて、選択します。
インストールするEC2を選択します。
実行ログをS3またはCloudWatchロググループに出力することができます。
「実行」を押下します。
Run Commandが完了すると以下の画面になります。
インスタンスIDを選択すると、ログの内容が確認できます。
また今回は、S3バケットにもログを出力するように設定しているためファイルが格納されています。
Dockerのインストール確認
先程度同様にセッションマネージャーを利用して、EC2に接続します。
セッションマネージャーで利用しているユーザーに対して、sudo権限でDockerコマンドを操作できるように以下のコマンドを実行します。
sudo gpasswd -a ssm-user docker
設定を反映させるために「終了」を押下して一旦ログアウトした後に、再度EC2に接続します。
以下のコマンドを実行し、Dockerがインストールされたことを確認します。
docker --version
sudo権限なしで実行できました。
docker images
最後に
いかがだったでしょうか。
Systems ManagerのRun Commandを利用することで、手動でDockerをインストールするコマンドを実行することなく、容易にコンテナを利用できるようになります。他のRun Commandについても便利なため、是非ドキュメントも覗いてみてください。
本記事が皆様のお役にたてば幸いです。
ではサウナラ~🔥