Dockerコンテナを管理するためのツール Dockerは単体ホスト上に複数コンテナを構築していたが、ホスト故障時の単一故障が発生する可能性がある。 k8sは複数ホスト上に複数コンテナを構築することで単一障害の可能性を潰す。 またコンテナ故障時には自動修復(再起動)する機能を持っていたり、ロードバランシングや自動スケーリング等の機能を持ち合わせている。
Docker単体で使用する場合はdockerコマンドやdocker-composeコマンドを使用していたが、kubernetes(以降、k8s)を使用する際はkubectlコマンド経由でDockerを操作する。
choco install minikube
minikube start --vm-driver=<driver_name>
minikube status
start済みの場合、以下のような内容が表示されるはず
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
minikube stop
choco install kubectl
kubectl version
Windows10 Proはインストール時にHyper-Vという仮想環境が起動されるようになっている。 (Docker for Windows使用するときに必要) しかし、k8sをVirtualBoxで使用するとき、Hyper-VとVirtualBoxで衝突が発生してしまう。(共存はできない) そのため、Hyper-Vを無効化する必要がある。
無効化
bcdedit /set hypervisorlaunchtype off
有効化
bcdedit /set hypervisorlaunchtype auto
いずれもPowerShell(管理者権限)で実行し、実行後は再起動が必要。 minikubeでvirtualboxをドライバーとするには以下のコマンド
minikube start --vm-driver=virtualbox
1つまたは複数のアプリケーションのコンテナを内包したもの。 管理上の基本単位となり、NICやストレージ、ボリュームを共有する。 Podはノード上に作成される。
apiVersion: v1
kind: Pod
metadata:
name: sample
spec:
containers:
- name: nginx
image: nginx:1.17.2-alpine
volumeMounts: # コンテナのマウント先
- name: storage #volumes.nameと同じ名前にする
mountPath: /home/nginx
volumes: # ホストのマウント情報
- name: storage
hostPath:
path: /data/storage
type: Directory
一時的で永続的なIPアドレスを持たないPodに対してクライアントがアクセスするための機能
Podは1つ1つにIPアドレスがふられているが、それぞれのPodと通信する場合IPアドレスを指定する必要がある。 Podはいつ消えるかわからない存在であるため、IPアドレスを覚えておくのはナンセンス。 1つのIPアドレス(Static IP)を用意しておき、Podへの接続を可能とすることで上記の問題を解消する。
いつ消えるかわからないPodのIPアドレスを抽象化し、代表となるIPアドレスを用意しておくことで ・Podへアクセスする際のPodのIPアドレスを知る必要がなくなる ・ロードバランスを動的に行ってくれる ・クラスタ内部間の通信のみ可能
サービス作成
kubectl expose pod <pod name> --type ClusterIP --port <port> --name <service name>
# kubectl get service ←サービス一覧確認
ClusterIPはクラスタ内部でしか有効ではない(外部との疎通が取れない)
クラスタ外へPodを公開しNodeIPとNodePort経由で外部との疎通を行うService 手軽に外部公開ができるNodePortは便利なものだが、ノードの再起動などが行われると内部のPodのIP等が切り替わるため 使用できなくなる。 また、NodeIPとNodePortを知っておく必要があるため本番環境での利用には適していない。
サービス作成
kubectl expose pod <pod name> --type NodePort --port <port> --name <service name>
ymlファイルの場合
# nginxを構築
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: web
env: study
spec:
containers:
- name: nginx
image: nginx:1.17.2-alpine
# 上記で定義したnginxに外部からアクセスできるようNodePortでServiceを作成する
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: NodePort
selector:
app: web
env: study
ports:
- port: 80
targetPort: 80
nodePort: 30000
クラスタ外へNodeIPにDNS名が動的に付与されるサービス。 DNSが付与されるので、IPおよびPortを把握しておく必要性がなくなる。 ただし、L4までしかサポートしていないためL7に対応させるにはIngressというリソースを使う必要がある。
サービス作成
kubectl expose pod <pod name> --type LoadBalancer --port <port> --name <service name>
Podをクラスタ内外へ公開するL7ロードバランサ URLによるロードバランスが可能(ドメイン、パスによる振り分けが可能になる)
minikube addons list
minikube addons enable ingress
kubectl get pods -n kube-system
kubectl apply -f ingress.yaml
ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: helloworld
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: helloworld-nodeport
servicePort: 8080
上記のyamlファイルを適用することでどのパスにアクセスしても helloworld-nodeportのpodが返ってくる。
Podの集合体、Podのスケールが可能
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: sample
spec:
replicas: 3 # 複製するPodの数
selector: # ReplicaSetとPodを紐づける template.metadata.labelsと一致する必要がある
matchLabels:
app: web
env: study
template: # 作成するPodのマニュフェストファイル
metadata:
name: nginx
labels:
app: web
env: study
spec:
containers:
- name: nginx
image: nginx:1.17.2-alpine
ReplicaSetの世代管理を行う。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
annotations: # Deploymentを更新するときにコメントを残すときに使う
kubernetes.io/change-cause: "Update nginx 1.17.3"
spec:
replicas: 2
selector:
matchLabels:
app: web
env: study
revisionHistoryLimit: 14 # 何個の世代を残すのか指定する。後々世代を戻すときに使える。
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # レプリカ数を超えてよいPod数
maxUnavailable: 1 # 1度に消失してよいPod数
template:
metadata:
name: nginx
labels:
app: web
env: study
spec:
containers:
- name: nginx
image: nginx:1.17.3-alpine
maxSurge, maxUnavailableのわかりやすい解説
ロールアップするときはymlファイルを更新し、再度kubectl apply -f <file>
することで更新してくれる。
kubectl rollout undo <type/name> [--to-revision=<revision number>]
# 例の場合だと14個のrevisionHisotryを残すので、to-revisionでも最大14を指定することが可能
k8sの設定情報を集約するリソース
Pod上で扱い機微情報を取り扱うリソース。 base64で暗号化した情報をPodに展開するときに複合したりできる。
apiVersion: v1
kind: Secret
metadata:
name: sample-secret
data:
message: SGVsbG8gV29ybGQ= # echo -n 'Hello World !' | base64
keyfile: WU9VUi1TRUNSRVQtS0VZ # cat ./keyfile | base64
---
apiVersion: v1
kind: Pod
metadata:
name: sample
namespace: default
spec:
containers:
- name: sample
image: nginx:1.17.2-alpine
env:
- name: MESSAGE
valueFrom:
secretKeyRef:
name: sample-secret
key: message
volumeMounts: # Secretで暗号化したいファイルを指定する場合のパターン
- name: secret-storage # spec.volumes.nameと名前を合わせる
mountPath: /home/nginx # Pod内の保存先
volumes:
- name: secret-storage
secret:
secretName: sample-secret
items:
- key: keyfile
path: keyfile #
ホスト→Pod
kubectl cp <src> <pod name>:<dest>
src: カレントディレクトリからのパス dest: 絶対パス
Pod→ホスト
kubectl cp <pod name>:<src> <dest>
src: 絶対パス dest: カレントディレクトリからのパス
kubectl cluster-info
kubectl get nodes
kubectl config view
どのk8sクラスタにどのユーザーとして接続するのかの接続設定をkubeconfigファイルが定義し、クライアントにあるkubeconfigファイルをkubectlが読み取って接続先を決めている。
kubectl get pod
kubectl get service
kubectl get rs
kubectl get deploy
kubectl get <type> -o wide
kubectl exec -it <pod name> sh
kubectl describe <type/name>
kubectl logs <type/name>
kubectl rollout history <type/name>