概要
前回の「初めてのkubernetes(Minikube) Windows環境構築編」を終えて、Kubernetes(以降 k8sとする)の公式チュートリアルを実践した内容と理解したことを残しています
おまけとして公式チュートリアル内にはなかったマニュフェストファイルからデプロイも追加しています
※以下のminikubeコマンドは管理者権限で実行してください
実行環境
- Windows 10 pro
- Minikube v0.28.0
- Docker Version 18.06.1-ce-win73 (19507)
事前準備
後述ではビルドしたDockerイメージをMinikubeにデプロイしますが、Dockerイメージのビルド先はローカル(Moby)のDocker Hostではなく、MinikubeのDocker Hostにビルドするため、以下のように一時的に環境変数を設定します
なお、Docker HubなどのMinikubeが参照できるレジストリからイメージを取得する場合は、こちらの設定は必要ありません
その際はイメージ名は適宜に変更してください
> minikube docker-env --shell powershell
# MinikubeのDocker Hostの環境変数が取得できる
$Env:DOCKER_TLS_VERIFY = "1"
$Env:DOCKER_HOST = "tcp://192.168.1.47:2376"
$Env:DOCKER_CERT_PATH = "C:\Users\user\.minikube\certs"
$Env:DOCKER_API_VERSION = "1.35"
上記の環境変数を設定することでDocker Hostを一時的にMinikube側にします
(コンソールを閉じれば設定が消えますのでご安心を)
> minikube docker-env --shell powershell | Invoke-Expression
前述の環境変数が設定されていることを確認
> Get-ChildItem env:
Minikube内のDockerイメージを参照
k8s関連のイメージがざっと確認できます
> docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/kube-proxy-amd64 v1.10.0 bfc21aadc7d3 5 months ago 97MB
k8s.gcr.io/kube-controller-manager-amd64 v1.10.0 ad86dbed1555 5 months ago 148MB
k8s.gcr.io/kube-scheduler-amd64 v1.10.0 704ba848e69a 5 months ago 50.4MB
k8s.gcr.io/kube-apiserver-amd64 v1.10.0 af20925d51a3 5 months ago 225MB
k8s.gcr.io/etcd-amd64 3.1.12 52920ad46f5b 6 months ago 193MB
k8s.gcr.io/kube-addon-manager v8.6 9c16409588eb 6 months ago 78.4MB
k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64 1.14.8 c2ce1ffb51ed 8 months ago 41MB
k8s.gcr.io/k8s-dns-sidecar-amd64 1.14.8 6f7f2dc7fab5 8 months ago 42.2MB
k8s.gcr.io/k8s-dns-kube-dns-amd64 1.14.8 80cc5ea4b547 8 months ago 50.5MB
k8s.gcr.io/pause-amd64 3.1 da86e6ba6ca1 8 months ago 742kB
k8s.gcr.io/kubernetes-dashboard-amd64 v1.8.1 e94d2f21bc0c 8 months ago 121MB
gcr.io/k8s-minikube/storage-provisioner v1.8.1 4689081edb10 10 months ago 80.8MB
・ログインが必要なセキュアなプライベートレジストリを利用したい場合は、認証情報などを管理する「Secret」に登録すると利用できます
・アンセキュアなプライベートレジストリを利用する場合は、insecure-registry
に登録すれば、利用できます
手始めに
Minikubeのバージョン確認
> minikube version
minikube version: v0.28.0
Minikubeの設定確認
前回の環境構築編で設定した値が確認できます
> minikube config view
- hyperv-virtual-switch: external-switch
- vm-driver: hyperv
~/.minikube/config/config.json
に保存された値が表示されます
kubectlでServer/Clientのバージョン確認
サーバとクライアントのバージョンが異なっていても問題はない
※マイナーバージョン2つ前まで互換性があります
> kubectl version
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.0", GitCommit:"91e7b4fd31fcd3d5f436da26c980becec37ceefe", GitTreeState:"clean", BuildDate:"2018-06-27T20:17:28Z", GoVersion:"go1.10.2", Compiler:"gc", Platform:"windows/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.0", GitCommit:"fc32d2f3698e36b93322a3465f63a14e9f0eaead", GitTreeState:"clean", BuildDate:"2018-03-26T16:44:10Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
kubectlの設定確認
clusterの設定を確認できます
cluster内で共有したい設定値(contexts)も確認できます
> kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority: ~\.minikube\ca.crt
server: https://192.168.1.46:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: ~\.minikube\client.crt
client-key: ~\.minikube\client.key
クラスタの状態確認
> kubectl cluster-info
Kubernetes master is running at https://192.168.1.46:8443
KubeDNS is running at https://192.168.1.47:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Node.jsサンプルアプリケーションをデプロイ
さっそく、公式のNode.jsサンプルアプリケーションを使ってデプロイしていきます
1. サンプルアプリケーションをビルドします
公式サンプルアプリケーションで使用されているDockerfile、server.jsを作成し、以下のようにビルドします
> docker build -t hello-node:v1 ./
2. 作成したDockerイメージをデプロイ(Deployment)します
-
hello-node
・・・Deploymentの名前になります(デプロイの管理単位) -
--image
・・・DeploymentでデプロイされるDockerイメージ -
--port
・・・外部公開用のポート(Minikube内で公開されるポート) -
--image-pull-policy=Never
・・・今回はローカルレジストリのみからDockerイメージを取得するため、Neverとする
> kubectl run hello-node --image=hello-node:v1 --port=8080 --image-pull-policy=Never
3. デプロイの確認
Deploymentの確認
-o wide
を付加するとより多くの情報が表示されるようになります
> kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1 1 1 1 3h
Podの確認
RunningになっていればOK
> kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-57c6b66f9c-prhkq 1/1 Running 0 3h
Podの詳細情報を取得します
> kubectl describe pods hello-node
4. アプリケーションを公開する
k8sでアプリケーションを公開するために、Serviceを作らなければならない
-
--type
・・・公開方法にはNodePort、LoadBalancer、ClusterIP、ExternalNameとあります
> kubectl expose deployment hello-node --type=LoadBalancer
ポートフォワードによる公開
単一Podに対してポートフォワードによる外部公開ができます
手軽に動作確認するときには有用かも?
なお、Deployment単位でポートフォワードによる公開は
# pod名で指定する
> kubectl.exe port-forward hello-node-57c6b66f9c-prhkq 8080:8080
ブラウザでhttp://localhost:8080
にアクセスすることで動作確認することができます
5. 動作確認
Serviceを確認
アプリの8080
ポートと外部公開用の32382
ポートがマッピングされます
任意のポートとマッピングするには?
> kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.111.163.219 <pending> 8080:32382/TCP 26m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
ブラウザで確認し、「hello world」が表示されればOK!!
> minikube service hello-node
ログを確認
console.log('xxxx')
があれば、その内容が表示されます
> kubectl logs <POD名(kubectl get podsで表示)>
6. アプリケーションを更新
server.jsで何かコード修正し、Dockerイメージをv2
としてビルドし直します
> docker build -t hello-node:v2 ./
7. Deploymentのイメージを更新
最新のイメージをセットすると自動でデプロイされます
deployment/hello-node
・・・deployment/<deployment名>
> kubectl set image deployment/hello-node hello-node=hello-node:v2
deployment.apps "hello-node" image updated
8. 動作確認
Deploymentの確認
v1のpodがTerminatingされていることが確認できます
自動で旧バージョンのPodがTerminateされます
> kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-node-57c6b66f9c-prhkq 1/1 Terminating 0 4h
hello-node-57c8dd9df8-tlk9g 1/1 Running 0 10s
ブラウザでコード修正した内容が変更されたことを確認
9. 一度後片付け
Service、Deploymentを削除
> kubectl delete service hello-node
> kubectl delete deployment hello-node
10. マニュフェストファイルでDeployment
上記のようにコマンドラインでデプロイするのではなく、Infrastructure as codeできるようにマニュフェストファイルからデプロイします
deployment-hello-node.ymlを作成し、以下のコマンドでデプロイします
マニュフェストって聞くと固い印象ですが、docker-compose.ymlみたいな設定ファイルだと思っていただければOKかと思います
> kubectl apply -f deployment-hello-node.yml
deployment.apps "hello-node" created
labels
・・・関連するキー:値でリソースの指定したりすることができます
例えば、リソースの参照する時に特定のlabelがついたものを抽出するなどに使用されます
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-node
labels:
app: hello-node
spec:
replicas: 1
selector:
matchLabels:
app: hello-node
template:
metadata:
labels:
app: hello-node
spec:
containers:
- name: hello-node
image: hello-node:v1
ports:
- containerPort: 8080
11. デプロイの確認
> kubectl get pods
12. マニュフェストファイルでService
Deploymentと同様にServiceもマニュフェストファイル化します
kind: Service
apiVersion: v1
metadata:
name: hello-node
labels:
app: hello-node
spec:
type: LoadBalancer
selector:
app: hello-node
ports:
- port: 8080
> kubectl apply -f service-hello-node.yml
service "hello-node" created
13. Serviceの確認と動作確認
> kubectl get service
> minikube service hello-node
14. アプリケーションの更新と適用
アプリケーションのソースコードを修正したら、Dockerイメージのリビルドを実行し、deployment-hello-node.ymlのimage:
のタグ名をv2に更新し、再度同じコマンドを実行するとデプロイされます
> kubectl apply -f deployment-hello-node.yml
アップデート戦略
デフォルトのアップデート動作はRollingUpdate
ですが、明示的にRecreate
を選択することも可能
Recreate
の場合は、旧バージョンのアプリケーションを停止してから、新アプリケーションをデプロイするので、サービスダウンが発生するが、新旧が混在することはない
spec:
replicas: 1
strategy:
type: Recreate
途中で変えられない?一度Deploymentを削除しなければならない?
> kubectl apply -f deployment-hello-node.yml
後片付け
マニュフェスト化しているので、リソースの削除も便利になります
マニュフェストで定義されているリソースをすべて削除してくれます
> kubectl delete -f deployment-hello-node.yml
> kubectl delete -f service-hello-node.yml
マニュフェストをまとめる
上記ではDeploymentマニュフェストとServiceマニュフェストをそれぞれのyamlファイルにしていましたが、1つにまとめて管理することができます(コマンドの入力も1回で済みます)
リソースの定義ごとに---
で区切ることで1ファイルで管理することができます
apiVersion: apps/v1
kind: Deployment
~中略~
---
apiVersion: v1
kind: Service
~中略~
また、管理するリソースが多くなるとマニュフェストファイルが長くなり、見通しが悪くなるため、管理しやすい単位にファイルを分割し、apply時に-f
時に保存されているディレクトリを指定することで、まとめて適用してくれます(ファイル名順)
> kubectl apply -f ./
指定したディレクトリ内を再帰的に読み込む場合は
> kubectl apply -f ./ -R
以上
次回は「初めてのkubernetes(Minikube) Pod連携とデータの永続化編」をご参照ください