Kubernetes (minikube)

Docker Swarmとの比較

Docker Swarm vs. Kubernetes: A Comparison

K8s and Docker Swarm have many of the same features, but each tool shines in different aspects. The table below offers a head-to-head Kubernetes vs Docker Swarm comparison:

Point of comparison Kubernetes Docker Swarm
Main selling point A complete container orchestration solution with advanced automation features and high customization An emphasis on ease of use and a seamless fit with other Docker products
Installation Somewhat complex as you need to install (and learn to use) kubectl Quick and easy setup (if you already run Docker)
Learning curve High learning curve (but has more features) Lightweight and easy to use (but limited functionality)
GUI Detailed native dashboards No out-of-the-box dashboards (but you can integrate a third-party tool)
Cluster setup Difficult to start a cluster (but the cluster is very strong once set up) Easy to start a cluster
Availability features Self-healing, intelligent scheduling, and replication features Availability controls and service duplication
Scalability All-in-one scaling based on traffic Values scaling quickly (approx. 5x faster than K8s) over scaling automatically
Horizontal auto-scaling Yes No
Monitoring capabilities Has built-in monitoring and logging Basic server log and event tools, but needs a third-party tool for advanced monitoring
Load balancing No built-in mechanism for auto load-balancing Internal load balancing
Security features Relies on transport layer security (TLS) and access control-related tasks Supports multiple security protocols (RBAC authorization, TLS/SSL, secrets management, policies, etc.)
CLI Needs a separate CLI Integrated Docker CLI, which can limit the functionality in some use cases
Community Huge and active community Reasonably popular, but the user base is getting smaller since the Mirantis acquisition
Optimal use case High-demand apps with a complex configuration Simple apps that are quick to deploy and easy to manage

Service Mesh

Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]

Basics

Configuration

Stateless Applications

Stateful Applications

Services

Security

minikube

Kubernetes 導入のメリットとして、クライアントの需要に応じたシステムの伸縮性やロードバランサーとしての機能、システム更新時や停止した際のレプリカによる補助機能などが挙げられます。

minikube はローカルマシン上で上記の kubernetes によるクラスターの配置・操作ができるアプリケーションです(ローカルマシン上での学習、開発用途)。

minikube

GitHub


他の代替アプリと3アプリの比較

  • MicroK8s
    Local and cloud Kubernetes cluster for developers and production, from Canonical.
  • K3S
    Lightweight Kubernetes cluster for local, cloud, edge, IoT deployments, originally from Rancher, currently a CNCF project.
MICROK8S K3S MINIKUBE
CNCF certified Yes Yes Yes
Vanilla Kubernetes Yes Yes
Architecture support x86, ARM64, s390x x86, ARM64, ARMhf x86, ARM64, ARMv7, ppc64, s390x
Enterprise support Yes Yes
Single-node support Yes Yes Yes
Multi-node cluster support Yes Yes
Automatic high availability Yes Yes
Automatic updates Yes Yes
Memory requirements 540 MB 512 MB 644 MB
Add-on functionality Yes Yes
Container runtime containerd, kata CRI-O Docker, containerd, CRI-O
Networking Calico, Cilium, CoreDNS, Traefik, NGINX, Ambassador, Multus, MetalLB Flannel, CoreDNS, Traefik, Canal, Klipper Calico, Cilium, Flannel, ingress, DNS, Kindnet
Default storage options Hostpath storage, OpenEBS, Ceph Hostpath storage, Longhorn Hostpath storage
GPU acceleration Yes Yes Yes

Container Runtime Interface (CRI)

下記 Docker Desktop を加えても良いでしょう。

  • Docker Desktop
    Including a local Kubernetes cluster for Docker users.

Cloud Native Computing Foundation (CNCF)による代表的なプロジェクト

https://www.cncf.io/

Popular graduated projects:
* Kubernetes container orchestrator
* etcd distributed key-value store
* CoreDNS DNS server
* containerd container runtime
* Envoy cloud native proxy
* Fluentd for unified logging
* Harbor registry
* Helm package management for Kubernetes
* Linkerd service mesh for Kubernetes
* Open Policy Agent policy engine
* Prometheus monitoring system and time series DB
* Rook cloud native storage orchestrator for Kubernetes

Installing Kubernetes with deployment tools

本番環境でのKubernetesのインストール


kubeadm
kubeadm is a first-class citizen on the Kubernetes ecosystem. It is a secure and recommended method to bootstrap a multi-node production ready Highly Available Kubernetes cluster, on-premises or in the cloud. kubeadm can also bootstrap a single-node cluster for learning. It has a set of building blocks to set up the cluster, but it is easily extendable to add more features. Please note that kubeadm does not support the provisioning of hosts - they should be provisioned separately with a tool of our choice.

kops
kops enables us to create, upgrade, and maintain production-grade, Highly Available Kubernetes clusters from the command line. It can provision the required infrastructure as well. Currently, AWS is officially supported. Support for DigitalOcean and OpenStack is in beta, Azure and GCE is in alpha support, and other platforms are planned for the future. Explore the kops project for more details.

kubespray
kubespray (formerly known as kargo) allows us to install Highly Available production ready Kubernetes clusters on AWS, GCP, Azure, OpenStack, vSphere, or bare metal. kubespray is based on Ansible, and is available on most Linux distributions. It is a Kubernetes Incubator project.

Kubernetesをホストしているクラウドサービス

minikubeをインストールする前の準備

Linuxでは VirtualBox and KVM2 hypervisors, または、Docker and Podman runtimes を用意すること。

注1)ホストマシンのBIOSで VT-x または AMD-v` を有効化すること。

ツールのインストール

kubectl

Podman

https://podman.io/getting-started/installation.html

Docker


Driver

Linux

DriverDocker, None, Podmanを指定する場合、上記 注1) BIOSによる仮想マシンVMの有効化は必要ありません。

Docker Driver


インストール

ubuntu 22.04

$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
$ sudo dpkg -i minikube_latest_amd64.deb

起動

$ minikube start
😄  Ubuntu 22.04 上の minikube v1.26.1
✨  docker ドライバーが自動的に選択されました
📌  root 権限を持つ Docker ドライバーを使用
👍  minikube クラスター中のコントロールプレーンの minikube ノードを起動しています
🚜  ベースイメージを取得しています...
💾  ロード済み Kubernetes v1.24.3 をダウンロードしています...
    > gcr.io/k8s-minikube/kicbase:  386.61 MiB / 386.61 MiB  100.00% 2.51 MiB p
    > preloaded-images-k8s-v18-v1...:  405.75 MiB / 405.75 MiB  100.00% 2.42 Mi
    > gcr.io/k8s-minikube/kicbase:  0 B [______________________] ?% ? p/s 2m22s
🔥  docker container (CPUs=2, Memory=2900MB) を作成しています...
🐳  Docker 20.10.17 で Kubernetes v1.24.3 を準備しています...
    ▪ 証明書と鍵を作成しています...
    ▪ コントロールプレーンを起動しています...
    ▪ RBAC のルールを設定中です...
🔎  Kubernetes コンポーネントを検証しています...
    ▪ gcr.io/k8s-minikube/storage-provisioner:v5 イメージを使用しています
🌟  有効なアドオン: default-storageclass, storage-provisioner
💡  kubectl が見つかりません。kubectl が必要な場合、'minikube kubectl -- get pods -A' を試してください
🏄  終了しました!kubectl がデフォルトで「minikube」クラスターと「default」ネームスペースを使用するよう設定されました

Kubernetesダッシュボードの起動

$ minikube dashboard
🔌  ダッシュボードを有効化しています...
    ▪ kubernetesui/metrics-scraper:v1.0.8 イメージを使用しています
    ▪ kubernetesui/dashboard:v2.6.0 イメージを使用しています
🤔  ダッシュボードの状態を検証しています...
🚀  プロキシーを起動しています...
🤔  プロキシーの状態を検証しています...
🎉  デフォルトブラウザーで http://127.0.0.1:34475/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ を開いています...
libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)
既存のブラウザ セッションで開いています。

ステータス

$ minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

停止

$ minikube stop
✋  「minikube」ノードを停止しています...
🛑  SSH 経由で「minikube」の電源をオフにしています...
🛑  1 台のノードが停止しました。

$ minikube kubectl --help
Kubernetes クライアントを実行します
(必要であればクライアントをダウンロードします)。kubectl の後に --
を忘れないでください!

これは、クラスターと同じバージョンの Kubernetes クライアント (kubectl) を実行します

通常、ホスト OS とアーキテクチャに一致するバイナリーをダウンロードしますが、
そのほかに SSH 接続経由でコントロールプレーン上で kubectl
を直接実行することもできます。
これは、未サポートホストなど、いくつかの理由によりローカルで kubectl
を実行できない場合に便利です。
--ssh を使用する場合、全パスがリモートマシンに適用されることに注意してください。

Examples:
minikube kubectl -- --help
minikube kubectl -- get pods --namespace kube-system

Options:
    --ssh=false:
	ノード上で実行中の Kubernetes クライアントへの接続に SSH を使用します

Usage:
  minikube kubectl [flags] [options]

Use "minikube options" for a list of global command-line options (applies to all commands).

minikube start コマンドにより作成されたクラスターリスト(デフォルトで作成されたクラスターminikube

$ minikube profile list
|----------|-----------|---------|--------------|------|---------|---------|-------|--------|
| Profile  | VM Driver | Runtime |      IP      | Port | Version | Status  | Nodes | Active |
|----------|-----------|---------|--------------|------|---------|---------|-------|--------|
| minikube | docker    | docker  | 192.168.49.2 | 8443 | v1.24.3 | Running |     1 | *      |
|----------|-----------|---------|--------------|------|---------|---------|-------|--------|

参考)Kubernetesによるクラスター概要図

Profileの各項目を指定して、新規クラスター doubledocker を起動する場合

$ minikube start --nodes=2 --kubernetes-version=v1.24.3 --driver=docker --profile doubledocker
😄  Ubuntu 22.04 上の [doubledocker] minikube v1.26.1
✨  ユーザーの設定に基づいて docker ドライバーを使用します
📌  root 権限を持つ Docker ドライバーを使用
👍  doubledocker クラスター中のコントロールプレーンの doubledocker ノードを起動しています
🚜  ベースイメージを取得しています...
🔥  docker container (CPUs=2, Memory=2200MB) を作成しています...
🐳  Docker 20.10.17 で Kubernetes v1.24.3 を準備しています...
    ▪ 証明書と鍵を作成しています...
    ▪ コントロールプレーンを起動しています...
    ▪ RBAC のルールを設定中です...
🔗  CNI (コンテナーネットワークインターフェース) を設定中です...
🔎  Kubernetes コンポーネントを検証しています...
    ▪ gcr.io/k8s-minikube/storage-provisioner:v5 イメージを使用しています
🌟  有効なアドオン: default-storageclass, storage-provisioner

👍  doubledocker クラスター中の doubledocker-m02 ワーカーノードを起動しています
🚜  ベースイメージを取得しています...
🔥  docker container (CPUs=2, Memory=2200MB) を作成しています...
🌐  ネットワークオプションが見つかりました:
    ▪ NO_PROXY=192.168.58.2
🐳  Docker 20.10.17 で Kubernetes v1.24.3 を準備しています...
    ▪ env NO_PROXY=192.168.58.2
🔎  Kubernetes コンポーネントを検証しています...
💡  kubectl が見つかりません。kubectl が必要な場合、'minikube kubectl -- get pods -A' を試してください
🏄  終了しました!kubectl がデフォルトで「doubledocker」クラスターと「default」ネームスペースを使用するよう設定されました

クラスターリスト

$ minikube profile list
|--------------|-----------|---------|--------------|------|---------|---------|-------|--------|
|   Profile    | VM Driver | Runtime |      IP      | Port | Version | Status  | Nodes | Active |
|--------------|-----------|---------|--------------|------|---------|---------|-------|--------|
| doubledocker | docker    | docker  | 192.168.58.2 | 8443 | v1.24.3 | Running |     2 |        |
| minikube     | docker    | docker  | 192.168.49.2 | 8443 | v1.24.3 | Stopped |     1 | *      |
|--------------|-----------|---------|--------------|------|---------|---------|-------|--------|

Profileを指定してクラスターを停止

$ minikube stop -p doubledocker
✋  「doubledocker」ノードを停止しています...
🛑  SSH 経由で「doubledocker」の電源をオフにしています...
✋  「doubledocker-m02」ノードを停止しています...
🛑  SSH 経由で「doubledocker-m02」の電源をオフにしています...
🛑  2 台のノードが停止しました。

カスタムクラスターその他の例

$ minikube start --kubernetes-version=v1.22.2 --driver=podman --profile minipod

$ minikube start --nodes=2 --kubernetes-version=v1.23.1 --driver=docker --profile doubledocker

$ minikube start --driver=virtualbox --nodes=3 --disk-size=10g --cpus=2 --memory=4g --kubernetes-version=v1.22.4 --cni=calico --container-runtime=containerd -p multivbox

$ minikube start --driver=docker --cpus=6 --memory=8g --kubernetes-version="1.23.2" -p largedock

$ minikube start --driver=virtualbox -n 3 --container-runtime=cri-o --cni=calico -p minibox

その他 minikube コマンド例

$ minikube version
minikube version: v1.26.1
commit: 62e108c3dfdec8029a890ad6d8ef96b6461426dc

ノードIP

$ minikube node list
minikube	192.168.49.2

クラスターIP

$ minikube ip -p minikube
192.168.49.2

プロフィール(クラスター)削除

$ minikube delete -p minikube

minikube コマンド

Pods

ファイルシステム、メモリ、CPU、ネームスペースを共有したコンテナ(群)の呼称。Kubernetesでは一般的に一つのPodに一つのコンテナを格納。Kubernetesではコンテナを直接管理するのではなく、このPodを管理します。


Single- and Multi-Container Pods


Nodes


kubectlのインストール

minikubeにはkubernetesクライアントであるkubectlがセットでインストールされますが、単独でkubectlをインストールした場合と比較してコマンド入力方法が異なります。

minikube kubectlを使用する場合

$ minikube kubectl -- <subcommand> <object-type> <object-name> -o --option

単独でkubectlをインストールした場合

$ kubectl <subcommand> <object-type> <object-name> -o --option

エイリアスを指定してminikubeのkubectlを使用しても良いですが、利便性と本番環境のことを考慮し、スタンドアローンで最新版kubectlをインストールします。

最新バージョンのダウンロード

$ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

チェックサムファイルのダウンロードと認証

$ curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
$ echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check
kubectl: OK

インストール

$ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

動作兼バージョン確認

$ kubectl version --client --output=yaml
clientVersion:
  buildDate: "2022-08-17T18:54:23Z"
  compiler: gc
  gitCommit: 95ee5ab382d64cfe6c28967f36b53970b8374491
  gitTreeState: clean
  gitVersion: v1.24.4
  goVersion: go1.18.5
  major: "1"
  minor: "24"
  platform: linux/amd64
kustomizeVersion: v4.5.4

minikube起動時に作成されるkubernetesデフォルトクラスター(profile:minikube)へのAPI接続設定確認
~/.kube/config

$ kubectl config view

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/student/.minikube/ca.crt
    server: https://192.168.99.100:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /home/student/.minikube/profiles/minikube/client.crt
    client-key: /home/student/.minikube/profiles/minikube/client.key

kubernetesクラスターインフォ

$ kubectl cluster-info

Kubernetes master is running at https://192.168.99.100:8443
KubeDNS is running at https://192.168.99.100:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

kubectl get

$ kubectl get nodes
NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   5d    v1.24.3
$ kubectl get namespaces
NAME                   STATUS   AGE
default                Active   5d
kube-node-lease        Active   5d
kube-public            Active   5d
kube-system            Active   5d
kubernetes-dashboard   Active   5d
$ kubectl get pods -A
NAMESPACE              NAME                                         READY   STATUS    RESTARTS       AGE
kube-system            coredns-6d4b75cb6d-gv9md                     1/1     Running   3 (54m ago)    5d
kube-system            etcd-minikube                                1/1     Running   3 (54m ago)    5d
kube-system            kube-apiserver-minikube                      1/1     Running   3 (4d2h ago)   5d
kube-system            kube-controller-manager-minikube             1/1     Running   3 (4d2h ago)   5d
kube-system            kube-proxy-l596g                             1/1     Running   3 (54m ago)    5d
kube-system            kube-scheduler-minikube                      1/1     Running   3 (54m ago)    5d
kube-system            storage-provisioner                          1/1     Running   7 (52m ago)    5d
kubernetes-dashboard   dashboard-metrics-scraper-78dbd9dbf5-w2kj5   1/1     Running   3 (54m ago)    5d
kubernetes-dashboard   kubernetes-dashboard-5fd5574d9f-j6chx        1/1     Running   4 (52m ago)    5d

kubectlリファレンス

kubectlコマンドリファレンス

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands


マニフェストyamlファイルに記述する際のリソースタイプ( apiVersion, kind )や略称などの確認

$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
podtemplates v1 true PodTemplate
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v2 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Job
certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
leases coordination.k8s.io/v1 true Lease
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
flowschemas flowcontrol.apiserver.k8s.io/v1beta2 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta2 false PriorityLevelConfiguration
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment

Kubernetesダッシュボード

minikubeアドオンリスト

$ minikube addons list
|-----------------------------|----------|--------------|--------------------------------|
|         ADDON NAME          | PROFILE  |    STATUS    |           MAINTAINER           |
|-----------------------------|----------|--------------|--------------------------------|
| ambassador                  | minikube | disabled     | 3rd party (Ambassador)         |
| auto-pause                  | minikube | disabled     | Google                         |
| csi-hostpath-driver         | minikube | disabled     | Kubernetes                     |
| dashboard                   | minikube | enabled ✅   | Kubernetes                     |
| default-storageclass        | minikube | enabled ✅   | Kubernetes                     |
| efk                         | minikube | disabled     | 3rd party (Elastic)            |
| freshpod                    | minikube | disabled     | Google                         |
| gcp-auth                    | minikube | disabled     | Google                         |
| gvisor                      | minikube | disabled     | Google                         |
| headlamp                    | minikube | disabled     | 3rd party (kinvolk.io)         |
| helm-tiller                 | minikube | disabled     | 3rd party (Helm)               |
| inaccel                     | minikube | disabled     | 3rd party (InAccel             |
|                             |          |              | [info@inaccel.com])            |
| ingress                     | minikube | disabled     | Kubernetes                     |
| ingress-dns                 | minikube | disabled     | Google                         |
| istio                       | minikube | disabled     | 3rd party (Istio)              |
| istio-provisioner           | minikube | disabled     | 3rd party (Istio)              |
| kong                        | minikube | disabled     | 3rd party (Kong HQ)            |
| kubevirt                    | minikube | disabled     | 3rd party (KubeVirt)           |
| logviewer                   | minikube | disabled     | 3rd party (unknown)            |
| metallb                     | minikube | disabled     | 3rd party (MetalLB)            |
| metrics-server              | minikube | disabled     | Kubernetes                     |
| nvidia-driver-installer     | minikube | disabled     | Google                         |
| nvidia-gpu-device-plugin    | minikube | disabled     | 3rd party (Nvidia)             |
| olm                         | minikube | disabled     | 3rd party (Operator Framework) |
| pod-security-policy         | minikube | disabled     | 3rd party (unknown)            |
| portainer                   | minikube | disabled     | 3rd party (Portainer.io)       |
| registry                    | minikube | disabled     | Google                         |
| registry-aliases            | minikube | disabled     | 3rd party (unknown)            |
| registry-creds              | minikube | disabled     | 3rd party (UPMC Enterprises)   |
| storage-provisioner         | minikube | enabled ✅   | Google                         |
| storage-provisioner-gluster | minikube | disabled     | 3rd party (Gluster)            |
| volumesnapshots             | minikube | disabled     | Kubernetes                     |
|-----------------------------|----------|--------------|--------------------------------|
💡  他のプロファイル用のアドオン一覧を表示するためには、`minikube addons -p name list` を実行します

metric-serverアドオンの有効化

$ minikube addons enable metrics-server

ダッシュボード起動

$ minikube dashboard
🤔  ダッシュボードの状態を検証しています...
🚀  プロキシーを起動しています...
🤔  プロキシーの状態を検証しています...
🎉  デフォルトブラウザーで http://127.0.0.1:45927/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ を開いています...
libva error: vaGetDriverNameByIndex() failed with unknown libva error, driver_name = (null)
既存のブラウザ セッションで開いています。

APIサーバへのアクセス

kubectl proxyコマンドにより起動したプロキシサーバ経由でAPIサーバへアクセス

$ kubectl proxy &
Starting to serve on 127.0.0.1:8001

curlによるAPIサーバへのリクエストパス

$ curl http://localhost:8001/
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apps",
    "/apis/apps/v1",
    "/apis/authentication.k8s.io",
    "/apis/authentication.k8s.io/v1",
    "/apis/authorization.k8s.io",
    "/apis/authorization.k8s.io/v1",
    "/apis/autoscaling",
    "/apis/autoscaling/v1",
    "/apis/autoscaling/v2",
    "/apis/autoscaling/v2beta1",
    .....
    .....
    .....
    "/readyz/poststarthook/start-kube-apiserver-admission-initializer",
    "/readyz/shutdown",
    "/version"
  ]
}

上記サブディレクトリへアクセスすることにより各種データが取得できます。
ex)

$ curl http://localhost:8001/api/v1
$ curl http://localhost:8001/apis/apps/v1
$ curl http://localhost:8001/version

APIプロキシサーバのダッシュボードへアクセス

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/#/pod?namespace=default

バックグラウンドで稼働しているプロキシーサーバの停止

$ jobs
[1]+  実行中               kubectl proxy &
$ fg
kubectl proxy

^C を入力して終了


Bearerトークンによる認証方式によりAPIサーバへアクセス

# Check all possible clusters, as your .KUBECONFIG may have multiple contexts:
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'

# Select name of cluster you want to interact with from above output:
export CLUSTER_NAME="some_server_name"

# Point to the API server referring the cluster name
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")

# Create a secret to hold a token for the default service account
kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
  name: default-token
  annotations:
    kubernetes.io/service-account.name: default
type: kubernetes.io/service-account-token
EOF

# Wait for the token controller to populate the secret with a token:
while ! kubectl describe secret default-token | grep -E '^token' >/dev/null; do
  echo "waiting for token..." >&2
  sleep 1
done

# Get the token value
TOKEN=$(kubectl get secret default-token -o jsonpath='{.data.token}' | base64 --decode)

# Explore the API with TOKEN
curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure

アウトプット

{
  "kind": "APIVersions",
  "versions": [
    "v1"
  ],
  "serverAddressByClientCIDRs": [
    {
      "clientCIDR": "0.0.0.0/0",
      "serverAddress": "10.0.1.149:443"
    }
  ]
}

NodeへのPodの割当・起動

kubectl apply

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#apply

通常はPodのリソースを記述したyamlファイルを指定してNodeに割当てる。

simple-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

上記ファイルを指定してNodeにPodを割当て

$ kubectl apply -f simple-pod.yaml

kubectl get

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get

デフォルトNodeであるminikubeに割当てられたPod

$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          24m   172.17.0.7   minikube   <none>           <none>

kubectl delete

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#delete

Podの削除

$ kubectl delete pods nginx
pod "nginx" deleted

kubectl run

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#run

runコマンドによるPodの起動

$ kubectl run pod001 --image=nginx

kubectl describe

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#describe

describeコマンドによるPod詳細表示

$ kubectl describe pod/pod001
Name:         pod001
Namespace:    default
Priority:     0
Node:         minikube/192.168.49.2
Start Time:   Wed, 24 Aug 2022 23:08:42 +0900
Labels:       run=pod001
Annotations:  <none>
Status:       Running
IP:           172.17.0.7
IPs:
  IP:  172.17.0.7
Containers:
  pod001:
    Container ID:   docker://e816491126d6d6f5c7156aa26f27d73dad5e69164135ac1e3222f88aabcff97a
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:b95a99feebf7797479e0c5eb5ec0bdfa5d9f504bc94da550c2f58e839ea6914f
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 24 Aug 2022 23:09:25 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-qwxnm (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-qwxnm:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  14m   default-scheduler  Successfully assigned default/pod001 to minikube
  Normal  Pulling    14m   kubelet            Pulling image "nginx"
  Normal  Pulled     14m   kubelet            Successfully pulled image "nginx" in 35.272085622s
  Normal  Created    14m   kubelet            Created container pod001
  Normal  Started    14m   kubelet            Started container pod001

Labels

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

メタデータにラベル追加
environment: production
app: nginx

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

Deployment

nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

The apiVersion field is the first required field, and it specifies the API endpoint on the API server which we want to connect to; it must match an existing version for the object type defined. The second required field is kind , specifying the object type - in our case it is Deployment , but it can be Pod, ReplicaSet, Namespace, Service, etc. The third required field metadata , holds the object’s basic information, such as name, annotations, labels, namespaces, etc. Our example shows two spec fields (spec and spec.template.spec ). The fourth required field spec marks the beginning of the block defining the desired state of the Deployment object. In our example, we are requesting that 3 replicas, that is 3 instances of the Pod, are running at any given time. The Pods are created using the Pod Template defined in spec.template . A nested object, such as the Pod being part of a Deployment, retains its metadata and spec and loses its own apiVersion and kind - both being replaced by template . In spec.template.spec , we define the desired state of the Pod. Our Pod creates a single container running the nginx:1.14.2 image from Docker Hub.

$ kubectl apply -f nginx-deployment.yaml

ReplicaSet

frontend.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # modify replicas according to your case
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
$ kubectl apply -f frontend.yaml

DeploymentとReplicaSetの関係

DeploymentによりReplicaSetが作成される。


kubectl create deployment

イメージ更新による新規レプリカセット作成とロールバック
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-deployment-em-

Create a deployment with the specified name.

$ kubectl create deployment NAME --image=image -- [COMMAND] [args...]

ex)

deployment mynginx の作成

$ kubectl create deployment mynginx --image=nginx

上記コマンドで作成された Deployment, ReplicaSet, Podのリスト

$ kubectl get deploy,rs,po -l app=mynginx
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mynginx   1/1     1            1           2m27s

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/mynginx-654f8684f8   1         1         1       2m27s

NAME                           READY   STATUS    RESTARTS   AGE
pod/mynginx-654f8684f8-whcsv   1/1     Running   0          2m27s

レプリカセットの作成(Podのレプリカを3つ作成)

$ kubectl scale deploy mynginx --replicas=3

作成されたレプリカ replicaset.apps/mynginx-654f8684f8 (3つのPod)の確認

$ kubectl get deploy,rs,po -l app=mynginx
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mynginx   3/3     3            3           9m23s

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/mynginx-654f8684f8   3         3         3       9m23s

NAME                           READY   STATUS    RESTARTS   AGE
pod/mynginx-654f8684f8-6frj5   1/1     Running   0          30s
pod/mynginx-654f8684f8-7j7vg   1/1     Running   0          30s
pod/mynginx-654f8684f8-whcsv   1/1     Running   0          9m23s

kubectl rollout

$ kubectl rollout history deployment/mynginx
deployment.apps/mynginx 
REVISION  CHANGE-CAUSE
1         <none>

$ kubectl rollout history deployment/mynginx --revision=1
deployment.apps/mynginx with revision #1
Pod Template:
  Labels:	app=mynginx
	pod-template-hash=654f8684f8
  Containers:
   nginx:
    Image:	nginx
    Port:	<none>
    Host Port:	<none>
    Environment:	<none>
    Mounts:	<none>
  Volumes:	<none>

nginx イメージのバージョン変更・アップデート(リビジョン2)

$ kubectl set image deployment mynginx nginx=nginx:1.21-alpine
deployment.apps/mynginx image updated

ロールアウト履歴

$ kubectl rollout history deployment/mynginx
deployment.apps/mynginx 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

$ kubectl rollout history deployment/mynginx --revision=2
deployment.apps/mynginx with revision #2
Pod Template:
  Labels:	app=mynginx
	pod-template-hash=574494d858
  Containers:
   nginx:
    Image:	nginx:1.21-alpine
    Port:	<none>
    Host Port:	<none>
    Environment:	<none>
    Mounts:	<none>
  Volumes:	<none>

レプリカセットが更新したイメージを反映しているか確認(変更したイメージに基づき新規レプリカセット replicaset.apps/mynginx-654f8684f8 が作成される)

$ kubectl get deploy,rs,po -l app=mynginx
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mynginx   3/3     3            3           34m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/mynginx-574494d858   3         3         3       4m10s
replicaset.apps/mynginx-654f8684f8   0         0         0       34m

NAME                           READY   STATUS    RESTARTS   AGE
pod/mynginx-574494d858-5kflv   1/1     Running   0          4m10s
pod/mynginx-574494d858-7cw4x   1/1     Running   0          3m28s
pod/mynginx-574494d858-b7ksw   1/1     Running   0          3m44s

リビジョン1へのロールバック

$ kubectl rollout undo deployment mynginx --to-revision=1
deployment.apps/mynginx rolled back

ロールバックするとリビジョン1が消去されてリビジョン3に移行します。

$ kubectl rollout history deployment/mynginx
deployment.apps/mynginx 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

元のレプリカセット replicaset.apps/mynginx-654f8684f8 に戻ったことを確認

$ kubectl get deploy,rs,po -l app=mynginx
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mynginx   3/3     3            3           48m

NAME                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/mynginx-574494d858   0         0         0       17m
replicaset.apps/mynginx-654f8684f8   3         3         3       48m

NAME                           READY   STATUS    RESTARTS   AGE
pod/mynginx-654f8684f8-99vj5   1/1     Running   0          2m1s
pod/mynginx-654f8684f8-ch8rk   1/1     Running   0          93s
pod/mynginx-654f8684f8-xjwpq   1/1     Running   0          108s

kubectl for Docker Users

Pod内のコンテナへのアクセス

Podの確認

$ kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
pod001   1/1     Running   0          8m3s

コンテナシェルへ移動—> ls コマンド実行

$ kubectl exec -ti pod001 -- sh
# ls 
bin   dev		   docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
boot  docker-entrypoint.d  etc			 lib   media  opt  root  sbin  sys  usr

ポッドに複数のコンテナが稼働している場合

ポッドの詳細から稼働イメージ(コンテナ)の名称を確認

$ kubectl describe pods POD_NAME

コンテナ名を指定してコンテナシェル( bash または sh )に移動

$ kubectl exec -ti pods POD_NAME -c CONTAINER_NAME -- bash

ログ確認

Examples:
  # Return snapshot logs from pod nginx with only one container
  kubectl logs nginx
  
  # Return snapshot logs from pod nginx with multi containers
  kubectl logs nginx --all-containers=true
  
  # Return snapshot logs from all containers in pods defined by label app=nginx
  kubectl logs -l app=nginx --all-containers=true
  
  # Return snapshot of previous terminated ruby container logs from pod web-1
  kubectl logs -p -c ruby web-1
  
  # Begin streaming the logs of the ruby container in pod web-1
  kubectl logs -f -c ruby web-1
  
  # Begin streaming the logs from all containers in pods defined by label app=nginx
  kubectl logs -f -l app=nginx --all-containers=true
  
  # Display only the most recent 20 lines of output in pod nginx
  kubectl logs --tail=20 nginx
  
  # Show all logs from pod nginx written in the last hour
  kubectl logs --since=1h nginx
  
  # Show logs from a kubelet with an expired serving certificate
  kubectl logs --insecure-skip-tls-verify-backend nginx
  
  # Return snapshot logs from first container of a job named hello
  kubectl logs job/hello
  
  # Return snapshot logs from container nginx-1 of a deployment named nginx
  kubectl logs deployment/nginx -c nginx-1

Images

Image names

Container images are usually given a name such as pause, example/mycontainer, or kube-apiserver. Images can also include a registry hostname; for example: fictional.registry.example/imagename, and possibly a port number as well; for example: fictional.registry.example:10443/imagename.

Image pull policy

The imagePullPolicy for a container and the tag of the image affect when the kubelet attempts to pull (download) the specified image.

Here’s a list of the values you can set for imagePullPolicy and the effects these values have:

IfNotPresent
the image is pulled only if it is not already present locally.

Always
every time the kubelet launches a container, the kubelet queries the container image registry to resolve the name to an image digest. If the kubelet has a container image with that exact digest cached locally, the kubelet uses its cached image; otherwise, the kubelet pulls the image with the resolved digest, and uses that image to launch the container.

Never
the kubelet does not try fetching the image. If the image is somehow already present locally, the kubelet attempts to start the container; otherwise, startup fails. See pre-pulled images for more details.

DaemonSet

他のワークロード オブジェクトと同様に、DaemonSet は複製された Pod のグループを管理します。ただし、DaemonSet は、クラスタ全体またはノードのサブセットに渡って、ノードあたり 1 つの Pod のモデルを維持しようとします。ノードプールにノードが追加されると、DaemonSet は必要に応じて自動的に新しいノードに Pod を追加します。

DaemonSet は、Pod テンプレートを使用します。これには、その Pod の仕様が含まれています。Pod 仕様によって、各 Pod の外観(コンテナ内で実行するアプリケーション、マウントするボリューム、ラベルとセレクタなど)が決定されます。

DaemonSet Pod には、他の Pod と同じ優先順位のルールが適用されます。DaemonSet Pod は taint と許容値を考慮しますが、DaemonSet Pod には暗黙的な許容値があります

使用パターン

DaemonSet は、すべてのノードまたは特定のノードで実行する必要があり、ユーザーの介入を必要としない、進行中のバックグラウンド タスクのデプロイに便利です。このようなタスクの例としては、ceph などのストレージ デーモン、fluent-bit などのログ収集デーモン、collectd などのノード モニタリング デーモンがあります。

たとえば、すべてのノードでデーモンのタイプごとに DaemonSet を実行できます。または、1 つのタイプのデーモンに対して複数の DaemonSet を実行することもできますが、ハードウェア タイプやリソースニーズによって異なる構成を使用することもできます。


Service

Service とは、一連の Pod エンドポイントを 1 つのリソースにグループ化したものです。このグループにアクセスするさまざまな方法を構成できます。デフォルトでは固定クラスタ IP アドレスを取得し、クラスタ内のクライアントはそれを使って Service 内の Pod と通信できます。クライアントがこの IP アドレスにリクエストを送信すると、リクエストが Service 内のポッドの 1 つにルーティングされます。

Service は、セレクタを使用してメンバーの Pod を識別します。Pod が Service のメンバーとして識別されるには、セレクタで指定されたすべてのラベルが Pod に設定されている必要があります。ラベルは、オブジェクトに関連する任意の Key-Value ペアです。

次の Service マニフェストのセレクタには 2 つのラベルが指定されています。selector フィールドでは、app: metrics ラベルと department:engineering ラベルの両方を持つ Pod がこの Service のメンバーであることを示しています。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: engineering
  ports:
  ...

Kubernetes Service を使用する理由

Kubernetes クラスタの各 Pod は内部 IP アドレスを持ちます。しかし、Deployment 内の Pod が稼働して停止すると、IP アドレスが変わります。このため、Pod IP アドレスを直接使用しても意味はありません。Service を使用すると、メンバー Pod の IP アドレスが変更されても、Service の存続期間中に固定の IP アドレスを取得できます。

Service は負荷分散としても機能します。クライアントは単一の固定 IP アドレスを呼び出しますが、リクエストは Service のメンバーである Pod 全体で負荷分散されます。

Kubernetes Service のタイプ

Service には、次の 5 つのタイプがあります。

  • ClusterIP(デフォルト): 内部クライアントが内部の固定 IP アドレスにリクエストを送信します。
  • NodePort: クライアントは、Service が指定した 1 つ以上の nodePort 値を使用して、ノードの IP アドレスにリクエストを送信します。
  • LoadBalancer: クライアントがネットワーク ロードバランサの IP アドレスにリクエストを送信します。
  • ExternalName: 内部クライアントが、外部 DNS 名のエイリアスとして Service の DNS 名を使用します。
  • Headless: headless Service は、Pod のグループ化を行うものの、固定 IP アドレスは必要ない場合に使用します。

NodePort タイプは ClusterIP の拡張タイプです。したがって、NodePort タイプの Service はクラスタ IP アドレスを使用します。

LoadBalancer タイプは NodePort の拡張タイプです。したがって、LoadBalancer タイプの Service は、クラスタ IP アドレスと 1 つ以上の nodePort 値を使用します。

Kubernetes APIへのアクセスコントロール ( Authentication, Authorization, and Admission Control)

Kubernetes APIにはkubectl やクライアントライブラリ、あるいはRESTリクエストを用いてアクセスします。 APIアクセスには、人間のユーザーとKubernetesサービスアカウントの両方が認証可能です。 リクエストがAPIに到達すると、次の図のようにいくつかの段階を経ます。

トランスポート層のセキュリティ

一般的なKubernetesクラスターでは、APIはTLSで保護された443番ポートで提供されます。 APIサーバーは証明書を提示します。 この証明書は、プライベート認証局(CA)を用いて署名することも、一般に認知されているCAと連携した公開鍵基盤に基づき署名することも可能です。

クラスターがプライベート認証局を使用している場合、接続を信頼し、傍受されていないと確信できるように、クライアント上の~/.kube/configに設定されたそのCA証明書のコピーが必要です。

クライアントは、この段階でTLSクライアント証明書を提示することができます。

認証 (Authentication)

TLSが確立されると、HTTPリクエストは認証のステップに移行します。 これは図中のステップ1に該当します。 クラスター作成スクリプトまたはクラスター管理者は、1つまたは複数のAuthenticatorモジュールを実行するようにAPIサーバーを設定します。 Authenticatorについては、認証で詳しく説明されています。

認証ステップへの入力はHTTPリクエスト全体ですが、通常はヘッダとクライアント証明書の両方、またはどちらかを調べます。

認証モジュールには、クライアント証明書、パスワード、プレーントークン、ブートストラップトークン、JSON Web Tokens(サービスアカウントに使用)などがあります。

複数の認証モジュールを指定することができ、その場合、1つの認証モジュールが成功するまで、それぞれを順番に試行します。

認証できない場合、HTTPステータスコード401で拒否されます。 そうでなければ、ユーザーは特定のusernameとして認証され、そのユーザー名は後続のステップでの判断に使用できるようになります。 また、ユーザーのグループメンバーシップを提供する認証機関と、提供しない認証機関があります。

Kubernetesはアクセスコントロールの決定やリクエストログにユーザー名を使用しますが、Userオブジェクトを持たず、ユーザー名やその他のユーザーに関する情報をAPIはに保存しません。

認可 (Authorization)

リクエストが特定のユーザーからのものであると認証された後、そのリクエストは認可される必要があります。 これは図のステップ2に該当します。

リクエストには、リクエスト者のユーザー名、リクエストされたアクション、そのアクションによって影響を受けるオブジェクトを含める必要があります。 既存のポリシーで、ユーザーが要求されたアクションを完了するための権限を持っていると宣言されている場合、リクエストは承認されます。

例えば、Bobが以下のようなポリシーを持っている場合、彼は名前空間projectCaribou内のPodのみを読むことができます。

{
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
        "user": "bob",
        "namespace": "projectCaribou",
        "resource": "pods",
        "readonly": true
    }
}

Bobが次のようなリクエストをした場合、Bobは名前空間projectCaribouのオブジェクトを読むことが許可されているので、このリクエストは認可されます。

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "spec": {
    "resourceAttributes": {
      "namespace": "projectCaribou",
      "verb": "get",
      "group": "unicorn.example.org",
      "resource": "pods"
    }
  }
}

Bobが名前空間projectCaribouのオブジェクトに書き込み(createまたはupdate)のリクエストをした場合、承認は拒否されます。 また、もしBobがprojectFishのような別の名前空間にあるオブジェクトを読み込む(get)リクエストをした場合も、承認は拒否されます。

Kubernetesの認可では、組織全体またはクラウドプロバイダー全体の既存のアクセスコントロールシステムと対話するために、共通のREST属性を使用する必要があります。 これらのコントロールシステムは、Kubernetes API以外のAPIとやり取りする可能性があるため、REST形式を使用することが重要です。

Kubernetesは、ABACモード、RBACモード、Webhookモードなど、複数の認可モジュールをサポートしています。 管理者はクラスターを作成する際に、APIサーバーで使用する認証モジュールを設定します。 複数の認可モジュールが設定されている場合、Kubernetesは各モジュールをチェックし、いずれかのモジュールがリクエストを認可した場合、リクエストを続行することができます。 すべてのモジュールがリクエストを拒否した場合、リクエストは拒否されます(HTTPステータスコード403)。

サポートされている認可モジュールを使用したポリシー作成の詳細を含む、Kubernetesの認可については、認可を参照してください。

アドミッションコントロール (Admission Control)

アドミッションコントロールモジュールは、リクエストを変更したり拒否したりすることができるソフトウェアモジュールです。 認可モジュールが利用できる属性に加えて、アドミッションコントロールモジュールは、作成または修正されるオブジェクトのコンテンツにアクセスすることができます。

アドミッションコントローラーは、オブジェクトの作成、変更、削除、または接続(プロキシ)を行うリクエストに対して動作します。 アドミッションコントローラーは、単にオブジェクトを読み取るだけのリクエストには動作しません。 複数のアドミッションコントローラーが設定されている場合は、順番に呼び出されます。

これは図中のステップ3に該当します。

認証・認可モジュールとは異なり、いずれかのアドミッションコントローラーモジュールが拒否した場合、リクエストは即座に拒否されます。

オブジェクトを拒否するだけでなく、アドミッションコントローラーは、フィールドに複雑なデフォルトを設定することもできます。

利用可能なアドミッションコントロールモジュールは、アドミッションコントローラーに記載されています。

リクエストがすべてのアドミッションコントローラーを通過すると、対応するAPIオブジェクトの検証ルーチンを使って検証され、オブジェクトストアに書き込まれます(図のステップ4に該当します)。


証明書の作成

認証方式によりAPIサーバへアクセスする場合に必要なセルフ証明書の作成

X.509


API Overview

API Reference

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/#-strong-api-groups-strong-

RBAC認証によるAPIサーバへのアクセス(具体例)

認証局CAのキーファイルとこのキーファイルから作成されたCA証明書は minikube 起動時に作成されています ( .minikube/ ) 。

Role-based access control (RBAC)

RBACのAPIでは、次の4種のオブジェクト (kind) を定義しています。

Role , ClusterRole , RoleBinding, ClusterRoleBinding

新規 namespace の作成

$ kubectl create namespace auth-test
namespace/auth-test created

RBAC認証に必要な認証用ファイルを格納するディレクトリを作成し移動

$ mkdir rbac
$ cd rbac

新規作成した namespace にアクセスできるユーザ k9s-auth を登録

$ sudo useradd -s /bin/bash k9s-auth
$ sudo passwd k9s-auth
新しい パスワード: 
新しい パスワードを再入力してください: 
passwd: パスワードは正しく更新されました

クライアント(ユーザ : k9s-auth )側のRSAキーペア k9s-auth.key を作成

$ openssl genpkey -algorithm RSA -out k9s-auth.key -pkeyopt rsa_keygen_bits:2048
..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.......+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+..............+......+.+...
.....
.....
..+..+.......+...............+.....+..........+.....+......+..........+......+....................+.+.....+...+.......+.....+......................+.....+.+............+..+...+..........+.........+.....+....+..+...+.+.....+......+...+.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

ユーザ公開キーの証明書署名要求 k9s-auth.csr を作成します

$ openssl req -new -key k9s-auth.key -out k9s-auth.csr -subj "/CN=k9s-auth/O=learner"

ここで kubectl で証明書署名要求する際に必要となる設定ファイル signing-request.yaml を作成します。

request: <assign encoded value from next cat command>

の箇所は後ほど指定します。

$ nano signing-request.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: k9s-auth-csr
spec:
  groups:
  - system:authenticated
  request: <assign encoded value from next cat command>
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - digital signature
  - key encipherment
  - client auth

証明書署名要求をBase64でエンコードし、その出力結果を上記request: <assign encoded value from next cat command> にコピーします。

$ cat k9s-auth.csr | base64 | tr -d '\n','%'
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..........................
..............
..............

出力結果をコピー

$ nano signing-request.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: k9s-auth-csr
spec:
  groups:
  - system:authenticated
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0..........................
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - digital signature
  - key encipherment
  - client auth

上記設定ファイルを指定して kubectl で証明書署名要求オブジェクトを作成します

$ kubectl create -f signing-request.yaml
certificatesigningrequest.certificates.k8s.io/k9s-auth-csr created

上記オブジェクトの状態を確認

$ kubectl get csr
NAME           AGE   SIGNERNAME                            REQUESTOR       REQUESTEDDURATION   CONDITION
k9s-auth-csr   27s   kubernetes.io/kube-apiserver-client   minikube-user   <none>              Pending

上記オブジェクトを承認します。

$ kubectl certificate approve k9s-auth-csr
certificatesigningrequest.certificates.k8s.io/k9s-auth-csr approved

再度オブジェクトの状態確認

$ kubectl get csr
NAME           AGE    SIGNERNAME                            REQUESTOR       REQUESTEDDURATION   CONDITION
k9s-auth-csr   111s   kubernetes.io/kube-apiserver-client   minikube-user   <none>              Approved,Issued

証明書署名要求が承認されたので、ユーザの公開キーを含むその証明書をBase64でデコードし k9s-auth.crt として出力します

$ kubectl get csr k9s-auth-csr -o jsonpath='{.status.certificate}' | base64 -d > k9s-auth.crt

証明書の中身を確認します

$ cat k9s-auth.crt
-----BEGIN CERTIFICATE-----
MIIDGjCCAgKgAwIBAgIQP3NjqIyzzDNEMISgSMrtcjANBgkqhkiG9w0BAQsFADAV
MRMwEQYDVQQDEwptaW5pa3ViZUNBMB4XDTIyMDkwMTAyMjM1M1oXDTIzMDkwMTAy
.....
.....
.....
1UnAKWlA8ywjohwUOmo3s6v/n4B3o6phzFLBuBlI31jWVTH8AoR6BPaWpP823Cdn
QKeOO6on+JpI1RoW1nMHZEmNC+BWBiD0brS2GlpE
-----END CERTIFICATE-----

kubectl のクライアント設定ファイルにプライベートキーとCAによる公開キーの証明書を保有するユーザ k9s-auth を追加します

$ kubectl config set-credentials k9s-auth --client-certificate=k9s-auth.crt --client-key=k9s-auth.key
User "k9s-auth" set.

同じく上記クライアント設定ファイルにユーザ k9s-auth 向けの新しい context : k9s-auth-contextを作成します

$ kubectl config set-context k9s-auth-context --cluster=minikube --namespace=auth-test --user=k9s-auth
k9s-auth
Context "k9s-auth-context" created.

Note) 上記 k9s-authk9s-auth-context を除外する場合

$ kubectl config unset users.k9s-auth
$ kubectl config unset contexts.k9s-auth-context

上記内容を反映したクライアント設定ファイルを確認します

$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/user001/.minikube/ca.crt
    extensions:
    - extension:
        last-update: Mon, 29 Aug 2022 15:14:57 JST
        provider: minikube.sigs.k8s.io
        version: v1.26.1
      name: cluster_info
    server: https://192.168.49.2:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    namespace: auth-test
    user: k9s-auth
  name: k9s-auth-context
- context:
    cluster: minikube
    extensions:
    - extension:
        last-update: Mon, 29 Aug 2022 15:14:57 JST
        provider: minikube.sigs.k8s.io
        version: v1.26.1
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: k9s-auth
  user:
    client-certificate: /home/use001/rbac/k9s-auth.crt
    client-key: /home/user001/rbac/k9s-auth.key
- name: minikube
  user:
    client-certificate: /home/user001/.minikube/profiles/minikube/client.crt
    client-key: /home/user001/.minikube/profiles/minikube/client.key

namespace : auth-testnginx をデプロイします

$ kubectl -n auth-test create deployment nginx --image=nginx:alpine
deployment.apps/nginx created

ここで contextk9s-auth-context に指定してpodの確認をすると、指定した context でのユーザ k9s-auth にアクセス権限が設定されていないため以下のエラーが発生します。

$ kubectl --context=k9s-auth-context get pods
Error from server (Forbidden): pods is forbidden: User "k9s-auth" cannot list resource "pods" in API group "" in the namespace "auth-test"

pod-reader というロールオブジェクトを作成するための設定ファイルを作成します。namespace : test-authpod リソースに対して get, watch, list の権限を付与します。

$ nano role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: auth-test
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

ロールオブジェクトを作成します

$ kubectl create -f role.yaml
role.rbac.authorization.k8s.io/pod-reader created

ロールオブジェクトの確認

$ kubectl -n auth-test get roles
NAME         CREATED AT
pod-reader   2022-09-01T02:47:42Z

ロールオブジェクト pod-reader にユーザ k9s-auth を割当てるためのロールバインディングオブジェクトを作成するための設定ファイルを作成します。

$ nano rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-read-access
  namespace: auth-test
subjects:
- kind: User
  name: k9s-auth
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

上記設定ファイルを指定してオブジェクトを作成

$ kubectl create -f rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/pod-read-access created

contextを指定して get コマンドにより pod リソースがリストアップされるかどうか確認します

$ kubectl --context=k9s-auth-context get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-d7b6f6c9c-l8gfb   1/1     Running   0          6m52s

アドミッションコントローラ

以下アドミッションコントローラにイメージプルポリシーを追加することにより、ポリシー追加前と追加後で作成されるPodにそのポリシーがどのように反映されるか確認するデモです。

初めにAPIサーバでデフォルトで有効となっているアドミッションコントローラを確認します

$ kubectl -n kube-system describe pods/kube-apiserver-minikube | grep -i admission
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota

アドミッションコントローラ AlwaysPullImages を使用しないように(イメージプルポリシーを IfNotPresent で指定)して Nginx をデプロイ

$ kubectl run admitted --image=nginx --image-pull-policy=IfNotPresent
pod/admitted created

上記 Pod のステータス

$ kubectl get po
NAME       READY   STATUS    RESTARTS   AGE
admitted   1/1     Running   0          5m58s

PodImagePullPolicy の確認(yamlフォーマットで出力)

$ kubectl get pod admitted -o yaml | grep -i imagepull
    imagePullPolicy: IfNotPresent

ここでアドミッションコントローラにイメージプルポリシーを指定するため minikube sshminikube のノードにアクセスします。

$ minikube ssh

以下のコマンドで kube-apiserver で定義されているアドミッションコントローラを確認します。

$ sudo grep admission /etc/kubernetes/manifests/kube-apiserver.yaml
    - --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota

結果は $ kubectl -n kube-system describe pods/kube-apiserver-minikube | grep -i admission で出力した結果と同じになります。

:bangbang: kube-apiserver の設定を変更するため、変更前の設定ファイルをバックアップしておきます。

$ sudo cp /etc/kubernetes/manifests/kube-apiserver.yaml /kube-apiserver-yaml-backup

vienable-admission-pluginsAlwaysPullImages を追加します。

$ sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
.....
.....
- --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,AlwaysPullImages
.....
.....

kube-apiserverへのssh接続を切断します。

$ exit

アドミッションコントローラに AlwaysPullImages が追加されていることを確認

$ kubectl -n kube-system describe pods/kube-apiserver-minikube | grep -i admission
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,AlwaysPullImages

再び アドミッションコントローラ AlwaysPullImages を使用しないように Nginx をデプロイ

$ kubectl run mutated --image=nginx --image-pull-policy=IfNotPresent
pod/mutated created

起動Podの確認

$ kubectl get po 
NAME       READY   STATUS    RESTARTS   AGE
admitted   1/1     Running   0          76m
mutated    1/1     Running   0          82s

IfNotPresent を指定してもアドミッションコントローラで AlwaysPullImages を指定しているので Always が優先されます。

$ kubectl get pod mutated -o yaml | grep -i imagepull
    imagePullPolicy: Always

変更前に起動したpodについてはポリシーの変更はありません。

$ kubectl get pod admitted -o yaml | grep -i imagepull
    imagePullPolicy: IfNotPresent

Understanding Kubernetes Objects

Describing a Kubernetes object

When you create an object in Kubernetes, you must provide the object spec that describes its desired state, as well as some basic information about the object (such as a name). When you use the Kubernetes API to create the object (either directly or via kubectl), that API request must include that information as JSON in the request body. Most often, you provide the information to kubectl in a .yaml file. kubectl converts the information to JSON when making the API request.

Here’s an example .yaml file that shows the required fields and object spec for a Kubernetes Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

One way to create a Deployment using a .yaml file like the one above is to use the kubectl apply command in the kubectl command-line interface, passing the .yaml file as an argument. Here’s an example:

$ kubectl apply -f https://k8s.io/examples/application/deployment.yaml
deployment.apps/nginx-deployment created

Required Fields

In the .yaml file for the Kubernetes object you want to create, you’ll need to set values for the following fields:

  • apiVersion - Which version of the Kubernetes API you’re using to create this object
  • kind - What kind of object you want to create
  • metadata - Data that helps uniquely identify the object, including a name string, UID, and optional namespace
  • spec - What state you desire for the object

The precise format of the object spec is different for every Kubernetes object, and contains nested fields specific to that object.

The Kubernetes API Reference

can help you find the spec format for all of the objects you can create using Kubernetes.

Service

Kubernetes Service とは

Service とは、一連の Pod エンドポイントを 1 つのリソースにグループ化したものです。このグループにアクセスするさまざまな方法を構成できます。デフォルトでは固定クラスタ IP アドレスを取得し、クラスタ内のクライアントはそれを使って Service 内の Pod と通信できます。クライアントがこの IP アドレスにリクエストを送信すると、リクエストが Service 内のポッドの 1 つにルーティングされます。

Service は、セレクタを使用してメンバーの Pod を識別します。Pod が Service のメンバーとして識別されるには、セレクタで指定されたすべてのラベルが Pod に設定されている必要があります。ラベルは、オブジェクトに関連する任意の Key-Value ペアです。

次の Service マニフェストのセレクタには 2 つのラベルが指定されています。selector フィールドでは、app: metrics ラベルと department:engineering ラベルの両方を持つ Pod がこの Service のメンバーであることを示しています。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: engineering
  ports:
  ...

Kubernetes Service を使用する理由

Kubernetes クラスタの各 Pod は内部 IP アドレスを持ちます。しかし、Deployment 内の Pod が稼働して停止すると、IP アドレスが変わります。このため、Pod IP アドレスを直接使用しても意味はありません。Service を使用すると、メンバー Pod の IP アドレスが変更されても、Service の存続期間中に固定の IP アドレスを取得できます。

Service は負荷分散としても機能します。クライアントは単一の固定 IP アドレスを呼び出しますが、リクエストは Service のメンバーである Pod 全体で負荷分散されます。

Kubernetes Service のタイプ

Service には、次の 5 つのタイプがあります。

  • ClusterIP(デフォルト): 内部クライアントが内部の固定 IP アドレスにリクエストを送信します。
  • NodePort: クライアントは、Service が指定した 1 つ以上の nodePort 値を使用して、ノードの IP アドレスにリクエストを送信します。
  • LoadBalancer: クライアントがネットワーク ロードバランサの IP アドレスにリクエストを送信します。
  • ExternalName: 内部クライアントが、外部 DNS 名のエイリアスとして Service の DNS 名を使用します。
  • Headless: headless Service は、Pod のグループ化を行うものの、固定 IP アドレスは必要ない場合に使用します。

NodePort タイプは ClusterIP の拡張タイプです。したがって、NodePort タイプの Service はクラスタ IP アドレスを使用します。

LoadBalancer タイプは NodePort の拡張タイプです。したがって、LoadBalancer タイプの Service は、クラスタ IP アドレスと 1 つ以上の nodePort 値を使用します。


デフォルトサービスのClusterIPをNodePortに変更して外部からNodeにアクセス(デモ)

Pod:pod-hello の起動

$ kubectl run pod-hello --image=pbitty/hello-from:latest --port=80 --expose=true
service/pod-hello created
pod/pod-hello created

Pod, Service, Endpoint の確認

$ kubectl get po,svc,ep --show-labels
NAME            READY   STATUS    RESTARTS   AGE   LABELS
pod/pod-hello   1/1     Running   0          98s   run=pod-hello

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   LABELS
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   18d   component=apiserver,provider=kubernetes
service/pod-hello    ClusterIP   10.99.121.52   <none>        80/TCP    98s   <none>

NAME                   ENDPOINTS           AGE   LABELS
endpoints/kubernetes   192.168.49.2:8443   18d   endpointslice.kubernetes.io/skip-mirror=true
endpoints/pod-hello    172.17.0.8:80       98s   <none>

pod-hello サービスのセレクター確認

$ kubectl describe svc pod-hello | grep -i selector
Selector:          run=pod-hello

デフォルトでは外部(ホスト)からノードにアクセスできません。

$ minikube service --all
|-----------|------------|-------------|--------------|
| NAMESPACE |    NAME    | TARGET PORT |     URL      |
|-----------|------------|-------------|--------------|
| default   | kubernetes |             | No node port |
|-----------|------------|-------------|--------------|
😿  サービス default/kubernetes は NodePort がありません
|-----------|-----------|-------------|--------------|
| NAMESPACE |   NAME    | TARGET PORT |     URL      |
|-----------|-----------|-------------|--------------|
| default   | pod-hello |             | No node port |
|-----------|-----------|-------------|--------------|
😿  サービス default/pod-hello は NodePort がありません

minikube ssh によりクラスターのシェルに移動

$ minikube ssh
Last login: Sat Sep  3 04:09:13 2022 from 192.168.49.1

クラスター内ではサービスのクラスターIP 10.99.121.52 またはエンドポイント 172.17.0.8 を指定することでPodにアクセスできます。

$ curl 10.99.121.52
Hello from pod-hello (172.17.0.8)

$ curl 172.17.0.8
Hello from pod-hello (172.17.0.8)

クラスターのシェルから出て、ホストのシェルに戻ります。

$ exit

外部(ホスト)からアクセスできるようにサービスの内容を変更します。
type: ClusterIP から type: NodePort に変更します。

$ kubectl edit svc pod-hello
service/pod-hello edited

pod-hello のサービスタイプが ClusterIP から NodePort に変更になったことを確認

$ kubectl get po,svc,ep --show-labels
NAME            READY   STATUS    RESTARTS   AGE   LABELS
pod/pod-hello   1/1     Running   0          26m   run=pod-hello

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE   LABELS
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP        19d   component=apiserver,provider=kubernetes
service/pod-hello    NodePort    10.99.121.52   <none>        80:30613/TCP   26m   <none>

NAME                   ENDPOINTS           AGE   LABELS
endpoints/kubernetes   192.168.49.2:8443   19d   endpointslice.kubernetes.io/skip-mirror=true
endpoints/pod-hello    172.17.0.8:80       26m   <none>

以下割当てられたURLにアクセスするとブラウザで Hello from pod-hello (172.17.0.8) という表示が確認できます。

$ minikube service --all
|-----------|------------|-------------|--------------|
| NAMESPACE |    NAME    | TARGET PORT |     URL      |
|-----------|------------|-------------|--------------|
| default   | kubernetes |             | No node port |
|-----------|------------|-------------|--------------|
😿  サービス default/kubernetes は NodePort がありません
|-----------|-----------|-------------|---------------------------|
| NAMESPACE |   NAME    | TARGET PORT |            URL            |
|-----------|-----------|-------------|---------------------------|
| default   | pod-hello |          80 | http://192.168.49.2:30613 |
|-----------|-----------|-------------|---------------------------|
🎉  デフォルトブラウザーで default/pod-hello サービスを開いています...

次に同じイメージによるpodを3つデプロイし、 kubectl expose コマンドでタイプに NodePort を指定します。

$ kubectl create deployment deploy-hello --image=pbitty/hello-from:latest --port=80 --replicas=3
deployment.apps/deploy-hello created

$ kubectl expose deployment deploy-hello --type=NodePort
service/deploy-hello exposed

ラベル app=deploy-hello を指定してDeployment, Pod, Service, Endpoint の確認

$ kubectl get deploy,po,svc,ep -l app=deploy-hello --show-labels
NAME                           READY   UP-TO-DATE   AVAILABLE   AGE    LABELS
deployment.apps/deploy-hello   3/3     3            3           2m5s   app=deploy-hello

NAME                               READY   STATUS    RESTARTS   AGE    LABELS
pod/deploy-hello-6c5fd5cc9-4kc7n   1/1     Running   0          2m4s   app=deploy-hello,pod-template-hash=6c5fd5cc9
pod/deploy-hello-6c5fd5cc9-mkvhr   1/1     Running   0          2m4s   app=deploy-hello,pod-template-hash=6c5fd5cc9
pod/deploy-hello-6c5fd5cc9-zscq2   1/1     Running   0          2m4s   app=deploy-hello,pod-template-hash=6c5fd5cc9

NAME                   TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE   LABELS
service/deploy-hello   NodePort   10.97.23.69   <none>        80:30322/TCP   64s   app=deploy-hello

NAME                     ENDPOINTS                                     AGE   LABELS
endpoints/deploy-hello   172.17.0.10:80,172.17.0.11:80,172.17.0.9:80   64s   app=deploy-hello

deploy-hello のURLの確認

$ minikube service --all
|-----------|--------------|-------------|---------------------------|
| NAMESPACE |     NAME     | TARGET PORT |            URL            |
|-----------|--------------|-------------|---------------------------|
| default   | deploy-hello |          80 | http://192.168.49.2:30322 |
|-----------|--------------|-------------|---------------------------|
|-----------|------------|-------------|--------------|
| NAMESPACE |    NAME    | TARGET PORT |     URL      |
|-----------|------------|-------------|--------------|
| default   | kubernetes |             | No node port |
|-----------|------------|-------------|--------------|
😿  サービス default/kubernetes は NodePort がありません
|-----------|-----------|-------------|---------------------------|
| NAMESPACE |   NAME    | TARGET PORT |            URL            |
|-----------|-----------|-------------|---------------------------|
| default   | pod-hello |          80 | http://192.168.49.2:30613 |
|-----------|-----------|-------------|---------------------------|
🎉  デフォルトブラウザーで default/deploy-hello サービスを開いています...
🎉  デフォルトブラウザーで default/pod-hello サービスを開いています...

ホストからアクセスすると3つのpodの何れかに割り振られていることが確認できます。

$ curl http://192.168.49.2:30322
Hello from deploy-hello-6c5fd5cc9-4kc7n (172.17.0.9)
$ curl http://192.168.49.2:30322
Hello from deploy-hello-6c5fd5cc9-zscq2 (172.17.0.11)
$ curl http://192.168.49.2:30322
Hello from deploy-hello-6c5fd5cc9-zscq2 (172.17.0.11)
$ curl http://192.168.49.2:30322
Hello from deploy-hello-6c5fd5cc9-mkvhr (172.17.0.10)

yamlフォーマットによる pod, service, endpoint の各マニフェスト

$ kubectl get pod/pod-hello -o yaml
$ kubectl get svc/pod-hello -o yaml
$ kubectl get ep/pod-hello -o yaml

マルチポート設定

pod-hello のポート設定変更・追加

$ kubectl edit svc pod-hello
.....
.....
ports:
  - name: http
    nodePort: 30613
    port: 8080
    protocol: TCP
    targetPort: 80
  - name: https
    nodePort: 31443
    port: 8443
    protocol: TCP
    targetPort: 80
.....
.....

変更・追加した pod, service, endpoint の確認

$ kubectl get po,svc,ep pod-hello 
NAME            READY   STATUS    RESTARTS   AGE
pod/pod-hello   1/1     Running   0          20h

NAME                TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                         AGE
service/pod-hello   NodePort   10.99.121.52   <none>        8080:30613/TCP,8443:31443/TCP   20h

NAME                  ENDPOINTS                     AGE
endpoints/pod-hello   172.17.0.8:80,172.17.0.8:80   20h

クラスター内部からはクラスターIPまたは pod のIPとポートを指定することによりアクセス可能

$ minikube ssh

$ curl http://10.99.121.52:8080
Hello from pod-hello (172.17.0.8)

$ curl http://10.99.121.52:8443
Hello from pod-hello (172.17.0.8)

$ curl http://172.17.0.8       
Hello from pod-hello (172.17.0.8)

クラスター外部からは kubernetes のシステムIPとnodePortを指定してアクセス

$ curl http://192.168.49.2:30613
Hello from pod-hello (172.17.0.8)

$ curl http://192.168.49.2:31443
Hello from pod-hello (172.17.0.8)