IK.AM

@making's tech note


Kubo(Kubernetes on BOSH)をGCPにデプロイ

🗃 {Dev/CaaS/Kubernetes}
🏷 Kubo 🏷 BOSH 🏷 Kubernetes 🏷 GCP 
🗓 Updated at 2017-09-30T19:59:52Z  🗓 Created at 2017-08-21T14:46:53Z   🌎 English Page

目次

Kuboとは

KuboはKubernetesのBOSH Releaseです。BOSHを利用して、Kubernetesのデプロイ、運用を行うことができます。

PivotalとGoogleのエンジニアで共同開発されています。

image.png

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は

です。

GCP環境のセットアップ

まずはGCPにBOSHをデプロイするための下準備です。

image.png

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}

サブネットが作成されています。

image.png

VMが2つ作成されています。***bosh-bastionがBastion(踏み台)サーバー、***nat-instance-primaryがNATです。

image.png

以降は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です。

image.png

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が作成されます。

image.png

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

です。

image.png

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に振られていることがわかります。

image.png

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に振られていることがわかります。

image.png

これで、次のコマンドでコンテナにアクセスできます。

curl 35.200.95.68:8080

と、思ったのですが、繋がらない......

よくよく見てみると、LBに対応するFirewall Ruleが適用されるには${prefix}bosh-kubo-workerタグが設定されている必要があるのですが、

image.png

Worker Nodeには設定されていません。。。

image.png

次の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から削除します。

image.png

しばらくするとVMの新規作成が始まります。

image.png

そして、Worker Nodeとして復帰します。

image.png

この機能は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)

image.png

$ 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が削除されたことがわかります。

image.png

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

image.png

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にデプロイしようかな。


✒️️ Edit  ⏰ History  🗑 Delete