Kubernetes CLIオンリーのデプロイ環境構築

わざわざJenkinsを立てるのはかったるい、でもデプロイユーザーは欲しい。
そんなわがままな構成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56925/fa14ba94-1d13-aa19-d617-e404c8a5ba3c.png)
Github, aws ECR, k8s(not EKS)という構成。deployサーバはk8sとは別だがEC2。
②～⑥までをSkaffoldが行います。

# tl;dr

deployユーザーを作成し、skaffold runできるところまでの要点をまとめています。

# Deployサーバのユーザー調整

Dockerはインストールしてdeployサーバ上で動かしておいてください。
k8sは、deployサーバから管理者ユーザーからkubectlが一通り動くようにしておいてください。(deployユーザーは別途作ります)

## POSIXユーザー作成

Deployサーバに普通にadduserしてください。sudo権限はいりません。今回はdeployユーザーとします。

## Github DeployKey登録

レポジトリのSettingsからDeploy Keysってのを登録できます。
`sshkeygen -t ed25519` とかで作ってください。

## ssh 秘密鍵作成

Githubへのアクセス権限とサーバへのアクセス権限は変わってくるので別で作っておくことをお勧めします。
きょうびed25519でよいでしょう。
~/.ssh/authorized_keysに追加するのをお忘れなく。

## sudoなしでdockerコマンドを実行できるように。

こちらを参考に。
https://qiita.com/DQNEO/items/da5df074c48b012152ee
deployユーザにsudo権限はつけないほうがいいので別ユーザーでdeployユーザーをdocker groupに入れてあげておくれまし。
dockerdの再起動とdockerユーザーの再ログインが必要です。

## k8s ServiceAccount, Role, RoleBinding作成

deployユーザーでk8sのクラスタにアクセスできるようにします。
awsのセキュリティグループで、deployサーバからk8sのapiにアクセスできるようにするのを忘れないようにしましょう。デフォルトだと6443番とか？

https://qiita.com/murata-tomohide/items/a8a6d66534f55491bd01 を参考にdeployユーザーのサービスアカウントを作成して、ロールを作ります。

※RoleBindingにしてnamespaceを限定しようとしたのだが、Skaffoldする際にクラスターの読み取りができないと怒られた。`could not fetch deployments: could not fetch deployments: deployments.apps is forbidden: User "system:serviceaccount:[namespace]:deploy" cannot list resource "deployments" in API group "apps" at the cluster scope` と言われる。

ClusterRole/viewとnamespace内はフルアクセスできるRoleを作った。(viewはデフォルトである)
下のような感じ。

```

cat <<EOF | kubectl apply -f -

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: [namespace]-rolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
- kind: ServiceAccount
  name: deploy
  namespace: [namespace]

EOF



cat <<EOF | kubectl apply -f -

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: [namespace]-rolebinding
  namespace: [namespace]
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: service-deploy-role
subjects:
- kind: ServiceAccount
  name: deploy
  namespace: [namespace]

EOF


cat <<EOF | kubectl apply -f -

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: service-deploy-role
  namespace: [namespace]
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'

EOF


```


# aws ECR

Elastic Container Registryの略、Dockerのレジストリですね。
deployサーバからはpushが行える必要があり、k8sのクラスタからはpullができる必要があります。
EC2ロールを使うか、IAMでユーザー作るかはあなた次第。

- ECRリポジトリ作成
- ポリシー調整
  - 今回はRoleを付けました。ポリシーはecr:なんちゃら、既存のならばAmazonEC2ContainerRegistryなんちゃらです。

VPCエンドポイントを作成するのを忘れないようにしてください。https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html#ecr-vpc-endpoint-considerations
ようするに、VPCエンドポイントでECRへのアクセスは内側を通るように設定しましょう。ということです。今回はs3に加えてecrを設定しました。

# k8s ECR設定

今回はEC2内のノードなので、AmazonEC2ContainerRegistryReadOnlyポリシーEC2のIAMロールに当てました。
ロール使っているのでsecretなどの設定は不要です。

# github からソースを持ってくる。

githubのDeploykeysを使ってソースを落とします。
環境変数GIT_SSH_COMMANDを入れれば指定した鍵を使ってくれます。（必ずしも~/.gitconfigに書く必要はありません）

`$ GIT_SSH_COMMAND='ssh -i ~/.ssh/hogehoge' git clone`

# Skaffoldでpushする

最初にECRのログインパスワードを取得してログインしておくのを忘れないようにしてください。ECRのpushコマンドの1個目です。（セッション切れ次第再度実行する必要があり〼。）
`aws ecr get-login-password --region [region] | docker login --username AWS --password-stdin [repoURL]`

マニフェストは
build.artifacts[].imageにECRのリポジトリのURLを入れます。tagはなくてもOKです。同じようにk8sのyamlも変えます。
build.local.pushをtrueにします。

https://qiita.com/murata-tomohide/items/5f40a8e6528ecf2e3794


# できた

これでdeployサーバからdockerユーザーで一連のデプロイが行えるようになっているはずです。
shell等にしておけば一発ですね。（じゃあJenkinsでええやｒ、k8sならJenkinsXつかえｙ）
今回は要点だけにして、コマンド等は端折りました。（手抜き

みなさんデプロイオペレーションは自分のPCで行わないようにしましょう。お兄さんとの約束だ。