EC2とDockerで手軽にJenkinsを試す #1
第1回目はEC2へdockerをセットアップし、JenkinsのイメージをRunする。
Jenkinsの動作確認までをしていきたい。
第2回目でCodeシリーズあたりと連携をしていきたいと思う。
EC2へのDockerのインストール
そこら中に記事があるので、そちらを参照。
Jenkinsのセットアップ
jenkins blueoceanのダウンロード
docker pull jenkinsci/blueocean
Jenkins用のディレクトリ作成
mkdir ~/docker/jenkins
Imageの起動
こちらのサイトを多分に参考にさせて頂きました。
sudo docker run \ -u root \ --rm \ -d \ -p 8080:8080 \ -v $HOME/docker/jenkins:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ jenkinsci/blueocean
一行版。
sudo docker run -u root --rm -d -p 8080:8080 -v $HOME/docker/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean
Web画面でのJenkinsのセットアップ
上記設定で起動すれば、http://EC2-public-IP:8080にアクセスすると、初期画面が出る。 初期画面ではパスワードを入れろと言われるので、下記にあるパスワードを調べる。
cat ~/docker/jenkins/secrets/initialAdminPassword
入力してあげると、こんな画面が出る。
Install suggested pluginを選ぶと、インストールが進む。
インストールが終わると、初期ユーザー登録画面が出てくる。 ユーザ名やパスワードなどを登録する。
わーい。
Adminでログインになった場合
initial passwordを使ってLoginしたところ、Adminでログインになることがある。 その場合は、jenkinsの管理→ユーザーの管理からユーザーを作成しておけばOK。
Jenkinsの動作確認
まずは新規ジョブの作成→フリースタイル・プロジェクトのビルドを選ぶ。
ビルド手順の追加→シェルの実行を選択。
サンプルとして、Hello Worldの表示をテストしてみる。 下記のように入力し、保存。
ビルドを実行。ビルド履歴を確認。
コンソール出力を見ると、hello worldが出力されて、 エラーなくテストが成功していることがわかる。 ちなみに&JOB_NAMEはtestという新規ジョブを作ったため、その名前が出力されている。
付録(Dockerの便利コマンド)
# Imageのダウンロード docker pull <Image> # コンテナの一覧表示 docker ps -a # イメージの一覧表示 docker images # コンテナの削除 docker rm <container-ID> # イメージの削除 docker rmi <image-ID>
CloudFormationで簡単に機械学習の開発環境を整える
はじめに
ちょっと検討をしてみようと思うたびに、VPC作ってSubnet作って、InternetGatewayとElasticIP取得して、NatGateway設置して・・
と単純なprivate, publicサブネットを置くだけでも何度もやると面倒くさい。
特に機械学習開発環境代わりに使うような場合は、複数AZにまたがるような可用性云々じゃなくて、検討用土台をさくっと作りたい。
でもSageMakerのNotebookインスタンスじゃ物足りないという人がいると思う。
構成図
前回も紹介したこれを自動で作ることにする。
●ポイント
- 踏み台サーバーでセキュリティ対策
- NATゲートウェイでPrivate環境でもソフトを更新可能
- さくっと検討用に使いたいのでOneZone構成
自分の練習用
はまりどころ
いろいろハマったけど、下記はその一例。参考になれば。
NATGatewayでのElasticIPの指定
IPアドレスではなくIDで指定するため、下記のように"Fn::GetAtt::"を使って指定している。
NATGateway: Type: AWS::EC2::NatGateway Properties: AllocationId: Fn::GetAtt: - ElasticIP - AllocationId
NATGatewayへのRoute
RouteでGatewayIdではなく、NATGatewayIdを使う必要あり。
PrivateRoute: Type: AWS::EC2::Route Properties: NatGatewayId: !Ref NATGateway
EC2のSecurityGroupの設定はリストで
SecurityGroupIdsのように、複数形になっているのでリストで渡すことをお忘れなく。
PrivateInstance: Type: AWS::EC2::Instance Properties: SecurityGroupIds: - !Ref PrivateSecurityGroup
yamlファイル全体はこちら
これをcloud formationに入れることで一発で踏み台サーバーと検討用のprivateサーバーを起動することが可能。 インスタンスのファミリーとかサイズは適宜変えるとよい。
AWSTemplateFormatVersion: "2010-09-09" Description: OneZone VPC/Subnet/EC2 Create Parameters: # 踏み台サーバーはAmazonLinux & t2.microで簡素に BationHostImageId: Type: AWS::SSM::Parameter::Value<String> Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 BationHostInstanceType: Type: String Default: t2.micro # 機械学習用インスタンスはDeepLearning AMIを使って、実験用と高機能用などを用意 PrivateImageId: Type: String Default: ami-088585cfb750459af PrivateInstanceType: Type: String Default: m5.2xlarge AllowedValues : ["t2.micro", "m5.2xlarge"] # SSHでつなぐための接続元IP(自分のIP) MyIP: Description: IP address allowed to access EC2 Type: String Default: 0.0.0.0/32 # SSH用のKeyはすでにある前提 KeyName: Description: The EC2 Key Pair to allow SSH access to the instance Type: "AWS::EC2::KeyPair::KeyName" Default: .pem Resources: # ##################################### # VPC & IG # ##################################### VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.5.0.0/16 EnableDnsHostnames: false EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: my-vpc-stack InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: my-ig-stack InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VPC # ##################################### # Subnet & NAT # ##################################### PublicSubnet: Type: AWS::EC2::Subnet Properties: AvailabilityZone: "ap-northeast-1a" CidrBlock: 10.5.0.0/24 MapPublicIpOnLaunch: true Tags: - Key: Name Value: public-subnet-stack VpcId: !Ref VPC PrivateSubnet: Type: AWS::EC2::Subnet Properties: AvailabilityZone: "ap-northeast-1a" CidrBlock: 10.5.1.0/24 MapPublicIpOnLaunch: false Tags: - Key: Name Value: private-subnet-stack VpcId: !Ref VPC NatIP: Type: AWS::EC2::EIP Properties: Domain: vpc Tags: - Key: Name Value: nat-eip-stack NATGateway: Type: AWS::EC2::NatGateway Properties: AllocationId: Fn::GetAtt: - NatIP - AllocationId SubnetId: !Ref PublicSubnet Tags: - Key: Name Value: my-nat-stack # ##################################### # RouteTable & Routing # ##################################### PublicRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: rt-public-stack PublicRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: "0.0.0.0/0" GatewayId: !Ref InternetGateway PublicRouteAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnet PrivateRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: rt-private-stack PrivateRoute: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRouteTable DestinationCidrBlock: "0.0.0.0/0" NatGatewayId: !Ref NATGateway PrivateRouteAssociation: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PrivateRouteTable SubnetId: !Ref PrivateSubnet # ##################################### # SecurityGroup # ##################################### PublicSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow SSH to BationHost GroupName: allow-ssh-to-bation-stack VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref MyIP PrivateSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow SSH from bation GroupName: allow-ssh-from-bation-stack VpcId: !Ref VPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 SourceSecurityGroupId: !Ref PublicSecurityGroup # ##################################### # EC2 # ##################################### BationHost: Type: AWS::EC2::Instance Properties: ImageId: !Ref BationHostImageId InstanceType: !Ref BationHostInstanceType KeyName: !Ref KeyName NetworkInterfaces: - AssociatePublicIpAddress: "true" DeviceIndex: "0" SubnetId: !Ref PublicSubnet GroupSet: - !Ref PublicSecurityGroup Tags: - Key: Name Value: bation-host-stack EC2IP: Type: AWS::EC2::EIP Properties: InstanceId: !Ref BationHost Tags: - Key: Name Value: ec2-eip-stack PrivateInstance: Type: AWS::EC2::Instance Properties: ImageId: !Ref PrivateImageId InstanceType: !Ref PrivateInstanceType KeyName: !Ref KeyName SubnetId: !Ref PrivateSubnet SecurityGroupIds: - !Ref PrivateSecurityGroup Tags: - Key: Name Value: private-instance-stack # SSH接続用にPublicとPrivateのIPを出力しておくと便利 Outputs: PublicIP: Value: !GetAtt BationHost.PublicIp Description: Public IP of BationHost PrivateIP: Value: !GetAtt PrivateInstance.PrivateIp Description: Private IP of EC2 instance
AWSアカウント間でのCodeCommitからのClone
AWSアカウントAのリポジトリからAWSアカウントBの人がCloneする
Bの人がAのアクセスキーIDとシークレットアクセスキーを持っている場合
非常に簡単。 AWSアカウントBの人のEC2で、下記コマンドでAWSアカウントAのcredential情報を入力。 credentialを入れるので、できればprivate subnetで踏み台サーバー経由が良いと思う。
aws config --profile <ENVNAME>
その上で下記コマンドでリポジトリをCloneできる。
git clone codecommit://<ENVNAME>@<repository_name> git clone codecommit::<REGION>://<repository_name> # region指定の場合
Git認証情報がある場合
CodeCommitからリポジトリをクローンする
IAMユーザーから認証情報を作成
AWS CodeCommitのHTTPS Git認証情報を生成をクリック。
ユーザー名とパスワードをダウンロードしておく。
Git cloneするだけ
git clone https://git-codecommit.ap-northeast-1.amazonaws.com/*********/
こうするとユーザ名とパスワードを聞かれるので、 先程ダウンロードしておいたユーザ名とパスワードを使えば良い。
毎回Credential情報入力するのが面倒な方へ
MaxOSXの場合は下記コマンドを使うと、OSXのキー保存機能で保存してくれる。 細かく知りたい方は別途検索すると良い。
git config --global credential.helper osxkeychain
VSCODEから踏み台サーバー越しにSSH接続をする
この記事で行っている多段SSHは既にベストプラクティスではないので、Session Managerを使うことをお勧めします。 構成はこちらのQiitaを参照のこと。
多段SSHしたい
機械学習の研究開発用だと、SageMakerのJupyter NoteBookじゃ物足りず、EC2にSSHで入って開発したくなる。僕の使い方が悪いのか・・?開発用にEC2を置くなら、Privateに開発用、Publicに踏み台サーバーを置くといいかなぁと思う。(特に会社とかで使う場合)
要はこういう状態 。
SSH config
VSCODEのSSHのconfigには下記を書けばOK。 どちらの.pemファイルもローカルのファイルを指定すれば良い。 publicEC2に鍵を置かなくて良い点が安心感。
Host public HostName PUBLIC EC2のIP User ec2-user IdentityFile ****.pem(フルパスで書いたほうが良い) Host private Hostname PRIVATE EC2のIP User ec2-user IdentityFile ****.pem(フルパスで書いたほうが良い。) ProxyCommand ssh -W %h:%p public
VSCODE
あとは直接privateのほうを開くだけ。
EC2の設定どうする
SSHフルオープンが心配な場合は、Public EC2のセキュリティグループでインバウンドで自分のIPを指定すると良い。 さらにPrivate EC2のセキュリティグループのインバウンドに、Public EC2に設定してあるセキュリティグループを設定してあげればこちらも安心。
EC2へS3からデータをダウンロードする(VPCエンドポイント編)
事前準備
VPCエンドポイントを作成
VPCのエンドポイントを作成する。サービスとしてS3を選択。 フルアクセス設定と、RouteTableを指定して作ってしまえば、このVPC内の指定されたトラフィックはS3のエンドポイントへ向かうようになる。
AWS S3コマンドで見てみる
同一VPC内のEC2にSSHなどで入って、S3にあるバケットが確認できるようになっている。
aws s3 ls
データのダウンロードなどはaws s3のコマンドを別途調べると良いが、個人的にはよくsyncを使っている。
aws s3 sync s3://bucket-name/object-name ./DIRECTORY