Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
オンプレを少しずつコンテナ化する
JAWS-UG CLI専門支部 岡崎 賢吉
自己紹介
• 社内情シスでインフラ担当しています(自社クラウド?それをオンプレと言うんじゃ…
昨年まではポータルサイトのAWSへの移行とか
• 好きなAWSのサービス 
• JAWSの活動 CLI専門支部懇親会係・情シス支部運営
• 黒い画面の...
SORACOMリレーブログに参加しました
• https://blog.soracom.jp/relay-blog/2015-11/
• 「SORACOMとAWSで家電話」というタイトルでAWS直結
でスマホからIP電話を使う試みを書きました。
少しずつコンテナにしよう
• オンプレは永遠に不滅です!
無くなると自分の仕事が…w
• 共存しつつコンテナをどう使っていくか
• サービスごとにオンプレから切り出す
DNSサーバ
Webサーバ
あたりが比較的簡単かな?ADとかムリ
コンテナの特徴
• コンテナとは仮想化ではなくユーザ空間で
動くプロセスである。 by クラウド婚にあこがれるZ佛さん(仮名)
• コンテナは起動時に指定したプロセスが終了するとコン
テナも消滅する。
• デーモンとして起動されるサービスをその...
どう実装するか
• コンテナは終了すると中のデータが消滅する
• 内部にデータを持たない設計が必要
• コンテナ起動時にS3から必要なデータを読み込み、コン
テナ自体はデータを持たない構造とした
構築手順概要
• S3へコンテンツデータを準備する
• EC2コンテナインスタンスの作成
• コンテナの作成
• リポジトリへpush
• コンテナの起動
• 動作確認
コンテナ暴走。詰んだ
(後日談:原因はリソース不足で操作不能に陥っていたようです…)
コンテナインスタンスの作成
インスタンスプロファイル(IAMロール)の作成
$ AWS_DEFAULT_REGION=ap-northeast-1
$ IAM_ROLE_NAME=ecsInstanceRole
$ IAM_POLICY_NAM...
コンテナインスタンスの作成
セキュリティグループ・鍵ペア・インスタンスプロファイルの作成
$ VPC_SG_NAME='ec2-http-dns-global-inbound'
$ VPC_SG_DESC='EC2 HTTP/DNS Globa...
コンテナインスタンスの作成
インスタンスの起動
$ EC2_INSTANCE_TYPE='c4.8xlarge'
$ AMZLINUX_VERSION='2015.03.d'
$ EC2_IMAGE_NAME="amzn-ami-${AMZLI...
httpdコンテナ
apache httpdコンテナを作る
• ベースとなるコンテナ(centos:6)に追加したいファイルを準備
/root/.aws/config /root/.aws/credential /etc/httpd/conf/...
httpdコンテナ
コンテナのビルド
• これらのファイルを1つのディレクトリに入れ(ここでは ./lt-httpd/) build
# docker build --rm -t xiaomiho/lt-httpd ./lt-httpd
Sen...
httpdコンテナ
リポジトリへコンテナをpush、コンテナの起動
• 完成したdocker imageをリポジトリへpushする
# docker push xiaomiho/lt-httpd
The push refers to a rep...
無事ブラウザでコンテンツが表示されました。
namedコンテナ
bindコンテナを作る
• 先程と同様にベースとなるコンテナ(centos:6)に追加したいファイルを準備
/root/.aws/config /root/.aws/credential /etc/rc.local (後述)...
namedコンテナ
bindコンテナのビルド、リポジトリへpush、そして起動。
• これらのファイルを1つのディレクトリに入れ(ここでは ./lt-dns/) build
# docker build --rm -t xiaomiho/lt-...
通常はこれが…
毒入り成功!
課題
• コンテナが落ちた時の自動復帰
ECSにすれば自動処理されるようなので、ECSに載せる方向で。
• アクセスログの管理
Amazon EFSと連携してNFSマウントしたファイルシステムにアクセスログをゴリゴリ書
きたいところですが…
I...
ありがとうございました!
Nächste SlideShare
Wird geladen in …5
×

オンプレを少しずつコンテナ化する

1.386 Aufrufe

Veröffentlicht am

JAWS-UG コンテナ支部 第3回LT
オンプレで動いているサービスを少しずつ切り出してコンテナ化しクラウド(AWS)へ移行しようと考えた。

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

オンプレを少しずつコンテナ化する

  1. 1. オンプレを少しずつコンテナ化する JAWS-UG CLI専門支部 岡崎 賢吉
  2. 2. 自己紹介 • 社内情シスでインフラ担当しています(自社クラウド?それをオンプレと言うんじゃ… 昨年まではポータルサイトのAWSへの移行とか • 好きなAWSのサービス  • JAWSの活動 CLI専門支部懇親会係・情シス支部運営 • 黒い画面の布教活動 • 普段はIP電話やL3SWをいじってる低レイヤの人です • コンテナはあまり詳しくないです。。。
  3. 3. SORACOMリレーブログに参加しました • https://blog.soracom.jp/relay-blog/2015-11/ • 「SORACOMとAWSで家電話」というタイトルでAWS直結 でスマホからIP電話を使う試みを書きました。
  4. 4. 少しずつコンテナにしよう • オンプレは永遠に不滅です! 無くなると自分の仕事が…w • 共存しつつコンテナをどう使っていくか • サービスごとにオンプレから切り出す DNSサーバ Webサーバ あたりが比較的簡単かな?ADとかムリ
  5. 5. コンテナの特徴 • コンテナとは仮想化ではなくユーザ空間で 動くプロセスである。 by クラウド婚にあこがれるZ佛さん(仮名) • コンテナは起動時に指定したプロセスが終了するとコン テナも消滅する。 • デーモンとして起動されるサービスをそのまま動かそうと すると、一瞬でコンテナが消滅してハマる>< • 起動スクリプトの最後に tail -f /dev/null を実行しっぱな しにする力業とかが見かけるけどイクナイ。 • 目的のサービスをforegroundで起動する必要がある。
  6. 6. どう実装するか • コンテナは終了すると中のデータが消滅する • 内部にデータを持たない設計が必要 • コンテナ起動時にS3から必要なデータを読み込み、コン テナ自体はデータを持たない構造とした
  7. 7. 構築手順概要 • S3へコンテンツデータを準備する • EC2コンテナインスタンスの作成 • コンテナの作成 • リポジトリへpush • コンテナの起動 • 動作確認
  8. 8. コンテナ暴走。詰んだ (後日談:原因はリソース不足で操作不能に陥っていたようです…)
  9. 9. コンテナインスタンスの作成 インスタンスプロファイル(IAMロール)の作成 $ AWS_DEFAULT_REGION=ap-northeast-1 $ IAM_ROLE_NAME=ecsInstanceRole $ IAM_POLICY_NAME='AmazonEC2ContainerServiceforEC2Role' $ IAM_POLICY_ARN=$( aws iam list-policies --max-items 1000 --query "Policies[?PolicyName==¥`${IAM_POLICY_NAME}¥`].Arn" --output text ) && echo "${IAM_POLICY_ARN}" $ IAM_POLICY_VERSION=$( aws iam list-policies --max-items 1000 --query "Policies[?PolicyName==¥`${IAM_POLICY_NAME}¥`].DefaultVersionId" --output text ) && echo ${IAM_POLICY_VERSION} $ FILE_ROLE_DOC="${IAM_ROLE_NAME}.json" && echo ${FILE_ROLE_DOC} $ cat << EOF > ${FILE_ROLE_DOC} { "Version": "2008-10-17", "Statement": [ { Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] } EOF $ aws iam create-role --role-name ${IAM_ROLE_NAME} --assume-role-policy-document file://${FILE_ROLE_DOC} $ aws iam list-attached-role-policies --role-name ${IAM_ROLE_NAME} $ aws iam attach-role-policy --role-name ${IAM_ROLE_NAME} --policy-arn ${IAM_POLICY_ARN} $ IAM_ROLE_NAME="ecsInstanceRole" $ IAM_INSTANCE_PROFILE_NAME=${IAM_ROLE_NAME} && echo ${IAM_INSTANCE_PROFILE_NAME} $ cat << ETX IAM_INSTANCE_PROFILE_NAME: ${IAM_INSTANCE_PROFILE_NAME} ETX $ aws iam create-instance-profile --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME} $ ARRAY_IAM_ROLES=$( aws iam get-instance-profile --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME} --query 'InstanceProfile.Roles[].RoleName' --output text ) && echo ${ARRAY_IAM_ROLES} $ aws iam add-role-to-instance-profile --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME} --role-name ${IAM_ROLE_NAME} $ ARRAY_IAM_ROLES=$( aws iam get-instance-profile --instance-profile-name ${IAM_INSTANCE_PROFILE_NAME} --query 'InstanceProfile.Roles[].RoleName' --output text ) && echo ${ARRAY_IAM_ROLES}
  10. 10. コンテナインスタンスの作成 セキュリティグループ・鍵ペア・インスタンスプロファイルの作成 $ VPC_SG_NAME='ec2-http-dns-global-inbound' $ VPC_SG_DESC='EC2 HTTP/DNS Global inbound' $ aws ec2 create-security-group --group-name ${VPC_SG_NAME} --description "${VPC_SG_DESC}" $ VPC_SG_ID=$( aws ec2 describe-security-groups --filter Name=group-name,Values=${VPC_SG_NAME} --query 'SecurityGroups[].GroupId' --output text ) && echo ${VPC_SG_ID} $ VPC_SG_PROTOCOL='tcp' $ VPC_SG_PORT='80' $ VPC_SG_CIDR='0.0.0.0/0' $ aws ec2 authorize-security-group-ingress --group-id ${VPC_SG_ID} --protocol ${VPC_SG_PROTOCOL} --port ${VPC_SG_PORT} --cidr ${VPC_SG_CIDR} $ VPC_SG_PROTOCOL='udp' $ VPC_SG_PORT='53' $ VPC_SG_CIDR='0.0.0.0/0' $ aws ec2 authorize-security-group-ingress --group-id ${VPC_SG_ID} --protocol ${VPC_SG_PROTOCOL} --port ${VPC_SG_PORT} --cidr ${VPC_SG_CIDR} $ VPC_SG_PROTOCOL='tcp' $ VPC_SG_PORT='22' $ VPC_SG_CIDR='■端末IP■/32' $ aws ec2 authorize-security-group-ingress --group-id ${VPC_SG_ID} --protocol ${VPC_SG_PROTOCOL} --port ${VPC_SG_PORT} --cidr ${VPC_SG_CIDR} $ PRJ_NAME=ecshandson $ EC2_KEY_NAME="${PRJ_NAME}-${AWS_DEFAULT_REGION}-ec2" && echo ${EC2_KEY_NAME} $ FILE_SSH_KEY="${HOME}/.ssh/${EC2_KEY_NAME}.pem" && echo ${FILE_SSH_KEY} $ aws ec2 create-key-pair --key-name ${EC2_KEY_NAME} --query 'KeyMaterial' --output text > ${FILE_SSH_KEY} && cat ${FILE_SSH_KEY} && chmod 400 ${FILE_SSH_KEY} $ aws iam list-instance-profiles --query 'InstanceProfiles[].InstanceProfileName' $ IAM_INSTANCE_PROFILE_NAME='ecsInstanceRole' $ VPC_SG_NAME='ec2-http-dns-global-inbound' $ VPC_SG_ID=` aws ec2 describe-security-groups --filter Name=group-name,Values=${VPC_SG_NAME} --query 'SecurityGroups[].GroupId' --output text ` && echo ${VPC_SG_ID} $ ARRAY_VPC_SG_ID="${VPC_SG_ID} ${ARRAY_VPC_SG_ID}" && echo ${ARRAY_VPC_SG_ID} $ aws ec2 describe-security-groups --group-ids ${VPC_SG_ID}
  11. 11. コンテナインスタンスの作成 インスタンスの起動 $ EC2_INSTANCE_TYPE='c4.8xlarge' $ AMZLINUX_VERSION='2015.03.d' $ EC2_IMAGE_NAME="amzn-ami-${AMZLINUX_VERSION}-amazon-ecs-optimized" $ EC2_IMAGE_ID=`aws ec2 describe-images --filters Name=name,Values="${EC2_IMAGE_NAME}" --query 'Images[].ImageId' --output text` && echo ${EC2_IMAGE_ID} $ ECS_CLUSTER_NAME='handson-cluster' $ FILE_EC2_USERDATA="ecs-userdata-${ECS_CLUSTER_NAME}.bash" $ cat << EOF > ${FILE_EC2_USERDATA} echo ECS_CLUSTER=${ECS_CLUSTER_NAME} > /etc/ecs/ecs.config EOF $ aws ecs create-cluster --cluster-name ${ECS_CLUSTER_NAME} $ aws ec2 run-instances --image-id ${EC2_IMAGE_ID} --instance-type ${EC2_INSTANCE_TYPE} --security-group-ids ${ARRAY_VPC_SG_ID} ¥ --key-name ${EC2_KEY_NAME} --associate-public-ip-address --user-data file://${FILE_EC2_USERDATA} --iam-instance-profile Name=${IAM_INSTANCE_PROFILE_NAME} $ EC2_INSTANCE_ID=` aws ec2 describe-instances --filters Name=instance-state-name,Values=pending --query 'Reservations[].Instances[].InstanceId' ¥ --output text ` && echo ${EC2_INSTANCE_ID} $ EC2_PUBLIC_IP=` aws ec2 describe-instances --instance-id ${EC2_INSTANCE_ID} --query "Reservations[].Instances[].PublicIpAddress" ¥ --output text ` && echo ${EC2_PUBLIC_IP} • 数分待ってからコンテナインスタンスへログイン ssh -i ${FILE_SSH_KEY} ec2-user@${EC2_PUBLIC_IP} • 以後の作業はログインしたコンテナインスタンス上から行います。
  12. 12. httpdコンテナ apache httpdコンテナを作る • ベースとなるコンテナ(centos:6)に追加したいファイルを準備 /root/.aws/config /root/.aws/credential /etc/httpd/conf/httpd.conf.add /etc/rc.local (後述) • rc.localはS3からWebコンテンツを取得してapacheを起動する設定を記述 apacheをフォアグラウンドで起動させるためにapachectlを直接呼び出す。 #!/bin/sh /usr/bin/aws s3 sync s3://ecs-handson/html /var/www/html /usr/sbin/apachectl -DFOREGROUND • Dockerfileファイルを新規作成し構築したい内容を記述 FROM centos:6 RUN curl -O https://bootstrap.pypa.io/get-pip.py RUN python get-pip.py RUN pip install awscli RUN yum -y install httpd ADD config /root/.aws/config ADD credentials /root/.aws/credentials ADD httpd.conf.add /tmp/httpd.conf.add RUN cat /tmp/httpd.conf.add >> /etc/httpd/conf/httpd.conf ADD rc.local /etc/rc.local CMD /etc/rc.local
  13. 13. httpdコンテナ コンテナのビルド • これらのファイルを1つのディレクトリに入れ(ここでは ./lt-httpd/) build # docker build --rm -t xiaomiho/lt-httpd ./lt-httpd Sending build context to Docker daemon 6.144 kB Sending build context to Docker daemon Step 0 : FROM centos:6 ---> 3bbbf0aca359 Step 1 : RUN curl -O https://bootstrap.pypa.io/get-pip.py ---> Using cache ---> b2657c17a25d Step 2 : RUN python get-pip.py ---> Using cache ---> 7f81e9867e4c Step 3 : RUN pip install awscli ---> Using cache ---> 69c2fe677515 Step 4 : RUN yum -y install httpd ---> Using cache ---> c4e9e346f87a Step 5 : ADD config /root/.aws/config ---> Using cache ---> c05b256e202c Step 6 : ADD credentials /root/.aws/credentials ---> Using cache ---> 203b855206db Step 7 : ADD httpd.conf.add /tmp/httpd.conf.add ---> bad97ea080ef Removing intermediate container 32c25d8a8ded Step 8 : RUN cat /tmp/httpd.conf.add >> /etc/httpd/conf/httpd.conf ---> Running in f90024c961d5 ---> e819ed1c1d4b Removing intermediate container f90024c961d5 Step 9 : ADD rc.local /etc/rc.local ---> 04f297d4b8f4 Removing intermediate container 089a2986981b Step 10 : CMD /etc/rc.local ---> Running in 65b18d2f4f3a ---> cdd53146bb20 Removing intermediate container 65b18d2f4f3a Successfully built cdd53146bb20 ←■最後の行 built隣の文字列がdocker image番号 #
  14. 14. httpdコンテナ リポジトリへコンテナをpush、コンテナの起動 • 完成したdocker imageをリポジトリへpushする # docker push xiaomiho/lt-httpd The push refers to a repository [xiaomiho/lt-httpd] (len: 1) cdd53146bb20: Image already exists 04f297d4b8f4: Image successfully pushed e819ed1c1d4b: Image successfully pushed bad97ea080ef: Image successfully pushed 203b855206db: Image already exists c05b256e202c: Image already exists c4e9e346f87a: Image already exists 69c2fe677515: Image successfully pushed 7f81e9867e4c: Image already exists b2657c17a25d: Image already exists 3bbbf0aca359: Image already exists fea77d2fd61e: Image already exists 91e6f84b8fe8: Image already exists 2c2557968d48: Image already exists 47d44cb6f252: Image already exists Digest: sha256:23b61d265fa481ba9c462bacda40f38cb70a30390e1705ffdd32bcfe2549768b # • コンテナを起動する # docker run -d -p 80:80 xiaomiho/lt-httpd e2caa45cf32b31cc317dccda3377a0b3cd57f248cc0ecf690def2366f06037c8 # 正しく起動されるとコンテナIDが返されます。(長い文字列) • 作業完了。Webブラウザで確認してみましょう
  15. 15. 無事ブラウザでコンテンツが表示されました。
  16. 16. namedコンテナ bindコンテナを作る • 先程と同様にベースとなるコンテナ(centos:6)に追加したいファイルを準備 /root/.aws/config /root/.aws/credential /etc/rc.local (後述) • rc.localはS3からゾーン情報などを取得してbindを起動する設定を記述 bindをフォアグラウンドで起動させるためにnamedを直接呼び出す。 #!/bin/sh /usr/bin/aws s3 cp s3://ecs-handson/etc/named.conf /etc/ /usr/bin/aws s3 sync s3://ecs-handson/named /var/named /usr/sbin/named -u named -f • Dockerfileファイルを新規作成し構築したい内容を記述 FROM centos:6 RUN curl -O https://bootstrap.pypa.io/get-pip.py RUN python get-pip.py RUN pip install awscli RUN yum -y install bind initscripts ADD config /root/.aws/config ADD credentials /root/.aws/credentials ADD rc.local /etc/rc.local CMD /etc/rc.local
  17. 17. namedコンテナ bindコンテナのビルド、リポジトリへpush、そして起動。 • これらのファイルを1つのディレクトリに入れ(ここでは ./lt-dns/) build # docker build --rm -t xiaomiho/lt-dns ./lt-dns (中略) Successfully built 86b9ec61a298 # • 完成したdocker imageをリポジトリへpushする # docker push xiaomiho/lt-dns The push refers to a repository [xiaomiho/lt-dns] (len: 1) (中略) Digest: sha256:4da38320fad6f7b0526d0d26acc6031e871a6cfd15b906e917c24fe59f8ee267 # • コンテナを起動する # docker run -d -p 53:53/udp xiaomiho/lt-dns 121d50299f765aa3f415ac72aacac4b0e1d3c280db939c4d9c1003dc0c57c97b # • 作業完了。DNSサーバが機能しているか確認してみましょう DNSサーバの動作確認って表現が難しいので、今回はSUPINFさんのドメインに偽ゾーン情報を入れてみました。 正しく動作していれば、Webブラウザで予期せぬページが表示されるはずです。
  18. 18. 通常はこれが… 毒入り成功!
  19. 19. 課題 • コンテナが落ちた時の自動復帰 ECSにすれば自動処理されるようなので、ECSに載せる方向で。 • アクセスログの管理 Amazon EFSと連携してNFSマウントしたファイルシステムにアクセスログをゴリゴリ書 きたいところですが… IPv4アドレス枯渇に伴いCGNのなどが登場し、アクセス元ポート番号まで記録が必要 になりつつある昨今、自前でログを書いて解析するのは大変。 • ELBがS3へログを記録する機能を使ってKibanaで可視化する試みも公開されている のでこれが最適解かも。
  20. 20. ありがとうございました!

×