#author("2024-09-30T09:34:04+00:00","default:wikiadmin","wikiadmin") #author("2024-09-30T09:37:12+00:00","default:wikiadmin","wikiadmin") #contents *EC2 概要 [#qd362611] サーバーインスタンスだが、他のサービスもEC2ベースとしており、AWSの基本中の基本サービス。 *構成要素 [#la0054b2] |EC2|サーバー本体| |EBS|ディスク| |ENI|ネットワークインターフェース。1つのEC2に複数アタッチ可能だが、最初のENIのIPは固定になるので、作成時に指定し忘れるとDHCPの割当となる。なおEC2からデタッチして、別のEC2にあタッチできる(IPの引き継ぎ)| **EC2 ライフサイクル [#j3d29ec5] 起動、停止、terminateは削除なので間違わないように **Userdata [#s568c7da] インストール後に実行するコマンド。terraformに渡すにはbase64エンコードして設定する必要がある。 #!/bin/bashは必要でないと動かない&sudo不要 sudo yum install -y java-1.8.0-openjdk-devel -JSTにしてSSHポートを10022に変更する例(AmazonLinux3ではポート変更失敗) #!/bin/bash # set hostname hostnamectl set-hostname ec2host # UTC to JST cp /usr/share/zoneinfo/Japan /etc/localtime sed -i 's|^ZONE=[a-zA-Z0-9\.\-\"]*$|ZONE="Asia/Tokyo"|g' /etc/sysconfig/clock echo "LANG=ja_JP.UTF-8" > /etc/sysconfig/i18n # change ssh port /bin/sed -i -e 's/^#Port 22$/Port 1022/' /etc/ssh/sshd_config service sshd restart -docker (amazon linux 2023) sudo dnf install -y docker sudo systemctl enable --now docker DOCKER_CONFIG=${DOCKER_CONFIG:-/usr/local/lib/docker} sudo mkdir -p $DOCKER_CONFIG/cli-plugins sudo curl -SL https://github.com/docker/compose/releases/download/v2.17.3/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose #ElasticSearch sudo sh -c 'echo "vm.max_map_count = 262144" >> /etc/sysctl.d/90_sonarqube.conf' sudo sysctl --system # other tools sudo yum install -y git tmux # swap sudo dd if=/dev/zero of=/swap bs=1M count=2048 sudo chmod 600 /swap sudo mkswap /swap sudo swapon /swap sudo sh -c 'echo "/swap none swap defaults 0 0" >> /etc/fstab' # goofys sudo dnf install -y fuse curl -L https://github.com/kahing/goofys/releases/latest/download/goofys -o /usr/local/bin/goofys chmod +x /usr/local/bin/goofys yum update -y sudo yum install -y git sudo yum install -y nodejs sudo yum install -y mariadb105-server-utils sudo yum install -y java-11-amazon-corretto sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo sudo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key sudo yum install -y jenkins sudo yum install -y httpd sudo systemctl start jenkins # npm curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash - sudo yum install -y --enablerepo=nodesource nodejs ***node 20 [#g4747388] sudo dnf install -y nodejs20.x86_64 sudo dnf install -y git sudo dnf install -y mariadb105-server-utils ***ubuntu jenkins [#b755b0c3] sudo apt update sudo apt install -y openjdk-8-jdk sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' sudo apt update sudo apt-get install -y jenkins **DNATを作成 [#x0796c21] -ポートが開放されていないときにhttpのポートを利用して、接続する方法。 まずはSGを開放する。 #!/bin/bash sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward" sudo sh -c "echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects" sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 目的のIP:目的のポート sudo iptables -t nat -A POSTROUTING -j MASQUERADE sudo service iptables save **MySQLクライアントインストール [#k7a7e31f] *cli [#za97f3c1] -特定のタグがあるものを抽出(値は何でも良い) aws ec2 describe-instances --filters "Name=tag:Group,Values=*" | jq -r '[.Reservations[].Instances[] | .InstanceId] | join(" ")' -タグで絞ってInstanceId取得(NameならばGroupのところをNameに変更) aws ec2 describe-instances --filters "Name=tag:Group,Values=blue" | jq -r .Reservations[].Instances[].InstanceId -Stoppedのインスタンスを取得 aws ec2 describe-instances | jq -r '[.Reservations[].Instances[] | select(.State.Name == "stopped") | .InstanceId] | join(" ")' -runningのインスタンスを取得 aws ec2 describe-instances | jq -r '[.Reservations[].Instances[] | select(.State.Name == "running") | .InstanceId] | join(" ")' -target-groupに所属するインスタンスID aws elbv2 describe-target-health --target-group-arn TG_ARN | jq '[.TargetHealthDescriptions[].Target.Id] | join(" ")' -起動(上のシェルと合わせると複数起動可能) aws ec2 start-instances --instance-ids インスタンスID aws ec2 stop-instances --instance-ids $(aws ec2 describe-instances | jq -r '[.Reservations[].Instances[] | select(.State.Name == "running") | .InstanceId] | join(" ")') -タグ付け aws ec2 create-tags --resources インスタンスID --tags Key=Stack,Value=production -lambda aws lambda invoke --function-name randomfailure --profile assume lambda_exec.txt *EBS [#ye41fadf] Elastic Block Storeの略。スナップショット機能など多彩な機能がある。通常インスタンスストレージは停止したら消えるのであまり使わずEBSがEC2のメインストレージとなるだろう。EBSは同一AZでのインスタンスにしかアタッチできない。スナップショットから別AZへコピーできる **EBSの種類 [#q5651211] GP2は容量を増やすとパフォーマンスが伸びる。Provisioned IOPSは自分でパフォーマンスを指定できるが、増やしすぎると値段が上がるので注意。 *AMI [#e386e448] マシンのOSイメージのこと。マイクロインスタンスであれば、RHELもWindowsも無料の枠内に収まるとのこと。「free tier eligible」とあればマイクロインスタンスとの組み合わせで無料。自分でAMIを作ることが可能で、実用上は公式提供のAMIをカスタマイズして自分のシステムのベースを作る。仮想マシンの方式がhvmとparavirtualがあるが、今後の主流はhvmであるのでhvmベースで作成すべし! *EC2初期設定 [#r784a890] **Cloudinit [#w44c5a7f] 起動時に設定などを実施できるcloud-init(yml)かシェルスクリプトを設定できる。APIからも設定可能。 **コンソールから入れる場合 [#e26f12fe] #!/bin/bash #TIMEZONE JST /bin/cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime yum install -y postfix yum install -y mysql-server yum install -y nginx # start service /etc/init.d/postfix start /etc/init.d/mysqld start /etc/init.d/nginx start # enable service auto start chkconfig --level 345 postfix on chkconfig --level 345 nginx on chkconfig --level 345 mysqld on *EC2インスタンスの作成からログインまで [#c821f1f7] 無料枠を超えないようにインスタンスはT2.micro、その他はデフォルトで進める。秘密鍵のペアはpemファイルとなるが、puttygenでインポートしてからputty形式のファイルにして、ec2-userでログイン成功 **インスタンスの作成手順詳細 [#nb48d03b] +AMIを選ぶ +6. Configure Security GroupでSGを指定する **インスタンスタイプ [#h1acbc5e] |名称|備考| |t1,t2|CPUがバースト可能。しかし低コストなので常時CPUが必要ならC1,C2を| |c1,c2|CPUに重点を置いたタイプ。| |r3|データベース向け| **Elastic IP [#j220cd0e] 静的なIPでインスタンスにひもづけることができる。起動していないインスタンスにEIPを確保しておくと課金対象。ここを見るとPrivate IPとの紐づけも見られる。 一応使わないでも再起動しなければ起動時に動的に割り当てられたpublic IPでアクセスできる。PublicIPの自動割り当て機能は起動時のみ利用出来る為、起動後に付与したくなった場合にはEIPを利用する必要がある。 *ELB [#s3dd8aa7] Elastic Load Balancing。インスタンスを複数ぶら下げて振り分ける。異常からの復帰時はデフォルトだと最低300秒かかるので気長にまつか、設定を変更する。それぞれのAZで等しい台数とスペックをぶら下げるのが基本。 **Internal ELB [#y2f14c2c] 名前解決はpublicなDNSで行うため、利用側にインターネット接続必要。またスケールアップ時にIPが変わるため、直接IPでアクセスしてはいけない。 **ELB負荷対策 [#vc930c5a] ELBのスケールアップ・スケールアウトはAWS側で勝手にやってくれる。配下でインスタンスが全滅していると勝手に一個になる。復帰すると2個になる。apache benchをやり続けるとそのIPだけタイムアウトになってしまう!なにか見ているのかも? こちらで負荷監視する項目はCloudWatchから取得できる処理数や処理待ちなどのデータ。 **スティッキーセッション [#p4395bda] クラウド時代にはあまり好ましくはないが、特定のサーバーに振り分けるスティッキーセッションの設定もできる。ELBの説明欄から維持設定をクリック **元アクセスのリクエストヘッダ [#e02f337f] -以下のヘッダーについてくるのでアクセスログのフォーマットを変更する。 HTTP_X_FORWARDED_FOR HTTP_X_FORWARDED_PORT HTTP_X_FORWARDED_PROTO **ELBのサブネット [#g1d8a78c] 所属するサブネットに最低8IPの空きが必要。 *EC2 オートスケール [#j212581c] 負荷状況に合わせて増やしたり、一定数以上の稼働を保証させることができる仕組み。もととなるAMIを使って起動するので、そのAMIを作成しておく。起動設定でアプリのデプロイをしてELBに関連づけ(AutoScaleの設定画面から既存ELBを選択)しておくとよい。 *Security Group [#o2df0a78] **基本 [#l4ef6d13] インスタンス単位で設定。サブネット単位で設定するACLよりもよく使われる。セキュリティGを持つものを許可するという設定があり、デフォルトSGを許可しておけば内部通信は問題なくなる。ネットワークACLと違ってステートフルなので、INが許可されていれば、OUTは拒否されていても大丈夫(SSHのクライアントポートが10000以上でも22のINが許可されているので問題なし。ネットワークACLだとステートレスなのでNGとなる。) **HTTPの外回りと内回り [#g33f7ada] 同じインスタンスにアクセスする場合PrivateIP指定の場合は内回りとなり、SGのアクセス元としてSGを持っていることが指定できる。Global IPを指定した場合は外回りのアクセスとなり、一般的なIP制限と同じようにIP指定で許可しないとつながらない。 **デフォルトSG [#e8ba0d7a] 基本的にプライベート内部は全部の通信が許可されるデフォルトSGが存在する。 特に支障がない限りこれを各インスタンスにつけておくことをお勧めする。 デフォルトSGを持っているのものを全部許可する設定になっているので *ネットワークACL [#n2b8dbaa] サブネット単位で設定するが、ポート単位で指定すると動的にポートが変わるものがブロックされてしまうので、ポートでは絞らずに、送信元IPで制限するのがよい。 *EC2複製 [#uccfb57c] **AMIを作成して複製 [#wbef98cb] 固定PrivateIPだと既存EC2消さないとダメ **EBSボリューム複製して既存インスタンスにアタッチ [#e7ab05dd] これは複製ではなく障害復旧だな。 **EBSボリュームを複製して手動マウント [#m2a6c4f3] 上記2パターンがうまくいかないときの最終手段。