| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

「MicroK8s」の版間の差分

提供: MyMemoWiki
ナビゲーションに移動 検索に移動
 
(同じ利用者による、間の263版が非表示)
1行目: 1行目:
| [[Kubernetes]] | [[Docker]] |
+
| [[Kubernetes]] | [[Kubectl]] | [[Minikube]] | [[Docker]] | [[Multipass]] |  [[Ubuntu]] |
 
==MicroK8s==
 
==MicroK8s==
{{amazon|4873118409}}
 
 
 
{{amazon|B07HFS7TDT}}
 
{{amazon|B07HFS7TDT}}
  
 
*https://microk8s.io/
 
*https://microk8s.io/
 +
*https://kubernetes.io/
 +
*https://kubernetes.io/docs/tutorials/kubernetes-basics/
  
==インストール==
+
==基本操作==
===[[Mac]]にインストール===
+
===Document===
 +
*[https://kubernetes.io/docs/tutorials/ チュートリアル]
 +
*[https://kubernetes.io/docs/reference/glossary/?fundamental=true 標準用語集]
 +
 
 +
===インストール===
 +
====[[Mac]]にインストール====
 
*https://jp.ubuntu.com/blog/kubernetes-on-mac-how-to-set-up-jp
 
*https://jp.ubuntu.com/blog/kubernetes-on-mac-how-to-set-up-jp
 
*https://microk8s.io/docs/install-alternatives#heading--macos
 
*https://microk8s.io/docs/install-alternatives#heading--macos
 
<pre>
 
<pre>
 
$ brew install ubuntu/microk8s/microk8s
 
$ brew install ubuntu/microk8s/microk8s
 +
</pre>
 +
*Driverを[[VirtualBox]]に変更する場合、先に変更してから、install
 +
*[https://www.typea.info/blog/index.php/2020/11/20/mac_multipass_microk8s_virtuabox_networibridge/ Virtual Boxでネットワークブリッジを作成する]
 +
<pre>
 
$ microk8s install
 
$ microk8s install
 
</pre>
 
</pre>
====[[Mac]]ネットワークトラブルシュート====
 
*https://multipass.run/docs/troubleshooting-networking-on-macos
 
  
===[[Ubuntu]]にインストール===
+
====[[Ubuntu]]にインストール====
 
<pre>
 
<pre>
 
$ sudo snap install microk8s --classic
 
$ sudo snap install microk8s --classic
 
</pre>
 
</pre>
===ステータスの確認===
+
*アンインストール
 +
<pre>
 +
$ sudo snap remove microk8s
 +
</pre>
 +
 
 +
====ステータスの確認====
 +
*microk8s status でステータスの確認
 +
*インストール中などは、--wait-ready で状況確認できる
 
<pre>
 
<pre>
 
$ microk8s status --wait-ready
 
$ microk8s status --wait-ready
35行目: 49行目:
 
     ambassador          # Ambassador API Gateway and Ingress
 
     ambassador          # Ambassador API Gateway and Ingress
 
     cilium              # SDN, fast with full network policy
 
     cilium              # SDN, fast with full network policy
    dashboard            # The Kubernetes dashboard
+
         :
    dns                  # CoreDNS
 
    fluentd              # Elasticsearch-Fluentd-Kibana logging and monitoring
 
    gpu                  # Automatic enablement of Nvidia CUDA
 
    helm                # Helm 2 - the package manager for Kubernetes
 
    helm3                # Helm 3 - Kubernetes package manager
 
    host-access         # Allow Pods connecting to Host services smoothly
 
    ingress              # Ingress controller for external access
 
    istio                # Core Istio service mesh services
 
    jaeger              # Kubernetes Jaeger operator with its simple config
 
    knative              # The Knative framework on Kubernetes.
 
    kubeflow            # Kubeflow for easy ML deployments
 
    linkerd              # Linkerd is a service mesh for Kubernetes and other frameworks
 
    metallb              # Loadbalancer for your Kubernetes cluster
 
    metrics-server      # K8s Metrics Server for API access to service metrics
 
    multus              # Multus CNI enables attaching multiple network interfaces to pods
 
    prometheus          # Prometheus operator for monitoring and logging
 
    rbac                # Role-Based Access Control for authorisation
 
    registry            # Private image registry exposed on localhost:32000
 
 
     storage              # Storage class; allocates storage from host directory
 
     storage              # Storage class; allocates storage from host directory
 
</pre>
 
</pre>
  
 +
===開始と終了===
 +
*MicroK8sは、停止するまで実行し続ける。停止と開始は、以下のコマンド。
 +
<pre>
 +
$ microk8s stop
 +
$microk8s start
 +
</pre>
 +
===アドオンの使用===
 +
*MicroK8s は最低限のコンポーネントを使用するが、豊富な機能が "add-ons" とタイプすることで利用できる
 +
*サービス間の連携を容易にするDNS管理、 アプリケーションがストレージが必要な場合、'storage' アドオンはホストに直接領域を提供する。これらは簡単にセットアップできる
 +
[https://microk8s.io/docs/addons#heading--list アドオンの一覧]
  
===サービスの有効化/無効化===
+
====サービスの有効化/無効化====
 
*組み込みで有効化可能なアドオンサービスの確認
 
*組み込みで有効化可能なアドオンサービスの確認
 
*サービスを無効化する場合は、disable
 
*サービスを無効化する場合は、disable
65行目: 71行目:
 
</pre>
 
</pre>
 
*サービスを有効化する
 
*サービスを有効化する
 +
*status でどのアドオンが有効/無効かを確認できる
 
<pre>
 
<pre>
 
$ microk8s enable dashboard dns registry istio
 
$ microk8s enable dashboard dns registry istio
</pre>
 
===ダッシュボード===
 
<pre>
 
$ microk8s dashboard-proxy
 
</pre>
 
 
*https://gihyo.jp/admin/serial/01/ubuntu-recipe/0560?page=2
 
 
===[[Kubernetes|Kubectl]]===
 
*MicroK8s は専用のバージョンのkubrctlをバンドルしている。
 
*コマンドを監視と制御のために実行することができる。
 
<pre>
 
$ microk8s kubectl get all --all-namespaces
 
NAMESPACE            NAME                                            READY  STATUS              RESTARTS  AGE
 
kube-system          pod/calico-node-m9j8n                            1/1    Running            0          90m
 
kube-system          pod/metrics-server-8bbfb4bdb-679mc              1/1    Running            0          7m38s
 
            :
 
</pre>
 
*MicroK8s は、すでにインストール済みのkubectlとの衝突を防ぐためにネームスペースを指定したkubectlコマンドを使用する
 
*もしインストール済みの物がないのであれば、簡単にエイリアスを指定できる
 
*~/.bash_aliases に以下を記載
 
<pre>
 
alias kubectl='microk8s kubectl'
 
</pre>
 
 
*~/.bash_profile に以下を追記
 
<pre>
 
if [ -f ~/.bash_aliases ]; then
 
    . ~/.bash_aliases
 
fi
 
 
</pre>
 
</pre>
  
*https://hondou.homedns.org/pukiwiki/index.php?k8s%20microK8s
+
===コマンド===
 
 
<pre>
 
$ token=$(microk8s kubectl -n kube-system get secret | grep default-token | cut -d " " -f1)
 
$ microk8s kubectl -n kube-system describe secret $token
 
$ microk8s kubectl port-forward -n kube-system service/kubernetes-dashboard 10443:443
 
</pre>
 
 
 
https://127.0.0.1:10443
 
 
 
==コマンド==
 
 
https://microk8s.io/docs/commands
 
https://microk8s.io/docs/commands
 
{| class="wikitable"
 
{| class="wikitable"
165行目: 132行目:
 
|}
 
|}
  
==はじめに==
+
===マニフェスト===
*https://microk8s.io/docs
+
*[https://kubernetes.io/ja/docs/reference/ リファレンス]
 +
*[https://kubernetes.io/docs/reference/using-api/api-overview/ API概要]
 +
*[https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/ リファレンス v1.19]
 +
 
 +
===ダッシュボード===
 +
*https://microk8s.io/docs/addon-dashboard
 +
*https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/README.md
 +
[https://www.typea.info/blog/index.php/2020/11/17/mac_microk8s_dashboard_etc/ ダッシュボード接続手順、トラブルシュート]
 +
<pre>
 +
$ microk8s enable dashboard dns
 +
$ microk8s dashboard-proxy
 +
</pre>
 +
 
 +
===[[Kubectl]]===
 +
*MicroK8s は専用のバージョンの[[kubectl]]をバンドルしている。
 +
*コマンドを監視と制御のために実行することができる。
 +
<pre>
 +
$ microk8s kubectl get all --all-namespaces
 +
NAMESPACE            NAME                                            READY  STATUS              RESTARTS  AGE
 +
kube-system          pod/calico-node-m9j8n                            1/1    Running            0          90m
 +
kube-system          pod/metrics-server-8bbfb4bdb-679mc              1/1    Running            0          7m38s
 +
            :
 +
</pre>
 +
*MicroK8s は、すでにインストール済みのkubectlとの衝突を防ぐためにネームスペースを指定したkubectlコマンドを使用する
 +
*もしインストール済みの物がないのであれば、簡単にエイリアスを指定できる
 +
*~/.bash_aliases に以下を記載
 +
<pre>
 +
alias kubectl='microk8s kubectl'
 +
</pre>
 +
 
 +
*~/.bash_profile に以下を追記
 +
<pre>
 +
if [ -f ~/.bash_aliases ]; then
 +
    . ~/.bash_aliases
 +
fi
 +
</pre>
 +
 
 +
===Kubeconfig===
 +
*https://microk8s.io/docs/working-with-kubectl
 +
*https://qiita.com/imamura_sh/items/91208a9b30e701d1e7f2
 +
<pre>
 +
$ cd ~/
 +
$ mkdir .kube
 +
$ cd .kube
 +
$ microk8s config > config
 +
</pre>
 +
 
 +
==[https://github.com/kubernetes/examples Kubernetesサンプル]==
 +
==Up and Deploy==
 +
{{amazon|4873118409}}
 +
*https://github.com/kubernetes-up-and-running/kuard
 +
===クラスタ===
 +
----
 +
*https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/
 +
*Kubernetesクラスターは以下の2種類のリソースで構成
 +
**マスターがクラスターを管理する、マスターはクラスターの管理を担当
 +
**ノードがアプリケーションを動かすワーカーとなる、ノードは、Kubernetesクラスターのワーカーマシンとして機能するVMまたは物理マシン
 +
 
 +
<pre>
 +
$ kubectl cluster-info
 +
Kubernetes master is running at https://127.0.0.1:16443
 +
 
 +
$ kubectl get nodes
 +
NAME          STATUS  ROLES    AGE  VERSION
 +
microk8s-vm  Ready    <none>  47h  v1.19.3-34+a56971609ff35a
 +
</pre>
 +
 
 +
===Pod===
 +
====作成====
 +
*一番シンプルな方法は kubectl run
 +
<pre>
 +
$ kubectl run nginx --image=nginx
 +
pod/nginx created
 +
</pre>
 +
====マニフェスト====
 +
=====準備=====
 +
*kubectl で -f したときのルートが、/home/ubuntu なので、ローカルの作業フォルダfiles をマウントする
 +
<pre>
 +
multipass mount `pwd`/files microk8s-vm:/home/ubuntu/files
 +
</pre>
 +
=====適用=====
 +
*pod-nginx.yaml
 +
<pre>
 +
apiVersion: v1
 +
kind: Pod
 +
metadata:
 +
  name: nginx-pod
 +
spec:
 +
  containers:
 +
    - name: nginx-container
 +
      image: nginx:latest
 +
      ports:
 +
        - containerPort: 8080
 +
          name: http
 +
          protocol: TCP
 +
</pre>
 +
*適用
 +
<pre>
 +
$ kubectl apply -f files/pod/pod-nginx.yaml
 +
pod/nginx-pod created
 +
</pre>
 +
 
 +
====確認====
 +
=====簡易=====
 +
<pre>
 +
$ kubectl get pods
 +
NAME        READY  STATUS    RESTARTS  AGE
 +
nginx-pod  0/1    Unknown  3          91m
 +
</pre>
 +
=====詳細=====
 +
以下の内容が表示される
 +
#基本情報
 +
#Pod内で動いているコンテナ情報
 +
#Podに関するイベント情報
 +
<pre>
 +
$ kubectl describe pod nginx-pod
 +
Name:        nginx-pod
 +
Namespace:    default
 +
Priority:    0
 +
Node:        microk8s-vm/192.168.64.2
 +
Start Time:  Wed, 18 Nov 2020 22:43:16 +0900
 +
Labels:      <none>
 +
Annotations:  cni.projectcalico.org/podIP: 10.1.254.126/32
 +
              cni.projectcalico.org/podIPs: 10.1.254.126/32
 +
Status:      Running
 +
    :
 +
</pre>
 +
====ポートフォワード====
 +
<pre>
 +
$ kubectl port-forward pod/nginx-pod 80 80
 +
Forwarding from 127.0.0.1:80 -> 80
 +
Forwarding from [::1]:80 -> 80
 +
Unable to listen on port 80: Listeners failed to create with the following errors: [unable to create listener: Error listen tcp4 127.0.0.1:80: bind: address already in use unable to create listener: Error listen tcp6 [::1]:80: bind: address already in use]
 +
</pre>
 +
*macの場合vmに入れば、、、
 +
<pre>
 +
ubuntu@microk8s-vm:~$ curl http://localhost:80
 +
Handling connection for 80
 +
&lt;!DOCTYPE html&gt;
 +
&lt;html&gt;
 +
&lt;head&gt;
 +
&lt;title&gt;Welcome to nginx!&lt;/title&gt;
 +
&lt;style&gt;
 +
    body {
 +
        width: 35em;
 +
        margin: 0 auto;
 +
        font-family: Tahoma, Verdana, Arial, sans-serif;
 +
    }
 +
&lt;/style&gt;
 +
&lt;/head&gt;
 +
&lt;body&gt;
 +
&lt;h1&gt;Welcome to nginx!&lt;/h1&gt;
 +
&lt;p&gt;If you see this page, the nginx web server is successfully installed and
 +
working. Further configuration is required.&lt;/p&gt;
 +
 
 +
&lt;p&gt;For online documentation and support please refer to
 +
&lt;a href="http://nginx.org/"&gt;nginx.org&lt;/a&gt;.&lt;br/&gt;
 +
Commercial support is available at
 +
&lt;a href="http://nginx.com/"&gt;nginx.com&lt;/a&gt;.&lt;/p&gt;
 +
 
 +
&lt;p&gt;&lt;em&gt;Thank you for using nginx.&lt;/em&gt;&lt;/p&gt;
 +
&lt;/body&gt;
 +
&lt;/html&gt;
 +
</pre>
 +
====ログの確認====
 +
<pre>
 +
$ kubectl logs nginx-pod
 +
</pre>
 +
====execでコマンド実行====
 +
*[[kubectl]] -it で対話実行
 +
<pre>
 +
$ kubectl exec -it pod/nginx-pod -- /bin/sh
 +
#
 +
</pre>
 +
 
 +
====コンテナローカル間でファイルコピー====
 +
*ローカル のファイルを、Podにコピー
 +
<pre>
 +
$ kubectl cp files/etc/aaa.html  nginx-pod:/usr/share/nginx/html/aaa.html
 +
</pre>
 +
*Podのファイルをローカルにコピー
 +
<pre>
 +
$ kubectl cp  nginx-pod:/usr/share/nginx/html/index.html files/etc/index.html
 +
</pre>
 +
 
 +
===Service===
 +
[https://kubernetes.io/ja/docs/tutorials/stateless-application/expose-external-ip-address/ クラスター内のアプリケーションにアクセスするために外部IPアドレスを公開]
 +
 
 +
====5つのPodで起動しているアプリケーションへのServiceの作成====
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml
 +
deployment.apps/hello-world created
 +
</pre>
 +
 
 +
<pre>
 +
$ kubectl get pods
 +
NAME                          READY  STATUS              RESTARTS  AGE
 +
hello-world-6df5659cb7-6flwb  0/1    ContainerCreating  0          45s
 +
hello-world-6df5659cb7-lzmnx  0/1    ContainerCreating  0          45s
 +
hello-world-6df5659cb7-ghbfs  0/1    ContainerCreating  0          45s
 +
hello-world-6df5659cb7-jbz9t  0/1    ContainerCreating  0          45s
 +
hello-world-6df5659cb7-fqv2z  0/1    ContainerCreating  0          45s
 +
</pre>
 +
 
 +
<pre>
 +
$ kubectl get deployment hello-world
 +
NAME          READY  UP-TO-DATE  AVAILABLE  AGE
 +
hello-world  5/5    5            5          3m19s
 +
</pre>
 +
 
 +
<pre>
 +
$ kubectl get replicaset
 +
NAME                    DESIRED  CURRENT  READY  AGE
 +
hello-world-6df5659cb7  5        5        5      5m26s
 +
</pre>
 +
====Deploymentを公開するサービスの生成====
 +
*LoadBlancerの有効化
 +
<pre>
 +
$ microk8s enable metallb
 +
</pre>
 +
*Deploymentの生成
 +
<pre>
 +
$ kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
 +
service/my-service exposed
 +
</pre>
 +
*サービスの確認
 +
<pre>
 +
$ kubectl get service my-service
 +
NAME        TYPE          CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
 +
my-service  LoadBalancer  10.152.183.120  192.168.0.120  8080:32132/TCP  20m
 +
</pre>
 +
*実行
 +
<pre>
 +
$ curl http://192.168.0.120:8080
 +
Hello Kubernetes!
 +
</pre>
 +
 
 +
*クリーンアップ
 +
<pre>
 +
$ kubectl delete service my-service
 +
service "my-service" deleted
 +
$ kubectl delete deployment hello-world
 +
deployment.apps "hello-world" deleted
 +
</pre>
  
*Kubernetes は、appやserviceをデプロイするためにあるので、kubecltでそれらを[[Kubernetes]]に対して行うことができる
+
==PHPアプリサンプル==
*デモアプリをインストールしてみる
+
===データストア([https://redis.io/ Radis] )の作成===
 +
*https://kubernetes.io/docs/tutorials/stateless-application/guestbook/
 +
====[https://redis.io/ Radis] Master Deployment====
 +
*ゲストブックアプリケーションは、データストアに、[https://redis.io/ Radis] を使用する
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
 +
</pre>
 +
====[https://redis.io/ Radis] Master Service====
 +
*ゲストブックアプリケーションは、データストアと通信する必要がある
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
 +
</pre>
 +
====[https://redis.io/ Radis] Slave Deployment====
 +
*Radis Slave として、レプリカを2つ作成
 
<pre>
 
<pre>
$ kubectl create deployment nginx --image=nginx
+
$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-deployment.yaml
 
</pre>
 
</pre>
*確認
+
 
 
<pre>
 
<pre>
 
$ kubectl get pods
 
$ kubectl get pods
 +
NAME                          READY  STATUS              RESTARTS  AGE
 +
redis-master-f46ff57fd-lh4lh  1/1    Running            1          19m
 +
redis-slave-bbc7f655d-5vjpb    0/1    ContainerCreating  0          13s
 +
redis-slave-bbc7f655d-954c5    0/1    ContainerCreating  0          13s
 +
</pre>
 +
====[https://redis.io/ Radis] Slave Service====
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-service.yaml
 +
</pre>
 +
 +
<pre>
 +
$ kubectl get services
 +
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP  PORT(S)    AGE
 +
kubernetes    ClusterIP  10.152.183.1    <none>        443/TCP    33h
 +
redis-master  ClusterIP  10.152.183.90  <none>        6379/TCP  11m
 +
redis-slave    ClusterIP  10.152.183.62  <none>        6379/TCP  18s
 +
</pre>
 +
 +
===ゲストブックのセットアップと公開===
 +
====Frontend Development====
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
 +
</pre>
 +
====Frontend Service====
 +
*上記で作成した、Radis サービスは、コンテナ内部からのみアクセス可能。
 +
*デフォルトのサービスは、ClusterIPで、ClusterIPはPodの1つのIPを差す(このIPはクラスタ内殻のみ参照可能)
 +
*もし、ゲストをゲストブックにアクセスさせたい場合、Frontend サービスを外部に見えるようにする必要がある。
 +
*クライアントがコンテナクラスターの外部からサービスにリクエストするためには、NodePortサービスを公開することで可能となる
 +
 +
=====LoadBalancer経由で参照する=====
 +
*type を LoadBalancerに変更して、apply
 +
<pre>
 +
apiVersion: v1
 +
kind: Service
 +
metadata:
 +
  name: frontend
 +
  labels:
 +
    app: guestbook
 +
    tier: frontend
 +
spec:
 +
  # comment or delete the following line if you want to use a LoadBalancer
 +
  #type: NodePort
 +
  # if your cluster supports it, uncomment the following to automatically create
 +
  # an external load-balanced IP for the frontend service.
 +
  type: LoadBalancer
 +
  ports:
 +
  - port: 80
 +
  selector:
 +
    app: guestbook
 +
    tier: frontend
 +
</pre>
 +
 +
*URL(kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml)ではなく、上記を変更した、ローカルファイルからapplyする。
 +
*Macで[[Multipass]]上のため、事前にマウントを実施済み
 +
<pre>
 +
$ kubectl apply -f ./files/php_guest_book/frontend-service.yaml
 +
</pre>
 +
 +
<pre>
 +
$ kubectl get services
 +
NAME          TYPE          CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
 +
kubernetes    ClusterIP      10.152.183.1    <none>          443/TCP        36h
 +
redis-master  ClusterIP      10.152.183.90    <none>          6379/TCP      3h1m
 +
redis-slave    ClusterIP      10.152.183.62    <none>          6379/TCP      169m
 +
frontend      LoadBalancer  10.152.183.187  192.168.0.120  80:30334/TCP  3m10s
 +
</pre>
 +
 +
[[File:microk8s_php_guestbook.png|400px]]
 +
*ダッシュボード
 +
[[File:microk8s_php_guestbook_dashboard.png|400px]]
 +
===クリーンアップ===
 +
<pre>
 +
$ kubectl delete deployment -l app=redis
 +
$ kubectl delete service -l app=redis
 +
$ kubectl delete deployment -l app=guestbook
 +
$ kubectl delete service -l app=guestbook
 +
</pre>
 +
 +
==永続ボリューム==
 +
*https://kubernetes.io/ja/docs/concepts/storage/persistent-volumes/
 +
*ストレージを管理することはインスタンスを管理することとは全くの別物
 +
*PersistentVolumeサブシステムは、ストレージが何から提供されているか、どのように消費されているかをユーザーと管理者から抽象化するAPIを提供
 +
*Podは、PersistentVolumeClaimを通して「こういうspecのVolumeが欲しい」と要求を出すと、その要求に一番近いPersistentVolumeがmountされるという仕組み
 +
*metadata.name、metadata.labelsと、spec.selector.matchLabels、spec.selector.matchExpressionsの値を合わせることで、PersistentVolumeとPersistentVolumeClaimのマッチングをより明示的に、期待したとおりにできる
 +
*https://thinkit.co.jp/article/14195
 +
===PersistentVolume (PV)===
 +
*ストレージクラスを使って管理者もしくは動的にプロビジョニングされるクラスターのストレージの一部
 +
*Nodeと同じようにクラスターリソースの一部
 +
*PVはVolumeのようなボリュームプラグインですが、PVを使う個別のPodとは独立したライフサイクルを持っています
 +
*このAPIオブジェクトはNFS、iSCSIやクラウドプロバイダー固有のストレージシステムの実装の詳細を捕捉します。
 +
 +
===PersistentVolumeClaim (PVC)===
 +
*ユーザーによって要求されるストレージで、これはPodと似ています
 +
*PodはNodeリソースを消費し、PVCはPVリソースを消費します
 +
*Podは特定レベルのCPUとメモリーリソースを要求することができます。クレームは特定のサイズやアクセスモード(例えば、ReadWriteOnce、ReadOnlyMany、ReadWriteManyにマウントできます
 +
 +
*PersistentVolumeClaimはユーザーに抽象化されたストレージリソースの消費を許可する一方、ユーザーは色々な問題に対処するためにパフォーマンスといった様々なプロパティを持ったPersistentVolumeを必要とすることは一般的なことです。
 +
*クラスター管理者はユーザーに様々なボリュームがどのように実装されているかを表に出すことなく、サイズやアクセスモードだけではない色々な点で異なった、様々なPersistentVolumeを提供できる必要があります。これらのニーズに応えるために StorageClass リソースがあります。
 +
 +
===チュートリアル===
 +
*https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
 +
 +
*クラスター管理者の場合、PersistentVolumeを物理ストレージに作成し、VolumeをPodに関連づける必要はない
 +
*開発者、クラスタユーザーの場合、PersistentVolumeChlaimを作成すると、自動的に適したPersistentVolumeに結び付けられる
 +
*Podを生成し、PersistentVolumeClaimを利用することで、ストレージを利用できる
 +
====index.htmlをNodeの作成する====
 +
<pre>
 +
$ multipass sh microk8s-vm
 +
ubuntu@microk8s-vm:~$ sudo mkdir /mnt/data
 +
ubuntu@microk8s-vm:~$ sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"
 +
</pre>
 +
====PersistentVolume生成====
 +
*hostPath PersistentVolume を作成する。KubernetesはhostPathをシングルノードクラスタの開発/テストでサポートする
 +
*hostPath PersistentVolume は、ネットワークアタッチドストレージをエミュレートしたものとしてNodeのファイル、もしくはディレクトリを使用する
 +
*製品版のクラスタでは、hostPathを使わない方が良い。クラスター管理者は、その代わりにネットワークリソース、Google Compute Engine 永続ディスクや、NFS 共有、Amazon Elastic Block Store Volumeを準備する
 +
*クラスター管理者は動的プロビジョニングのために、StorageClassを利用する
 +
<pre>
 +
apiVersion: v1
 +
kind: PersistentVolume
 +
metadata:
 +
  name: task-pv-volume
 +
  labels:
 +
    type: local
 +
spec:
 +
  storageClassName: manual
 +
  capacity:
 +
    storage: 10Gi
 +
  accessModes:
 +
    - ReadWriteOnce
 +
  hostPath:
 +
    path: "/mnt/data"
 +
</pre>
 +
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
 +
persistentvolume/task-pv-volume created
 +
</pre>
 +
 +
<pre>
 +
$ kubectl get pv
 +
NAME            CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS      CLAIM  STORAGECLASS  REASON  AGE
 +
task-pv-volume  10Gi      RWO            Retain          Available          manual                  41s
 +
</pre>
 +
====PersistentVolumeClaimの生成====
 +
*PodはPersistentVolumeClaimを物理ストレージの要求に使用する
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml
 +
persistentvolumeclaim/task-pv-claim created
 +
</pre>
 +
 +
<pre>
 +
$ kubectl get pv
 +
NAME            CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS  CLAIM                  STORAGECLASS  REASON  AGE
 +
task-pv-volume  10Gi      RWO            Retain          Bound    default/task-pv-claim  manual                  44m
 +
$ kubectl get pvc
 +
NAME            STATUS    VOLUME          CAPACITY  ACCESS MODES  STORAGECLASS  AGE
 +
task-pv-claim  Bound    task-pv-volume  10Gi      RWO            manual        77s
 +
</pre>
 +
====Podの生成====
 +
*PersistentVolumeClaimをVolumeとして利用するPodの作成
 +
 +
<pre>
 +
apiVersion: v1
 +
kind: Pod
 +
metadata:
 +
  name: task-pv-pod
 +
spec:
 +
  volumes:
 +
    - name: task-pv-storage
 +
      persistentVolumeClaim:
 +
        claimName: task-pv-claim
 +
  containers:
 +
    - name: task-pv-container
 +
      image: nginx
 +
      ports:
 +
        - containerPort: 80
 +
          name: "http-server"
 +
      volumeMounts:
 +
        - mountPath: "/usr/share/nginx/html"
 +
          name: task-pv-storage
 +
</pre>
 +
<pre>
 +
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml
 +
pod/task-pv-pod created
 +
</pre>
 +
 +
<pre>
 +
$ kubectl get pod
 +
NAME          READY  STATUS    RESTARTS  AGE
 +
task-pv-pod  1/1    Running  0          2m5s
 +
</pre>
 +
*マウントしたVolume情報を確認
 +
<pre>
 +
kubectl exec -it pod/task-pv-pod -- /bin/sh
 +
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
 +
# cat /usr/share/nginx/html/index.html
 +
Hello from Kubernetes storage
 +
</pre>
 +
 +
 +
<pre>
 +
# apt update
 +
# apt install curl
 +
# curl http://localhost
 +
Hello from Kubernetes storage
 +
</pre>
 +
====クリーンアップ====
 +
<pre>
 +
$ kubectl delete pod task-pv-pod
 +
$ kubectl delete pvc task-pv-claim
 +
$ kubectl delete pv task-pv-volume
 +
</pre>
 +
 +
==StatefulSet==
 +
*https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/
 +
===事前準備===
 +
*[https://kubernetes.io/docs/concepts/workloads/pods/ Pods]
 +
*[https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ Cluster DNS]
 +
*[https://kubernetes.io/docs/concepts/services-networking/service/#headless-services Headless Services]
 +
*[https://kubernetes.io/docs/concepts/storage/persistent-volumes/ PersistentVolumes]
 +
*[https://github.com/kubernetes/examples/tree/master/staging/persistent-volume-provisioning/ PersistentVolume Provisioning]
 +
*[https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ StatefulSets]
 +
 +
===StatefulSet作成===
 +
 +
*https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/web/web.yaml
 +
*ダウンロードしてapply
 +
 +
<pre>
 +
$ kubectl apply -f ./files/statefulset-basic/web.yaml
 +
service/nginx created
 +
statefulset.apps/web created
 +
</pre>
 +
 +
<pre>
 +
$ kubectl get services nginx
 +
NAME    TYPE        CLUSTER-IP  EXTERNAL-IP  PORT(S)  AGE
 +
nginx  ClusterIP  None        <none>        80/TCP    4m18s
 +
$ kubectl get statefulset
 +
NAME  READY  AGE
 +
web    0/2    4m22s
 +
</pre>
 +
 +
====PersistentVolumeClaimsエラーの対応====
 +
<pre>
 +
$ kubectl describe pods
 +
Name:          web-0
 +
    :
 +
Events:
 +
  Type    Reason            Age                  From              Message
 +
  ----    ------            ----                ----              -------
 +
  Warning  FailedScheduling  40s (x8 over 9m33s)  default-scheduler  0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.
 +
</pre>
 +
 +
*https://qiita.com/silverbirder/items/d3522237b28703a9adb6
 +
*https://stackoverflow.com/questions/52668938/pod-has-unbound-persistentvolumeclaims
 +
 +
<pre>
 +
$ multipass sh microk8s-vm
 +
ubuntu@microk8s-vm:~$ sudo mkdir /mnt/data
 +
</pre>
 +
*[https://kubernetes.io/ja/docs/concepts/storage/persistent-volumes/ accessModes]
 +
**ReadWriteOnce –ボリュームは単一のNodeで読み取り/書き込みとしてマウントできます
 +
**ReadOnlyMany –ボリュームは多数のNodeで読み取り専用としてマウントできます
 +
**ReadWriteMany –ボリュームは多数のNodeで読み取り/書き込みとしてマウントできます
 +
<blockquote>
 +
HostPath は、ReadWriteOnce しか選択できない
 +
</blockquote>
 +
<pre>
 +
apiVersion: v1
 +
kind: PersistentVolume
 +
metadata:
 +
  name: web-pv
 +
  labels:
 +
    type: local
 +
spec:
 +
  capacity:
 +
    storage: 5Gi
 +
  accessModes:
 +
    - ReadWriteOnce
 +
  hostPath:
 +
    path: "/mnt/data"
 
</pre>
 
</pre>
===アドオンの使用===
+
 
*MicroK8s は最低限のコンポーネントを使用するが、豊富な機能が "add-ons" とタイプすることで利用できる
+
<pre>
*サービス間の連携を容易にするDNS管理、 アプリケーションがストレージが必要な場合、'storage' アドオンはホストに直接領域を提供する。これらは簡単にセットアップできる
+
$ microk8s apply -f ./files/statefulset-basic/pv.yaml
 +
persistentvolume/web-pv created
 +
</pre>
 +
 
 +
===順序付けられた Pod 生成===
 +
*StatefulSet n レプリカのために、Pod がデプロイされるときシーケンシャルに生成され順序づけられる(0...n-1)
 +
<pre>
 +
$ kubectl get pods -w -l app=nginx
 +
NAME    READY  STATUS    RESTARTS  AGE
 +
web-0  0/1    Pending  0          7m32s
 +
web-0  0/1    Pending  0          20m
 +
web-0  0/1    ContainerCreating  0          20m
 +
web-0  0/1    ContainerCreating  0          20m
 +
web-0  1/1    Running            0          20m
 +
web-1  0/1    Pending            0          0s
 +
web-1  0/1    Pending            0          0s
 +
</pre>
 +
 
 +
===StatefulSetのpod===
 +
*StatefulSetに含まれるPodは、一意な順序と安定したネットワークIDを持つ
 +
*StetefulSetのPod は一意のIDを持つ
 +
*このIDは、一意の順序付けられたインデックス、それぞれのpodがStatefulSetコントローラに結び付けられている
 +
*Pod の名前は、<statefulset名>-<順序づけれれたindex> となる。
 
<pre>
 
<pre>
$ microk8s enable dns storage
+
$ kubectl get pods -l app=nginx
 +
NAME    READY  STATUS    RESTARTS  AGE
 +
web-1  0/1    Pending  0          22h
 +
web-0  0/1    Unknown  0          23h
 
</pre>
 
</pre>
[https://microk8s.io/docs/addons#heading--list アドオンの一覧]
+
 
===開始と終了===
+
===Stable ネットワークIDを使用する ===
*MicroK8sは、停止するまで実行し続ける。停止と開始は、以下のコマンド。
+
*それぞれのPod は順序付けられたインデックスに基づく安定したホスト名を持つ
 +
*kubectl exec でそれぞれのpodにhostname コマンドを実行する
 +
 
 
<pre>
 
<pre>
$ microk8s stop
+
$ for i in 0 1; do kubectl exec pod/web-$i hostname; done
$microk8s start
+
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
 +
web-0
 +
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
 +
Error from server (BadRequest): pod web-1 does not have a host assigned
 +
An error occurred when trying to execute 'sudo microk8s.kubectl exec pod/web-1 hostname' with 'multipass': returned exit code 1.
 
</pre>
 
</pre>
===クラスタリング===
 
*https://microk8s.io/docs/clustering
 
  
*2つ以上のすでに稼働しているMicoroK8sインスタンスにクラスタを作成するには、add-nodeコマンドを使用
+
<blockquote>
*このコマンドが実行されたMicroK8sインスタンスが、クラスタのマスターとなり、[[Kubernetes]]コントロールプレーンをホストする
+
永続化Volumeが、hostPath指定の場合、1つのPodからしか接続できないため立ち上がらない。
 +
</blockquote>
 
<pre>
 
<pre>
$ multipass list
+
$ kubectl describe pods web-1
Name                    State            IPv4            Image
+
    :
microk8s-vm            Running          192.168.64.2    Ubuntu 18.04 LTS
+
Type    Reason            Age                From              Message
delhi:~ hirotoyagi$ multipass shell
+
  ----    ------            ----                ----              -------
 +
  Warning  FailedScheduling  22h (x14 over 23h)  default-scheduler  0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.
 +
</pre>
 +
===[[Ubuntu NFS構成|NFS]]の構成===
 +
*[[Ubuntu NFS構成]]
 +
*[https://www.server-world.info/en/note?os=Ubuntu_20.04&p=microk8s&f=5 microk8s storage class]
 +
*[https://qiita.com/Esfahan/items/7ad7695ea78c7630239a 外部ストレージをマウント]
 +
*[https://qiita.com/Esfahan/items/68e2d97545091cb6d0ac NFS storage class]
  
$ multipass exec microk8s-vm  -- sudo iptables -P FORWARD ACCEPT
+
*https://thinkit.co.jp/article/14195
 +
*https://kubernetes.io/docs/concepts/storage/volumes/
 +
*https://github.com/kubernetes/examples/tree/master/staging/volumes/nfs
  
$ microk8s add-node
+
[https://baremetal.jp/blog/2018/04/17/541/ NFS]
From the node you wish to join to this cluster, run the following:
 
microk8s join 192.168.0.47:25000/8d0a8aefaa574545524af88c13a36647
 
  
If the node you are adding is not reachable through the default interface you can use one of the following:
+
<pre>
microk8s join 192.168.0.46:25000/8d0a8aefaa574545524af88c13a36647
+
apiVersion: v1
microk8s join 192.168.0.47:25000/8d0a8aefaa574545524af88c13a36647
+
kind: PersistentVolume
microk8s join 192.168.122.1:25000/8d0a8aefaa574545524af88c13a36647
+
metadata:
microk8s join 172.17.0.1:25000/8d0a8aefaa574545524af88c13a36647
+
  name: web-pv
microk8s join 10.1.220.128:25000/8d0a8aefaa574545524af88c13a36647
+
  labels:
 +
    type: local
 +
spec:
 +
  capacity:
 +
    storage: 5Gi
 +
  accessModes:
 +
    - ReadWriteMany
 +
  storageClassName: slow
 +
  nfs:
 +
    server: 192.168.0.47
 +
    path: "/var/nfs/general"
 
</pre>
 
</pre>
  
*add-node コマンドは、 microk8s joinコマンドでジョインしたいクラスタをMicroK8sで 実行すべきコマンドを出力する
 
*add-nodeを実行したマスター側で出力されたコマンドを、参加させたいワーカーノード側で実行する
 
  
 +
<pre>
 +
$ kubectl describe pv
 +
Name:            web-pv
 +
Labels:          type=local
 +
Annotations:    &lt;none&gt;
 +
Finalizers:      [kubernetes.io/pv-protection]
 +
StorageClass:    slow
 +
Status:          Available
 +
Claim:         
 +
Reclaim Policy:  Retain
 +
Access Modes:    RWX
 +
VolumeMode:      Filesystem
 +
Capacity:        5Gi
 +
Node Affinity:  &lt;none&gt;
 +
Message:       
 +
Source:
 +
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
 +
    Server:    192.168.0.47
 +
    Path:      /var/nfs/general
 +
    ReadOnly:  false
 +
Events:        &lt;none&gt;
 +
</pre>
  
 +
 +
https://qiita.com/silverbirder/items/d3522237b28703a9adb6
 
<pre>
 
<pre>
$ multipass info --all
+
Type    Reason            Age                From              Message
Name:          microk8s-vm
+
  ----    ------            ----                ----              -------
State:          Running
+
  Warning  FailedScheduling  2s (x6 over 5m58s) default-scheduler  0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.
IPv4:          192.168.64.2
+
</pre>
Release:        Ubuntu 18.04.5 LTS
 
Image hash:    9fdd8fa3091b (Ubuntu 18.04 LTS)
 
Load:          0.92 1.13 0.77
 
Disk usage:     6.0G out of 48.3G
 
Memory usage:  674.4M out of 3.9G
 
  
$ multipass ls
+
==デプロイ==
Name                    State            IPv4            Image
+
Kubernetesにアプリケーションをデプロイするときは、
microk8s-vm             Running          192.168.64.2     Ubuntu 18.04 LTS
+
#マスターにアプリケーションコンテナを起動するように指示
 +
#マスターはコンテナがクラスターのノードで実行されるようにスケジュール
 +
#ノードは、マスターが公開しているKubernetes APIを使用してマスターと通信
 +
##エンドユーザーは、Kubernetes APIを直接使用して対話することもできます
 +
コンテナ化アプリケーションをデプロイ
 +
#KubernetesのDeployment の設定を作成
 +
#DeploymentはKubernetesにアプリケーションのインスタンスを作成し、更新する方法を指示
 +
#Deploymentを作成すると、KubernetesマスターはDeployment内に含まれるアプリケーションインスタンスをクラスター内の個々のノードで実行するようにスケジュール
 +
#アプリケーションインスタンスが作成されると、Kubernetes Deploymentコントローラーは、それらのインスタンスを継続的に監視
 +
#インスタンスをホストしているノードが停止、削除された場合、Deploymentコントローラーはそのインスタンスをクラスター内の別のノード上のインスタンスと置き換え,マシンの故障やメンテナンスに対処するためのセルフヒーリングの仕組みを提供
 +
 
 +
===リソースの作成===
 +
*Macの場合、[[multipass]]の中で動いているので、ローカルファイルを[[kubectl]]に渡す場合、mountする必要がある。
 +
<pre>
 +
$ multipass mount `pwd` microk8s-vm:/home/ubuntu/files
 +
</pre>
 +
*マニフェスト
 +
sample-pod.yaml
 +
<pre>
 +
apiVersion: v1
 +
kind: Pod
 +
metadata:
 +
  name: sample-pod
 +
spec:
 +
  containers:
 +
     - name: nginx-container
 +
      image: nginx:latest
 
</pre>
 
</pre>
 +
*生成
 +
<pre>
 +
$ kubectl create -f ./files/pod/sample-pod.yaml
 +
pod/sample-pod created
 +
</pre>
 +
*確認
 +
<pre>
 +
$ kubectl get pods
 +
NAME        READY  STATUS    RESTARTS  AGE
 +
sample-pod  1/1    Running  0          76s
 +
</pre>
 +
 +
===Memo===
 +
 +
*https://microk8s.io/docs
 +
====NginxをPodとしてインストール====
 +
*Kubernetes は、appやserviceをデプロイするためにあるので、kubecltでそれらを[[Kubernetes]]に対して行うことができる
 +
*デモアプリをインストールしてみる
 +
<pre>
 +
$ kubectl enable dns metallb
 +
$ kubectl create deployment nginx --image=nginx
 +
deployment.apps/nginx created
 +
</pre>
 +
*確認
 +
<pre>
 +
$ kubectl get pods
 +
NAME                    READY  STATUS    RESTARTS  AGE
 +
nginx-6799fc88d8-c69r9  1/1    Running  0          17m
 +
</pre>
 +
 +
====サービスとして公開====
 +
*Deploymentを確認
 +
<pre>
 +
$ kubectl get deployment
 +
NAME    READY  UP-TO-DATE  AVAILABLE  AGE
 +
nginx  1/1    1            1          108m
 +
</pre>
 +
*Deploymentに接続するために、Serviceとして公開
 +
*https://kubernetes.io/ja/docs/concepts/services-networking/service/
 +
*https://kubernetes.io/ja/docs/tutorials/stateless-application/expose-external-ip-address/
 +
<pre>
 +
$ kubectl expose deployment nginx --type=LoadBalancer --name=nginx-service --port=8080
 +
service/nginx-service exposed
 +
</pre>
 +
*サービスを確認(EXTERNAL-IP/PORT)
 +
<pre>
 +
$ kubectl get services
 +
NAME            TYPE          CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
 +
kubernetes      ClusterIP      10.152.183.1    <none>          443/TCP          47h
 +
nginx-service  LoadBalancer  10.152.183.63  192.168.64.100  8080:31344/TCP  33s
 +
</pre>
 +
 +
====ポートフォワード====
 +
*手順を確認
 +
<pre>
 +
$ kubeclt port-forward -h
 +
kubectl port-forward TYPE/NAME [options] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]
 +
</pre>
 +
 +
<pre>
 +
$ kubectl port-forward nginx-6799fc88d8-c69r9 8090:80
 +
Forwarding from 127.0.0.1:8090 -> 80
 +
Forwarding from [::1]:8090 -> 80
 +
</pre>
 +
 +
===クラスタリング===
 +
*https://microk8s.io/docs/clustering
 +
*https://tech.virtualtech.jp/entry/2019/10/25/150802
 +
*2つ以上のすでに稼働しているMicoroK8sインスタンスにクラスタを作成するには、add-nodeコマンドを使用
 +
*このコマンドが実行されたMicroK8sインスタンスが、クラスタのマスターとなり、[[Kubernetes]]コントロールプレーンをホストする
 +
[https://www.typea.info/blog/index.php/2020/11/13/mac_ubuntu_microk8s_node_cluster/ クラスタを作成する(Virtual Boxを使用)]
 +
 +
===サービスメッシュ===
 +
====Istio====
 +
*https://www.slideshare.net/yokawasa/istio-114360124
  
====[[Mac]]問題====
+
==Tips==
*https://discourse.ubuntu.com/t/troubleshooting-networking-on-macos/12901#arp-problems
+
===[https://multipass.run/docs/troubleshooting-networking-on-macos Macネットワークトラブルシュート]===
The macOS bridge used for hyperkit filters packets so that only the IP address originally assigned to the VM is allowed through. If you add an additional address (e.g. IP alias) to the VM, the ARP broadcast will get through but the ARP response will be filtered out.
 

2021年2月16日 (火) 11:28時点における最新版

| Kubernetes | Kubectl | Minikube | Docker | Multipass | Ubuntu |

目次

MicroK8s

基本操作

Document

インストール

Macにインストール

$ brew install ubuntu/microk8s/microk8s
$ microk8s install

Ubuntuにインストール

$ sudo snap install microk8s --classic
  • アンインストール
$ sudo snap remove microk8s

ステータスの確認

  • microk8s status でステータスの確認
  • インストール中などは、--wait-ready で状況確認できる
$ microk8s status --wait-ready
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    ha-cluster           # Configure high availability on the current node
  disabled:
    ambassador           # Ambassador API Gateway and Ingress
    cilium               # SDN, fast with full network policy
         :
    storage              # Storage class; allocates storage from host directory

開始と終了

  • MicroK8sは、停止するまで実行し続ける。停止と開始は、以下のコマンド。
$ microk8s stop
$microk8s start

アドオンの使用

  • MicroK8s は最低限のコンポーネントを使用するが、豊富な機能が "add-ons" とタイプすることで利用できる
  • サービス間の連携を容易にするDNS管理、 アプリケーションがストレージが必要な場合、'storage' アドオンはホストに直接領域を提供する。これらは簡単にセットアップできる

アドオンの一覧

サービスの有効化/無効化

  • 組み込みで有効化可能なアドオンサービスの確認
  • サービスを無効化する場合は、disable
$ microk8s enable --help
  • サービスを有効化する
  • status でどのアドオンが有効/無効かを確認できる
$ microk8s enable dashboard dns registry istio

コマンド

https://microk8s.io/docs/commands

コマンド 内容
microk8s add-node クラスタへの接続文字列を生成
microk8s config
microk8s ctr
microk8s dbctl
microk8s disable
microk8s enable
microk8s inspect
microk8s join
microk8s kubectl
microk8s leave
microk8s refresh-certs
microk8s remove-node
microk8s reset ノードを初期状態にリセット
microk8s start 停止されたノードを開始
microk8s status ステータス情報を表示
microk8s stop カレントノードの停止

マニフェスト

ダッシュボード

ダッシュボード接続手順、トラブルシュート

$ microk8s enable dashboard dns
$ microk8s dashboard-proxy

Kubectl

  • MicroK8s は専用のバージョンのkubectlをバンドルしている。
  • コマンドを監視と制御のために実行することができる。
$ microk8s kubectl get all --all-namespaces
NAMESPACE            NAME                                             READY   STATUS              RESTARTS   AGE
kube-system          pod/calico-node-m9j8n                            1/1     Running             0          90m
kube-system          pod/metrics-server-8bbfb4bdb-679mc               1/1     Running             0          7m38s
            :
  • MicroK8s は、すでにインストール済みのkubectlとの衝突を防ぐためにネームスペースを指定したkubectlコマンドを使用する
  • もしインストール済みの物がないのであれば、簡単にエイリアスを指定できる
  • ~/.bash_aliases に以下を記載
alias kubectl='microk8s kubectl'
  • ~/.bash_profile に以下を追記
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

Kubeconfig

$ cd ~/
$ mkdir .kube
$ cd .kube
$ microk8s config > config

Kubernetesサンプル

Up and Deploy

クラスタ


  • https://kubernetes.io/ja/docs/tutorials/kubernetes-basics/
  • Kubernetesクラスターは以下の2種類のリソースで構成
    • マスターがクラスターを管理する、マスターはクラスターの管理を担当
    • ノードがアプリケーションを動かすワーカーとなる、ノードは、Kubernetesクラスターのワーカーマシンとして機能するVMまたは物理マシン
$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:16443

$ kubectl get nodes
NAME          STATUS   ROLES    AGE   VERSION
microk8s-vm   Ready    <none>   47h   v1.19.3-34+a56971609ff35a

Pod

作成

  • 一番シンプルな方法は kubectl run
$ kubectl run nginx --image=nginx
pod/nginx created

マニフェスト

準備
  • kubectl で -f したときのルートが、/home/ubuntu なので、ローカルの作業フォルダfiles をマウントする
multipass mount `pwd`/files microk8s-vm:/home/ubuntu/files
適用
  • pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx-container
      image: nginx:latest
      ports:
        - containerPort: 8080
          name: http
          protocol: TCP
  • 適用
$ kubectl apply -f files/pod/pod-nginx.yaml 
pod/nginx-pod created

確認

簡易
$ kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   0/1     Unknown   3          91m
詳細

以下の内容が表示される

  1. 基本情報
  2. Pod内で動いているコンテナ情報
  3. Podに関するイベント情報
$ kubectl describe pod nginx-pod
Name:         nginx-pod
Namespace:    default
Priority:     0
Node:         microk8s-vm/192.168.64.2
Start Time:   Wed, 18 Nov 2020 22:43:16 +0900
Labels:       <none>
Annotations:  cni.projectcalico.org/podIP: 10.1.254.126/32
              cni.projectcalico.org/podIPs: 10.1.254.126/32
Status:       Running
    :

ポートフォワード

$ kubectl port-forward pod/nginx-pod 80 80
Forwarding from 127.0.0.1:80 -> 80
Forwarding from [::1]:80 -> 80
Unable to listen on port 80: Listeners failed to create with the following errors: [unable to create listener: Error listen tcp4 127.0.0.1:80: bind: address already in use unable to create listener: Error listen tcp6 [::1]:80: bind: address already in use]
  • macの場合vmに入れば、、、
ubuntu@microk8s-vm:~$ curl http://localhost:80
Handling connection for 80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

ログの確認

$ kubectl logs nginx-pod

execでコマンド実行

$ kubectl exec -it pod/nginx-pod -- /bin/sh
# 

コンテナローカル間でファイルコピー

  • ローカル のファイルを、Podにコピー
$ kubectl cp files/etc/aaa.html  nginx-pod:/usr/share/nginx/html/aaa.html 
  • Podのファイルをローカルにコピー
$ kubectl cp  nginx-pod:/usr/share/nginx/html/index.html files/etc/index.html

Service

クラスター内のアプリケーションにアクセスするために外部IPアドレスを公開

5つのPodで起動しているアプリケーションへのServiceの作成

$ kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml
deployment.apps/hello-world created
$ kubectl get pods
NAME                           READY   STATUS              RESTARTS   AGE
hello-world-6df5659cb7-6flwb   0/1     ContainerCreating   0          45s
hello-world-6df5659cb7-lzmnx   0/1     ContainerCreating   0          45s
hello-world-6df5659cb7-ghbfs   0/1     ContainerCreating   0          45s
hello-world-6df5659cb7-jbz9t   0/1     ContainerCreating   0          45s
hello-world-6df5659cb7-fqv2z   0/1     ContainerCreating   0          45s
$ kubectl get deployment hello-world
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
hello-world   5/5     5            5           3m19s
$ kubectl get replicaset
NAME                     DESIRED   CURRENT   READY   AGE
hello-world-6df5659cb7   5         5         5       5m26s

Deploymentを公開するサービスの生成

  • LoadBlancerの有効化
$ microk8s enable metallb
  • Deploymentの生成
$ kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
service/my-service exposed
  • サービスの確認
$ kubectl get service my-service
NAME         TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)          AGE
my-service   LoadBalancer   10.152.183.120   192.168.0.120   8080:32132/TCP   20m
  • 実行
$ curl http://192.168.0.120:8080
Hello Kubernetes!
  • クリーンアップ
$ kubectl delete service my-service
service "my-service" deleted
$ kubectl delete deployment hello-world
deployment.apps "hello-world" deleted

PHPアプリサンプル

データストア(Radis )の作成

Radis Master Deployment

  • ゲストブックアプリケーションは、データストアに、Radis を使用する
$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml

Radis Master Service

  • ゲストブックアプリケーションは、データストアと通信する必要がある
$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml

Radis Slave Deployment

  • Radis Slave として、レプリカを2つ作成
$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-deployment.yaml
$ kubectl get pods
NAME                           READY   STATUS              RESTARTS   AGE
redis-master-f46ff57fd-lh4lh   1/1     Running             1          19m
redis-slave-bbc7f655d-5vjpb    0/1     ContainerCreating   0          13s
redis-slave-bbc7f655d-954c5    0/1     ContainerCreating   0          13s

Radis Slave Service

$ kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-service.yaml
$ kubectl get services
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     ClusterIP   10.152.183.1    <none>        443/TCP    33h
redis-master   ClusterIP   10.152.183.90   <none>        6379/TCP   11m
redis-slave    ClusterIP   10.152.183.62   <none>        6379/TCP   18s

ゲストブックのセットアップと公開

Frontend Development

$ kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml

Frontend Service

  • 上記で作成した、Radis サービスは、コンテナ内部からのみアクセス可能。
  • デフォルトのサービスは、ClusterIPで、ClusterIPはPodの1つのIPを差す(このIPはクラスタ内殻のみ参照可能)
  • もし、ゲストをゲストブックにアクセスさせたい場合、Frontend サービスを外部に見えるようにする必要がある。
  • クライアントがコンテナクラスターの外部からサービスにリクエストするためには、NodePortサービスを公開することで可能となる
LoadBalancer経由で参照する
  • type を LoadBalancerに変更して、apply
apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # comment or delete the following line if you want to use a LoadBalancer
  #type: NodePort 
  # if your cluster supports it, uncomment the following to automatically create
  # an external load-balanced IP for the frontend service.
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: guestbook
    tier: frontend
$ kubectl apply -f ./files/php_guest_book/frontend-service.yaml 
$ kubectl get services
NAME           TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
kubernetes     ClusterIP      10.152.183.1     <none>          443/TCP        36h
redis-master   ClusterIP      10.152.183.90    <none>          6379/TCP       3h1m
redis-slave    ClusterIP      10.152.183.62    <none>          6379/TCP       169m
frontend       LoadBalancer   10.152.183.187   192.168.0.120   80:30334/TCP   3m10s

Microk8s php guestbook.png

  • ダッシュボード

Microk8s php guestbook dashboard.png

クリーンアップ

$ kubectl delete deployment -l app=redis
$ kubectl delete service -l app=redis
$ kubectl delete deployment -l app=guestbook
$ kubectl delete service -l app=guestbook

永続ボリューム

  • https://kubernetes.io/ja/docs/concepts/storage/persistent-volumes/
  • ストレージを管理することはインスタンスを管理することとは全くの別物
  • PersistentVolumeサブシステムは、ストレージが何から提供されているか、どのように消費されているかをユーザーと管理者から抽象化するAPIを提供
  • Podは、PersistentVolumeClaimを通して「こういうspecのVolumeが欲しい」と要求を出すと、その要求に一番近いPersistentVolumeがmountされるという仕組み
  • metadata.name、metadata.labelsと、spec.selector.matchLabels、spec.selector.matchExpressionsの値を合わせることで、PersistentVolumeとPersistentVolumeClaimのマッチングをより明示的に、期待したとおりにできる
  • https://thinkit.co.jp/article/14195

PersistentVolume (PV)

  • ストレージクラスを使って管理者もしくは動的にプロビジョニングされるクラスターのストレージの一部
  • Nodeと同じようにクラスターリソースの一部
  • PVはVolumeのようなボリュームプラグインですが、PVを使う個別のPodとは独立したライフサイクルを持っています
  • このAPIオブジェクトはNFS、iSCSIやクラウドプロバイダー固有のストレージシステムの実装の詳細を捕捉します。

PersistentVolumeClaim (PVC)

  • ユーザーによって要求されるストレージで、これはPodと似ています
  • PodはNodeリソースを消費し、PVCはPVリソースを消費します
  • Podは特定レベルのCPUとメモリーリソースを要求することができます。クレームは特定のサイズやアクセスモード(例えば、ReadWriteOnce、ReadOnlyMany、ReadWriteManyにマウントできます
  • PersistentVolumeClaimはユーザーに抽象化されたストレージリソースの消費を許可する一方、ユーザーは色々な問題に対処するためにパフォーマンスといった様々なプロパティを持ったPersistentVolumeを必要とすることは一般的なことです。
  • クラスター管理者はユーザーに様々なボリュームがどのように実装されているかを表に出すことなく、サイズやアクセスモードだけではない色々な点で異なった、様々なPersistentVolumeを提供できる必要があります。これらのニーズに応えるために StorageClass リソースがあります。

チュートリアル

  • クラスター管理者の場合、PersistentVolumeを物理ストレージに作成し、VolumeをPodに関連づける必要はない
  • 開発者、クラスタユーザーの場合、PersistentVolumeChlaimを作成すると、自動的に適したPersistentVolumeに結び付けられる
  • Podを生成し、PersistentVolumeClaimを利用することで、ストレージを利用できる

index.htmlをNodeの作成する

$ multipass sh microk8s-vm
ubuntu@microk8s-vm:~$ sudo mkdir /mnt/data
ubuntu@microk8s-vm:~$ sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"

PersistentVolume生成

  • hostPath PersistentVolume を作成する。KubernetesはhostPathをシングルノードクラスタの開発/テストでサポートする
  • hostPath PersistentVolume は、ネットワークアタッチドストレージをエミュレートしたものとしてNodeのファイル、もしくはディレクトリを使用する
  • 製品版のクラスタでは、hostPathを使わない方が良い。クラスター管理者は、その代わりにネットワークリソース、Google Compute Engine 永続ディスクや、NFS 共有、Amazon Elastic Block Store Volumeを準備する
  • クラスター管理者は動的プロビジョニングのために、StorageClassを利用する
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
persistentvolume/task-pv-volume created
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
task-pv-volume   10Gi       RWO            Retain           Available           manual                  41s

PersistentVolumeClaimの生成

  • PodはPersistentVolumeClaimを物理ストレージの要求に使用する
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml
persistentvolumeclaim/task-pv-claim created
$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                   STORAGECLASS   REASON   AGE
task-pv-volume   10Gi       RWO            Retain           Bound    default/task-pv-claim   manual                  44m
$ kubectl get pvc
NAME            STATUS    VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   AGE
task-pv-claim   Bound     task-pv-volume   10Gi       RWO            manual         77s

Podの生成

  • PersistentVolumeClaimをVolumeとして利用するPodの作成
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage
$ kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml
pod/task-pv-pod created
$ kubectl get pod
NAME          READY   STATUS    RESTARTS   AGE
task-pv-pod   1/1     Running   0          2m5s
  • マウントしたVolume情報を確認
 kubectl exec -it pod/task-pv-pod -- /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# cat /usr/share/nginx/html/index.html
Hello from Kubernetes storage


# apt update
# apt install curl
# curl http://localhost
Hello from Kubernetes storage

クリーンアップ

$ kubectl delete pod task-pv-pod
$ kubectl delete pvc task-pv-claim
$ kubectl delete pv task-pv-volume

StatefulSet

事前準備

StatefulSet作成

$ kubectl apply -f ./files/statefulset-basic/web.yaml 
service/nginx created
statefulset.apps/web created
$ kubectl get services nginx
NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   None         <none>        80/TCP    4m18s
$ kubectl get statefulset
NAME   READY   AGE
web    0/2     4m22s

PersistentVolumeClaimsエラーの対応

$ kubectl describe pods
Name:           web-0
    :
Events:
  Type     Reason            Age                  From               Message
  ----     ------            ----                 ----               -------
  Warning  FailedScheduling  40s (x8 over 9m33s)  default-scheduler  0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.
$ multipass sh microk8s-vm
ubuntu@microk8s-vm:~$ sudo mkdir /mnt/data
  • accessModes
    • ReadWriteOnce –ボリュームは単一のNodeで読み取り/書き込みとしてマウントできます
    • ReadOnlyMany –ボリュームは多数のNodeで読み取り専用としてマウントできます
    • ReadWriteMany –ボリュームは多数のNodeで読み取り/書き込みとしてマウントできます

HostPath は、ReadWriteOnce しか選択できない

apiVersion: v1
kind: PersistentVolume
metadata:
  name: web-pv
  labels:
    type: local
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
$ microk8s apply -f ./files/statefulset-basic/pv.yaml 
persistentvolume/web-pv created

順序付けられた Pod 生成

  • StatefulSet n レプリカのために、Pod がデプロイされるときシーケンシャルに生成され順序づけられる(0...n-1)
$ kubectl get pods -w -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   0/1     Pending   0          7m32s
web-0   0/1     Pending   0          20m
web-0   0/1     ContainerCreating   0          20m
web-0   0/1     ContainerCreating   0          20m
web-0   1/1     Running             0          20m
web-1   0/1     Pending             0          0s
web-1   0/1     Pending             0          0s

StatefulSetのpod

  • StatefulSetに含まれるPodは、一意な順序と安定したネットワークIDを持つ
  • StetefulSetのPod は一意のIDを持つ
  • このIDは、一意の順序付けられたインデックス、それぞれのpodがStatefulSetコントローラに結び付けられている
  • Pod の名前は、<statefulset名>-<順序づけれれたindex> となる。
$ kubectl get pods -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-1   0/1     Pending   0          22h
web-0   0/1     Unknown   0          23h

Stable ネットワークIDを使用する

  • それぞれのPod は順序付けられたインデックスに基づく安定したホスト名を持つ
  • kubectl exec でそれぞれのpodにhostname コマンドを実行する
$ for i in 0 1; do kubectl exec pod/web-$i hostname; done
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
web-0
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
Error from server (BadRequest): pod web-1 does not have a host assigned
An error occurred when trying to execute 'sudo microk8s.kubectl exec pod/web-1 hostname' with 'multipass': returned exit code 1.

永続化Volumeが、hostPath指定の場合、1つのPodからしか接続できないため立ち上がらない。

$ kubectl describe pods web-1
    :
Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  22h (x14 over 23h)  default-scheduler  0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.

NFSの構成

NFS

apiVersion: v1
kind: PersistentVolume
metadata:
  name: web-pv
  labels:
    type: local
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  storageClassName: slow
  nfs:
    server: 192.168.0.47
    path: "/var/nfs/general"


$ kubectl describe pv
Name:            web-pv
Labels:          type=local
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    slow
Status:          Available
Claim:           
Reclaim Policy:  Retain
Access Modes:    RWX
VolumeMode:      Filesystem
Capacity:        5Gi
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    192.168.0.47
    Path:      /var/nfs/general
    ReadOnly:  false
Events:        <none>


https://qiita.com/silverbirder/items/d3522237b28703a9adb6

 Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  2s (x6 over 5m58s)  default-scheduler  0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims.

デプロイ

Kubernetesにアプリケーションをデプロイするときは、

  1. マスターにアプリケーションコンテナを起動するように指示
  2. マスターはコンテナがクラスターのノードで実行されるようにスケジュール
  3. ノードは、マスターが公開しているKubernetes APIを使用してマスターと通信
    1. エンドユーザーは、Kubernetes APIを直接使用して対話することもできます

コンテナ化アプリケーションをデプロイ

  1. KubernetesのDeployment の設定を作成
  2. DeploymentはKubernetesにアプリケーションのインスタンスを作成し、更新する方法を指示
  3. Deploymentを作成すると、KubernetesマスターはDeployment内に含まれるアプリケーションインスタンスをクラスター内の個々のノードで実行するようにスケジュール
  4. アプリケーションインスタンスが作成されると、Kubernetes Deploymentコントローラーは、それらのインスタンスを継続的に監視
  5. インスタンスをホストしているノードが停止、削除された場合、Deploymentコントローラーはそのインスタンスをクラスター内の別のノード上のインスタンスと置き換え,マシンの故障やメンテナンスに対処するためのセルフヒーリングの仕組みを提供

リソースの作成

  • Macの場合、multipassの中で動いているので、ローカルファイルをkubectlに渡す場合、mountする必要がある。
$ multipass mount `pwd` microk8s-vm:/home/ubuntu/files
  • マニフェスト

sample-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - name: nginx-container
      image: nginx:latest
  • 生成
$ kubectl create -f ./files/pod/sample-pod.yaml
pod/sample-pod created
  • 確認
$ kubectl get pods
NAME         READY   STATUS    RESTARTS   AGE
sample-pod   1/1     Running   0          76s

Memo

NginxをPodとしてインストール

  • Kubernetes は、appやserviceをデプロイするためにあるので、kubecltでそれらをKubernetesに対して行うことができる
  • デモアプリをインストールしてみる
$ kubectl enable dns metallb
$ kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
  • 確認
$ kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-c69r9   1/1     Running   0          17m

サービスとして公開

  • Deploymentを確認
$ kubectl get deployment
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           108m
$ kubectl expose deployment nginx --type=LoadBalancer --name=nginx-service --port=8080
service/nginx-service exposed
  • サービスを確認(EXTERNAL-IP/PORT)
$ kubectl get services
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
kubernetes      ClusterIP      10.152.183.1    <none>           443/TCP          47h
nginx-service   LoadBalancer   10.152.183.63   192.168.64.100   8080:31344/TCP   33s

ポートフォワード

  • 手順を確認
$ kubeclt port-forward -h
 kubectl port-forward TYPE/NAME [options] [LOCAL_PORT:]REMOTE_PORT [...[LOCAL_PORT_N:]REMOTE_PORT_N]
$ kubectl port-forward nginx-6799fc88d8-c69r9 8090:80
Forwarding from 127.0.0.1:8090 -> 80
Forwarding from [::1]:8090 -> 80

クラスタリング

クラスタを作成する(Virtual Boxを使用)

サービスメッシュ

Istio

Tips

Macネットワークトラブルシュート