EKSとJenkinsの連携について

目的

jenkinsからEKSへのCI/CDを実現させる。
CI = 継続的インテグレーション
CD = 継続的デリバリー
CI/CDを実現させる事により、都度手動でのリリースは不要になり
git等でソースがコミットされたタイミングで自動リリースすることが可能となる。

前提

  • jenkinsの操作、AWSの操作が一通り出来る読者を対象とする。
  • OSはcentosを使用する。
  • Dockerがインストール済みであること。
  • EKSは作成済みであること。
  • awsコマンドが使用可能であること。

AWS側の準備

  1. AWS Identity and Access Management(以下IAM)でjenkinsユーザーを作成する。

    ※ユーザー名「jenkins」とする。
    必要に応じて権限を設定する。※以下はECRにPushPull出来る権限設定をAWSコンソールで設定する

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowPushPull",
          "Effect": "Allow",
          "Action": [
            "ecr:GetDownloadUrlForLayer",
            "ecr:BatchGetImage",
            "ecr:BatchCheckLayerAvailability",
            "ecr:PutImage",
            "ecr:InitiateLayerUpload",
            "ecr:UploadLayerPart",
            "ecr:CompleteLayerUpload",
            "ecr:GetAuthorizationToken"
          ],
          "Resource": "*"
        }
      ]
    }

jenkins(Docker)のインストール

以下はceontosのコンソールで実行する

  1. jenkinsイメージのカスタムDockerfileを作成する
    jenkinsでkubectl、awscliを使用出来るように、centos上で以下のDockerfileを作成する。
    ※コマンド実行はホームディレクトリ(~/)で行う

    FROM jenkins/jenkins:2.277.1-lts
    
    USER root
    
    ## kubectl
    RUN wget -O /tmp/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.19.3/bin/linux/amd64/kubectl
    RUN chmod +x /tmp/kubectl
    RUN mv /tmp/kubectl /usr/local/bin/kubectl
    
    ## aws cli
    RUN wget -O /tmp/awscliv2.zip https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip
    RUN unzip /tmp/awscliv2.zip -d /tmp
    RUN /tmp/aws/install
    
    USER jenkins
  2. Dockerタグ「jenkins/jenkins:eks」を指定してビルドを行う

    docker build -t jenkins/jenkins:eks .
  3. docker-compose.ymlを作成する
    以下のdocker-compose.ymlを作成し実行する。※マウント先の「/srv/jenkins」は作成しておく

    sversion: '3.8'
    services:
      jenkins:
        image: jenkins/jenkins:eks
        container_name: 'jenkins'
        ports:
          - 8080
          - 5000:5000
        volumes:
          - /srv/jenkins:/var/jenkins_home
        restart: always
        environment:
          TZ: Asia/Tokyo
  4. Dockerをバックグラウンドで起動する。

    docker-compose -f docker-compose.yml up -d
  5. jenkins(http://localhost:8080)にアクセスしAdmin設定、プラグインの設定を行ってインストール完了

jenkinsとEKSを連携させる

以下はceontosのコンソールで実行する

  1. jenkinsのawsコマンドを設定する。
    マウントした場所「/srv/jenkins/」に「.aws」ディレクリを作成する。

    mkdir /srv/jenkins/.aws

    上記で作成した「.aws」以下にconfigファイルを作成

    vi /srv/jenkins/.aws/config
    [default] 
    region = ap-northeast-1 
    output = json

    上記で作成した「.aws」以下にcredentialsファイルを作成

    vi /srv/jenkins/.aws/credentials

    [default]
    aws_access_key_id = XXXXXXXXXXXXXXXXx
    aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXX

    ※「■AWS側の準備」で作成した「jenkins」ユーザーのアクセスキー、パスを設定する

    所有者をjenkinsに変更

    chown 1000. /srv/jenkins/.aws -R
  2. jenkins上のkubectlコマンドを設定する。
    EKSの設定を取得する。※コマンド実行はホームディレクトリ(~/)で行う

    aws eks --region ap-northeast-1 update-kubeconfig --name cluster-name

    ※「ap-northeast-1」「cluster-name」は自分の環境に合わせて変更すること
    上記コマンドで「~/.kube」作成されるのでそのファイルをjenkinsマウントポジションにコピー

    cp ~/.kube /srv/jenkins

    所有者をjenkinsに変更

    chown 1000. /srv/jenkins/.aws

jenkinsユーザーからkubectlを実行できるようにする

以下はceontosのコンソールで実行する

  1. aws-authにjenkinsユーザーを追加する。
    kubectlコマンドでEKSのaws-authを編集する。

    kubectl edit -n kube-system configmap/aws-auth
    apiVersion: v1
    data:
      mapRoles: |
        - rolearn: <arn:aws:iam::111122223333:role/eksctl-my-cluster-nodegroup-standard-wo-NodeInstanceRole-1WP3NUE3O6UCF>
          username: <system:node:{{EC2PrivateDNSName}}>
          groups:
            - 
            - 
      mapUsers: |
        - userarn: <arn:aws:iam::111122223333:user/admin>
          username: 
          groups:
            - 
    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ この部分を追加する ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
      mapUsers: |
        - userarn: arn:aws:iam::XXXXXXXX:user/jenkins
          username: jenkins
          groups:
            - system:masters
    ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ この部分を追加する ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

jenkinsのpipeline等でkubectlコマンドを使用してEKSに連携する

以下はjenkinsのjob設定でテスト作成する。

  1. Jenkinsfileを作成する。

    pipeline {
        agent any
    
        // 環境変数
        environment {
            // k8sの設定ファイル
            KUBECONFIG = "${env.JENKINS_HOME}/.kube/config"
        }
        // デプロイ
        stages {
            stage('deploy'){
                steps {
                    // k8s deploy
                    sh "kubectl apply -f ${env.WORKSPACE}/test.yaml"
                }
            }
        }
    }
  2. 実行結果にkubectlの実行でエラーが出ていなければ連携完了。

Smallitのサービス