📝 BLOG.IK.AM

@making's memo
(🗃 Categories 🏷 Tags)

Cloud Foundry Container Runtime 0.17.0 (Kubernetes on BOSH)をBOSH-wayでAWSにデプロイ

🗃 {Dev/CaaS/Kubernetes/CFCR}

🏷 AWS 🏷 BOSH 🏷 CFCR 🏷 Kubernetes 🏷 Kubo 🏷 PKS

🗓 Updated at 2018-07-08T00:23:23+09:00 by Toshiaki Maki  🗓 Created at 2018-06-01T03:44:02+09:00 by Toshiaki Maki  {✒️️ Edit  ⏰ History}


ℹ️ 本記事の作成方法は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_keysecret_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

次の図のような環境ができました。

image

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 [email protected]${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

次の図のような環境ができました。

image

BOSH Directorをアップデートしたい場合はbosh-deploymentgit 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 envbosh 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

次の図のような環境ができました。

image

bosh vmsbosh 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-deploymentgit 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インスタンスは次の通りです。

image

クラスタのスケールアウト

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コンソールは次のようになります。

image

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

というコマンドを実行すれば、クラスタが作成されます。

次の図のようになります。

image

CFCRのKubernetesクラスタをオンデマンドで作成するのがPKSです。

あとはCNI実装としてのNSX-T連携やHabor Docker Registry連携などもあります。
1.0ではIaaSとしてvSphereとGCPのみサポートされていますが、他のIaaSも順次対応予定です。

このブログでも今後PKSのインストールについて扱いたいと思います。

興味のある方はドキュメントを参照しつつ、@makingにも声をかけてみてください。