こんにちは。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についても便利なため、是非ドキュメントも覗いてみてください。
本記事が皆様のお役にたてば幸いです。
ではサウナラ~?











