Amazon EFSのマウントターゲットのカスタムドメインにEFSマウントヘルパーを使ってマウントできるのか確認してみた
カスタムドメインでマウントする時もEFSマウントヘルパーを使いたいな
こんにちは、のんピ(@non____97)です。
皆さんはAmazon EFSのカスタムドメインに対してEFSマウントヘルパーでマウントしたいなと思ったことはありますか? 私はあります。
EFSマウントヘルパーを使うことで得られる主なメリットは以下の4つ考えています。
- IAM認証が使用できる
- EFS用に最適化されたマウントオプションを自動で使用してくれる
- 転送中の暗号化を簡単に実装できる
- マウント時のログが出力される
EFSマウントヘルパーを使える環境であれば、EFSマウントヘルパーを使わない手はないですね。
EFSマウントヘルパーを使ってマウントする際は以下の3つの方法でEFSを指定します。
- ファイルシステム DNS 名 — ファイルシステム DNS 名を使用しても、マウントヘルパーがそれを解決できない場合、たとえばファイルシステムを別の VPC にマウントする場合、マウントターゲット IP アドレスの使用にフォールバックします。詳細については、「別の AWS アカウント または VPC から EFS ファイルシステムをマウントする」を参照してください。
- ファイルシステム ID — ファイルシステム ID を使用する場合、マウントヘルパーは、外部リソースを呼び出さずに、マウントターゲットの elastic network interface (ENI) のローカル IP アドレスを解決します。
- マウントターゲット IP アドレス – ファイルシステムのマウントターゲットのいずれかの IP アドレスを使用できます。
EFS マウントヘルパーを使用して EFS ファイルシステムをマウントする - Amazon Elastic File System
ここで、ふとカスタムドメインでも接続できるのかが気になりました。
EFSファイルシステムのDNS名は、そのEFSファイルシステムのVPC内のRoute 53 Resolverでなければ名前解決できません。
そのため、別VPCからEFSファイルシステムのDNS名を指定してマウントしようとしたり、オンプレのDNSサーバーを参照している状態でマウントしようとしたりすると名前解決に失敗し、接続できません。
AWS公式ドキュメントには「手動でマウントターゲットの名前解決をしろ」と記載があります。
EFS マウントヘルパーを使用し、NFS クライアントおよび EFS アクセスポイントに対して IAM 認証を使用することで、Amazon EFS ファイルシステムをマウントできます。既定では、EFS マウントヘルパーは、ドメインネームサービス (DNS) を使用して、EFS マウントターゲットの IP アドレスを解決します。別のアカウントまたは Virtual Private Cloud (VPC) からファイルシステムをマウントする場合は、EFS マウントターゲットを手動で解決する必要があります。
EFS マウントヘルパーを使用して EFS ファイルシステムをマウントする - Amazon Elastic File System
では、DNSサーバーのレコードとしてマウントターゲットのIPアドレスを登録し、そのカスタムドメインを指定してEFSマウントヘルパーを使う場合は正常に接続できるのでしょうか。
気になって朝4時半に起きたので検証します。
いきなりまとめ
- Amazon EFSのカスタムドメインにEFSマウントヘルパーを使ってマウントできる
- ただし、ファイルシステムIDを指定する必要がある
- 特段カスタムドメインを使うことによるメリットは薄い
- 存在しないマウントターゲットのIPアドレスを指定する場合、存在しないファイルシステムIDを指定しても接続できる
- マウントターゲットのIPアドレスとファイルシステムIDの整合性チェックは行われない
- ただし、存在しないファイルシステムのIDであるためIAM認証はできない
- TLS接続はできる
検証環境
検証環境は以下の通りです。
VPCが2つあり、VPC間はVPCピアリングで接続しています。
それぞれのEC2インスタンスからEFSファイルシステムに対してEFSマウントヘルパーでマウントしにいきます。
Route 53 Private Hosted Zoneのレコードは以下の通りです。
EFSファイルシステムのマウントターゲットのIPアドレス(10.0.0.206
)をAレコードとして登録したものと、EFSファイルシステムのDNS名をCNAMEレコードとして登録したものの2つ用意しました。
EFSマウントヘルパーはdnfでインストールしました。
$ sudo dnf install amazon-efs-utils -y Last metadata expiration check: 0:13:38 ago on Mon Jul 3 09:06:53 2023. Dependencies resolved. ============================================================================================================================================================== Package Architecture Version Repository Size ============================================================================================================================================================== Installing: amazon-efs-utils noarch 1.35.0-1.amzn2023 amazonlinux 56 k Installing dependencies: stunnel x86_64 5.58-1.amzn2023.0.2 amazonlinux 156 k Transaction Summary ============================================================================================================================================================== Install 2 Packages Total download size: 212 k Installed size: 556 k Downloading Packages: (1/2): amazon-efs-utils-1.35.0-1.amzn2023.noarch.rpm 734 kB/s | 56 kB 00:00 (2/2): stunnel-5.58-1.amzn2023.0.2.x86_64.rpm 1.1 MB/s | 156 kB 00:00 -------------------------------------------------------------------------------------------------------------------------------------------------------------- Total 1.1 MB/s | 212 kB 00:00 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Running transaction Preparing : 1/1 Installing : stunnel-5.58-1.amzn2023.0.2.x86_64 1/2 Running scriptlet: stunnel-5.58-1.amzn2023.0.2.x86_64 1/2 Installing : amazon-efs-utils-1.35.0-1.amzn2023.noarch 2/2 Running scriptlet: amazon-efs-utils-1.35.0-1.amzn2023.noarch 2/2 Verifying : stunnel-5.58-1.amzn2023.0.2.x86_64 1/2 Verifying : amazon-efs-utils-1.35.0-1.amzn2023.noarch 2/2 Installed: amazon-efs-utils-1.35.0-1.amzn2023.noarch stunnel-5.58-1.amzn2023.0.2.x86_64 Complete!
VPC AのEC2インスタンスからマウント
ファイルシステムIDを指定してEFSマウントヘルパーでマウント
まずは、ファイルシステムIDを指定してEFSマウントヘルパーでマウントをしてみます。
# マウントポイントの作成 $ sudo mkdir -p /mount/efs # ファイルシステムIDを指定してEFSマウントヘルパーでマウント $ sudo mount -t efs -o tls,iam fs-0e211df86678573e6 /mount/efs # マウントできているか確認 $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs
マウントできましたね。
ついでに書き込みができることも確認します。
$ sudo touch /mount/efs/test $ ls -l /mount/efs/ total 4 -rw-r--r--. 1 root root 0 Jul 3 09:23 test
問題なくできますね。
ファイルシステムのDNS名を指定してEFSマウントヘルパーでマウント
続いて、ファイルシステムのDNS名を指定してEFSマウントヘルパーでマウントします。
# ファイルシステムのDNS名を指定してEFSマウントヘルパーでマウント $ sudo mount -t efs -o tls,iam fs-0e211df86678573e6.efs.us-east-1.amazonaws.com /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs/ total 4 -rw-r--r--. 1 root root 0 Jul 3 09:23 test
こちらも何事もなくマウントできましたね。
マウントターゲットのIPアドレスを指定してEFSマウントヘルパーでマウント
次に、マウントターゲットのIPアドレスを指定してEFSマウントヘルパーでマウントします。
まず、マウントターゲットのIPアドレスを確認します。
$ dig fs-0e211df86678573e6.efs.us-east-1.amazonaws.com +short 10.0.0.206
10.0.0.206
でした。
こちらのIPアドレスをマウントします。
$ sudo mount -t efs -o tls,iam 10.0.0.206 /mount/efs The specified CNAME "10.0.0.206" did not resolve to a valid DNS name for an EFS mount target. Please refer to the EFS documentation for mounting with DNS names for examples: https://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html $ sudo mount -t efs -o tls 10.0.0.206 /mount/efs The specified CNAME "10.0.0.206" did not resolve to a valid DNS name for an EFS mount target. Please refer to the EFS documentation for mounting with DNS names for examples: https://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html
「そんなCNAMEはない」と怒られてしまいました。
ログを確認してみましょう。
$ cat /var/log/amazon/efs/mount.log 2023-07-03 09:21:08 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None} 2023-07-03 09:21:09 UTC - INFO - binding 20326 2023-07-03 09:21:09 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-03 09:21:09 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.20326" 2023-07-03 09:21:09 UTC - INFO - Started TLS tunnel, pid: 25419 2023-07-03 09:21:09 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20326" with 15 sec time limit. 2023-07-03 09:21:24 UTC - ERROR - Mounting fs-0e211df86678573e6.efs.us-east-1.amazonaws.com to /mount/efs failed due to timeout after 15 sec, mount attempt 1/3, wait 0 sec before next attempt. 2023-07-03 09:21:24 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20326" with 15 sec time limit. 2023-07-03 09:21:39 UTC - ERROR - Mounting fs-0e211df86678573e6.efs.us-east-1.amazonaws.com to /mount/efs failed due to timeout after 15 sec, mount attempt 2/3, wait 0 sec before next attempt. 2023-07-03 09:21:39 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20326" 2023-07-03 09:21:53 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs 2023-07-03 09:26:28 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None} 2023-07-03 09:26:28 UTC - INFO - binding 21008 2023-07-03 09:26:28 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-03 09:26:28 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.21008" 2023-07-03 09:26:28 UTC - INFO - Started TLS tunnel, pid: 26031 2023-07-03 09:26:28 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=21008" with 15 sec time limit. 2023-07-03 09:26:28 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs 2023-07-03 09:28:12 UTC - ERROR - The specified CNAME "10.0.0.206" did not resolve to a valid DNS name for an EFS mount target. Please refer to the EFS documentation for mounting with DNS names for examples: https://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html 2023-07-03 09:32:34 UTC - ERROR - The specified CNAME "10.0.0.206" did not resolve to a valid DNS name for an EFS mount target. Please refer to the EFS documentation for mounting with DNS names for examples: https://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html
特に目新しい情報はないですね。
EFSマウントヘルパーのマニュアルを見てみましょう。
# マニュアルをファイルに出力 $ man mount.efs | col -bfx > mount.efs.txt # EFSマウントヘルパーのマニュアル確認 $ cat mount.efs.txt EFS(8) System Manager's Manual EFS(8) NAME mount.efs - Mount helper for using Amazon EFS file systems. SYNOPSIS mount.efs fs-id-or-dns-name mount-point [-o options] DESCRIPTION mount.efs is part of the amazon-efs-utils package, which simplifies using EFS file systems. mount.efs is meant to be used through the mount(8) command for mounting EFS file systems. fs-id-or-dns-name has to be of one of the following two forms: • An EFS filesystem ID in the form of "fs-abcd1234", generated when the file system is created. • A domain name that has a resolvable DNS-CNAME record, which in turn points to a fully-qualified EFS DNS name in the form of "fs-abcd1234.efs.us-east-1.amazonaws.com" or "us-east-1a.fs-abcd1234.efs.us-east-1.amazonaws.com". mount-point is the local directory on which the file system will be mounted. mount.efs automatically applies the following NFS options: nfsvers=4.1 rsize=1048576 wsize=1048576 hard timeo=600 retrans=2 noresvport tls (for Mac distributions) By default, when using the Amazon EFS mount helper with Transport Layer Security (TLS), the mount helper enforces the certificate hostname checking and disables the use of Online Certificate Status Protocol (OCSP). These options can be configured in the config file located at /etc/ama‐ zon/efs/efs-utils.conf. Additionally, the Amazon EFS mount helper has built-in logging for troubleshooting purposes. These logs are located at /var/log/amazon/efs. It is possible to configure your Amazon EC2 instance to automatically remount your Amazon EFS file system when it reboots. For more information, see the online documentation at: https://docs.aws.amazon.com/efs/latest/ug/mount-fs-auto-mount-onreboot.html. OPTIONS -o, Options are specified with a -o flag followed by a comma separated string of options. All of the options specified in nfs(5) are available, in addition to the following EFS-specific options: tls Mounts the EFS file system over TLS. For EC2 instances using Mac distributions, this option is by default passed and the EFS file system is mounted over TLS. notls Mounts the EFS file system without TLS, applies for Mac distributions only. tlsport=n Configure the TLS relay to listen on the specified port. By default, the tlsport is choosing randomly from port range defined in the config file located at /etc/amazon/efs/efs-utils.conf. verify=n Verify TLS certificates using the specified stunnel verify level. For more information, see stunnel(8). ocsp / noocsp Selects whether to perform OCSP validation on TLS certificates, overriding /etc/amazon/efs/efs-utils.conf. By default OCSP is disabled. For more information, see stunnel(8). iam Use the system's IAM identity to authenticate with EFS. The mount helper will try to retrieve the required IAM credentials from the fol‐ lowing locations: the aws credentials URI passed by mount option, the AWS CLI credentials file (~/.aws/credentials), and the AWS CLI config file (~/.aws/config), the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variable, the AssumeRoleWithWebIdentity, the EC2 in‐ stance profile. The first location that has credentials will be used. This option requires the tls option. rolearn Role ARN for IAM authentication with AssumeRoleWithWebIdentity API. jwtpath Identity token for IAM authentication with AssumeRoleWithWebIdentity API. accesspoint Mount the EFS file system using the specified access point. This option requires the tls option. The access point must be in the "avail‐ able" state before it can be used to mount EFS. awsprofile Use the named profile used to lookup IAM credentials in the AWS CLI credentials file (~/.aws/credentials) or AWS CLI config file (~/.aws/config). If botocore is installed, assume the named profile and use the credentials of the assumed profile. If "awsprofile" is not specified, the "default" profile is used. awscredsuri Use the relative uri to lookup IAM credentials from ecs task metadata endpoint. cafile Use the cafile as the stunnel certificate authority file. netns Mount the EFS file system to the specified network namespace. az Mount the EFS file system to the specified availability zone mount target. mountport Use the port 2049 to bypass portmapper daemon on EC2 Mac instances running macOS Big Sur. mounttargetip Mount the EFS file system to the specified mount target ip address. EXAMPLES sudo mount -t efs fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" without encryption of data in transit. sudo mount -t efs -o mounttargetip=192.0.0.1 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" on the mount target that belongs to the file system with address "192.0.0.1" without encryption of data in transit. sudo mount -t efs -o netns=/proc/1/net/ns fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" without encryption of data in transit in given network namespace '/proc/1/net/ns' sudo mount -t efs -o az=us-east-1a fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" to the mount target in availability zone us-east-1a sudo mount -t efs fs-abcd1234:/child /mnt/efs Mount a non-root directory of an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" without encryption of data in transit. sudo mount -t efs -o tls fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" using encryption of data in transit. sudo mount -t efs -o tls,verify=0 fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" using encryption of data in transit and a verify level of 0. sudo mount -t efs -o tls,ocsp fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" using encryption of data in transit and with OCSP vali‐ dation enabled. sudo mount -t efs custom-cname.example.com /mnt/efs Mount an EFS file system using the custom DNS name "custom-cname.example.com" — which has to resolve to a fully-qualified EFS DNS name such as "fs-abcd1234.efs.us-east-1.amazonaws.com" — at mount point "/mnt/efs" without encryption of data in transit. sudo mount -t efs -o tls custom-cname.example.com /mnt/efs Mount an EFS file system using the custom DNS name "custom-cname.example.com" — which has to resolve to a fully-qualified EFS DNS name such as "fs-abcd1234.efs.us-east-1.amazonaws.com" — at mount point "/mnt/efs" using encryption of data in transit. sudo mount -t efs -o tls,iam fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" with encryption of data in transit. The mount helper will authenticate with EFS using the system's IAM identity. sudo mount -t efs -o tls,iam,rolearn="ROLE_ARN",jwtpath="PATH/JWT_TOKEN_FILE" fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" with encryption of data in transit. The mount helper will assume the role "ROLE_ARN" by calling the AssumeRoleWithWebIdentity API with the identity token at "PATH/JWT_TOKEN_FILE". sudo mount -t efs -o tls,iam,awsprofile=test-profile fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" with encryption of data in transit. The mount helper will authenticate with EFS using the system's IAM identity named profile "test profile", for which the credentials are retrieved either from /root/.aws/credentials or /root/.aws/config. If the credentials are not present in the credentials or config files, and there is a "[profile test-profile]" section in the /root/.aws/config file, the mount helper will assume the named profile "test-profile" based on the profile section configuration in root/.aws/config and use the credentials retrieved with botocore to mount (botocore must be pre-installed). sudo mount -t efs -o tls,accesspoint=fsap-12345678 fs-abcd1234 /mnt/efs Mount an EFS file system with file system ID "fs-abcd1234" at mount point "/mnt/efs" with encryption of data in transit. The file system is mounted using the access point "fsap-12345678". FILES /sbin/mount.efs The executable for the Amazon EFS mount helper. /usr/bin/amazon-efs-mount-watchdog The executable for the supervisor process that monitors the network relay. /etc/amazon/efs/efs-utils.conf The configuration file for the Amazon EFS mount helper. /etc/amazon/efs/efs-utils.crt The default Certificate Authority file used by the Amazon EFS mount helper. /etc/init/amazon-efs-mount-watchdog.conf The configuration file for the supervisor process. /var/log/amazon/efs/ The directory where logs for the Amazon EFS mount helper, the stunnel network relay, and the supervisor process are stored. /usr/share/man/man8/mount.efs.8 The man page for the Amazon EFS mount helper. NOTES For more information on using the amazon-efs-utils package, see https://docs.aws.amazon.com/efs/latest/ug/using-amazon-efs-utils.html in the Amazon EFS User Guide. The paths on EC2 MacOS instances are relocated under /usr/local/Cellar/amazon-efs-utils/<version>/libexec directory. SEE ALSO nfs(8), stunnel(8), fstab(5) COPYING Copyright 2017-2018 Amazon.com, Inc. and its affiliates. All Rights Reserved.
例にsudo mount -t efs -o mounttargetip=192.0.0.1 /mnt/efs
とある通り、mounttargetip
をオプションとして指定する必要があるようですね。
試してみましょう。
$ sudo mount -t efs -o tls,iam,mounttargetip=10.0.0.206 /mount/efs mount: /mount/efs: can't find in /etc/fstab. $ sudo mount -t efs -o mounttargetip=10.0.0.206 /mount/efs mount: /mount/efs: can't find in /etc/fstab.
マウントできないですね。
もう少し調べてみると、どうやらマウントターゲットのIPアドレスを指定する際はファイルシステムIDも一緒に指定する必要があるようです。
- マウントターゲット IP アドレスを使用してマウントするには:
sudo mount -t efs -o tls,mounttargetip=mount-target-ip file-system-id efs-mount-point/sudo mount -t efs -o tls,mounttargetip=192.0.2.0 fs-abcd123456789ef0 efs/EFS マウントヘルパーを使用した Amazon EC2 Linux インスタンスをマウントする - Amazon Elastic File System
実際に試してみましょう。
$ sudo mount -t efs -o tls,iam,mounttargetip=10.0.0.206 fs-0e211df86678573e6 /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs/ total 4 -rw-r--r--. 1 root root 0 Jul 3 09:23 test
マウントできましたね。
ログも確認してみましょう。
$ cat /var/log/amazon/efs/mount.log . . (中略) . . 2023-07-03 09:51:17 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None, 'mounttargetip': '10.0.0.206'} 2023-07-03 09:51:17 UTC - INFO - Use the mount target ip address 10.0.0.206 provided in the mount options to mount. 2023-07-03 09:51:17 UTC - INFO - binding 20597 2023-07-03 09:51:17 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-03 09:51:17 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.20597" 2023-07-03 09:51:17 UTC - INFO - Started TLS tunnel, pid: 27191 2023-07-03 09:51:17 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20597" with 15 sec time limit. 2023-07-03 09:51:17 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs
マウントターゲットのIPアドレスが確かに指定されていることが分かります。
EFSファイルシステムのDNS名のCNAMEレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウント
次に、EFSファイルシステムのDNS名のCNAMEレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウントします。
まず、名前解決できることを確認します。
$ dig efs-cname.corp.non-97 +short fs-0e211df86678573e6.efs.us-east-1.amazonaws.com. 10.0.0.206
名前解決できますね。
# EFSファイルシステムのDNS名のCNAMEレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウント $ sudo mount -t efs -o tls,iam efs-cname.corp.non-97 /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs/ total 4 -rw-r--r--. 1 root root 0 Jul 3 09:23 test # マウント時のログ確認 $ tail /var/log/amazon/efs/mount.log 2023-07-03 09:51:17 UTC - INFO - Started TLS tunnel, pid: 27191 2023-07-03 09:51:17 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20597" with 15 sec time limit. 2023-07-03 09:51:17 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs 2023-07-03 10:00:42 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None} 2023-07-03 10:00:42 UTC - INFO - binding 20752 2023-07-03 10:00:42 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-03 10:00:42 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.20752" 2023-07-03 10:00:42 UTC - INFO - Started TLS tunnel, pid: 27786 2023-07-03 10:00:42 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20752" with 15 sec time limit. 2023-07-03 10:00:42 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs
問題なくマウントできました。
ログを確認したところ、ファイルシステムのDNS名を認識しているようですね。
マウントターゲットのIPアドレスのAレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウント
続いて、マウントターゲットのIPアドレスのAレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウントします。
まず、名前解決できることを確認します。
$ dig efs-a.corp.non-97 +short 10.0.0.206
名前解決できますね。
# マウントターゲットのIPアドレスのAレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウント $ sudo mount -t efs -o tls,iam efs-cname.corp.non-97 /mount/efs $ sudo mount -t efs -o tls,iam efs-a.corp.non-97 /mount/efs The specified CNAME "efs-a.corp.non-97" did not resolve to a valid DNS name for an EFS mount target. Please refer to the EFS documentation for mounting with DNS namesfor examples: https://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html
「そんなCNAMEは名前解決できない」と怒られてしまいました。
ファイルシステムのDNS名以外のAレコードをDNS名として指定することはできないようですね。
ちなみに、EFSマウントヘルパーを使わずに普通にNFSv4でマウントする場合は、問題なくマウントできます。
$ sudo mount -t nfs4 efs-a.corp.non-97:/ /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on efs-a.corp.non-97:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs total 4 -rw-r--r--. 1 root root 0 Jul 3 09:23 test
マウントターゲットのIPアドレスのAレコードであるカスタムドメインとファイルシステムIDを指定してEFSマウントヘルパーでマウント
どうにかして対応する方法はないものかと思ったので、EFSマウントヘルパーのソースコードを覗いてみます。
The specified CNAME xxx did not resolve to a valid DNS name for an EFS mount target
というメッセージを出力している箇所を探すとmatch_device()
というEFSファイルシステムのIDとパス、AZを返す関数がありました。
def match_device(config, device, options): """Return the EFS id, the remote path, and the az to mount""" try: remote, path = device.split(":", 1) except ValueError: remote = device path = "/" if FS_ID_RE.match(remote): return remote, path, None try: primary, secondaries, _ = socket.gethostbyname_ex(remote) hostnames = list(filter(lambda e: e is not None, [primary] + secondaries)) except socket.gaierror: create_default_cloudwatchlog_agent_if_not_exist(config, options) fatal_error( 'Failed to resolve "%s" - check that the specified DNS name is a CNAME record resolving to a valid EFS DNS ' "name" % remote, 'Failed to resolve "%s"' % remote, ) if not hostnames: create_default_cloudwatchlog_agent_if_not_exist(config, options) fatal_error( 'The specified domain name "%s" did not resolve to an EFS mount target' % remote ) for hostname in hostnames: efs_fqdn_match = EFS_FQDN_RE.match(hostname) if efs_fqdn_match: az = efs_fqdn_match.group("az") fs_id = efs_fqdn_match.group("fs_id") if az and "az" in options and az != options["az"]: fatal_error( 'The hostname "%s" resolved by the specified domain name "%s" does not match the az provided in the ' "mount options, expected = %s, given = %s" % (hostname, remote, options["az"], az) ) expected_dns_name, _ = get_dns_name_and_fallback_mount_target_ip_address( config, fs_id, add_field_in_options(options, "az", az) ) # check that the DNS name of the mount target matches exactly the DNS name the CNAME resolves to if hostname == expected_dns_name: return fs_id, path, az else: create_default_cloudwatchlog_agent_if_not_exist(config, options) fatal_error( 'The specified CNAME "%s" did not resolve to a valid DNS name for an EFS mount target. ' "Please refer to the EFS documentation for mounting with DNS names for examples: %s" % ( remote, "https://docs.aws.amazon.com/efs/latest/ug/mounting-fs-mount-cmd-dns-name.html", ) )
DNS名がEFS_FQDN_RE
とマッチしない場合は上述のエラー分のステートに遷移するようですね。
ちなみにFS_ID_RE
やEFS_FQDN_RE
は以下の通り、ファイルシステムのIDやファイルシステムのDNS名の正規表現です。
FS_ID_RE = re.compile("^(?P<fs_id>fs-[0-9a-f]+)$") EFS_FQDN_RE = re.compile( r"^((?P<az>[a-z0-9-]+)\.)?(?P<fs_id>fs-[0-9a-f]+)\.efs\." r"(?P<region>[a-z0-9-]+)\.(?P<dns_name_suffix>[a-z0-9.]+)$" )
match_device()
を呼び出しているのはparse_arguments()
です。
def parse_arguments(config, args=None): """Parse arguments, return (fsid, path, mountpoint, options)""" if args is None: args = sys.argv fsname = None mountpoint = None options = {} if not check_if_platform_is_mac(): if len(args) > 1: fsname = args[1] if len(args) > 2: mountpoint = args[2] if len(args) > 4 and "-o" in args[:-1]: options_index = args.index("-o") + 1 options = parse_options(args[options_index]) else: if len(args) > 1: fsname = args[-2] if len(args) > 2: mountpoint = args[-1] if len(args) > 4 and "-o" in args[:-2]: for arg in args[1:-2]: if arg != "-o": options.update(parse_options(arg)) if not fsname or not mountpoint: usage(out=sys.stderr) # We treat az as an option when customer is using dns name of az mount target to mount, # even if they don't provide az with option, we update the options with that info fs_id, path, az = match_device(config, fsname, options) return fs_id, path, mountpoint, add_field_in_options(options, "az", az)
そして、parse_arguments()
はmain()
で呼び出されています。
def main(): parse_arguments_early_exit() assert_root() config = read_config() bootstrap_logging(config) if check_if_platform_is_mac() and not check_if_mac_version_is_supported(): fatal_error( "We do not support EFS on MacOS Kernel version " + platform.release() ) fs_id, path, mountpoint, options = parse_arguments(config) logging.info("version=%s options=%s", VERSION, options) global CLOUDWATCHLOG_AGENT CLOUDWATCHLOG_AGENT = bootstrap_cloudwatch_logging(config, options, fs_id) check_unsupported_options(options) check_options_validity(options) init_system = get_init_system() check_network_status(fs_id, init_system) dns_name, fallback_ip_address = get_dns_name_and_fallback_mount_target_ip_address( config, fs_id, options ) if check_if_platform_is_mac() and "notls" not in options: options["tls"] = None if "tls" in options: mount_tls( config, init_system, dns_name, path, fs_id, mountpoint, options, fallback_ip_address=fallback_ip_address, ) else: mount_nfs( config, dns_name, path, mountpoint, options, fallback_ip_address=fallback_ip_address, ) if "__main__" == __name__: main()
では、マウントターゲットのIPアドレスが指定された場合の検証はどこでしているのかというと、get_dns_name_and_fallback_mount_target_ip_address()
で行われています。
def get_dns_name_and_fallback_mount_target_ip_address(config, fs_id, options): def _validate_replacement_field_count(format_str, expected_ct): if format_str.count("{") != expected_ct or format_str.count("}") != expected_ct: raise ValueError( "DNS name format has an incorrect number of replacement fields" ) dns_name_format = config.get(CONFIG_SECTION, "dns_name_format") if "{fs_id}" not in dns_name_format: raise ValueError("DNS name format must include {fs_id}") format_args = {"fs_id": fs_id} expected_replacement_field_ct = 1 if "{az}" in dns_name_format: az = options.get("az") if az: expected_replacement_field_ct += 1 format_args["az"] = az else: dns_name_format = dns_name_format.replace("{az}.", "") if "{region}" in dns_name_format: expected_replacement_field_ct += 1 format_args["region"] = get_target_region(config) if "{dns_name_suffix}" in dns_name_format: expected_replacement_field_ct += 1 config_section = CONFIG_SECTION region = format_args.get("region") if region: config_section = get_config_section(config, region) format_args["dns_name_suffix"] = config.get(config_section, "dns_name_suffix") logging.debug( "Using dns_name_suffix %s in config section [%s]", format_args.get("dns_name_suffix"), config_section, ) _validate_replacement_field_count(dns_name_format, expected_replacement_field_ct) dns_name = dns_name_format.format(**format_args) if "mounttargetip" in options: ip_address = options.get("mounttargetip") logging.info( "Use the mount target ip address %s provided in the mount options to mount." % ip_address ) try: mount_target_ip_address_can_be_resolved( ip_address, passed_via_options=True, network_namespace=options.get("netns") if "netns" in options else None, ) return dns_name, options.get("mounttargetip") except FallbackException as e: fallback_message = e.message throw_ip_address_connect_failure_with_fallback_message( ip_address=ip_address, fallback_message=fallback_message ) if dns_name_can_be_resolved(dns_name): return dns_name, None logging.info( "Failed to resolve %s, attempting to lookup mount target ip address using botocore.", dns_name, ) try: fallback_mount_target_ip_address = get_fallback_mount_target_ip_address( config, options, fs_id, dns_name ) logging.info( "Found fall back mount target ip address %s for file system %s", fallback_mount_target_ip_address, fs_id, ) return dns_name, fallback_mount_target_ip_address except FallbackException as e: fallback_message = e.message throw_dns_resolve_failure_with_fallback_message(dns_name, fallback_message)
mount_target_ip_address_can_be_resolved()
で解決できた場合、マウントターゲットのIPアドレスをDNS名のフォールバック用のIPアドレスとして返すようですね。
mount_target_ip_address_can_be_resolved()
では、mount_target_ip_address
に対して到達可能かどうかチェックしているようです。
def mount_target_ip_address_can_be_resolved( mount_target_ip_address, passed_via_options=False, network_namespace=None ): tries = 3 for attempt in range(tries): try: # Open a socket connection to mount target nfs port to verify that the mount target can be connected if not network_namespace: s = socket.create_connection((mount_target_ip_address, 2049), timeout=2) else: with NetNS(nspath=network_namespace): s = socket.create_connection( (mount_target_ip_address, 2049), timeout=2 ) s.close() return True except socket.timeout: if attempt < tries - 1: message = ( "The ip address %s cannot be connected yet, sleep 0.5s, %s retry time(s) left" % (mount_target_ip_address, tries - attempt - 1) ) logging.warning(message) time.sleep(0.5) continue else: raise FallbackException( "Connection to the mount target IP address %s timeout. Please retry in 5 minutes if the " "mount target is newly created. Otherwise check your VPC and security group " "configuration to ensure your file system is reachable via TCP port 2049 from your " "instance." % mount_target_ip_address ) except Exception as e: hint_message = ( " Please check if the mount target ip address passed via mount option is correct." if passed_via_options else "" ) raise FallbackException( "Unknown error when connecting to mount target IP address %s, %s.%s" % (mount_target_ip_address, e, hint_message) )
実際にマウント処理はmount_tls()
やmount_nfs()
で行われます。これら関数の引数にはDNS名を必ず指定する必要があります。そのため、mounttargetip=mount-target-ip
のみを指定するのはよろしくないということですね。
ちなみに、フォールバック用のIPアドレスと言いつつ、fallback_ip_address
が存在する場合はDNS名ではなく、fallback_ip_address
に対してTLSのトンネルを掘ったり、接続をしたりしています。
def write_stunnel_config_file( config, state_file_dir, fs_id, mountpoint, tls_port, dns_name, verify_level, ocsp_enabled, options, region, log_dir=LOG_DIR, cert_details=None, fallback_ip_address=None, ): """ Serializes stunnel configuration to a file. Unfortunately this does not conform to Python's config file format, so we have to hand-serialize it. """ stunnel_options = get_stunnel_options() mount_filename = get_mount_specific_filename(fs_id, mountpoint, tls_port) system_release_version = get_system_release_version() global_config = dict(STUNNEL_GLOBAL_CONFIG) if is_stunnel_option_supported( stunnel_options, b"foreground", b"quiet", emit_warning_log=False ): # Do not log to stderr of subprocess in addition to the destinations specified with syslog and output. # Only support in stunnel version 5.25+. global_config["foreground"] = "quiet" if any( release in system_release_version for release in SKIP_NO_SO_BINDTODEVICE_RELEASES ): global_config["socket"].remove("a:SO_BINDTODEVICE=lo") if get_boolean_config_item_value( config, CONFIG_SECTION, "stunnel_debug_enabled", default_value=False ): global_config["debug"] = "debug" # If the stunnel debug is enabled, we also redirect stunnel log to stderr to capture any error while launching # the stunnel. global_config["foreground"] = "yes" if config.has_option(CONFIG_SECTION, "stunnel_logs_file"): global_config["output"] = config.get( CONFIG_SECTION, "stunnel_logs_file" ).replace("{fs_id}", fs_id) else: global_config["output"] = os.path.join( log_dir, "%s.stunnel.log" % mount_filename ) global_config["pid"] = os.path.join( state_file_dir, mount_filename + "+", "stunnel.pid" ) if get_fips_config(config): global_config["fips"] = "yes" efs_config = dict(STUNNEL_EFS_CONFIG) efs_config["accept"] = efs_config["accept"] % tls_port if fallback_ip_address: efs_config["connect"] = efs_config["connect"] % fallback_ip_address else: efs_config["connect"] = efs_config["connect"] % dns_name . . (以下略) . .
def mount_nfs(config, dns_name, path, mountpoint, options, fallback_ip_address=None): if "tls" in options: mount_path = "127.0.0.1:%s" % path elif fallback_ip_address: mount_path = "%s:%s" % (fallback_ip_address, path) else: mount_path = "%s:%s" % (dns_name, path) . . (以下略) . .
試しにマウントターゲットのIPアドレスのAレコードであるカスタムドメインとファイルシステムIDを指定してEFSマウントヘルパーでマウントできるか試してみましょう。
$ sudo mount -t efs -o tls,iam,mounttargetip=efs-a.corp.non-97 fs-0e211df86678573e6 /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs total 4 $ tail /var/log/amazon/efs/mount.log 2023-07-03 10:07:11 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs 2023-07-03 20:42:12 UTC - ERROR - Failed to resolve "mounttargetip=efs-a.corp.non-97" 2023-07-03 20:43:30 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None, 'mounttargetip': 'efs-a.corp.non-97'} 2023-07-03 20:43:30 UTC - INFO - Use the mount target ip address efs-a.corp.non-97 provided in the mount options to mount. 2023-07-03 20:43:30 UTC - INFO - binding 20675 2023-07-03 20:43:30 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-03 20:43:30 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.20675" 2023-07-03 20:43:30 UTC - INFO - Started TLS tunnel, pid: 1933 2023-07-03 20:43:30 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20675" with 15 sec time limit. 2023-07-03 20:43:31 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs
マウントできましたね。
自身のIPアドレスをマウントターゲットIPアドレスとして指定した際もマウントできるのか確認しましょう。
下準備としてNFSサーバーの設定をして、起動させます。
# エクスポート設定が存在しないことを確認 $ ls -l /etc/exports.d/ total 0 # エクスポート設定の追加 $ sudo vi /etc/exports.d/export-nfs.exports # / をエクスポートする設定が追加されたことを確認 $ cat /etc/exports.d/export-nfs.exports / *(rw,no_root_squash) # エクスポート設定の反映 $ sudo exportfs -ar # エクスポート設定が反映されたことを確認 $ sudo exportfs -v / <world>(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash) # NFSサーバーのサービス起動 $ sudo systemctl start nfs-server # NFSサーバーが起動できていることを確認 $ systemctl status nfs-server ● nfs-server.service - NFS server and services Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled; preset: disabled) Active: active (exited) since Tue 2023-07-04 01:35:22 UTC; 12s ago Process: 3577 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS) Process: 3578 ExecStart=/usr/sbin/rpc.nfsd (code=exited, status=0/SUCCESS) Process: 3595 ExecStart=/bin/sh -c if systemctl -q is-active gssproxy; then systemctl reload gssproxy ; fi (code=exited, status=0/SUCCESS) Main PID: 3595 (code=exited, status=0/SUCCESS) CPU: 28ms Jul 04 01:35:22 ip-10-0-0-23.ec2.internal systemd[1]: Starting nfs-server.service - NFS server and services... Jul 04 01:35:22 ip-10-0-0-23.ec2.internal rpc.nfsd[3578]: rpc.nfsd: Unable to request RDMA services: Protocol not supported Jul 04 01:35:22 ip-10-0-0-23.ec2.internal systemd[1]: Finished nfs-server.service - NFS server and services.
起動後、NFSでマウントできることを確認します。
$ sudo mount -t nfs4 127.0.0.1:/ /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0G 2.2G 5.8G 28% /mount/efs $ ls -l /mount/efs/ total 32 lrwxrwxrwx. 1 root root 7 Jan 30 02:31 bin -> usr/bin dr-xr-xr-x. 5 root root 16384 Jun 28 15:33 boot drwxr-xr-x. 3 root root 136 Jun 28 15:33 dev drwxr-xr-x. 79 root root 16384 Jul 3 09:20 etc drwxr-xr-x. 3 root root 22 Jul 3 09:06 home lrwxrwxrwx. 1 root root 7 Jan 30 02:31 lib -> usr/lib lrwxrwxrwx. 1 root root 9 Jan 30 02:31 lib64 -> usr/lib64 drwxr-xr-x. 2 root root 6 Jun 28 15:31 local drwxr-xr-x. 2 root root 6 Jan 30 02:31 media drwxr-xr-x. 2 root root 6 Jan 30 02:31 mnt drwxr-xr-x. 3 root root 17 Jul 3 09:20 mount drwxr-xr-x. 3 root root 17 Jun 28 15:32 opt drwxr-xr-x. 2 root root 6 Jun 28 15:31 proc dr-xr-x---. 3 root root 119 Jul 4 01:40 root drwxr-xr-x. 2 root root 6 Jun 28 15:33 run lrwxrwxrwx. 1 root root 8 Jan 30 02:31 sbin -> usr/sbin drwxr-xr-x. 2 root root 6 Jan 30 02:31 srv drwxr-xr-x. 2 root root 6 Jun 28 15:31 sys drwxrwxrwt. 2 root root 6 Jun 28 15:31 tmp drwxr-xr-x. 12 root root 144 Jun 28 15:32 usr drwxr-xr-x. 19 root root 266 Jul 3 09:06 var
NFSで自身の/
をマウントできることを確認できました。
それでは、IPアドレスをマウントターゲットIPアドレスとしてEFSマウントヘルパーでマウントしてみます。
$ sudo mount -t efs -o tls,iam,mounttargetip=127.0.0.1 fs-0e211df86678573e6 /mount/efs Mount attempt 1/3 failed due to timeout after 15 sec, wait 0 sec before next attempt. Mount attempt 2/3 failed due to timeout after 15 sec, wait 0 sec before next attempt. ^CTraceback (most recent call last): File "/sbin/mount.efs", line 3811, in <module> [ec2-user@ip-10-0-0-23 ~]$ main() File "/sbin/mount.efs", line 3789, in main mount_tls( File "/sbin/mount.efs", line 2935, in mount_tls mount_nfs(config, dns_name, path, mountpoint, options) File "/sbin/mount.efs", line 1801, in mount_nfs out, err = proc.communicate() File "/usr/lib64/python3.9/subprocess.py", line 1134, in communicate stdout, stderr = self._communicate(input, endtime, timeout) File "/usr/lib64/python3.9/subprocess.py", line 1979, in _communicate ready = selector.select(timeout) File "/usr/lib64/python3.9/selectors.py", line 416, in select fd_event_list = self._selector.poll(timeout) KeyboardInterrupt ^C $ tail -n11 /var/log/amazon/efs/mount.log 2023-07-04 02:04:43 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None, 'mounttargetip': '127.0.0.1'} 2023-07-04 02:04:43 UTC - INFO - Use the mount target ip address 127.0.0.1 provided in the mount options to mount. 2023-07-04 02:04:43 UTC - INFO - binding 20715 2023-07-04 02:04:43 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-04 02:04:43 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.20715" 2023-07-04 02:04:43 UTC - INFO - Started TLS tunnel, pid: 623531 2023-07-04 02:04:44 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20715" with 15 sectime limit. 2023-07-04 02:04:59 UTC - ERROR - Mounting fs-0e211df86678573e6.efs.us-east-1.amazonaws.com to /mount/efs failed due to timeout after 15 sec, mount attempt 1/3, wait 0 sec before next attempt. 2023-07-04 02:04:59 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20715" with 15 sectime limit. 2023-07-04 02:05:14 UTC - ERROR - Mounting fs-0e211df86678573e6.efs.us-east-1.amazonaws.com to /mount/efs failed due to timeout after 15 sec, mount attempt 2/3, wait 0 sec before next attempt. 2023-07-04 02:05:14 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20715"
なかなかマウントが進まなかったので、途中でCtrl + C
でキャンセルしてしまいましたが、ファイルシステムIDfs-0e211df86678573e6
のマウントターゲットのIPアドレスとして127.0.0.1
に接続しようとしたのがログから確認できます。
続いて、ファイルシステムのIDを適当なものにした場合もマウントできるか確認します。
$ sudo mount -t efs -o tls,iam,mounttargetip=efs-a.corp.non-97 fs-0e211df86678573ex /mount/efs Failed to resolve "fs-0e211df86678573ex" - check that the specified DNS name is a CNAME record resolving to a valid EFS DNS name
ファイルシステムIDを使った名前解決ができず、怒られてしまいました。
ファイルシステムIDの正規表現は^(?Pfs-[0-9a-f]+)$
とx
は含まれないようです。正規表現に当てはまるようなファイルシステムIDに修正して接続します。
$ sudo mount -t efs -o tls,iam,mounttargetip=efs-a.corp.non-97 fs-0e211df86678573ea /mount/efs b'mount.nfs4: access denied by server while mounting 127.0.0.1:/' $ tail /var/log/amazon/efs/mount.log 2023-07-04 02:08:59 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs 2023-07-04 02:09:15 UTC - ERROR - Failed to resolve "fs-0e211df86678573ex" 2023-07-04 04:43:57 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None, 'mounttargetip': 'efs-a.corp.non-97'} 2023-07-04 04:43:57 UTC - INFO - Use the mount target ip address efs-a.corp.non-97 provided in the mount options to mount. 2023-07-04 04:43:57 UTC - INFO - binding 20473 2023-07-04 04:43:57 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-04 04:43:57 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573ea.mount.efs.20473" 2023-07-04 04:43:57 UTC - INFO - Started TLS tunnel, pid: 2113 2023-07-04 04:43:58 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20473" with 15 sectime limit. 2023-07-04 04:43:58 UTC - ERROR - Failed to mount fs-0e211df86678573ea.efs.us-east-1.amazonaws.com at /mount/efs: returncode=32, stderr="b'mount.nfs4: access denied by server while mounting 127.0.0.1:/'"
エラーメッセージが変わりましたね。
おそらく、IAM認証だと認証先のEFSファイルシステムがそもそも存在しないため接続のだと考えます。
IAM認証を行わず接続します。
$ sudo mount -t efs -o tls,mounttargetip=efs-a.corp.non-97 fs-0e211df86678573ea /mount/efs $ tail /var/log/amazon/efs/mount.log 2023-07-04 04:43:58 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20473" with 15 sectime limit. 2023-07-04 04:43:58 UTC - ERROR - Failed to mount fs-0e211df86678573ea.efs.us-east-1.amazonaws.com at /mount/efs: returncode=32, stderr="b'mount.nfs4: access denied by server while mounting 127.0.0.1:/'" 2023-07-04 04:44:27 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'mounttargetip': 'efs-a.corp.non-97'} 2023-07-04 04:44:27 UTC - INFO - Use the mount target ip address efs-a.corp.non-97 provided in the mount options to mount. 2023-07-04 04:44:27 UTC - INFO - binding 20372 2023-07-04 04:44:27 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-04 04:44:27 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573ea.mount.efs.20372" 2023-07-04 04:44:27 UTC - INFO - Started TLS tunnel, pid: 2170 2023-07-04 04:44:27 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20372" with 15 sectime limit. 2023-07-04 04:44:27 UTC - INFO - Successfully mounted fs-0e211df86678573ea.efs.us-east-1.amazonaws.com at /mount/efs
はい、マウントできました。
ファイルシステムIDの正規表現さえ合っていれば、存在しないファイルシステムIDであってもTLS接続はできることを確認できました。
VPC BのEC2インスタンスからマウント
ファイルシステムIDを指定してEFSマウントヘルパーでマウント
続いて、EFSファイルシステムとは別のVPC上のEC2インスタンスからマウントします。
まず、ファイルシステムIDを指定してEFSマウントヘルパーでマウントしてみます。
# マウントポイントの作成 $ sudo mkdir -p /mount/efs $ sudo mount -t efs -o tls,iam fs-0e211df86678573e6 /mount/efs Failed to resolve "fs-0e211df86678573e6.efs.us-east-1.amazonaws.com" - check that your file system ID is correct, and ensure that the VPC has an EFS mount target for this file system ID. See https://docs.aws.amazon.com/console/efs/mount-dns-name for more detail. Attempting to lookup mount target ip address using botocore. Failed to import necessary dependency botocore, please install botocore first.
はい、怒られました。
ファイルシステムのIDからDNS名を生成し、そのDNS名を名前解決しようとしたが失敗したようです。
マウントターゲットのIPアドレスを指定してEFSマウントヘルパーでマウント
マウントターゲットのIPアドレスを指定してEFSマウントヘルパーでマウントします。
$ sudo mount -t efs -o tls,iam,mounttargetip=10.0.0.206 fs-0e211df86678573e6 /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs total 4 $ cat /var/log/amazon/efs/mount.log 2023-07-03 10:13:48 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None} 2023-07-03 10:13:48 UTC - INFO - Failed to resolve fs-0e211df86678573e6.efs.us-east-1.amazonaws.com, attempting to lookup mount target ip address using botocore. 2023-07-03 10:13:48 UTC - ERROR - Failed to resolve "fs-0e211df86678573e6.efs.us-east-1.amazonaws.com" - check that your file system ID is correct, and ensure that the VPC has an EFS mount target for this file system ID. See https://docs.aws.amazon.com/console/efs/mount-dns-name for more detail. Attempting to lookup mount target ip address using botocore. Failed to import necessary dependency botocore, please install botocore first. 2023-07-03 10:15:38 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None, 'mounttargetip': '10.0.0.206'} 2023-07-03 10:15:38 UTC - INFO - Use the mount target ip address 10.0.0.206 provided in the mount options to mount. 2023-07-03 10:15:38 UTC - INFO - binding 20528 2023-07-03 10:15:39 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-03 10:15:39 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.20528" 2023-07-03 10:15:39 UTC - INFO - Started TLS tunnel, pid: 26810 2023-07-03 10:15:39 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20528" with 15 sec time limit. 2023-07-03 10:15:39 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs
マウントできましたね。
マウントターゲットのIPアドレスとファイルシステムIDが分かっていれば別VPCからでもEFSマウントヘルパーでマウントできることが分かりました。
EFSファイルシステムのDNS名のCNAMEレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウント
EFSファイルシステムのDNS名のCNAMEレコードであるカスタムドメインを指定してEFSマウントヘルパーでマウントします。
以下のようにそもそも名前解決ができないので、望み薄ですが念のため確認します。
$ dig efs-cname.corp.non-97 +short fs-0e211df86678573e6.efs.us-east-1.amazonaws.com. $ dig fs-0e211df86678573e6.efs.us-east-1.amazonaws.com. +short
実行結果は以下の通りです。
$ sudo mount -t efs -o tls,iam efs-cname.corp.non-97 /mount/efs Failed to resolve "efs-cname.corp.non-97" - check that the specified DNS name is a CNAME record resolving to a valid EFS DNS name
やはり名前解決できないと怒られました。
マウントターゲットのIPアドレスのAレコードであるカスタムドメインとファイルシステムIDを指定してEFSマウントヘルパーでマウント
最後にマウントターゲットのIPアドレスのAレコードであるカスタムドメインとファイルシステムIDを指定してEFSマウントヘルパーでマウントしてみます。
$ sudo mount -t efs -o tls,iam,mounttargetip=efs-a.corp.non-97 fs-0e211df86678573e6 /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs total 4 -rw-r--r--. 1 root root 0 Jul 3 09:23 test $ tail /var/log/amazon/efs/mount.log 2023-07-03 20:49:34 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20468" with 15 sectime limit. 2023-07-03 20:49:35 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs 2023-07-04 02:59:54 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None, 'mounttargetip': 'efs-a.corp.non-97'} 2023-07-04 02:59:54 UTC - INFO - Use the mount target ip address efs-a.corp.non-97 provided in the mount options to mount. 2023-07-04 02:59:54 UTC - INFO - binding 20389 2023-07-04 02:59:54 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-04 02:59:54 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573e6.mount.efs.20389" 2023-07-04 02:59:54 UTC - INFO - Started TLS tunnel, pid: 1822 2023-07-04 02:59:54 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20389" with 15 sectime limit. 2023-07-04 02:59:54 UTC - INFO - Successfully mounted fs-0e211df86678573e6.efs.us-east-1.amazonaws.com at /mount/efs
マウントできました。
おまけでファイルシステムのIDを適当なものにした場合をマウントできるか試します。
$ sudo mount -t efs -o tls,iam,mounttargetip=efs-a.corp.non-97 fs-0e211df86678573ea /mount/efs b'mount.nfs4: access denied by server while mounting 127.0.0.1:/' $ tail /var/log/amazon/efs/mount.log 2023-07-04 04:38:34 UTC - INFO - Use the mount target ip address efs-a.corp.non-97 provided in the mount options to mount. 2023-07-04 04:38:34 UTC - WARNING - /mount/efs is already mounted, mount aborted 2023-07-04 04:38:43 UTC - INFO - version=1.35.0 options={'rw': None, 'tls': None, 'iam': None, 'mounttargetip': 'efs-a.corp.non-97'} 2023-07-04 04:38:43 UTC - INFO - Use the mount target ip address efs-a.corp.non-97 provided in the mount options to mount. 2023-07-04 04:38:43 UTC - INFO - binding 20656 2023-07-04 04:38:43 UTC - WARNING - stunnel does not support "b'libwrap'" 2023-07-04 04:38:43 UTC - INFO - Starting TLS tunnel: "/usr/bin/stunnel /var/run/efs/stunnel-config.fs-0e211df86678573ea.mount.efs.20656" 2023-07-04 04:38:43 UTC - INFO - Started TLS tunnel, pid: 2430 2023-07-04 04:38:43 UTC - INFO - Executing: "/sbin/mount.nfs4 127.0.0.1:/ /mount/efs -o rw,nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport,port=20656" with 15 sectime limit. 2023-07-04 04:38:43 UTC - ERROR - Failed to mount fs-0e211df86678573ea.efs.us-east-1.amazonaws.com at /mount/efs: returncode=32, stderr="b'mount.nfs4: access denied by server while mounting 127.0.0.1:/'"
やはりIAM認証だと認証先のEFSファイルシステムがそもそも存在しないので接続できなそうですね。
IAM認証を行わずに接続してみます。
$ sudo mount -t efs -o tls,mounttargetip=efs-a.corp.non-97 fs-0e211df86678573ea /mount/efs $ df -hT -t nfs4 Filesystem Type Size Used Avail Use% Mounted on 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /mount/efs $ ls -l /mount/efs total 4 -rw-r--r--. 1 root root 0 Jul 3 09:23 test
はい、こちらはマウントできました。
カスタムドメインで接続できるけれども
Amazon EFSのカスタムドメインにEFSマウントヘルパーを使ってマウントできるのか確認してみました。
カスタムドメインを使ってEFSマウントヘルパーを使ってマウントは可能ですが、結局のところファイルシステムIDを指定する必要があるというのがネックですね。
移行などで、「DNSレコードを変更するだけで違うEFSファイルシステムに振り分けるようにする」といったことは出来ないと考えます。併せてファイルシステムIDの変更も行う必要があるためです。
加えて、カスタムドメインを使う場合 = マウントターゲットを指定しまうことになるため、マウント元のAZと同じAZのマウントターゲットを自動で判別して接続してれなくなります。
もし、「カスタムドメインを使いたい。でも、AZを跨ぐレイテンシーや料金が気になる。」のであれば、マウントターゲット毎にカスタムドメインを用意する必要があると考えます。
カスタムドメインを使ってEFSマウントヘルパーを使いたい場面としては、別VPCからアクセスする時でしょうか。ただし、わざわざカスタムドメインを用意せずにマウントターゲットのIPアドレスを指定する形でも良いかなと考えます。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!