--- title: Cloud Foundry Container Runtime 0.16.0 (Kubernetes on BOSH)をBOSH-wayでAWSにデプロイ tags: ["Kubo", "BOSH", "Kubernetes", "AWS", "CFCR", "PKS"] categories: ["Dev", "CaaS", "Kubernetes", "CFCR"] date: 2018-05-22T14:29:11Z updated: 2018-05-31T18:46:00Z --- **[追記]** * **0.16.0から0.17.0にアップデートする方法**は[こちら](https://blog.ik.am/entries/452) * 0.17.0で新規インストールする方法は[こちら](https://blog.ik.am/entries/453) **目次** [Cloud Foundry Container Runtime](https://docs-cfcr.cfapps.io/)(CFCR)を使ってKubernetesを[BOSH](https://bosh.io)でAWSにデプロイします。 CFCRはかつてKubo(Kubernetes on BOSH)と言われていましたが、renameされました。 [Kubo 0.8.0の時](https://blog.ik.am/entries/436)にもメモを書いていたのですが、あまりにも古いので一旦環境作り直しです。 この記事で一度環境を作れば、今後は(Breaking Changeがない限り)簡単にバージョンアップに追従できるはずです。 ### CFCRのdeploy [Official Document](https://docs-cfcr.cfapps.io/installing/)のインストール方法は手作業が混じっているのとBOSHの操作を隠蔽してしまっており、BOSHユーザーには扱いづらい内容になっているので、 素直なBOSH wayでデプロイできるようにカスタマイズしました。またTerraformテンプレートも[オフィシャルのもの](https://github.com/cloudfoundry-incubator/kubo-deployment/tree/master/docs/terraform/aws)に加えてドキュメントの手作業部分も追加しました。 #### TerraformでAWS環境をPaving まずはBOSHおよびKuberneteに必要なAWS環境をPaving(舗装)します。ここでは[Terraform](https://www.terraform.io/)を使います。 [カスタマイズ済みTerraformテンプレート](https://github.com/making/cfcr-aws)を取得してください。 ```bash git clone https://github.com/making/cfcr-aws.git cd cfcr-aws/terraform ``` `terraform.tfvars`に変数を定義します。`access_key`と`secret_key`はTerraform実行用のIAMユーザーで`AdministratorAccess` Roleを持ったものを設定してください。 ```bash cat < 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 ``` 次の図のような環境ができました。 ![image](https://user-images.githubusercontent.com/106908/40372551-eb314806-5e1f-11e8-97df-d665b321c33a.png) #### Bastionサーバーへlogin 次に舗装された環境上でBOSHのプロビジョングを行いますが、作業はBastion(踏み台)サーバー上で行います。 ```bash 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ログインしてください。 ```bash ./ssh-bastion.sh ``` #### BOSHのprovisioning BOSH(BOSH Director)を[bosh-deployment](https://github.com/cloudfoundry/bosh-deployment)を使ってProvisioningします。 合わせて[kubo-deployment](https://github.com/cloudfoundry-incubator/kubo-deployment)も取得し、一旦Git管理します。 ```bash 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.16.0 cd .. git add -A git commit -m "import CFCR v0.16.0" ``` YAMLの差分ファイル(ops-file)は`ops-files`ディレクトリで管理します。 ```bash mkdir -p ops-files ``` BOSH DirectorのVMサイズを小さめの`t2.small`にするops-fileを作成します。 ```yaml cat < 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サーバーに設定済みです。 ```bash 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を作成してください。 ```bash ./deploy-bosh.sh ``` 次の図のような環境ができました。 ![image](https://user-images.githubusercontent.com/106908/40372434-a36b332e-5e1f-11e8-90e0-7ea768bb2b2f.png) BOSH Directorをアップデートしたい場合は`bosh-deployment`を`git pull`して`./deploy-bosh.sh`を再実行すれば良いです。 #### BOSH Directorの設定 BOSH Directorにアクセスするための設定を行い、BOSH Directorにログインします。 ```bash 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 ``` 次のコマンドを実行してください。 ```bash 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のもの](https://github.com/cloudfoundry-incubator/kubo-deployment/blob/v0.16.0/configurations/aws/cloud-config.yml)を使いますが、`vm_type`名がなぜか[`cfcr.yml`](https://github.com/cloudfoundry-incubator/kubo-deployment/blob/v0.16.0/manifests/cfcr.yml)で使われている値と違うため、renameするためのops-fileを作成します... ```yaml cat < 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`を小さくします。 ```yaml cat < 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`を作成します。 ```yaml cat < 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するためのスクリプトを作成します。 ```bash 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 ``` 次のコマンドを実行してください。 ```bash ./update-cloud-config.sh ``` #### Kubernetesクラスタのデプロイ Kubernetesのデプロイは[OfficialのManifest](https://github.com/cloudfoundry-incubator/kubo-deployment/blob/v0.16.0/manifests)をベースに差分をops-fileで適用する形で行います。 CFCR 0.16.0を使うops-fileを作成します。 ```yaml cat < ops-files/kubernetes-kubo-0.16.0.yml - type: replace path: /releases/name=kubo? value: name: kubo version: 0.16.0 url: https://bosh.io/d/github.com/cloudfoundry-incubator/kubo-release?v=0.16.0 sha1: 8a513e48cccdea224c17a92ce73edbda04acee91 EOF ``` Workerのインスタンス数を1に減らすops-fileを作成します。(Workerを増やしたい場合はこの値を変えてください) ```yaml cat < 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を作成します。 ```yaml cat < 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`ディレクトリ以下で管理します。 ```bash mkdir -p specs ``` EBS用のStorageClassをデフォルトとして登録するSpecを作成します。 ```yaml cat < 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をデプロイするスクリプトを作成します。 ```bash 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.16.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`を入力する必要があります。) ```bash ./deploy-kubernetes.sh ``` 次の図のような環境ができました。 ![image](https://user-images.githubusercontent.com/106908/40374599-59ebcdb2-5e24-11e8-8631-af8ef0c5f39d.png) `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でデプロイされます。次のコマンドを実行してください。 ```bash bosh -d cfcr run-errand apply-addons ``` #### CredHubへのログイン Kubernetesクラスタに関するCredentials情報はBOSH Director VM内のCredHubに保存されています。 TLS証明書やAdminのパスワードを取得するにはCredHubにアクセスする必要があります。 CredHubにログインするためのスクリプトを作成します。 ```bash 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にログインしてください。 ```bash ./credhub-login.sh ``` CredHubへのアクセストークンは1時間で切れるので、有効期限が切れたら再度ログインしてください。 #### Kubernetesへアクセス AdminのパスワードをCredHubから取得します。 ```bash admin_password=$(credhub get -n /bosh-aws/cfcr/kubo-admin-password | bosh int - --path=/value) ``` Master APIのTLS CA証明書を取得します。 ```bash tmp_ca_file="$(mktemp)" credhub get -n /bosh-aws/cfcr/tls-kubernetes | bosh int - --path=/value/ca > "${tmp_ca_file}" ``` `kubectl`のContextを設定します。 ```bash 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インスタンスは次の通りです。 ![image](https://user-images.githubusercontent.com/106908/40376301-f97e7fa6-5e28-11e8-99cf-e40fd3a309ff.png) #### CFCR 0.16.0での制約事項 CFCR 0.16.0では * Multi-AZ対応 * MasterのHA対応 がサポートされていません。次の0.17.0でサポートされる予定です。 ### CFCRのdestroy 使い終わった環境は削除します。 #### Kubernetesクラスタの削除 Kubernetesを次のコマンド削除します。 なお、KubernetesがprovisioningしたService用のELBやPersistentVolume用のEBSはBOSH管理外なので、`kubectl`コマンドで事前に削除してください。 ```bash bosh -d cfcr delete-deployment bosh -n clean-up --all ``` #### BOSH Directorの削除 BOSH Directorを次のコマンドで削除します。 ```bash eval "$(sed 's/create-env/delete-env/' deploy-bosh.sh)" ``` #### AWS環境の削除 AWS環境を次のコマンドで削除します。 ```bash terraform destroy ``` ### Pivotal Container Serviceについて CFCRを使えばBOSHを用いてKubernetesを簡単にデプロイでき、スケールアウト、アップデート、自動復旧も容易です。 CFCRはOSSですが、これのエンタープライズ版に相当するのが[Pivotal Container Service(PKS)](https://pivotal.io/platform/pivotal-container-service)です。 PKSでは、Kubernetesクラスタを一つ一つ手でインストールするのではなく、PKS ControllerというAPIサーバーがこの記事の内容を実行してKubernetesクラスタを作成してくれます。 PKSユーザーは ``` pks create-cluster my-k8s --external-hostname my-k8s.example.com --plan small --num-nodes 3 ``` というコマンドを実行すれば、クラスタが作成されます。 次の図のようになります。 ![image](https://user-images.githubusercontent.com/106908/40376882-7350c66c-5e2a-11e8-81bb-a1f4209e078b.png) CFCRのKubernetesクラスタをオンデマンドで作成するのがPKSです。 あとはCNI実装としての[NSX-T](https://docs.vmware.com/jp/VMware-NSX-T/index.html)連携や[Habor](https://vmware.github.io/harbor/) Docker Registry連携などもあります。 1.0ではIaaSとしてvSphereとGCPのみサポートされていますが、他のIaaSも順次対応予定です。 このブログでも今後PKSのインストールについて扱いたいと思います。 興味のある方は[ドキュメント](https://docs.pivotal.io/runtimes/pks/)を参照しつつ、[@making](https://twitter.com/making)にも声をかけてみてください。