EKSコマンドメモ

EKS関連

  • EKSへのログイン
$ aws eks --region ap-northeast-1 update-kubeconfig --name eks-test

K8メモ

  • コンテキストのリストの表示
$ kubectl config get-contexts
  • 現在のコンテキストの表示
$ kubectl config current-context
$ kubectl get po --selector=app=nginx --all-namespaces

terraformでfileを相対パス記載する

terraform version

  • 0.12以上

記載方法

  • module内にてfileを相対パスで指定したい場合、${path.module}が使える
    • 例えば"${path.module}/cert/sample.pem"でファイルのパスを作ってくれる(相対パスを作成してくれる)

具体例

  • certのpemを指定する場合(ファイルを展開したい場合)
    • moduleのcertディレクトリにあるファイルを指定したい
    • /path/to/module/cert/sample.pemを指定する
resource "aws_iot_certificate" "cert" {
  csr    = file("${path.module}/cert/sample.pem")
  active = true
}

memo

CodeCommitでDinDするときのメモ

サンプルbuildspec.yml

version: 0.2

phases:
  install:
    commands:
      - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2&
      - timeout 15 sh -c "until docker info; do echo .; sleep 1; done"
  pre_build:
    commands:
      - docker info
      - aws sts get-caller-identity
      - aws eks update-kubeconfig --name ${EKS_CLUSTER_NAME}
  build:
    commands:
      - echo build
      - kubectl get all

ポイント

docs.aws.amazon.com

  • installフェーズでdockerの起動をする
  install:
    commands:
      - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2&
      - timeout 15 sh -c "until docker info; do echo .; sleep 1; done"

AWS EKSをCodePipelineから操作するメモ

内容

  • CodeBuildeでkubectl applyを実施したい
  • エラーerror: You must be logged in to the server (Unauthorized)
    • CodeBuildでkubectlしたいが、このエラーが出てしまう

参考ページ

dev.classmethod.jp

qiita.com

メモ

  • 基本的に上記クラスメソッドさんのブログのように進めればOK
    1. EKS, EKSノードグループ作成
    2. CodePipeline, CodeBuild作成
    3. CodeBuildのロールの調整(CodeBuildがkubectlできるようにする)

上記 CodeBuildのロールの調整(CodeBuildがkubectlできるようにする)これでハマった

  • 上記ブログにもあるように、EKSクラスタのConfigMap情報を編集する必要がある
    • CodeBuildがEKSクラスタにアクセスできるような設定にしてやる必要がある
  • EKSクラスタにログインできるコンソールから以下のコマンドを実行してaws-auth
$ kubectl edit -n kube-system configmap/aws-auth

これでCodebuilで使用するロール情報を追記してやる必要がある

    - rolearn: <CodeBuildのサービスロールのARN>
      username: codebuild
      groups:
        - system:masters

これを追記

CodeBuildのサービスロールのARNについて

  • CodeBuildにアタッチしてあるロールを見てみると以下のようになってる
    • arn:aws:iam::xxxxxxxxx:role/service-role/codebuild-role
  • このarnrolearnとして記載してもうまくいかない
  • 上記Qiitaブログに書いてあるが
○: arn:aws:iam::xxxxx:role/codebuild-hoge-service-role
×: arn:aws:iam::xxxxx:role/service-role/codebuild-hoge-service-role

ということらしい

DockerにDocker in docker, aws-cli, kubectlをインストール

目的

  • Docker in docker実現したい
  • AWS-cli入れたい
  • kubectl入れたい

以上を1コンテナで。

結論

FROM docker:stable-dind

WORKDIR /k8s

# aws cliの実行が失敗するので、glibcのverupしてインストール
# https://github.com/aws/aws-cli/issues/4685#issuecomment-615872019
ENV GLIBC_VER=2.31-r0

# install glibc compatibility for alpine
RUN apk --no-cache add \
        binutils \
        curl \
    && curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-${GLIBC_VER}.apk \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk \
    && apk add --no-cache \
        glibc-${GLIBC_VER}.apk \
        glibc-bin-${GLIBC_VER}.apk \
    && curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip \
    && unzip awscliv2.zip \
    && aws/install \
    && rm -rf \
        awscliv2.zip \
        aws \
        /usr/local/aws-cli/v2/*/dist/aws_completer \
        /usr/local/aws-cli/v2/*/dist/awscli/data/ac.index \
        /usr/local/aws-cli/v2/*/dist/awscli/examples \
    && apk --no-cache del \
        binutils \
        curl \
    && rm glibc-${GLIBC_VER}.apk \
    && rm glibc-bin-${GLIBC_VER}.apk \
    && rm -rf /var/cache/apk/*

# install kubectl
RUN apk --no-cache add \
  curl && \
  curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \
  chmod +x ./kubectl && \
  mv ./kubectl /usr/local/bin/kubectl 

DinDの実行

  • 一度dockerコンテナをバックグラウンドで実行してからじゃないとDinDはうまく動かないとか。
$ docker image build -t dind .
$ docker container run --rm -it --privileged -d --name dindcontainer dind
$ docker exec -it dindcontainer sh
# コンテナ内で
$ docker info

Docker in docker

FROM docker:stable-dind

AWS-cli

  • 現状不具合があるのか、普通にコンテナ上にインストールするだけではうまくいかない様子。

github.com

ENV GLIBC_VER=2.31-r0

# install glibc compatibility for alpine
RUN apk --no-cache add \
        binutils \
        curl \
    && curl -sL https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-${GLIBC_VER}.apk \
    && curl -sLO https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VER}/glibc-bin-${GLIBC_VER}.apk \
    && apk add --no-cache \
        glibc-${GLIBC_VER}.apk \
        glibc-bin-${GLIBC_VER}.apk \
    && curl -sL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip \
    && unzip awscliv2.zip \
    && aws/install \
    && rm -rf \
        awscliv2.zip \
        aws \
        /usr/local/aws-cli/v2/*/dist/aws_completer \
        /usr/local/aws-cli/v2/*/dist/awscli/data/ac.index \
        /usr/local/aws-cli/v2/*/dist/awscli/examples \
    && apk --no-cache del \
        binutils \
        curl \
    && rm glibc-${GLIBC_VER}.apk \
    && rm glibc-bin-${GLIBC_VER}.apk \
    && rm -rf /var/cache/apk/*

kubectl

RUN apk --no-cache add \
  curl && \
  curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \
  chmod +x ./kubectl && \
  mv ./kubectl /usr/local/bin/kubectl 

メモ[10 things you (probably) don't know about Go]

メモ

  • 10 things you (probably) don't know about Go このメモがとても参考になったので忘れないようにメモ

1. Anonymous structs

var config struct {
    APIKey      string
    OAuthConfig oauth.Config
}

config.APIKey = "BADC0C0A"

7. Method expressions

talks.golang.org

type T struct {}
func (T) Foo(s string) { println(s) }

var fn func(T, string) = T.Foo

Goのhttpリクエストのmockについて

Goでhttpリクエス

いくつか方法はあるようだが、

client := &http.Client{
    CheckRedirect: redirectPolicyFunc,
}

resp, err := client.Get("http://example.com")
// ...

req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

こっちの書き方でクライアントを実装する(http.Clientを使用する)

実装コード

github.com

httpmockを使わない例

  • 以下のように実装できる(説明のためにちょっと修正)
type HttpClient interface {
    Do(req *http.Request) (*http.Response, error)
}

func NewContentUsecase(c HttpClient) *ContentUsecase {
    return &ContentUsecase{
        httpClient: c,
    }
}

type ContentUsecase struct {
    httpClient HttpClient
}

func (content ContentUsecase) GetContent() (string, error) {
    request, _ := http.NewRequest("GET", "https://google.com", nil)
    resp, _ := content.httpClient.Do(request)
    defer resp.Body.Close()
    byteArray, _ := ioutil.ReadAll(resp.Body)

    return string(byteArray), nil
}
  • キモとなるのはGetContentの引数に渡されてくるContentUsecase
  • このContentUsecaseHttpClientインターフェースを満たしており、それを引数で注入する
  • テスト時にはこの引数に渡すものをmockすれば良い

テスト(httpmockを使わない例)

type clientMock struct {
    HttpClient
    MockedDo func(req *http.Request) (*http.Response, error)
}

func (c *clientMock) Do(req *http.Request) (*http.Response, error) {
    return c.MockedDo(req)
}

func TestGetContent(t *testing.T) {
    t.Run("GetContent正常系", func(t *testing.T) {
        spyMocked := &clientMock{
            MockedDo: func(req *http.Request) (*http.Response, error) {
                return &http.Response{
                    StatusCode: http.StatusOK,
                    Body:       ioutil.NopCloser(bytes.NewBufferString("OK")),
                }, nil
            },
        }
        contentUsecase := NewContentUsecase(spyMocked)
        content, err := contentUsecase.GetContent()

        if err != nil {
            t.Errorf("err should be nil: %v", err)
        }

        if content != "OK" {
            t.Errorf("Returned Content invalid: %v", content)
        }
    })
}
  • HttpClientインターフェースの中身をMockする(Do関数を置き換える)
  • 実際のテストコードの中でDo関数が何を返すのかを実装してやれば良い(MockedDoを実装する)

httpmockを使う例

  • こっちのほうはとても簡単
  • でも、標準ライブラリのみで使える前者のほうがいいんではないかとか思ったりする

  • 一部プログラム変更してあります(エラーハンドリングなど)

func GetContentUseMock() (string, error) {
    request, _ := http.NewRequest("GET", "https://example.com", nil)
    client := &http.Client{}
    resp, _ := client.Do(request)
    defer resp.Body.Close()
    byteArray, _ := ioutil.ReadAll(resp.Body)

    return string(byteArray), nil
}

テスト

func TestGetContentUseMock(t *testing.T) {
    t.Run("GetContentUseMock正常系", func(t *testing.T) {
        httpmock.Activate()
        defer httpmock.DeactivateAndReset()

        httpmock.RegisterResponder("GET", "https://example.com",
            func(req *http.Request) (*http.Response, error) {
                res := httpmock.NewStringResponse(200, "ok")
                return res, nil
            },
        )

        content, err := GetContentUseMock()
        if err != nil {
            t.Errorf("error should be nil: %v", err)
        }

        if content != "ok" {
            t.Errorf("content invalid: %v", content)
        }
    })
}
  • RegisterResponderに何を返すのかを書くだけ。