Rio v0.0.3がリリースされましたね。
以前書いたRioの記事ではスタンドアロン版を試しましたので、 今回は既存KubernetesクラスタとしてDocker for Macを利用してRioを試してみようと思います。
前回と重複する内容も含まれますが、今回はRioがKubernetes/Istioをどう利用しているのかといった点を中心にみていきたいと思います。
(前回の記事でIstio周りもうちょい詳しく知りたかったという声もあったような気がしますので)
前回の記事(スタンドアロン版のRio)
必要なもの
- Docker for Mac(Kubernetesが有効化されていること)
おそらくDocker for Windowsでも動くと思いますが手元に環境がないため今回は試してません。
また、大事な注意点として、Rio v0.0.3時点では簡単にアンインストールする手段は提供されていません!!
Docker for Macをファクトリーリセットするか地道に手で一つ一つ消していくくらいしかアンインストール方法がないため、お手元で試される方はご注意ください。
<宣伝>
クラウド上に使い捨てKubernetesクラスタを建てる場合はTerraform+RKEがおすすめです。
Rioのインストール(Mac)
まずは手元のMacにRioをインストールしておきます。
RioはGoで書かれたシングルバイナリですのでダウンロード&展開&PATHの通った場所に配置すればOKです。
#rio v0.0.3のダウンロード $ curl -L -o rio.tgz https://github.com/rancher/rio/releases/download/v0.0.3/rio-v0.0.3-darwin.tar.gz #展開 $ tar zxvf rio.tgz #PATHの通った場所に移動 $ sudo mv rio-v0.0.3-darwin/rio /usr/local/bin/ #確認 $ rio -v # "rio version v0.0.3" と表示されればOK
Rioサーバ側コンポーネントのデプロイ
Rioはスタンドアロン版の場合はrio server
コマンドを実行することでembedなk8s(k3sとか呼ばれてるやつ)を起動してそこに各種コンポーネントをデプロイします。
既存のk8sクラスタを利用する場合はkubectl
の向き先に対してデプロイを行います。今回はこちらを利用します。
kubectl
コマンドの接続先の確認
始める前にkubectl
の向き先がDocker for Macになっているか確認しておいてください。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION docker-for-desktop Ready master 2d v1.10.3
NAMEの部分がdocker-for-desktop
になっていればOKですね。
現時点ではRioのデプロイを行うにはcluster-admin権限が必要です。
この辺は今後改善されるっぽいです。
Rioのコンポーネントのデプロイ
それではrio login
コマンドを実行してみましょう。
$ rio login [1] Connect to remote Rio server [2] Install Rio in existing Kubernetes Select Number [1]
こんな感じで選択肢が表示されます。今回は既存のk8sクラスタにデプロイしますので2
を選択してください。
その後以下のようなログが表示されるはずです。
INFO[0068] Installing Rio INFO[0071] Waiting to connect to Rio INFO[0111] Log in successful
Log in successful
と表示されるまで数分かかるかもしれません。気長に待ちましょう。
(手元のマシンでは1分ほどでした)
Rioを使ってみる
コンテナ起動 & 確認
まずは動かしてみます。
docker run
するような感覚でrio run
を実行することでコンテナの起動が可能です。
ここではDockerHubのnginxイメージを利用してfoobar
というサービスを起動します。
Rioでは「サービス」という概念があります。k8sやDockerでのserviceとは役割が異なり、単なる同じ役割を持つコンテナの集合ということです。 詳細はREADME.mdのServiceセクションを参照してください。
#DockerHubのnginxイメージを用いてコンテナ起動 $ rio run --name foobar nginx default-265db573:foobar # k8s上でのネームスペース:サービス名が表示される #起動しているか確認 $ rio ps NAME IMAGE CREATED SCALE STATE ENDPOINT DETAIL foobar nginx About a minute ago 1 active #foobarサービスのコンテナを確認 $ rio ps foobar NAME IMAGE CREATED NODE IP STATE DETAIL foobar/f6985f578-schpv nginx 2 minutes ago docker-for-desktop 10.1.3.58 running
起動したようですね。 dockerコマンドやkubectlコマンドなどと同じく、コンテナへのattachやexecも可能です。
# bashを実行(--interactive + --ttyオプションを指定 = dockerと同じ) $ rio exec -it foobar bash root@foobar-f6985f578-schpv:/# # 以下のようにサービス名/コンテナ名まで指定してもOK # rio exec -it foobar/f6985f578-schpv bash
次にk8sからはどう見えてるか確認してみます。
kubectlでKubernetes側から確認
# ネームスペースの確認 $ kubectl get namespaces NAME STATUS AGE default Active 2d default-265db573 Active 10m # rio runで作成されたネームスペース docker Active 2d istio-095b8502 Active 15m kube-public Active 2d kube-system Active 2d rio-defaults Active 15m rio-system Active 16m
Rioがいくつかnamespaceを作成してますね。rio run
実行後に表示されたdefault-265db573
というものも見えます。
実際のコンテナはこのネームスペースに配置されています。
それではこのネームスペースに何があるのか確認していきましょう。
実際に手元で試す際はdefault-265db573
の部分をそれぞれの手元で表示されたものに置き換えてください。
$ kubectl get all -n default-265db573 NAME READY STATUS RESTARTS AGE pod/foobar-f6985f578-schpv 2/2 Running 0 14m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/foobar ClusterIP 10.97.38.245 <none> 80/TCP 14m NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/foobar 1 1 1 1 14m NAME DESIRED CURRENT READY AGE replicaset.apps/foobar-f6985f578 1 1 1 14m
ServiceとDeploymentが作成され、そこからReplicaSetとPodも生えてますね。
それぞれ少し詳しくみておきます。
# Serviceの確認 $ kubectl get svc -o wide -n default-265db573 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR foobar ClusterIP 10.97.38.245 <none> 80/TCP 19m app=foobar,rio.cattle.io/namespace=default-265db573,rio.cattle.io/service=foobar,rio.cattle.io=true # Deploymentの確認 $ kubectl get deploy -o wide -n default-265db573 NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR foobar 1 1 1 1 20m foobar,istio-proxy nginx,docker.io/istio/proxy_debug:1.0.0 app=foobar,rio.cattle.io=true,rio.cattle.io/namespace=default-265db573,rio.cattle.io/revision=latest,rio.cattle.io/service=foobar # Podの確認 $ kubectl get pod -n default-265db573 NAME READY STATUS RESTARTS AGE foobar-f6985f578-schpv 2/2 Running 0 22m # Podの詳細 $ kubectl describe pod -n default-265db573 foobar-f6985f578-schpv Name: foobar-f6985f578-schpv Namespace: default-265db573 Node: docker-for-desktop/192.168.65.3 Labels: app=foobar pod-template-hash=925419134 rio.cattle.io=true rio.cattle.io/namespace=default-265db573 rio.cattle.io/revision=latest rio.cattle.io/service=foobar Status: Running Init Containers: istio-init: # ... enable-core-dump: # ... Containers: foobar: Image: nginx Port: <none> Host Port: <none> # ... istio-proxy: Image: docker.io/istio/proxy_debug:1.0.0 Mounts: /etc/certs/ from istio-certs (ro) /etc/istio/proxy from istio-envoy (rw) # ... Volumes: istio-envoy: Type: EmptyDir (a temporary directory that shares a pod s lifetime) Medium: Memory istio-certs: Type: Secret (a volume populated by a Secret) SecretName: istio.default Optional: true Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Created 23m kubelet, docker-for-desktop Created container #...
Istio+指定したnginxが起動してますね。
次にRioでサービス内のコンテナをスケールアウトさせてみましょう。
スケールアウトさせてみる
rio scale
コマンドでスケールさせることが出来ます。
$ rio scale foobar=3 default-265db573:foobar #確認 $ rio ps NAME IMAGE CREATED SCALE STATE ENDPOINT DETAIL foobar nginx 38 minutes ago 3 active #詳細確認 $ rio ps foobar NAME IMAGE CREATED NODE IP STATE DETAIL foobar/f6985f578-wbgwj nginx About a minute ago docker-for-desktop 10.1.3.60 running foobar/f6985f578-nrmhk nginx About a minute ago docker-for-desktop 10.1.3.59 running foobar/f6985f578-schpv nginx 39 minutes ago docker-for-desktop 10.1.3.58 running
Kubernetes側もみておきます。
#Deploymentの確認 $ kubectl get deploy -n default-265db573 NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE foobar 3 3 3 3 40m #Podの確認 $ kubectl get pod -n default-265db573 NAME READY STATUS RESTARTS AGE foobar-f6985f578-nrmhk 2/2 Running 0 2m foobar-f6985f578-schpv 2/2 Running 0 41m foobar-f6985f578-wbgwj 2/2 Running 0 2m
きちんとスケールアウトされてました。
サービスの削除
削除はrm
サブコマンドで行います。
#削除 $ rio rm foobar default-265db573:foobar #確認 $ rio ps NAME IMAGE CREATED SCALE STATE ENDPOINT DETAIL
外部からアクセス可能にしてみる(expose相当)
次に起動したサービスを外部からアクセス可能にしてみます。
外部からアクセス可能にするにはrio run
時に-p
(--publish
)オプションを指定します。
(rio edit
などでもOK)
# run時にオプションを指定して80番ポートを公開 $ rio run --name foobar -p 80/http nginx default-265db573:foobar # 確認 $ rio ps NAME IMAGE CREATED SCALE STATE ENDPOINT DETAIL foobar nginx 8 seconds ago 1 active http://foobar.default.127.0.0.1.nip.io
今度はENDPOINTというのが割り当てられましたね。 この辺は前回の記事で説明した通りノードのIPアドレスにを指すようなFQDNが割り振られます。
起動したらブラウザなどでENDPOINTのURLを開いてみましょう。
非常に簡単に公開できましたね。
Kubernetes側からのぞいてみる(外部からのアクセス編)
またKubernetes側を確認してみます。 まずはServiceです。
$ kubectl get svc -n default-265db573 -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR foobar ClusterIP 10.97.38.245 <none> 80/TCP 1h app=foobar,rio.cattle.io/namespace=default-265db573,rio.cattle.io/service=foobar,rio.cattle.io=true
前と変わってないですね。RioはIstioを使ってますのでそちらの方を確認なければいけませんね。 なおIstioについては以下を読んでおくと以降をスムーズに読めると思います。
# Istio Gatewayの確認 $ kubectl get gateways --all-namespaces NAMESPACE NAME AGE istio-095b8502 rio-gateway 1h # Gatewayの詳細確認 $ kubectl get gateways -n istio-095b8502 rio-gateway -o yaml #適当に省略してます apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: rio-gateway namespace: istio-095b8502 spec: selector: gateway: external servers: - hosts: - '*' port: number: 80 protocol: HTTP
ホスト名問わず80番ポートへのアクセスを扱うようになってますね。
セレクタに指定されているgateway: external
についても確認しておきます。
#全ネームスペースからgateway: externalというラベルを持つサービスを取得 $ kubectl get svc --all-namespaces -l gateway=external NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-095b8502 rio-lb LoadBalancer 10.102.122.149 localhost 80:31752/TCP 1h
Type: LoadBalancer
なServiceが作成されてますね。これで外部からのアクセスを受け付けています。
(実はDocker for Macは18.03.0-ce-rc1-mac54
以降でType: LoadBalancer
が利用できるようになってたりします)
次にIstioのVirtualServiceについてみてみます。
$ kubectl get virtualservices -n default-265db573 NAME AGE foobar 52m #詳細確認 $ kubectl get virtualservices -n default-265db573 -o yaml foobar # 適当に省略してます apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: foobar namespace: default-265db573 spec: gateways: - mesh - rio-gateway.istio-095b8502.svc.cluster.local hosts: - foobar - foobar:80 - foobar.default.127.0.0.1.nip.io - foobar.default.127.0.0.1.nip.io:80 http: - match: - gateways: - mesh - rio-gateway.istio-095b8502.svc.cluster.local port: 80 route: - destination: host: foobar # foobar.default-265db573.svc.cluster.localと解釈される port: number: 80 subset: latest weight: 100
先ほど確認したGatewayrio-gateway
にバインドされていますね。
また、ホスト名としてfoobar
とfoobar.default.127.0.0.1.nip.io
が指定されています。
後者は先ほどrio ps
で確認したENDPOINTに表示されていたものですね。
destinationも指定されているようです。latest
という名前のsubset宛てですね。
IstioのDestinationRuleも確認してみます。
$ kubectl get destinationrules -n default-265db573 NAME AGE foobar 1h #詳細確認 $ kubectl get destinationrules -n default-265db573 -o yaml foobar #適当に省略してます apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: foobar namespace: default-265db573 spec: host: foobar subsets: - labels: rio.cattle.io/revision: latest name: latest
latest
という名前のsubsetが定義されています。
rio.cattle.io/revision: latest
というラベルを持つPod宛てということですね。
#宛先Podの確認 $ kubectl get pod -l rio.cattle.io/revision=latest -n default-265db573 NAME READY STATUS RESTARTS AGE foobar-6554b575b7-fz7fz 2/2 Running 0 1h
ということでrio run
の裏ではIstioを上手く使って頑張っているようです。
次はカナリアリリースを試してみます。
カナリアリリース
Rioはカナリアリリースをサポートしています。 先ほどはfoobarサービスとしてnginxイメージを利用しましたので、Apache(httpd)を使うように更新しカナリアリリースしてみます。
まずfoobarサービスに対するステージング環境をデプロイします。
#Apache(httpd)イメージを指定、foobar:v2とする $ rio stage --image=httpd foobar:v2 #確認 # rio ps NAME IMAGE CREATED SCALE STATE ENDPOINT DETAIL foobar nginx 40 minutes ago 1 active http://foobar.default.127.0.0.1.nip.io foobar:v2 httpd 40 minutes ago 1 active http://foobar-v2.default.127.0.0.1.nip.io
foobar:v2
がデプロイされました。ENDPOINTをブラウザで開いて確認しておきます。
昔懐かしい"It works!"が表示されていますね。
続いて早速カナリアリリースしてみます。
元のfoobar
サービスのENDPOINTに対してアクセスした際に30%の確率で更新版であるfoobar:v2
が表示されるようにしてみます。
$ rio weight foobar:v2=30%
foobarのエンドポイントhttp://foobar.default.127.0.0.1.nip.io
にアクセスし何度かリロードしてると表示が切り替わるのが確認できるはずです。
(キャッシュに注意してくださいね)
では裏ではどうなってるのか、Kubernetes側を確認してみましょう。
Kubernetes側からのぞいてみる(カナリアリリース編)
まずVirtualServicesを確認してみます。(ちなみにGatewayは変更なし)
$ kubectl get virtualservices -n default-265db573
NAME AGE
foobar 1h
foobar-v2 9m
予想通りfoobar-v2が増えてますね。
これは先ほどまでで確認したfoobarと同等ですので省略し、カナリアリリースしているfoobar
の方がどう変わったか詳しく見ておきます。
$ kubectl get virtualservices -n default-265db573 -o yaml foobar #適当に省略してます apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: foobar namespace: default-265db573 spec: gateways: - mesh - rio-gateway.istio-095b8502.svc.cluster.local hosts: - foobar - foobar:80 - foobar.default.127.0.0.1.nip.io - foobar.default.127.0.0.1.nip.io:80 http: - match: - gateways: - mesh - rio-gateway.istio-095b8502.svc.cluster.local port: 80 route: - destination: host: foobar port: number: 80 subset: latest weight: 70 - destination: host: foobar port: number: 80 subset: v2 weight: 30
spec.http.route
の子要素が追加されてますね。
指定通りv2
の方は30%、latest
は70%となっています。
念のためDestinationRulesの方も載せておきます。
$ kubectl get destinationrules -n default-265db573 -o yaml foobar #適当に省略してます apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: foobar namespace: default-265db573 spec: host: foobar subsets: - labels: rio.cattle.io/revision: latest name: latest - labels: rio.cattle.io/revision: v2 name: v2
こちらでもRioがIstioを上手く使って頑張っているようですね。
ステージング => 本番へ昇格(プロモート)させる
最後にfoobar:v2を昇格させfoobarの代わりにfoobar:v2を利用するようにしてみます。
$ rio promote foobar:v3 # 確認 $ rio ps NAME IMAGE CREATED SCALE STATE ENDPOINT DETAIL foobar httpd About an hour ago 1 active http://foobar.default.127.0.0.1.nip.io
イメージがhttpd
に変わってますね。
v2
というラベルも無くなっているのもポイントです。
#プロモートするとタグは無くなる $ kubectl get pod -l rio.cattle.io/revision=v2 -n default-265db573 No resources found. #その代わりにこれまでのv2にはlatestというタグが改めて付与される $ kubectl get pod -l rio.cattle.io/revision=latest -n default-265db573 NAME READY STATUS RESTARTS AGE foobar-69c4b7944c-2jcxt 2/2 Running 0 1m
まとめ
ということで今回はRioがKubernetes/Istioをどう扱っているかについてみてみました。
まだまだ不安定な部分も結構あったりしますが、今もGitHubに大きめのPRが上がってきてたりと開発は進んでる様子なので今後に期待しています。
以上です。
Kubernetes完全ガイド (impress top gear)
- 作者: 青山真也
- 出版社/メーカー: インプレス
- 発売日: 2018/09/21
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
- 作者: 山田明憲
- 出版社/メーカー: 技術評論社
- 発売日: 2018/08/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る