目次
- Kuboとは
- GCP環境のセットアップ
- BOSHのデプロイ
- Routing方式の設定
- Kubernetesクラスタのデプロイ
- Kubernetesへのアクセス
- アプリケーションのデプロイ
- BOSHによるResurrection
- Kubernetesクラスタのスケールイン
- Kubernetesクラスタの停止
- Kubernetesクラスタの再開
- Kubernetesクラスタの削除
Kuboとは
KuboはKubernetesのBOSH Releaseです。BOSHを利用して、Kubernetesのデプロイ、運用を行うことができます。
PivotalとGoogleのエンジニアで共同開発されています。
BOSHはCloud Foundryの運用において長く使用されているツールです。
BOSHもKubernetesもGoogleのBorgを起源としており、Kubernetesがコンテナの管理をするのに対して、BOSHは同じように、その下のVMの管理を行います。
BOSHを使用することにより、
- マルチクラウド環境(GCP, AWS, Azure, vSphere, OpenStack)にデプロイできる (クラスタを分散できるわけではありません)
- Day 1 Operation(k8sクラスタのインストール、デプロイ)だけでなく、Day 2 Operation(k8sクラスタ自体の自動復旧、スケールアウト、Multi-AZ対応、ローリングアップデート)に対応できる
などのメリットがあり、他のKubernetesデプロイツールとの違いになっています。
GKEやACSのようなManaged Kubernetesが使えない場合や、パブリッククラウドとオンプレミスで同じ環境を使いたい場合の魅力的な選択肢になるかと思います。
本記事の執筆時点ではKubo(v0.6.0)は
- GCP
- vSphere
- OpenStack
- AWS
に対応しています。
以下はGCPにKuboをデプロイした時のメモです。
使用したcommitは
- kubo-deployment#34e334346a7801c874dede7441466a3ed70d794b
- kubo-release#25bad93ecb13fdb9c42f8be23b67571501331c20
です。
GCP環境のセットアップ
まずはGCPにBOSHをデプロイするための下準備です。
Google Cloud Shellで作業します。
まずはIAMを設定します。
export project_id=$(gcloud config get-value project)
export region=asia-northeast1
export zone=asia-northeast1-a
export prefix=${project_id}-kubo
export service_account_email=${prefix}terraform@${project_id}.iam.gserviceaccount.com
export network=${prefix}-net
export subnet_ip_prefix="10.0.1"
gcloud config set compute/zone ${zone}
gcloud config set compute/region ${region}
gcloud compute --project=${project_id} networks create ${network} --mode=custom
gcloud iam service-accounts create ${prefix}terraform
gcloud iam service-accounts keys create ~/terraform.key.json --iam-account ${service_account_email}
gcloud projects add-iam-policy-binding ${project_id} --member serviceAccount:${service_account_email} --role roles/owner
export GOOGLE_CREDENTIALS=$(cat ~/terraform.key.json)
次にBastion(踏み台)サーバーとNATのVMをTerraformで作成します。
cd ~
git clone https://github.com/cloudfoundry-incubator/kubo-deployment.git
cd ~/kubo-deployment/docs/user-guide/platforms/gcp
docker run -i -t \
-v $(pwd):/$(basename $(pwd)) \
-w /$(basename $(pwd)) \
hashicorp/terraform:light init
docker run -i -t \
-e CHECKPOINT_DISABLE=1 \
-e "GOOGLE_CREDENTIALS=${GOOGLE_CREDENTIALS}" \
-v $(pwd):/$(basename $(pwd)) \
-w /$(basename $(pwd)) \
hashicorp/terraform:light apply \
-var service_account_email=${service_account_email} \
-var projectid=${project_id} \
-var network=${network} \
-var region=${region} \
-var prefix=${prefix} \
-var zone=${zone} \
-var subnet_ip_prefix=${subnet_ip_prefix}
gcloud compute scp ~/terraform.key.json "${prefix}bosh-bastion":./ --zone ${zone}
gcloud compute scp --recurse ~/kubo-deployment "${prefix}bosh-bastion":/share/ --zone ${zone}
サブネットが作成されています。
VMが2つ作成されています。***bosh-bastion
がBastion(踏み台)サーバー、***nat-instance-primary
がNATです。
以降はBastionサーバーにログインして作業します。
gcloud compute ssh "${prefix}bosh-bastion" --zone ${zone}
BOSHのデプロイ
次にBOSH Directorをデプロイします。
cd /share/kubo-deployment
export kubo_envs=~/kubo-env
export kubo_env_name=kubo
export kubo_env_path="${kubo_envs}/${kubo_env_name}"
mkdir -p "${kubo_envs}"
./bin/generate_env_config "${kubo_envs}" ${kubo_env_name} gcp
/usr/bin/update_gcp_env "${kubo_env_path}/director.yml"
./bin/deploy_bosh "${kubo_env_path}" ~/terraform.key.json
Labelにdeployment=bosh, director=bosh-init
が設定されているVMがBOSH Directorです。
Routing方式の設定
KuboではKubernetesに対するルーティング方式として
- CF (Cloud Foundryと連携し、GoRouter, TCPRouterからk8sへアクセス可能にする)
- IaaS (IaaSのLBを使用する)
- HA Proxy (HA Proxyを使用する)
が選択可能です。今回はKubo単独のデプロイなので、IaaSを選択します。
cd /share/kubo-deployment/docs/user-guide/routing/gcp
export state_dir=~/kubo-env/${kubo_env_name}
export kubo_terraform_state=${state_dir}/terraform.tfstate
terraform apply \
-var network=${network} \
-var projectid=${project_id} \
-var region=${region} \
-var prefix=${prefix} \
-var ip_cidr_range="${subnet_ip_prefix}.0/24" \
-state=${kubo_terraform_state}
export master_target_pool=$(terraform output -state=${kubo_terraform_state} kubo_master_target_pool)
export kubernetes_master_host=$(terraform output -state=${kubo_terraform_state} master_lb_ip_address)
/usr/bin/set_iaas_routing "${state_dir}/director.yml"
まずはMaster NodeのAPI ServerへのLBが作成されます。
Kubernetesクラスタのデプロイ
いよいよ、BOSHを使ったKubernetesのデプロイです。
cd /share/kubo-deployment
bin/deploy_k8s ${kubo_env_path} ${prefix}cluster
しばらく待つと、VMが8つ追加されます。
- master x 2
- etcd x 3
- worker x 3
です。
BOSH DirectorにログインしてBOSH CLIを使用しましょう。
export BOSH_ENVIRONMENT=`gcloud compute instances list --filter labels.deployment=bosh | grep RUNNING | awk '{print $4}'`
export BOSH_CLIENT=admin
export BOSH_CLIENT_SECRET=`bosh-cli int ${kubo_env_path}/creds.yml --path /admin_password`
export BOSH_CA_CERT=`bosh-cli int ${kubo_env_path}/creds.yml --path /director_ssl/ca`
bosh-cli vms
でBOSHでデプロイしたVM一覧を取得できます。
$ bosh-cli vms
Using environment '10.0.1.252' as client 'admin'
Task 6. Done
Deployment 'fe-tmaki-kubocluster'
Instance Process State AZ IPs VM CID VM Type
etcd/29fc3df2-45dd-4f9c-9314-327a13a32283 running z1 10.0.1.7 vm-b86faa89-8726-4e86-7ef0-22cc86d479c9 common
etcd/7ea9a870-cc1e-490e-9ead-230a7ebc945a running z1 10.0.1.11 vm-0922c0b2-f997-4e0b-7c4e-26e2581eec23 common
etcd/aa84e25e-bfc4-4235-a668-520980338531 running z1 10.0.1.10 vm-00b71b57-ccdb-453a-6249-a7bc9ef5832c common
master/b003dbd2-b6a4-4d79-93b4-fb00d71cd4a1 running z1 10.0.1.4 vm-2ade7004-28a7-48e3-42ce-d2750ce9c5c5 master
master/f63be039-ffd9-4783-bc78-dd26065d97fb running z1 10.0.1.9 vm-9e961a54-194c-4b82-7819-18df78d053ca master
worker/ca43686b-058a-4c3e-8c71-7edc9aa2e756 running z1 10.0.1.6 vm-7bc295ca-d71b-4f4c-4fb1-863f8d36f989 worker
worker/e0393799-dfe4-4a6a-be5c-fa21d6c71836 running z1 10.0.1.5 vm-5c0eb0e7-1116-4a9a-7df3-67b213ecc2fa worker
worker/e43c01fa-f49b-473c-85d4-11644a050fa7 running z1 10.0.1.8 vm-08384a35-dbb6-421f-619c-3526b156100a worker
8 vms
Succeeded
bosh-cli releases
で使用中のBOSH Release(ソフトウェアのソースコード・バイナリ、設定ファイル、起動・監視スクリプト群)一覧を取得できます。
$ bosh-cli releases
Using environment '10.0.1.252' as client 'admin'
Name Version Commit Hash
docker 28.0.1* 8096ad43+
kubo 0.7.0-dev.3* 25bad93
kubo-etcd 2* aa57fc9
GCPのロードバランサを確認するとMaster Nodeに振られていることがわかります。
Kubernetesへのアクセス
デプロイしたKubernetesへアクセスしましょう。
bin/set_kubeconfig ${kubo_env_path} ${prefix}cluster
~/.kube/config
が更新されました。これでkubectl
を使ってアクセス可能です。
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.4", GitCommit:"793658f2d7ca7f064d2bdf606519f9fe1229c381", GitTreeState:"clean", BuildDate:"2017-08-17T08:48:23Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.1", GitCommit:"1dc5c66f5dd61da08412a74221ecc79208c2165b", GitTreeState:"clean", BuildDate:"2017-07-14T01:48:01Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
heapster-2986240809-t2x5m 1/1 Running 0 1h
kube-dns-3329716278-3wn5n 3/3 Running 0 1h
kubernetes-dashboard-1367211859-0zbv0 1/1 Running 0 1h
monitoring-influxdb-564852376-vn1f5 1/1 Running 0 1h
$ kubectl get node -o wide
NAME STATUS AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION
vm-08384a35-dbb6-421f-619c-3526b156100a Ready 1h v1.7.1 Ubuntu 14.04.5 LTS 4.4.0-83-generic
vm-5c0eb0e7-1116-4a9a-7df3-67b213ecc2fa Ready 1h v1.7.1 Ubuntu 14.04.5 LTS 4.4.0-83-generic
vm-7bc295ca-d71b-4f4c-4fb1-863f8d36f989 Ready 1h v1.7.1 Ubuntu 14.04.5 LTS 4.4.0-83-generic
アプリケーションのデプロイ
簡単なアプリケーションをデプロイします。次のhello-tomcat.yml
kind: Service
apiVersion: v1
metadata:
name: hello-tomcat-service
spec:
selector:
run: hello-tomcat
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: LoadBalancer
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: hello-tomcat-deployment
spec:
replicas: 2
template:
metadata:
labels:
run: hello-tomcat
spec:
containers:
- name: hello-tomcat
image: making/hello-tomcat:v1
ports:
- containerPort: 8080
kubectl create
でデプロイします。
kubectl create -f hello-tomcat.yml
しばらくするとPodとServiceが作成され、LBのIPアドレスが割り当てられます。
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-tomcat-deployment-1598259564-0v4cp 1/1 Running 0 2m
hello-tomcat-deployment-1598259564-b2cqg 1/1 Running 0 2m
$ kubectl get service hello-tomcat-service -o wide
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
hello-tomcat-service 10.100.200.178 35.200.95.68 8080:32517/TCP 11m run=hello-tomcat
GCPのLB画面を見ても、確かに新規のLBが作成され、Worker Nodeに振られていることがわかります。
これで、次のコマンドでコンテナにアクセスできます。
curl 35.200.95.68:8080
と、思ったのですが、繋がらない......
よくよく見てみると、LBに対応するFirewall Ruleが適用されるには${prefix}bosh-kubo-worker
タグが設定されている必要があるのですが、
Worker Nodeには設定されていません。。。
次のissueが上がっていましたのでバグのようです。
https://github.com/cloudfoundry-incubator/kubo-deployment/issues/162
ここは一旦Workarroundとして、手動でWorker Nodeにtagを設定します。
for vm in `gcloud compute instances list --filter labels.job=worker | grep RUNNING | awk '{print $1}'`;do
gcloud compute instances add-tags $vm --tags ${prefix}bosh-kubo-worker;
done
これでなんとかアクセスできました。
$ curl 35.200.95.68:8080
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
$ curl 35.200.95.68:8080/env
HELLO_TOMCAT_SERVICE_SERVICE_HOST: 10.100.200.178
PATH: /usr/local/tomcat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT: tcp://10.100.200.1:443
JAVA_HOME: /docker-java-home/jre
CA_CERTIFICATES_JAVA_VERSION: 20161107~bpo8+1
KUBERNETES_SERVICE_HOST: 10.100.200.1
LANG: C.UTF-8
TOMCAT_MAJOR: 8
TOMCAT_VERSION: 8.5.15
LD_LIBRARY_PATH: /usr/local/tomcat/native-jni-lib
OPENSSL_VERSION: 1.1.0e-2
HELLO_TOMCAT_SERVICE_PORT_8080_TCP_PROTO: tcp
TOMCAT_NATIVE_LIBDIR: /usr/local/tomcat/native-jni-lib
PWD: /usr/local/tomcat
JAVA_VERSION: 8u131
KUBERNETES_PORT_443_TCP: tcp://10.100.200.1:443
TOMCAT_TGZ_URL: https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-8/v8.5.15/bin/apache-tomcat-8.5.15.tar.gz
KUBERNETES_PORT_443_TCP_ADDR: 10.100.200.1
HELLO_TOMCAT_SERVICE_PORT_8080_TCP_ADDR: 10.100.200.178
CATALINA_HOME: /usr/local/tomcat
HELLO_TOMCAT_SERVICE_PORT: tcp://10.100.200.178:8080
KUBERNETES_PORT_443_TCP_PROTO: tcp
HELLO_TOMCAT_SERVICE_SERVICE_PORT: 8080
HELLO_TOMCAT_SERVICE_PORT_8080_TCP_PORT: 8080
KUBERNETES_SERVICE_PORT: 443
HOSTNAME: hello-tomcat-deployment-1598259564-dhmnw
JAVA_DEBIAN_VERSION: 8u131-b11-1~bpo8+1
TOMCAT_ASC_URL: https://www.apache.org/dist/tomcat/tomcat-8/v8.5.15/bin/apache-tomcat-8.5.15.tar.gz.asc
KUBERNETES_PORT_443_TCP_PORT: 443
KUBERNETES_SERVICE_PORT_HTTPS: 443
HELLO_TOMCAT_SERVICE_PORT_8080_TCP: tcp://10.100.200.178:8080
GPG_KEYS: 05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 713DA88BE50911535FE716F5208B0AB1D63011C7 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23
HOME: /root
ロードバランスできていることも確認できます。
$ for i in `seq 1 10`;do curl -s 35.200.95.68:8080/env | grep HOSTNAME;done
HOSTNAME: hello-tomcat-deployment-1598259564-dhmnw
HOSTNAME: hello-tomcat-deployment-1598259564-dhmnw
HOSTNAME: hello-tomcat-deployment-1598259564-vbknx
HOSTNAME: hello-tomcat-deployment-1598259564-vbknx
HOSTNAME: hello-tomcat-deployment-1598259564-vbknx
HOSTNAME: hello-tomcat-deployment-1598259564-dhmnw
HOSTNAME: hello-tomcat-deployment-1598259564-vbknx
HOSTNAME: hello-tomcat-deployment-1598259564-vbknx
HOSTNAME: hello-tomcat-deployment-1598259564-dhmnw
HOSTNAME: hello-tomcat-deployment-1598259564-vbknx
BOSHによるResurrection
次にBOSHによるVMのResurrection(自動復旧)を試してみます。
わざとWorker Nodeの一つ(vm-e43c01fa-f49b-473c-85d4-11644a050fa7
)をGCPのConsoleから削除します。
しばらくするとVMの新規作成が始まります。
そして、Worker Nodeとして復帰します。
この機能はBOSHの標準機能であり、特別な設定は不要です。
(が、またしても${prefix}bosh-kubo-worker
タグがついていませんでした。。。kubo-deployment#162修正待ち。)
Kubernetesクラスタのスケールイン
MasterとEtcdを1インスタンスに減らします。
bosh-cli manifest -d ${prefix}cluster > kubo.yml
cat <<EOF > scale-in.yml
- type: replace
path: /instance_groups/name=etcd/instances
value: 1
- type: replace
path: /instance_groups/name=master/instances
value: 1
- type: replace
path: /instance_groups/name=worker/instances
value: 3
EOF
bosh-cli deploy -d ${prefix}cluster <(bosh-cli int kubo.yml -o scale-in.yml)
$ bosh-cli vms
Using environment '10.0.1.252' as client 'admin'
Task 64. Done
Deployment 'fe-tmaki-kubocluster'
Instance Process State AZ IPs VM CID VM Type
etcd/7ea9a870-cc1e-490e-9ead-230a7ebc945a running z1 10.0.1.11 vm-f8fa6f1b-51cb-4335-46bc-d0def79d3143 common
master/b003dbd2-b6a4-4d79-93b4-fb00d71cd4a1 running z1 10.0.1.4 vm-8ff505ae-8f28-40fe-6fd5-01745368e5c3 master
worker/1c356a7e-50e4-4b1e-8edd-ec7ba943cc28 running z1 10.0.1.8 vm-1823d788-e7b3-488f-66ec-e1c5d085a797 worker
worker/21cc8f19-7bf3-407e-b4a7-d07f67510935 running z1 10.0.1.6 vm-f6dbd590-20a2-44e6-6be3-a2328639c9e4 worker
worker/e0393799-dfe4-4a6a-be5c-fa21d6c71836 running z1 10.0.1.5 vm-e9e1b93f-5ec1-4ac5-4b7a-165a4e934a71 worker
Kubernetesクラスタの停止
bosh-cli stop
でクラスタを停止できますが、デフォルトではプロセスが停止するだけです。VMの削除まで行いたい場合は、--hard
をつけます。
Cloud Foundryでの経験上、stop前のetcdは1インスタンスに減らしておくのが無難です。
bosh-cli stop --hard -d ${prefix}cluster
Master, Etcd, WorkerのVMが削除されたことがわかります。
VMは削除されますが、Persistent Diskは残っています。
注意: 運用中は行わない操作です。動作確認中に課金時間を少なくしたい場合のみ行います。
Kubernetesクラスタの再開
停止したクラスタはbosh-cli start
で再開できます。
bosh-cli start -d ${prefix}cluster
IPアドレスは再割り当てされます。
$ bosh-cli vms
Using environment '10.0.1.252' as client 'admin'
Task 71. Done
Deployment 'fe-tmaki-kubocluster'
Instance Process State AZ IPs VM CID VM Type
etcd/7ea9a870-cc1e-490e-9ead-230a7ebc945a running z1 10.0.1.8 vm-2abe4bd8-6c47-4d54-7ac0-d404daf857c2 common
master/b003dbd2-b6a4-4d79-93b4-fb00d71cd4a1 running z1 10.0.1.4 vm-8aa68b01-ea2a-46d4-628f-de9640753baf master
worker/1c356a7e-50e4-4b1e-8edd-ec7ba943cc28 running z1 10.0.1.5 vm-bc2d88c0-7e20-46c3-7ecd-cca800e65c89 worker
worker/21cc8f19-7bf3-407e-b4a7-d07f67510935 running z1 10.0.1.6 vm-c37a7eaf-8a67-4d9f-7e27-83cf70548dda worker
worker/e0393799-dfe4-4a6a-be5c-fa21d6c71836 running z1 10.0.1.7 vm-ec528f91-6222-4b41-5094-99d0a3e21eed worker
5 vms
Succeeded
Kubernetesクラスタの削除
動作確認が終われば、クラスタを削除します。
次のコマンドでk8sクラスタを削除できます。
bosh-cli delete-deployment -d ${prefix}cluster
この操作でBOSH Director、NAT、Bastionは削除されません。また、Kubernetesが作成したLBも削除されません。
GCPだとGKEがあるので、あまりメリットを感じないかもしれないけれども、
Cloud FoundryユーザーにとってはKuboを使うことで、Cloud FoundryのRouterを通じてk8sのコンテナにルーティングできたり、
将来的にはcf create-service
でk8sクラスタをオンデマンドで作成することができるようになるので、魅力的です。
またOpen Service Broker APIを通じて、CF <---> k8s間のバックエンドサービスの相互運用も可能になります。
今度はAWSにデプロイしようかな。