kubernetesとは?
kubernetesはコンテナオーケストレーションと呼ばれるものです。
物理リソースに対して大量のコンテナをデプロイ、管理していく仕組みです。
kubernetesはシステム運用で課題になっていた点を解決できるようになりました。
課題 | kubernetes |
システムリソースの利用率に無駄がある | 複数コンテンの共存 |
突発的な大量アクセスでシステムが応答しなくなる | 水平スケール |
突然、一部システムがダウン | 監視・自動デプロイ |
新機能リリースのたびにサービス停止が発生 | ローリングデプロイ |
これらの仕組みは使えるリソース(サーバー)を一元管理することで実現しています。
各リソースはworker-nodeと呼ばれるもので認識されています。
そして、worker-nodeを管理するmaster-nodeが存在します。
master-nodeとworker-nodeはネットワークで繋がっており、master-nodeにコマンドで命令を与えると、その配下にあるworker-nodeに対して指示が飛び、worker-nodeが認識しているリソースの操作を行います。
これがkubernetesの大枠の仕組みです。
master-nodeとworker-nodeはネットワークで繋がっていると言いましたが、同じネットワークにいるわけではありません。
master-nodeは外部ネットワーク、worker-nodeはクラスタネットワークに存在します。
クラスタネットワークは外から直接アクセスできない特徴があります。
master-nodeは外部ネットワークに接続されているので、あるコンテナの動作確認をするには、3種類方法があります。
・直接コンテナの中に入ってアクセスする
・踏み台コンテナ経由でアクセスする
・サービス経由でアクセスする
kubernetesの実行方法
k8s(kubernetes)の簡単な使い方をみていきます。
動作を確認しながら、k8sの挙動を見たい方はこちらを参考に環境を作っておいてください。
既に環境がある方はそちらを使ってもらって大丈夫です。
仮想環境にアクセスした状態で、下記のコマンドでk8sを起動します。
minikube start
無事起動できたら、kubectlコマンドを実行していきましょう
動作方法はdockerとほとんど一緒です。
kubectl run hello-world –image hello-world –restart=Never
> pod/hello-world created
最初のhello-worldはpod名になり、最後のhello-worldはイメージ名になります。
イメージの取得先はDocker Hubです。
実行後に
pod/hello-world created
と表示されれば完了です。
では、実際に立ち上がっているか確認してみます
kubectl get pod
問題なく立ち上がっています。
実際の業務でも良く使うのが、ログの確認です。
その方法を見ていきます。
kubectl logs pod/hello-world
これを実行すると、hello-wordコンテナ実行時の見覚えのあるログが確認できます。
最後に、削除方法を見ていきます。
kubectl delete pod/hello-world
> pod “hello-world” deleted
実行すると、runの時と同様な表示がされます。
kubernetesで扱うお主なリソース
k8sでは良く使うものを分類すると、大きく4つに分類でき、より詳細に分類すると10種類に分けることができます。
ワークロード | ・Pod ・ReplicaSet ・Deployment ・StatefulSet |
サービス | ・Service ・Ingress |
設定 | ・ConfigMap ・Secret |
ストレージ | ・PersistentVolume ・PersistentVolumeClaim |
それぞれの役割を簡単に説明していきます。
Pod
Podは最小単位で、Dockerの集合です
1つのPodに複数のDockerコンテナが入れられます。
ReplicaSet
Podの集合で、Podをスケール(複製)できます
Deployment
ReplicaSetの集合で、 ReplicaSetの世代を管理できます
ロールバックやロールフォワードと同様なものです。
StatefulSet
ReplicaSetと似ているのですが、スケールする際に名前が一定ルールでつけられる点が異なります。
Service
外部公開や名前解決、L4ロードバランサの役割を担います。
Ingress
Serviceと似たようなものですが、こちらは外部公開とL7ロードバランサーの役割を担います。
ConfigMap
名前の通り、設定情報を担います。
Secret
機微情報を扱い、base64でエンコードを行います
PersistentVolume
永続データの実態を担います。ストレージへの接続情報であったり、ストレージを抽象化するなどです。
PersistentVolumeClaim
永続データの要求を担います。抽象化されたストレージを要求するといった形です。
リソースの作成
リソースの作成手順としては、「定義作成」->「定義適用」の2ステップになります。
定義作成の方法はマニフェストファイル(YAMLファイル)を作成することでできます。
そして、マニフェストファイルをkubectlコマンドを使用してk8sに反映して適用します。
YAMLファイルはインデントで構造を定義するので、必要となるリソースを書き込んでいきます。具体的な方法を見ていきましょう。
dockerとk8sを実行な環境で任意のディレクトリを作成し、pod.ymlファイルを作成します。
pod.yml
apiVersion: v1
kind: Pod
metadata:
name: test
namespace: default
labels:
env: study
spec:
containers:
- name: hello-world
image: hello-world:linux
マニフェストファイルの構成は大きく3つに分かれます。
・種別
・メタデータ
・コンテナ定義
種別は、「apiVersion」と「kind」を指します。
kindはリソースが何のかを明示します。今回はPodですね。
apiVersionはkindに依存しており、指定するリソースによって変わります。
これはAPIドキュメントを参考にすると良いです。
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#pod-v1-core
メタデータ(metadata)は各リソースを特定のnamespace配下に一意で指定できるような名前を決めます。
k8sはnamespaceとnameの組み合わせで一意になる必要があります。
labelsはkey,valueのペアで任意に指定できます。
コンテナ定義はspecを指しており、複数のコンテナとイメージを定義する場所になります。ここでもイメージにはタグをつけるように注意してください。
リソース操作
ここで、作成したマニフェストファイルを適用して、リソースを作成してみます。
kubectl apply -f pod.yml
> pod/test created
リソースが作成できているか確認してみます。やり方は二つあります。
kubectl get -f pod.yml
or
kubectl get pod
※kubectl get pod -w => -wオプションをつけることで状態変化を追うことができます
このように表示できていれば作成されています。
ただ、この方法だとpod毎に確認する必要があるので、一括で確認する方法もあります。
kubectl get all
こうすることで、リソースを一覧で表示することができます。
そして、いらなくなったpodはdeleteコマンドで削除することができます。
kubectl delete -f pod.yml
> pod “test” deleted
dockerと同様にk8sにも省略記法があるので、公式ドキュメントを参考にしてみてください。
https://kubernetes.io/docs/reference/kubectl/overview/#resource-types
コンテナに入っての操作
dockerでも良く使うコンテナに入っての操作ですが、k8sでも同様に行うことができます。
コマンドもほとんど一緒なので、dockerに慣れている人はすぐに使いこなせると思います。
kubectl exec -it [POD] sh
違うのは、指定したPodに入ってシェル操作を行うので、中に入りたいPod名を指定することくらいです。
それでは、centosとnginxのpodを立てて、シェルの中に入りPodのIPアドレスを確認して動作確認をしてみます。
マニフェストファイルの作成
今回は複数のコンテナを定義するマニフェストファイルを作成していきます。
apiVersion: v1
kind: Pod
metadata:
name: debug
namespace: default
labels:
env: study
spec:
containers:
- name: debug
image: centos:7
command:
- "sh"
- "-c"
args:
- |
while true
do
sleep ${DELAY}
done
env:
- name: "DELAY"
value: "5"
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
env: study
spec:
containers:
- name: nginx
image: nginx:1.17.2-alpine
リソースの作成の時と同様にapplyコマンドで作成します。
そして、debug(centos)のpodからnginxのpodにアクセスを試みたいのですが、IPアドレス情報が必要になります。
そこでkubectl get allで確認してもいいのですが、量が多くなってきた時が大変なので、別のコマンドを用います。
kubectl get pod -o wide
これで、IPアドレス情報も確認できます。
最初に記載したコマンドを用いて、debugコンテナに入ります。
kubectl exec -it debug sh
そして、curlコマンドを使用してnginxしてみます
curl http://172.17.0.9
ちゃんとレスポンスが帰ってくれば成功です。
シェルから抜けるには、exitコマンドで抜けられます。
おまけ:ログの確認
Podが何かしらが原因で動かない時には、まずログを確認することが大事です。
ここでは、Podの状態と詳細を確認する方法を見ていきます。
リソースの状態を確認するには、describeコマンドを使います。
kubectl describe [TYPE/NAME]
※TYPE/NAMEはリソース種別とリソース名
describeだけでは良くわからないことがほとんどなので、ログを確認することの方が多いです。
kubectl logs [TYPE/NAME] [–tail=n]
※–tail=nは直近のnレコードだけ取得
具体的な使い方
コマンドの使い方の事例として、nginxのPodを立ててアクセスログを確認してみます。
先程のcentosとnginxのPodを利用します。
Podを削除してしまった方は再度curlでnginxにアクセスするところまでやっておいてください。
実際にdescribeを使用してみましょう。一旦centosの方から見てみます
kubectl describe pod/debug
yamlの中身などが表示されますが、重要なのは赤枠で囲ったEventsの部分です。
どういった動作が順番に実行されたかが記録されています。簡略な情報のみなので、これで原因が特定できればそれに越したことはありません。
では、本題のlogsコマンドでnginxのPodを見てみます。
kubectl logs pod/nginx
> 172.17.0.9 – – [01/May/2020:04:39:05 +0000] “GET / HTTP/1.1” 200 612 “-” “curl/7.29.0” “-“
そうすると、 centosからアクセスされたアクセスログが確認できます。
今回は問題のないログなのでいいのですが、エラーログなどを確認して何が原因なのかはこのように見ていく事になります。
ここまでで簡単にk8sの基本操作について見てきました。