見出し画像

ArgoCD構築ガイド(インフラ編)

はじめに

こんにちは、インフラエンジニアの北野です。

今回のブログでは、ArgoCDの構築手順と基本的な設定方法と動作確認の結果をご紹介しようと思います。

ArgoCDとは

ArgoCDは、KubernetesのためのCD(継続的デリバリー)ツールです。 イメージキャラはタコのような宇宙人のようなキャラです。かわいいですね。

ArgoCDは、Gitレポジトリのマニフェストファイルの内容を運用環境に自動的にデプロイメントしてくれます。

例えば、Gitレポジトリ側の指定したブランチやタグのアプリケーション定義を更新すると、 その定義を運用環境に自動で適用してくれます。

また、運用環境の状態を常に監視し、例えば誰かが運用環境の設定を更新したとき 自動で元のGitレポジトリの状態に戻してくれます。

要はGitと運用環境が同期していることを保証してくれるわけですね。

そんな「インフラとアプリケーションの両方を含めたシステム全体のコードをGitを使って管理する」GitOpsの考え方を実現してくれる便利なツールです。

環境構成

今回ArgoCDを構築する環境のシステム構成はこのようなものになります。

  • お手軽に構築できるよう手順をなるべく簡略化させた結果、VPCを2つに分けました

  • Gitlabの部分はGithubを使用しても問題ありません

構成図

構築手順

構築手順は以下の通りです。 AWSアカウントは作成済であることを前提にしているだけで、何もないところから構築できる手順にしました。

  1. ManagementサーバやGitlabサーバを配置するVPC、ネットワーク設定、サーバの構築

  2. EKSの構築

  3. ECRにレポジトリを作成

  4. ArgoCDの導入

  5. ECRレポジトリにテスト用Nginxのimageをpush

  6. GitlabにマニフェストをCommit

  7. ArgoCDに同期設定を作成

手順は、AWSコンソール上での操作は極力減らしてコードで構築するようにしています。 コードに記載された細かいパラメータの解説をしたいところですが、今回は割愛します。

また、手順が長いので、このページでは1~3について記載します。 5~9の手順は、ArgoCD構築ガイド(ArgoCD編)をご参照ください。

ManagementサーバやGitlabサーバを配置するVPC、ネットワーク設定、サーバの構築

まずはこの赤枠の部分を作成します。

今回はオハイオリージョンで構築します。 私の検証環境の東京リージョンのVPCの数が制限値に達していたためです。 オハイオ以外のリージョンで構築する場合は、適宜書き換えてください。

オハイオの場所はここですね。旅行気分で構築しましょう。

AWSコンソールにログイン、オハイオを選択

EC2 > キーペアをクリックし[キーペアを作成]をクリックします。 名前に任意の名前を入力し、プライベートキューファイル形式は[.pem]を選択後、[キーペアを作成]をクリック

グローバルIPアドレスを確認

以下のアドレスに接続し、自身のグローバルIPアドレスを確認する。 (「グローバルIPアドレス」で検索すると一番上に表示されるページです)

http://www.cman.jp/network/support/go_access.cgi

Cloud Formationで一気に構築します。

以下の内容のテキストファイル"ec2.yaml"を作業端末で作成します。

  • Git用にGitlabを構築しない場合は、[EC2GITLAB]から下の定義は削除してください

  • オハイオ以外の環境で構築する場合は、"ImageId"をの値をそのリージョンのAMIIDに置き換えてください

AWSTemplateFormatVersion: "2010-09-09"

Description: Provision EC2 for Managment server

Parameters: 
  # keypair名とグローバルIPアドレスは入力する形式でインプット
  KeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: "AWS::EC2::KeyPair::KeyName"

  MyIP:
    Description: IP address allowed to access EC2
    Type: String

Resources:
  # VPCの作成
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      Tags:
        - Key: Name
          Value: my-vpc

  # インターネットゲートウェイの作成
  IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: my-igw

  # インターネットゲートウェイをVPCに紐づけ
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW

  # サブネットの作成
  PubSub:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2a
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      Tags:
        - Key: Name
          Value: my-pub-sub-a

  # ルーティングを作成
  PubSubRT:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: my-pub-sub-a-rt

  # インターネットゲートウェイへのルーティングを設定
  PubSubToInternet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PubSubRT
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW

  # ルーティングをサブネットに紐づけ
  AssoPubSubRT:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PubSub
      RouteTableId: !Ref PubSubRT

  # EC2にアタッチするIAMroleの作成
  EC2Role:
    Type: AWS::IAM::Role
    Properties:
      Path: /
      RoleName: !Sub mgmt-EC2Role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      MaxSessionDuration: 3600
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/AdministratorAccess

  # IAMroleのインスタンスプロファイルを作成
  InstanceProfile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      Path: '/'
      Roles:
        - !Ref EC2Role
        
  # ManagementSeverのEC2を作成
  # この後必要となるコマンドをインストールしています。
  EC2MGMT: 
    Type: AWS::EC2::Instance
    Properties: 
      # us-east-2 Amazon Linux 2 Kernel 5.10 AMI 2.0.20230119.1 x86_64 HVM gp2
      ImageId: ami-05bfbece1ed5beb54
      KeyName: !Ref KeyName
      InstanceType: t2.small
      IamInstanceProfile: !Ref InstanceProfile
      SecurityGroupIds: 
        - !Ref SGMGMT
      SubnetId: !Ref PubSub
      UserData: !Base64 |
        #!/bin/bash

        # eksctl isntall
        curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
        sudo mv /tmp/eksctl /usr/local/bin

        # kubectl isntall
        curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.0/bin/linux/amd64/kubectl
        chmod +x ./kubectl
        sudo mv ./kubectl /usr/local/bin/kubectl

        # docker isntall
        yum install -y docker
        systemctl start docker
        usermod -a -G docker ec2-user
        systemctl enable docker
      Tags:
          - Key: Name
            Value: my-ec2-for-management

  # ElasticIPアドレスを作成
  ElasticIPMGMT:
    Type: "AWS::EC2::EIP"
    Properties:
      Domain: vpc

  # ElasticIPアドレスをManagementSeverに紐づけ
  ElasticIPAssociateMGMT:
    Type: AWS::EC2::EIPAssociation
    Properties: 
      AllocationId: !GetAtt ElasticIPMGMT.AllocationId
      InstanceId: !Ref EC2MGMT

  # ManagementSever用のセキュリティグループを作成
  SGMGMT:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: my-sg-for-mgmt
      GroupDescription: Allow SSH and HTTP access only MyIP
      VpcId: !Ref VPC
      SecurityGroupIngress:
        # ssh
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref MyIP

  # GitlabServerのEC2を作成    
  EC2GITLAB: 
    Type: AWS::EC2::Instance
    Properties: 
      # us-east-2 Canonical, Ubuntu, 20.04 LTS, amd64 focal image build on 2023-01-12
      ImageId: ami-00149760ce42c967b
      KeyName: !Ref KeyName
      InstanceType: t2.large
      SecurityGroupIds: 
        - !Ref SGGITLAB
      SubnetId: !Ref PubSub
      BlockDeviceMappings: 
      - DeviceName: "/dev/xvda"
        Ebs: 
          VolumeSize: 15
          VolumeType: "gp2"
      UserData: !Base64 |
        #!/bin/bash
        sudo apt update
        cd /tmp
        curl -LO https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh
        sudo bash /tmp/script.deb.sh
        sudo apt install gitlab-ce
      Tags:
          - Key: Name
            Value: my-ec2-for-gitlab

  # GitlabServer用のセキュリティグループを作成    
  SGGITLAB:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: my-sg-for-gitlab
      GroupDescription: Allow SSH and HTTP access only MyIP
      VpcId: !Ref VPC
      SecurityGroupIngress:
        # http
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: !Ref MyIP
        # ssh
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: !Ref MyIP

  # GitlabServer用のElasticIPアドレスを作成    
  ElasticIPGITLAB:
    Type: "AWS::EC2::EIP"
    Properties:
      Domain: vpc

  # ElasticIPアドレスをGitlabServerに紐づける    
  ElasticIPAssociateGITLAB:
    Type: AWS::EC2::EIPAssociation
    Properties: 
      AllocationId: !GetAtt ElasticIPGITLAB.AllocationId
      InstanceId: !Ref EC2GITLAB

CloudFormation > スタック をクリックし、[スタックの作成 ] > [新しいリソースを使用(標準)]をクリックする。

[テンプレートファイルのアップロード]をクリックし、[ファイルの選択]をクリック後、cfn.yamlを指定しアップロードする。

スタックの名前に"cfn-argocd"(任意)を、KeyNameに作成したキーペア名"my-keypair"を、MyIPにグローバルIPアドレスの末尾に"/32"を付与した値を設定し、[次へ]をクリックする。

スタックオプションの設定で、[次へ]をクリックする。

レビュー では、[AWS ~承認します。]にチェックを入れて、[送信]をクリックする。

cfn-argocdのステータスがCREATE COMPLETEとなったことを確認します。

これでManagementServerとGitlabSeverが構築され、sshログインができるようになりました。

では次にManagementServerにログインしEKSを構築しましょう。

EKSの構築

次にこの赤枠の部分(ArgoCDとテスト用のNginxを除く)を構築します。

EC2 > インスタンスから構築した"my-ec2-management"を選択し、パブリックIPv4アドレスをコピーする。

SSH接続ツール(画面はTeraterm)を起動し、"my-ec2-management"のパブリックIPv4アドレスを入力し、[OK]をクリックする。

セキュリティ警告が表示されるので、[続行]をクリックする。

ログイン名に"ec2-user"を入力し、[RSA/DSA~を使う]を選択後、秘密鍵にkey-pairを作成したときにダウンロードしたファイルを指定し、[OK]をクリックする。

ログインできることを確認する。

以下の内容のyamlファイルを作成する。

vi eks.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: my-eks
  region: us-east-2

nodeGroups:
  - name: my-eks-node
    instanceType: m5.large
    desiredCapacity: 3
    minSize: 3
    maxSize: 6
    iam:
      attachPolicyARNs:
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
        - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
        - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      withAddonPolicies:
        autoScaler: true
        albIngress: true
        externalDNS: true
        certManager: true
    privateNetworking: true
    ssh:
      allow: true
      publicKeyName: my-keypair
    volumeSize: 30
    amiFamily: "AmazonLinux2"
    availabilityZones:
      - "us-east-2a"
      - "us-east-2b"
      - "us-east-2c"

eksctlコマンドでEKSを構築します。 バックグラウンドでcloudformationからclusterとworkernodeが作成され、各種リソースが作成されます。 この処理は長いので、30分程度待機すること。

eksctl create cluster -f eks.yaml

WokernodeがReady状態であることを確認する。

kubectl get node

Podが全てReady状態であることを確認する。

kubectl get pod -A

コンテナからgitlabへの接続が可能となるように、セキュリティグループに追加する。

VPC > NAT ゲートウェイをクリックする。EKSクラスター作成時にNATゲートウェイが作成されているので、これのElasticIPアドレスを確認する。

VPC > セキュリティグループをクリックする。"my-sg-for-gitlab"のセキュリティグループの詳細画面を表示し、[インバウンドのルールを編集]をクリックする。

[ルールの追加]をクリックし、タイプはHTTP、ソースにNATゲートウェイのElasticIPアドレス(末尾に/32を付与)を設定し[ルールを保存]をクリックする。

設定が追加されたことを確認する。

ECRにレポジトリを作成

次にこの赤い部分のECRレポジトリ作成します。

aws ecr create-repository --repository-name nginx --image-scanning-configuration scanOnPush=true --region us-east-2

まとめ

このページではインフラ編として、コンテナ環境を動かすために必須となるEKSとECRレポジトリの作成までを実施しました。 参考になったら幸いです。

続きのArgoCD編ではArgoCDを駆使して、コンテナ上にテスト用のNGINXをデプロイします!

【あわせて読みたい関連記事】


執筆者プロフィール:北野 啓史
ITベンダーで13年間インフラエンジニアとして金融、人材などのお客様のITシステムの開発に携わってきた。
SHIFTには2021年に入社し、現在はコンテナ基盤のインフラ設計・構築を担当している。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/

PHOTO:UnsplashMarkus Spiske

みんなにも読んでほしいですか?

オススメした記事はフォロワーのタイムラインに表示されます!