環境構築

kubernetesの基本的な使い方と実行方法

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の基本操作について見てきました。