ガチ初心者がKubernetesでコンテナを立てる？まで・・・


#「Java Küche」のイベントに参加した！
2019/08/23の実施されたイベント「Kubernetes ハッカソン~Docker と Kubernetes にどっぷり浸かる二日間！ ~」を振り返る記事。

講師
  Microsoft・アドボケイト： 寺田 佳央さん

ありがとうございました。m(_ _)m



#流れ
今回は、踏み台用の環境としてのUbuntu、そしてDockerfileのpush先、さらにKubernetesを動かす環境の、計3つのリソースをAzureで作成する。

内容としては、
UbuntuでDockerイメージ作成。
Azure Container Registry (以下、ACR) にpushする。
Azure Kubernetes Service (以下、AKS) で、コンテナを起動する。
までを紹介する。

必要なファイルや情報は、寺田さんが大変綺麗にまとめてくださってます。
GitHubリンク： https://github.com/yoshioterada/k8s-Azure-Container-Service-AKS--on-Azure


よし！やっていこう！

#Outlookアカウント作成
  リンク： https://signup.live.com/signup
  ※この時に、hotmail.comでないとAzureアカウントの作成でエラーする？？



#Azureアカウント作って、クレジットカード登録する
  Azureのログインページ： https://portal.azure.com/#home
  ※クレジット登録してないと、Ubuntuのリソースを作ろうとしたときに再足される。

#Ubuntuのリソースを作成する
Azureのコンソール画面にて、「Create a resource」をクリック。
Ubuntu 18.04 LTS版を作る
  Resource gropは新規で作成！仮想マシン名も同じ。
  リージョンは、「東日本」
  SSH公開キーを「パスワード」
  sshの許可する

#作ったUbuntu環境にsshでアクセスする。
  ※resourceの詳細画面で、sshするときのip(パブリックIP)を調べとく。
  例) `ssh userName@ipAdress`


#Dockerをインストール
参考記事： https://qiita.com/myyasuda/items/cb8e076f4dba5c41afbc

  `sudo apt-get update`

  `sudo apt-get install apt-transport-https ca-certificates curl software-properties-common`

  `curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -`

  `sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable test edge"`

  `sudo apt-get update`

  `sudo apt-get install docker-ce`

  `docker --version`

#Azure CLIのインストール
  この後、ACR, AKSと連携したい。ので、AzureCLIをインストールするぞ！
参考記事： http://aka.ms/az-cli-install-jp
  `curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash`


// Dockerfileの作成と、Dockerイメージの違いが・・・
  ※Dockerfileは、Dockerイメージの為のレシピ。作り方、材料が書いてある。
  ※docker buildでイメージが作れる。らしい。

#Dockerfileを、Git Cloneする
  ※今回は寺田さんが、GitHubで公開してくれているやつを使わえてもらう。
めっちゃ感謝してます！！！！！
(>ω<)

移動
  `cd FrontService`

Dockerfileを眺めてみる
  `cat 0-Dockerfile-for-Maven`

  ※たくさん使うライブラリ郡を毎回ダウンロードするのは大変なので、それらを一度ダウンロードして、イメージとして作っておく。次からは、そのイメージを読み込むだけで良い。よく依存しそうなものは、イメージを作っておくのをオススメする。らしい。

  `docker build -t maven-include-localrepo:1.1 . -f 0-Dockerfile-for-Maven`
  ※sudo su で入っておいた方が良いかも。
  

  さっきのbuildできたか、確認。
  `docker images`

#Azure Container Registry の作成
  // Kubernetesは、ACR経由でDockerイメージを取りに来るイメージ。だと思う。
  // docker hubのプライベート版てきなやつかな？

  作ったイメージを、さっき言ったAzure Continer Registryにpushしたいので、先に作っておく。

  参考記事： https://github.com/yoshioterada/DEIS-k8s-ACS/blob/master/CreateAzureContainerRegistry.md
  ブラウザにてリソースを作成
  レジストリ名は、適当に決める。
  リソースグループは新規で適当に決める。
  管理ユーザーは有効にしといた。

#続けて、ACRへログイン
  ※docker login する。コマンドの引数として、user名とACRのドメインを与える。
  docker login -u [user名] [xxx.azurecr.io]
  の後に、パスワードを入力する

  ※必要な情報は、詳細画面でアクセスキーで確認できる。
  ※詳細画面で得られる情報 {
    user : 〇〇
    login-server: 〇〇〇〇.azurecr.io
    pass: 〇〇〇〇〇〇〇〇
  }


#Dockerイメージ作成とpushの準備

  // ACRへの認証はやった。(docker loginで。)
  ※イメージを作ると、コンテナが作れる。動いてる実態はコンテナ。

Dockerイメージの作成と、ACRへのpushを、.shファイル(2-build-create.sh)に寺田さんがまとめてくれてる。ので、shをコマンドで起動させれば良いらしい。が、そのpushするイメージの指定と、push先のリポジトリの2箇所はviで編集してね！

  ※ viでの編集箇所 
`vi 2-build-create.sh`
`    DOCKER_IMAGE=〇〇〇〇/front-spring-service   
    DOCKER_REPOSITORY=〇〇〇〇.azurecr.io   `
※ DOCKER_IMAGEには、ACRのuser名： fullund2。/の後には、imagesの名前(ここで付けた名前がイメージの名前になるっぽい。今回は、front-spring-serviceで行こう！)

#ACRへpushする
  ※コマンドを打つときに、バージョン指定を引数で受け取れるので・・・もし、2回目とかなら、2.0とかにしてね！
  `./2-build-create.sh [x.x]`

  ※ブラウザで、pushされているか確認してね！


#今回は試しに少しソースを編集してv2としてイメージ作成してみよう！
  `vi src/main/java/com/yoshio3/frontspring/FrontController.java`
の一番した、returnの文字列を少し変更してみよう！

よし、変更したソースを元に、作成しよう
  `./2-build-create.sh 2.0`
※引数のバージョンは、2.0にしとく。


#動作確認

  イメージの起動
    `docker run -p 8080:8080 -it [REPOSITORY名]:[x.x(TAGの数字)]`

  別タブで新たに開いて、curlでアクセスして確認してみよう！
    `curl http://localhost:8080/sample/hello`



次の目標： AKSでコンテナを立てたい。まずは、ACRにあるイメージを取りに行く！


#Azureページで、Create Kubernetes cluster を作る。

  またリソースグループは、新規で！クラスター名は一緒かな。
  リージョンは、東日本
  Node count 1にする。
  仮想ノードは有効

  HTTP application ・・・ Yes

#Kubectl コマンドのインストール
  `az aks install-cli`

#az-loginしようぜ
  `az login`
  ※ブラウザ経由でログインできる

#AKS接続用の資格情報の取得
  `az aks get-credentials --resource-group [xxxx] --name [xxxx]`
  ※これで、Kubernetesに繋がるようになった。

#試しにコマンドが使えるか確認してみるか
  `kubectl cluster-info`
  とか
  `kubectl get node`

#ACRにあるイメージを、Kubernetesに持ってきたい
 今のままだと、KubernetesがACRへアクセスできない。
なので、3-create-secret4reg.shをviで編集する。

  ※具体的には、ACRへAKSからpullの通信を送りたい。その認証を、3-create-secret4reg.shファイルに書いてある感じ。
  
  `kubectl create secret docker-registry docker-reg-credential --docker-server=〇〇〇〇.azurecr.io --docker-username=〇〇  --docker-password="〇〇〇〇" --docker-email=hoge@example.com  `

  ※うまくいったら、 `kubectl get secret` で確認してみよう！

よし、これでイメージを取りに行く事は出来そう！

#取ってくるイメージ名を修正する

  ※作成したACRサーバー名、コンテナのイメージ名に変更する
  `vi 4-create-deployment-svc.yaml`
  ※修正箇所 30行目。入力する内容としては、docker imagesでの長いやつ。/の後には、verを書けばよい。`
    image: 
    〇〇〇〇.azurecr.io/〇〇/front-spring-service:1.0
  `

  ※少し下も修正する。cpuの0.6を100mに変更。2箇所
  
※1.0を取りにいくなら、上の 
`template:
      metadata:
        labels:
          app: spring-front-service
          version: [ここを、"v1"としておく]`

よし！認証と取りに行くイメージは指定できた。

#実行
  ※applyコマンドを使って、ACRからイメージを取ってきて、コンテナを立てる事が出来る。
  `kubectl apply -f 4-create-deployment-svc.yaml`

#起動しているか確認
  `kubectl get po -w`

#動作確認
  ※実態はKubernetes側で動いてるから、lcoalhostへフォワードするコマンド
    `kubectl port-forward [spring-front-service-〇〇〇〇] 8080:8080`
    ※もし上手くいかなかったら、`docker stop`で動いてるの止める。

  別タブで・・・
    `curl localhost:8080/sample/hello`
    # 結果が表示される


#v2を作って、applyする
  4-create-deployment-svc.yamlを複製して、4-create-deployment-svc-v2.yamlとする。
  `vi 4-create-deployment-svc-v2.yaml` で編集
    ・4行目の  name: spring-front-serviceも末尾に、"-v2"を付けとく。
    ・imagesをいじる。:2.0にすると、v2のイメージを見ることになる。
    ・versionを、v2にする。

  `kubectl apply -f 4-create-deployment-svc-v2.yaml`
  ※なんか、sudo suに入らないと出来なかった。

#v2の起動確認
  `kubectl get po`

// 2つめも、port-forwardして確認すると良いかも。

これで、僕らはk8sで2つのコンテナを立てることに成功した！やった！！


#フィルタリングしてみよう！
  `kubectl get po --selector app=[],version=[v1]`
  -> つまり、selectorを書いて、どのpodへアクセスするか制御できる！！！



次に、Kubernetesでv2のコンテナを起動させて、v1をv2にアップデートさせる方法をやる。

#serviceについて

serviceってのを作って、それを起動させよう。
serviceがpodへのアクセスを仲介する感じ？？

podを実行すると、固定でipが生成されるよね。それってどう管理します？手動って大変。
実はip以外にもpodにアクセスする方法がある。
ipが頻繁に変化することになるのは、良くないですよね。

デプロイの肝
  => serviceを作って、この一意のIPアドレスを覚えてさえいれば、あとは、serviceのselectorでpodを変更できる。
  11-Service.yaml を確認してみよう！

#serviceの起動 
  `kubectl apply -f 11-Service.yaml`

#確認
  `kubectl get svc`

#メリット
  正常に動いているpodを立てたまま、新たなpodに以降できる。
  直ぐに戻す事も出来る！
  これが、kubernetesの凄く良いところ！！！！
  自分自身でやろうとすると、大変。
  yaml編集するだけ。

#ちなみに
  通常は、serviceはtype: ClusterIP！！
  まぁ一瞬だけでも、どうしても外部に公開したいなら、type: LoadBalancerにする。
  でも、よくない。危険。注意してね。

--> serviceが複数ある時、Ingressでまとめて、そのIngressの設定で、pathを設定する事で、URLに応じて呼び出すserviceを分岐できる。


#まとめ： Ingressを外部に公開すると良い。
  IngressでURLを分けて！serviceでpodを分岐する。
  イメージは、serviceのルーティング。受付嬢！！

  マイクロサービスを運営する上で、便利な機能。

#Ingressを修正して立ち上げてみる
  `vi 12-Ingress.yaml`
  修正箇所： `- host: front-service.[〇〇〇〇.aksapp.io]`
  この修正の中身は、ブラウザの、リソースの「HTTP アプリケーションのルーティング ドメイン」から貼り付け
  ※場所的には、ホーム > リソース グループ > [k8s] > [k8s] かな？

#立ち上げ
  `kubectl apply -f 12-Ingress.yaml`

#確認
  `kubectl get ing`

#アクセス
  `http://[front-service.〇〇〇〇.japaneast.aksapp.io]/sample/hello`

一応、イベントの内容はここまで。



#デザインオブフェアーという考え
  壊れる事が前提で、物事を作っていくマインドがないと、kubernetesは触らない方が良い。
  落ちる。影響範囲を小さくする。
  落ちないようにする努力よりも、落ちる前提で考えた方が良い。
  落ちた時の再構築の流れを考える。どこまでデザインオブフェアーをやり通すか。必ず落ちる。

#最後に
本当に寺田さん、ありがとうございました！
正直、Dockerは30分は触ってたので何となく分かったけど、Kubernetesは無知でした。
モブプロだった事も幸いし、なんとか最後まで出来た！！

(*´∀｀*)

後日、知り合いと3人で同じ内容をした。
本記事は、その時の成功例を元に作成した。

繰り返すって大事だなぁ。

Kubernetes、、、というかマイクロサービスをちょっと感じれて良かった。
またやりたい！(^・^)