ℹ️ 本記事の作成方法はMulti-AZに対応していません。Multi-AZ対応版はこちらです。
本記事はこちらのv0.17.0版です。 0.16.0から0.17.0にアップデートする方法はこちらを参照してください。
目次
Cloud Foundry Container Runtime(CFCR)を使ってKubernetesをBOSHでAWSにデプロイします。
CFCRはかつてKubo(Kubernetes on BOSH)と言われていましたが、renameされました。 この記事で一度環境を作れば、今後は(Breaking Changeがない限り)簡単にバージョンアップに追従できるはずです。
CFCRのdeploy
Official Documentのインストール方法は手作業が混じっているのとBOSHの操作を隠蔽してしまっており、BOSHユーザーには扱いづらい内容になっているので、 素直なBOSH wayでデプロイできるようにカスタマイズしました。またTerraformテンプレートもオフィシャルのものに加えてドキュメントの手作業部分も追加しました。
TerraformでAWS環境をPaving
まずはBOSHおよびKuberneteに必要なAWS環境をPaving(舗装)します。ここではTerraformを使います。
カスタマイズ済みTerraformテンプレートを取得してください。
git clone https://github.com/making/cfcr-aws.git
cd cfcr-aws/terraform
terraform.tfvars
に変数を定義します。access_key
とsecret_key
はTerraform実行用のIAMユーザーでAdministratorAccess
Roleを持ったものを設定してください。
cat <<EOF > terraform.tfvars
prefix = "demo"
access_key = "abcdef"
secret_key = "foobar"
region = "ap-northeast-1"
zone = "ap-northeast-1a"
vpc_cidr = "10.0.0.0/16"
public_subnet_ip_prefix = "10.0.1"
private_subnet_ip_prefix = "10.0.2"
EOF
次のコマンドでTerraformを実行してください。
terraform init
terraform plan -out plan
terraform apply plan
次の図のような環境ができました。
Bastionサーバーへlogin
次に舗装された環境上でBOSHのプロビジョングを行いますが、作業はBastion(踏み台)サーバー上で行います。
cat terraform.tfstate | jq -r '.modules[0].resources["tls_private_key.deployer"].primary.attributes.private_key_pem' > deployer.pem
chmod 600 deployer.pem
export BASTION_IP=`cat terraform.tfstate | jq -r '.modules[0].outputs["bosh_bastion_ip"].value'`
echo "ssh -o StrictHostKeyChecking=no -i $(pwd)/deployer.pem ubuntu@${BASTION_IP}" > ssh-bastion.sh
chmod +x ssh-bastion.sh
次のスクリプトを実行してBastionサーバーにsshログインしてください。
./ssh-bastion.sh
BOSHのprovisioning
BOSH(BOSH Director)をbosh-deploymentを使ってProvisioningします。 合わせてkubo-deploymentも取得し、一旦Git管理します。
mkdir cfcr-manifests
cd cfcr-manifests
git init
git submodule add https://github.com/cloudfoundry/bosh-deployment.git
git submodule add https://github.com/cloudfoundry-incubator/kubo-deployment.git
cd kubo-deployment
git checkout v0.17.0
cd ..
git add -A
git commit -m "import CFCR v0.17.0"
YAMLの差分ファイル(ops-file)はops-files
ディレクトリで管理します。
mkdir -p ops-files
BOSH DirectorのVMサイズを小さめのt2.small
にするops-fileを作成します。
cat <<EOF > ops-files/director-size-aws.yml
- type: replace
path: /resource_pools/name=vms/cloud_properties/instance_type
value: t2.small
EOF
BOSHをprovisioningするスクリプトを作成します。各種環境変数はTerraformでBastionサーバーに設定済みです。
cat <<'EOF' > deploy-bosh.sh
#!/bin/bash
bosh create-env bosh-deployment/bosh.yml \
-o bosh-deployment/aws/cpi.yml \
-o bosh-deployment/uaa.yml \
-o bosh-deployment/credhub.yml \
-o bosh-deployment/jumpbox-user.yml \
-o bosh-deployment/local-dns.yml \
-o ops-files/director-size-aws.yml \
-o kubo-deployment/configurations/generic/dns-addresses.yml \
-o kubo-deployment/configurations/generic/bosh-admin-client.yml \
-o kubo-deployment/manifests/ops-files/iaas/aws/bosh/tags.yml \
-v director_name=bosh-aws \
-v internal_cidr=${private_subnet_ip_prefix}.0/24 \
-v internal_gw=${private_subnet_ip_prefix}.1 \
-v internal_ip=${private_subnet_ip_prefix}.252 \
-v access_key_id=${AWS_ACCESS_KEY_ID} \
-v secret_access_key=${AWS_SECRET_ACCESS_KEY} \
-v region=${region} \
-v az=${zone} \
-v default_key_name=${default_key_name} \
-v default_security_groups=[${default_security_groups}] \
--var-file private_key=${HOME}/deployer.pem \
-v subnet_id=${private_subnet_id} \
--vars-store=bosh-aws-creds.yml \
--state bosh-aws-state.json
EOF
chmod +x deploy-bosh.sh
スクリプトを実行してBOSH Directorを作成してください。
./deploy-bosh.sh
次の図のような環境ができました。
BOSH Directorをアップデートしたい場合はbosh-deployment
をgit pull
して./deploy-bosh.sh
を再実行すれば良いです。
BOSH Directorの設定
BOSH Directorにアクセスするための設定を行い、BOSH Directorにログインします。
cat <<'EOF' > bosh-aws-env.sh
export BOSH_CLIENT=admin
export BOSH_CLIENT_SECRET=$(bosh int ./bosh-aws-creds.yml --path /admin_password)
export BOSH_CA_CERT=$(bosh int ./bosh-aws-creds.yml --path /director_ssl/ca)
export BOSH_ENVIRONMENT=${private_subnet_ip_prefix}.252
EOF
chmod +x bosh-aws-env.sh
次のコマンドを実行してください。
source bosh-aws-env.sh
bosh env
とbosh login
を確認してください。
$ bosh env
Using environment '10.0.2.252' as client 'admin'
Name bosh-aws
UUID 7feb01e4-0eee-4eae-a735-8e3183428087
Version 265.2.0 (00000000)
CPI aws_cpi
Features compiled_package_cache: disabled
config_server: enabled
dns: disabled
snapshots: disabled
User admin
Succeeded
$ bosh login
Successfully authenticated with UAA
Succeeded
Stemcellのupload
BOSHが作成するVMのテンプレートイメージであるStemcellをアップロードします。
STEMCELL_VERSION=$(bosh int kubo-deployment/manifests/cfcr.yml --path /stemcells/0/version)
bosh upload-stemcell https://s3.amazonaws.com/bosh-aws-light-stemcells/light-bosh-stemcell-${STEMCELL_VERSION}-aws-xen-hvm-ubuntu-trusty-go_agent.tgz
Cloud Configのupdate
BOSH DirectorにIaaSの環境上を設定するためのCloud Configを作成します。
Cloud ConfigのテンプレートはOfficialのものを使いますが、vm_type
名がなぜかcfcr.yml
で使われている値と違うため、renameするためのops-fileを作成します...
cat <<EOF > ops-files/cloud-config-rename-vm-types.yml
- type: replace
path: /vm_types/name=master/name
value: small
- type: replace
path: /vm_types/name=worker/name
value: small-highmem
- type: replace
path: /compilation/vm_type
value: small-highmem
EOF
instance_type
を小さくします。
cat <<EOF > ops-files/cloud-config-small-vm-types.yml
- type: replace
path: /vm_types/name=minimal/cloud_properties/instance_type
value: t2.micro
- type: replace
path: /vm_types/name=small/cloud_properties/instance_type
value: t2.micro
- type: replace
path: /vm_types/name=small-highmem/cloud_properties/instance_type
value: t2.medium
EOF
Master APIにLoadBalancerをアタッチするためのvm_extensions
を作成します。
cat <<EOF > ops-files/cloud-config-master-lb.yml
- type: replace
path: /vm_extensions?/-
value:
name: master-lb
cloud_properties:
elbs:
- ((master_target_pool))
EOF
Cloud Configをupdateするためのスクリプトを作成します。
cat <<'EOF' > update-cloud-config.sh
#!/bin/bash
bosh update-cloud-config kubo-deployment/configurations/aws/cloud-config.yml \
-o ops-files/cloud-config-rename-vm-types.yml \
-o ops-files/cloud-config-small-vm-types.yml \
-o ops-files/cloud-config-master-lb.yml \
-v az=${zone} \
-v master_iam_instance_profile=${prefix}-cfcr-master \
-v worker_iam_instance_profile=${prefix}-cfcr-worker \
-v internal_cidr=${private_subnet_ip_prefix}.0/24 \
-v internal_gw=${private_subnet_ip_prefix}.1 \
-v dns_recursor_ip=${private_subnet_ip_prefix}.1 \
-v subnet_id=${private_subnet_id} \
-v master_target_pool=${prefix}-cfcr-api
EOF
chmod +x update-cloud-config.sh
次のコマンドを実行してください。
./update-cloud-config.sh
Kubernetesクラスタのデプロイ
KubernetesのデプロイはOfficialのManifestをベースに差分をops-fileで適用する形で行います。
CFCR 0.17.0を使うops-fileを作成します。
cat <<EOF > ops-files/kubernetes-kubo-0.17.0.yml
- type: replace
path: /releases/name=kubo?
value:
name: kubo
version: 0.17.0
url: https://bosh.io/d/github.com/cloudfoundry-incubator/kubo-release?v=0.17.0
sha1: 0ab676b9f6f5363377498e93487e8ba31622768e
EOF
Workerのインスタンス数を1に減らすops-fileを作成します。(Workerを増やしたい場合はこの値を変えてください)
cat <<EOF > ops-files/kubernetes-worker.yml
- type: replace
path: /instance_groups/name=worker/instances
value: 1
EOF
MasterにLBをアタッチするためのvm_extensions
と、MasterのTLS証明書のSANにELBのDNS名を追加するops-fileを作成します。
cat <<EOF > ops-files/kubernetes-master-lb.yml
- type: replace
path: /instance_groups/name=master/vm_extensions?/-
value: master-lb
- type: replace
path: /variables/name=tls-kubernetes/options/alternative_names/-
value: ((kubernetes_master_host))
EOF
デプロイ時に追加で登録したいAddonはspecs
ディレクトリ以下で管理します。
mkdir -p specs
EBS用のStorageClassをデフォルトとして登録するSpecを作成します。
cat <<EOF > specs/aws-storage-class.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
annotations:
storageclass.beta.kubernetes.io/is-default-class: "true"
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: EnsureExists
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
EOF
Kubrnetesをデプロイするスクリプトを作成します。
cat <<'EOF' > deploy-kubernetes.sh
#!/bin/bash
bosh deploy -d cfcr kubo-deployment/manifests/cfcr.yml \
-o kubo-deployment/manifests/ops-files/misc/single-master.yml \
-o kubo-deployment/manifests/ops-files/addons-spec.yml \
-o kubo-deployment/manifests/ops-files/iaas/aws/lb.yml \
-o kubo-deployment/manifests/ops-files/iaas/aws/cloud-provider.yml \
-o ops-files/kubernetes-kubo-0.17.0.yml \
-o ops-files/kubernetes-worker.yml \
-o ops-files/kubernetes-master-lb.yml \
--var-file addons-spec=<(for f in `ls specs/*.yml`;do cat $f;echo;echo "---";done) \
-v kubernetes_cluster_tag=${kubernetes_cluster_tag} \
-v kubernetes_master_host=${master_lb_ip_address} \
--no-redact
EOF
chmod +x deploy-kubernetes.sh
次のコマンドを実行してデプロイしてください。(途中でy
を入力する必要があります。)
./deploy-kubernetes.sh
次の図のような環境ができました。
bosh vms
、bosh instances --ps
を実行してVM一覧、プロセス一覧を確認してください。
$ bosh -d cfcr vms
Using environment '10.0.2.252' as client 'admin'
Task 13. Done
Deployment 'cfcr'
Instance Process State AZ IPs VM CID VM Type Active
master/bc14d482-2481-4cd4-ab61-f8998959befe running z1 10.0.2.4 i-07b65c52ed5de9bfa small -
worker/9a57034a-99a5-48cb-9db0-59841e083a8c running z1 10.0.2.5 i-0cadb8a54cec35909 small-highmem -
$ bosh -d cfcr instances --ps
Using environment '10.0.2.252' as client 'admin'
Task 14. Done
Deployment 'cfcr'
Instance Process Process State AZ IPs
apply-addons/70988ada-d3b8-4015-b2a7-de93ebd21e92 - - z1 -
master/bc14d482-2481-4cd4-ab61-f8998959befe - running z1 10.0.2.4
~ bosh-dns running - -
~ bosh-dns-healthcheck running - -
~ bosh-dns-resolvconf running - -
~ etcd running - -
~ flanneld running - -
~ kube-apiserver running - -
~ kube-controller-manager running - -
~ kube-scheduler running - -
worker/9a57034a-99a5-48cb-9db0-59841e083a8c - running z1 10.0.2.5
~ bosh-dns running - -
~ bosh-dns-healthcheck running - -
~ bosh-dns-resolvconf running - -
~ docker running - -
~ flanneld running - -
~ kube-proxy running - -
~ kubelet running - -
18 instances
CFCRがアップデートされた場合は、Breaking Changeがなければkubo-deployment
をgit pull
して、./deploy-kubernetes.sh
を実行すれば良いです。
Addonのdeploy
KubeDNS, Kubenetes DashboardなどのAddonはerrandでデプロイされます。次のコマンドを実行してください。
bosh -d cfcr run-errand apply-addons
CredHubへのログイン
Kubernetesクラスタに関するCredentials情報はBOSH Director VM内のCredHubに保存されています。 TLS証明書やAdminのパスワードを取得するにはCredHubにアクセスする必要があります。
CredHubにログインするためのスクリプトを作成します。
cat <<'EOF' > credhub-login.sh
#!/bin/bash
credhub login \
-s ${BOSH_ENVIRONMENT}:8844 \
--client-name=credhub-admin \
--client-secret=$(bosh int ./bosh-aws-creds.yml --path /credhub_admin_client_secret) \
--ca-cert <(bosh int ./bosh-aws-creds.yml --path /uaa_ssl/ca) \
--ca-cert <(bosh int ./bosh-aws-creds.yml --path /credhub_ca/ca)
EOF
chmod +x credhub-login.sh
スクリプトを実行してCredHubにログインしてください。
./credhub-login.sh
CredHubへのアクセストークンは1時間で切れるので、有効期限が切れたら再度ログインしてください。
Kubernetesへアクセス
AdminのパスワードをCredHubから取得します。
admin_password=$(credhub get -n /bosh-aws/cfcr/kubo-admin-password | bosh int - --path=/value)
Master APIのTLS CA証明書を取得します。
tmp_ca_file="$(mktemp)"
credhub get -n /bosh-aws/cfcr/tls-kubernetes | bosh int - --path=/value/ca > "${tmp_ca_file}"
kubectl
のContextを設定します。
cluster_name="cfcr-aws"
user_name="admin-aws"
context_name="cfcr-aws"
kubectl config set-cluster "${cluster_name}" \
--server="https://${master_lb_ip_address}:8443" \
--certificate-authority="${tmp_ca_file}" \
--embed-certs=true
kubectl config set-credentials "${user_name}" --token="${admin_password}"
kubectl config set-context "${context_name}" --cluster="${cluster_name}" --user="${user_name}"
kubectl config use-context "${context_name}"
kubectl cluster-info
でクラスタ情報を確認してください。
$ kubectl cluster-info
Kubernetes master is running at https://demo-cfcr-api-658626716.ap-northeast-1.elb.amazonaws.com:8443
Heapster is running at https://demo-cfcr-api-658626716.ap-northeast-1.elb.amazonaws.com:8443/api/v1/namespaces/kube-system/services/heapster/proxy
KubeDNS is running at https://demo-cfcr-api-658626716.ap-northeast-1.elb.amazonaws.com:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
monitoring-influxdb is running at https://demo-cfcr-api-658626716.ap-northeast-1.elb.amazonaws.com:8443/api/v1/namespaces/kube-system/services/monitoring-influxdb/proxy
Master APIはInternet FacingなELBにアタッチされているので、~/.kube/config
の内容はBastionサーバー以外でも利用可能です。
最終的にこの記事で使用するEC2インスタンスは次の通りです。
クラスタのスケールアウト
Workerを2インスタンス、Masterを3インスタンスにスケールアウトしましょう。
cat <<EOF > ops-files/kubernetes-worker.yml
- type: replace
path: /instance_groups/name=worker/instances
value: 2
EOF
cat <<'EOF' > deploy-kubernetes.sh
#!/bin/bash
bosh deploy -d cfcr kubo-deployment/manifests/cfcr.yml \
-o kubo-deployment/manifests/ops-files/addons-spec.yml \
-o kubo-deployment/manifests/ops-files/iaas/aws/lb.yml \
-o kubo-deployment/manifests/ops-files/iaas/aws/cloud-provider.yml \
-o ops-files/kubernetes-kubo-0.17.0.yml \
-o ops-files/kubernetes-worker.yml \
-o ops-files/kubernetes-master-lb.yml \
--var-file addons-spec=<(for f in `ls specs/*.yml`;do cat $f;echo;echo "---";done) \
-v kubernetes_cluster_tag=${kubernetes_cluster_tag} \
-v kubernetes_master_host=${master_lb_ip_address} \
--no-redact
EOF
./deploy-kubernetes.sh
bosh vms
でVM一覧を確認。
$ bosh -d cfcr vms
Using environment '10.0.2.252' as client 'admin'
Task 61. Done
Deployment 'cfcr'
Instance Process State AZ IPs VM CID VM Type Active
master/485d11d9-6390-40d7-97dd-b6f92b3148c6 running z2 10.0.2.7 i-0f6a5ceca5c869797 small -
master/7e776fbe-ea80-499c-b1d6-9f1aa8af29bc running z3 10.0.2.8 i-01ef1a2a6b0e38f84 small -
master/bc14d482-2481-4cd4-ab61-f8998959befe running z1 10.0.2.4 i-0e0c6b90f7b2ee10d small -
worker/9a57034a-99a5-48cb-9db0-59841e083a8c running z1 10.0.2.5 i-03d3204bfe5f4ba1f small-highmem -
worker/ac71f182-ce0b-4c6d-8811-2605c3248121 running z2 10.0.2.9 i-0412554a975042d05 small-highmem -
5 vms
Succeeded
EC2コンソールは次のようになります。
CFCRのdestroy
使い終わった環境は削除します。
Kubernetesクラスタの削除
Kubernetesを次のコマンド削除します。
なお、KubernetesがprovisioningしたService用のELBやPersistentVolume用のEBSはBOSH管理外なので、kubectl
コマンドで事前に削除してください。
bosh -d cfcr delete-deployment
bosh -n clean-up --all
BOSH Directorの削除
BOSH Directorを次のコマンドで削除します。
eval "$(sed 's/create-env/delete-env/' deploy-bosh.sh)"
AWS環境の削除
AWS環境を次のコマンドで削除します。
terraform destroy
Pivotal Container Serviceについて
CFCRを使えばBOSHを用いてKubernetesを簡単にデプロイでき、スケールアウト、アップデート、自動復旧も容易です。 CFCRはOSSですが、これのエンタープライズ版に相当するのがPivotal Container Service(PKS)です。
PKSでは、Kubernetesクラスタを一つ一つ手でインストールするのではなく、PKS ControllerというAPIサーバーがこの記事の内容を実行してKubernetesクラスタを作成してくれます。
PKSユーザーは
pks create-cluster my-k8s --external-hostname my-k8s.example.com --plan small --num-nodes 3
というコマンドを実行すれば、クラスタが作成されます。
次の図のようになります。
CFCRのKubernetesクラスタをオンデマンドで作成するのがPKSです。
あとはCNI実装としてのNSX-T連携やHabor Docker Registry連携などもあります。 1.0ではIaaSとしてvSphereとGCPのみサポートされていますが、他のIaaSも順次対応予定です。
このブログでも今後PKSのインストールについて扱いたいと思います。