AWS

プライベートサブネットのインスタンスでyumを実行する

スポンサーリンク
プライベートサブネット内のインスタンスでyumを実行する AWS
スポンサーリンク
スポンサーリンク

プライベートサブネット内のインスタンスでyumを実行する構成

プライベートサブネット内のインスタンスで、yumを実行する方法を確認します。

構築する環境

Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Amazon.co.jp: AWS認定資格試験テキスト AWS認定ソリューションアーキテクト - アソシエイト 改訂第2版 : NRIネットコム株式会社, 佐々木 拓郎, 林 晋一郎, 金澤 圭: 本
Diagram of yum on instances in privates subnets.

プライベートサブネット内のインスタンスからyumの実行を、以下の2つのパターンで確認します。

  1. NATゲートウェイを経由して、インターネット上のyumリポジトリにアクセスし、yumを実行する ※パターン1
  2. VPCエンドポイントを経由して、S3バケット上のyumリポジトリにアクセスし、yumを実行する ※パターン2

環境構築用のCloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。

https://github.com/awstut-an-r/awstut-fa/tree/main/002

テンプレートファイルのポイント解説

今回の環境を構成するための、各テンプレートファイルのポイントを取り上げます。

パブリックサブネットにNATゲートウェイを配置する

まずパブリックサブネット周りのリソースを確認します。

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VPCCidrBlock
      EnableDnsHostnames: true
      EnableDnsSupport: true

  IGW:
    Type: AWS::EC2::InternetGateway
  
  IGWAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW
      
  EIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc
          
  NATGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt EIP.AllocationId
      SubnetId: !Ref PublicSubnet
      
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Ref CidrIp1
      VpcId: !Ref VPC
      AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone1}
      
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      
  RouteToInternet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW
Code language: YAML (yaml)

インターネットゲートウェイおよびパブリックサブネットを定義します。

パブリックサブネットとは、直接のインターネットゲートウェイ向きのルートを持つサブネットのことです。
今回はパブリックサブネット用のルートテーブルを作成し、インターネットゲートウェイ向けのデフォルトルートを定義します。
デフォルトルートはDestinationCidrBlockプロパティに「0.0.0.0/0」を指定することで作成することができます。

パブリックサブネット内にNATゲートウェイを配置します。

NAT ゲートウェイは、ネットワークアドレス変換 (NAT) サービスです。NAT ゲートウェイを使用すると、プライベートサブネット内のインスタンスは VPC 外のサービスに接続できますが、外部サービスはそれらのインスタンスとの接続を開始できません。

NAT ゲートウェイ

NATゲートウェイを配置することによって、後述のプライベートサブネット内のインスタンス①が、インターネット向けのアウトバウンド通信を実行できるようになります。

ルートテーブルにNATゲートウェイ向きのルートを設定する

プライベートサブネット①周りのリソースを確認します。

Resources:
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Ref CidrIp2
      VpcId: !Ref VPC
      AvailabilityZone: !Sub ${AWS::Region}${AvailabilityZone1}

  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      
  RouteToNATGateway:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NATGateway
      
  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable1
Code language: YAML (yaml)

プライベートサブネット①内のインスタンスは、NATゲートウェイを経由してyumを実行します。
そのため同サブネット用のルートテーブルを用意し、NATゲートウェイ向けのデフォルトルートを定義します。

VPCエンドポイント向きのルートテーブルを用意する

プライベートサブネット②周りのリソースを確認します。

Resources:
  PrivateRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      
  PrivateSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable2
Code language: YAML (yaml)

プライベートサブネット②内のインスタンスは、S3エンドポイント経由でyumを実行します。そのため同サブネット用のルートテーブルを用意します。
なお具体的なルートの定義は、エンドポイント定義時に指定します。

S3エンドポイントはAmazon Linux用のyumリポジトリへのアクセスを許可する

S3エンドポイント関係のリソースを確認します。

Resources:
  S3Endpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal: '*'
            Action:
              - s3:GetObject
            Resource:
              - !Sub arn:aws:s3:::amazonlinux.${AWS::Region}.amazonaws.com/*
              - !Sub arn:aws:s3:::amazonlinux-2-repos-${AWS::Region}/*
      RouteTableIds:
        - !Ref PrivateRouteTable2
      ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
      VpcId: !Ref VPC
Code language: YAML (yaml)

通常、yumを実行するためには、インターネット上にあるyumリポジトリにアクセスする必要があります。ただ例外的に、EC2インスタンスのOSがAmazon Linux (2)の場合、S3用のVPCエンドポイントを設置することで、インターネットを経由することなく、同OS用のyumリポジトリにアクセスすることができます。

Amazon Linux リポジトリは、Amazon Simple Storage Service (Amazon S3) バケットでホストされます。インターネット接続なしでインスタンスにパッケージを更新したりインストールしたりするには、S3 Amazon Virtual Private Cloud (Amazon VPC) ゲートウェイエンドポイントを作成します。S3 VPC ゲートウェイエンドポイントに、リポジトリバケットへのアクセスを許可するポリシーを含めます。次に、VPC エンドポイントをインスタンスサブネットのルーティングテーブルに関連付けます。

Amazon Linux 1 または Amazon Linux 2 を実行している EC2 インスタンスで、インターネットにアクセスせずに yum を更新したり、パッケージをインストールしたりするにはどうすればよいですか?

今回の構成では、Amazon Linux  2のEC2インスタンスを作成します。同インスタンスがS3上のリポジトリにアクセスするために必要なポリシーに関しては、以下の通り言及されています。

S3 バケット arn:aws:s3:::amazonlinux.region.amazonaws.com および arn:aws:s3:::amazonlinux-2-repos-region/* はレポジトリをホストします。次に、s3:GetObject API 呼び出しを許可するポリシーの例を示します。region を実際の AWS リージョンに置き換えます。

Amazon Linux 1 または Amazon Linux 2 を実行している EC2 インスタンスで、インターネットにアクセスせずに yum を更新したり、パッケージをインストールしたりするにはどうすればよいですか?

上記に従い、VPCエンドポイントのAction・Resourceプロパティを設定します。RouteTableIdsプロパティに、先述のプライベートサブネット②用のルートテーブルを指定します。

プライベートサブネット内のインスタンスには、パブリックアドレスは不要

EC2関係のリソースを確認します。

Resources:
  Instance1:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PrivateSubnet1
          GroupSet:
            - !Ref InstanceSecurityGroup
            
  Instance2:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PrivateSubnet2
          GroupSet:
            - !Ref InstanceSecurityGroup
Code language: YAML (yaml)

特別な設定は不要です。
2つのインスタンスを、2つのプライベートサブネットに1つずつ配置します。

ポイントはパブリックアドレスを設定する必要はないという点です。
インスタンス①が通信する場合、インターネットに抜ける際に、NATゲートウェイに付与したElastic IPアドレスを使用するため、パブリックアドレスは不要です。
インスタンス②の場合は、そもそもインターネットを経由しないため、パブリックアドレスが不要です。

SSM Session Manager経由でEC2インスタンスにアクセスする

EC2インスタンスへのアクセスは、キーペアを使用したSSHによるアクセスが一般的ですが、SSM Session Managerを使用することでもアクセスすることが可能です。
同サービスを使用してEC2インスタンスにアクセスするためには、同サービス向けのエンドポイントの設置、同エンドポイント用のセキュリティグループの作成、同サービスにアクセスする権限を含むIAMロールの作成とインスタンスへのアタッチが必要となります。

詳細は以下のページをご確認ください。

環境構築

CloudFormationを使用して本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。
AWS CLIからCloudFormationを実行する手順については、以下のページをご確認ください。

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • インスタンス1のID:i-02c9af257d624677e
  • インスタンス2のID:i-0635909198866aa1b
  • PrivateSubet1のID:subnet-091d74d3795b13935
  • PrivateSubet2のID:subnet-0a3135f67e2a4dffd
  • NATゲートウェイのID:nat-06dc9f13d6fbb74b7
  • S3用VPCエンドポイントのID:vpce-0ad8a5eb1d7adcfbe

AWS Managemet Consoleでもリソースの作成状況を確認します。
まずパターン1のルートテーブルを確認します。

To yum for the Internet, set the default route to NAT gateway.

NATゲートウェイ向けのデフォルトルートが定義されています。このルートによって、NATゲートウェイを通じてインターネット上のyumリポジトリにアクセスすることができます。

次にパターン2のルートテーブルを確認します。

Configure route for S3 endpoint to yum for s3 repository.

S3用VPCエンドポイント向けのルートが定義されています。このルートの送信先にはプレフィックスリストが設定されています。リストの中身は以下の通りです。

Route for S3 endpoint contains multiple entries.

10行分のCIDRがエントリーされています。つまり先ほどのルート1行を定義することによって、送信先が上記だった場合は、S3用VPCエンドポイントにルーティングされるということになります。

動作確認1:NATゲートウェイ経由のyum

準備が整いましたので、実際に挙動を確認します。
まずNATゲートウェイ経由のyumを確認します。

インスタンス①にSSM Session Manager経由でアクセスします。

$ aws ssm start-session \
--target i-02c9af257d624677e

Starting session with SessionId: root-0d0faefc86ccd5a14
sh-4.2$
Code language: Bash (bash)

インターネットにアクセスできるかPingで確認します。

sh-4.2$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=104 time=2.88 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=104 time=2.43 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=104 time=2.47 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=104 time=2.48 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 2.432/2.568/2.888/0.185 ms
Code language: Bash (bash)

確かにNATゲートウェイ経由で、インターネットにアクセスすることができます。

それではyumを実行します。

sh-4.2$ sudo yum install httpd -y
...
Installed:
  httpd.x86_64 0:2.4.48-2.amzn2                                                                                                                                     
...
Complete!Code language: Bash (bash)

正常に実行できました。
NATゲートウェイを経由して、インターネット上のyumリポジトリにアクセスし、yumが実行できることがわかりました。

動作確認2:VPCエンドポイント経由のyum

続いてS3エンドポイント経由のyumを確認します。

インスタンス②にSSM Session Manager経由でアクセスします。

$ aws ssm start-session \
--target i-0635909198866aa1b

Starting session with SessionId: root-01e1d55c4aaf53e13
sh-4.2
Code language: Bash (bash)

インターネットにアクセスできるかPingで確認します。

sh-4.2$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
^C
--- 8.8.8.8 ping statistics ---
28 packets transmitted, 0 received, 100% packet loss, time 27624ms
Code language: Bash (bash)

やはりできません。プライベートサブネット②には、インターネットに抜けられるルートがないためです。

それではyumを実行します。

sh-4.2$ sudo yum install httpd -y
...
Installed:
  httpd.x86_64 0:2.4.48-2.amzn2                                                                                                                                     
...
Complete!
Code language: Bash (bash)

正常に実行できました。
VPCエンドポイントを経由して、S3バケット上のyumリポジトリにアクセスし、yumを実行できることがわかりました。

まとめ

プライベートサブネット上のEC2インスタンスで、yumを実行する方法を2パターン確認しました。
1つ目はNATゲートウェイを経由して、インターネット上のyumリポジトリにアクセスし、yumを実行する方法です。
2つ目はVPCエンドポイントを経由して、S3バケット上のyumリポジトリにアクセスし、yumを実行する方法です。

タイトルとURLをコピーしました