「MicroK8s」の版間の差分
ナビゲーションに移動
検索に移動
(同じ利用者による、間の244版が非表示) | |||
1行目: | 1行目: | ||
− | | [[Kubernetes]] | [[Docker]] | | + | | [[Kubernetes]] | [[Kubectl]] | [[Minikube]] | [[Docker]] | [[Multipass]] | [[Ubuntu]] | |
==MicroK8s== | ==MicroK8s== | ||
− | |||
− | |||
{{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> | ||
− | |||
− | |||
− | ===[[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 | ||
− | + | : | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
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> | ||
− | + | ===コマンド=== | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | ==コマンド== | ||
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 | ||
+ | <!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> | ||
+ | </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> | ||
− | * | + | ==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 | + | $ 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> | </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> | <pre> | ||
− | + | # apt update | |
+ | # apt install curl | ||
+ | # curl http://localhost | ||
+ | Hello from Kubernetes storage | ||
</pre> | </pre> | ||
− | + | ====クリーンアップ==== | |
− | === | ||
− | |||
<pre> | <pre> | ||
− | $ | + | $ kubectl delete pod task-pv-pod |
− | $ | + | $ kubectl delete pvc task-pv-claim |
+ | $ kubectl delete pv task-pv-volume | ||
</pre> | </pre> | ||
− | |||
− | |||
− | === | + | ==StatefulSet== |
− | *https:// | + | *https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/ |
− | *https:// | + | ===事前準備=== |
− | * | + | *[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> | <pre> | ||
− | $ | + | $ kubectl apply -f ./files/statefulset-basic/web.yaml |
− | + | service/nginx created | |
+ | statefulset.apps/web created | ||
</pre> | </pre> | ||
− | |||
− | |||
<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> | </pre> | ||
− | + | ||
− | + | ====PersistentVolumeClaimsエラーの対応==== | |
<pre> | <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> | </pre> | ||
− | * | + | *[https://kubernetes.io/ja/docs/concepts/storage/persistent-volumes/ accessModes] |
+ | **ReadWriteOnce –ボリュームは単一のNodeで読み取り/書き込みとしてマウントできます | ||
+ | **ReadOnlyMany –ボリュームは多数のNodeで読み取り専用としてマウントできます | ||
+ | **ReadWriteMany –ボリュームは多数のNodeで読み取り/書き込みとしてマウントできます | ||
+ | <blockquote> | ||
+ | HostPath は、ReadWriteOnce しか選択できない | ||
+ | </blockquote> | ||
<pre> | <pre> | ||
− | + | apiVersion: v1 | |
− | + | kind: PersistentVolume | |
+ | metadata: | ||
+ | name: web-pv | ||
+ | labels: | ||
+ | type: local | ||
+ | spec: | ||
+ | capacity: | ||
+ | storage: 5Gi | ||
+ | accessModes: | ||
+ | - ReadWriteOnce | ||
+ | hostPath: | ||
+ | path: "/mnt/data" | ||
</pre> | </pre> | ||
− | + | ||
<pre> | <pre> | ||
− | + | $ 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> | </pre> | ||
+ | ===StatefulSetのpod=== | ||
+ | *StatefulSetに含まれるPodは、一意な順序と安定したネットワークIDを持つ | ||
+ | *StetefulSetのPod は一意のIDを持つ | ||
+ | *このIDは、一意の順序付けられたインデックス、それぞれのpodがStatefulSetコントローラに結び付けられている | ||
+ | *Pod の名前は、<statefulset名>-<順序づけれれたindex> となる。 | ||
<pre> | <pre> | ||
− | $ | + | $ 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> | ||
+ | |||
+ | ===Stable ネットワークIDを使用する === | ||
+ | *それぞれのPod は順序付けられたインデックスに基づく安定したホスト名を持つ | ||
+ | *kubectl exec でそれぞれのpodにhostname コマンドを実行する | ||
<pre> | <pre> | ||
− | $ | + | $ 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. | |
− | microk8s | + | 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> | ||
− | + | <blockquote> | |
− | + | 永続化Volumeが、hostPath指定の場合、1つのPodからしか接続できないため立ち上がらない。 | |
− | + | </blockquote> | |
+ | <pre> | ||
+ | $ 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. | ||
</pre> | </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] | ||
+ | |||
+ | *https://thinkit.co.jp/article/14195 | ||
+ | *https://kubernetes.io/docs/concepts/storage/volumes/ | ||
+ | *https://github.com/kubernetes/examples/tree/master/staging/volumes/nfs | ||
+ | |||
+ | [https://baremetal.jp/blog/2018/04/17/541/ NFS] | ||
<pre> | <pre> | ||
− | + | 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" | ||
</pre> | </pre> | ||
− | |||
<pre> | <pre> | ||
− | $ | + | $ 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> | ||
+ | </pre> | ||
− | |||
− | |||
− | |||
− | |||
− | + | https://qiita.com/silverbirder/items/d3522237b28703a9adb6 | |
+ | <pre> | ||
+ | Type Reason Age From Message | ||
+ | ---- ------ ---- ---- ------- | ||
+ | Warning FailedScheduling 2s (x6 over 5m58s) default-scheduler 0/1 nodes are available: 1 pod has unbound immediate PersistentVolumeClaims. | ||
+ | </pre> | ||
− | + | ==デプロイ== | |
− | + | Kubernetesにアプリケーションをデプロイするときは、 | |
− | + | #マスターにアプリケーションコンテナを起動するように指示 | |
+ | #マスターはコンテナがクラスターのノードで実行されるようにスケジュール | ||
+ | #ノードは、マスターが公開している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> | ||
+ | $ 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> | </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> | <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> | ||
− | + | <pre> | |
− | + | $ kubectl port-forward nginx-6799fc88d8-c69r9 8090:80 | |
− | + | Forwarding from 127.0.0.1:8090 -> 80 | |
− | + | Forwarding from [::1]:8090 -> 80 | |
+ | </pre> | ||
− | * | + | ===クラスタリング=== |
− | *https:// | + | *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 | ||
− | + | ==Tips== | |
− | https:// | + | ===[https://multipass.run/docs/troubleshooting-networking-on-macos Macネットワークトラブルシュート]=== |
− | |||
− |
2021年2月16日 (火) 11:28時点における最新版
| Kubernetes | Kubectl | Minikube | Docker | Multipass | Ubuntu |
目次
MicroK8s
基本操作
Document
インストール
Macにインストール
- https://jp.ubuntu.com/blog/kubernetes-on-mac-how-to-set-up-jp
- https://microk8s.io/docs/install-alternatives#heading--macos
$ brew install ubuntu/microk8s/microk8s
- DriverをVirtualBoxに変更する場合、先に変更してから、install
- Virtual Boxでネットワークブリッジを作成する
$ 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 | カレントノードの停止 |
マニフェスト
ダッシュボード
- https://microk8s.io/docs/addon-dashboard
- https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/README.md
$ 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
- https://microk8s.io/docs/working-with-kubectl
- https://qiita.com/imamura_sh/items/91208a9b30e701d1e7f2
$ 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
詳細
以下の内容が表示される
- 基本情報
- Pod内で動いているコンテナ情報
- 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 -it で対話実行
$ 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
- URL(kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml)ではなく、上記を変更した、ローカルファイルからapplyする。
- MacでMultipass上のため、事前にマウントを実施済み
$ 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
- ダッシュボード
クリーンアップ
$ 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作成
- https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/web/web.yaml
- ダウンロードしてapply
$ 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.
- https://qiita.com/silverbirder/items/d3522237b28703a9adb6
- https://stackoverflow.com/questions/52668938/pod-has-unbound-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の構成
- https://thinkit.co.jp/article/14195
- https://kubernetes.io/docs/concepts/storage/volumes/
- https://github.com/kubernetes/examples/tree/master/staging/volumes/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にアプリケーションをデプロイするときは、
- マスターにアプリケーションコンテナを起動するように指示
- マスターはコンテナがクラスターのノードで実行されるようにスケジュール
- ノードは、マスターが公開しているKubernetes APIを使用してマスターと通信
- エンドユーザーは、Kubernetes APIを直接使用して対話することもできます
コンテナ化アプリケーションをデプロイ
- KubernetesのDeployment の設定を作成
- DeploymentはKubernetesにアプリケーションのインスタンスを作成し、更新する方法を指示
- Deploymentを作成すると、KubernetesマスターはDeployment内に含まれるアプリケーションインスタンスをクラスター内の個々のノードで実行するようにスケジュール
- アプリケーションインスタンスが作成されると、Kubernetes Deploymentコントローラーは、それらのインスタンスを継続的に監視
- インスタンスをホストしているノードが停止、削除された場合、Deploymentコントローラーはそのインスタンスをクラスター内の別のノード上のインスタンスと置き換え,マシンの故障やメンテナンスに対処するためのセルフヒーリングの仕組みを提供
リソースの作成
$ 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
- Deploymentに接続するために、Serviceとして公開
- https://kubernetes.io/ja/docs/concepts/services-networking/service/
- https://kubernetes.io/ja/docs/tutorials/stateless-application/expose-external-ip-address/
$ 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
クラスタリング
- https://microk8s.io/docs/clustering
- https://tech.virtualtech.jp/entry/2019/10/25/150802
- 2つ以上のすでに稼働しているMicoroK8sインスタンスにクラスタを作成するには、add-nodeコマンドを使用
- このコマンドが実行されたMicroK8sインスタンスが、クラスタのマスターとなり、Kubernetesコントロールプレーンをホストする
サービスメッシュ
Istio
Tips
Macネットワークトラブルシュート
© 2006 矢木浩人