--- title: Pivotal Container Service (PKS) 1.3をCLIでAzureにインストールするメモ tags: ["Kubernetes", "PKS", "Azure", "BOSH", "CFCR"] categories: ["Dev", "CaaS", "Kubernetes", "PKS", "Azure"] date: 2019-01-17T18:44:31Z updated: 2019-01-17T19:08:32Z --- [PKS 1.3](https://docs.pivotal.io/runtimes/pks/1-3/)をAzureインストールするメモです。 PKSはクラウド非依存のGKEとかAKSみたいなソフトウェアで、k8s自体をインストールする以上の話になります。 なので、本記事でk8sクラスタ作成までちょっと作業が多いです。単純にGKEやAKSのクラスタ作成と比較するのはフェアではないです。 この記事では環境作成をCIで自動化するための事前作業としてCLIで手作業した内容のメモです。 PKSを初めて使う場合はGUI(Web UI)で操作することが多いので、この記事はAdvancedな内容です。 公式なインストール手順は[こちら](https://docs.pivotal.io/runtimes/pks/1-3/azure-index.html)です。 **目次** ### CLIのインストール 各種CLIをインストールします。 `om`はPKSをインストールするGUIであるOpsManagerをCLIで操作するためのツールです。 `pivnet`はPKSやテンプレートVMのStemcellをCLIでダウンロードするためのツールです。 `az-automation`はTerraform用のAzureアカウントを作成するツールです。 ``` brew tap starkandwayne/cf brew install om brew tap pivotal/tap brew install pivnet-cli brew tap genevieve/tap brew install azure-cli brew install az-automation ``` ``` $ om --version 0.50.0 $ pivnet --version 0.0.55 $ az --version azure-cli (2.0.54) ``` ### TerraformでAzureの環境作成 `az login`済みの前提です。 Terraformのtemplateを取得します。この記事の内容は[`c4c5a3170f0f7da06535c2523e98fe4a98fad8c4`](https://github.com/pivotal-cf/terraforming-azure/tree/c4c5a3170f0f7da06535c2523e98fe4a98fad8c4)で試しました。 ``` git clone https://github.com/pivotal-cf/terraforming-azure.git ``` `az-automation`でアカウント作成します。引数は適当に変えてください。 ``` az-automation \ --account xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \ --identifier-uri http://tf.maki \ --display-name tf-maki \ --credential-output-file creds.vars ``` `creds.vars`にアカウント情報が出力されます。 `terraform.tfvars`を作成します。 `ops_manager_image_uri`は[Pivotal Network](https://network.pivotal.io/products/ops-manager)の`Pivotal Cloud Foundry Ops Manager for Azure`から取得可能です。2.4の最新版のイメージを取得するのがオススメです。 `terraform.tfvars`を作成します`env_name`、`env_short_name`(`-`を含めてはいけない)、`dns_suffix`、`location`は好きなように変更してください。 ``` sed -e 's/= /= "/g' -e 's/$/"/g' creds.vars > terraform.tfvars cat <> terraform.tfvars env_name = "pks" env_short_name = "pks" location = "Japan East" ops_manager_image_uri = "https://opsmanagersoutheastasia.blob.core.windows.net/images/ops-manager-2.4-build.131.vhd" dns_suffix = "ik.am" vm_admin_username = "admin" EOF ``` > 執筆時点ではAKSはJapan Westで利用できませんが、PKSはJapan Westにもインストール可能です。 用意されているTerraformのテンプレートのnetwork security groupが少し都合が悪いので、ポートを変更します。 ``` sed -i.bak \ -e 's/mysql-healthcheck/pks-api/g' \ -e 's/destination_port_range = 1936/destination_port_range = 9021/g' \ -e 's/diego-ssh/uaa/g' \ -e 's/destination_port_range = 2222/destination_port_range = 8443/g' \ terraforming-azure/modules/infra/main.tf ``` terraformを実行します。 ``` terraform init \ terraforming-azure/terraforming-pks terraform plan \ -out=plan \ terraforming-azure/terraforming-pks terraform apply "plan" ``` しばらくするとPKSをインストールするために必要な諸々のリソースが作成されます。 ![image](https://user-images.githubusercontent.com/106908/51164040-0c05ef80-18df-11e9-9331-2e9d29ae17af.png) 以下をDNSのAレコードに登録します。 OpsManager * hostname `terraform output -json | jq -r .ops_manager_dns.value` * public-ip `terraform output -json | jq -r .ops_manager_ip.value` PKS API * hostname `terraform output -json | jq -r .ops_manager_dns.value | sed 's/pcf/pks/g'` * public-ip `cat terraform.tfstate | jq -r '.modules[] | select(.path[1] == "pks") | .resources["azurerm_public_ip.pks-lb-ip"].primary.attributes.ip_address'` DNSが使えない場合はIPアドレスを使っても良いですが、この記事はDNS名前提になっているので読み替えが必要です。 DNSに登録した場合は`https://pcf.(env_name).(dns_suffix)`でOpsManagerにアクセスできます。DNSを使わない場合は`terraform output -json | jq -r .ops_manager_ip.value`のIPアドレスに直接アクセスしてください。 ![image](https://user-images.githubusercontent.com/106908/51163977-e11b9b80-18de-11e9-9a1c-3b98217823f3.png) 全てCLIで設定するのでブラウザでは操作しないでください。 ### OpsManagerの設定 `om`コマンドでOpsManagerの初期設定を行います。 管理者ユーザーを作成します。usernameやpasswordは適当に変更してください。 ``` export OM_USERNAME=admin export OM_PASSWORD=pkssword export OM_DECRYPTION_PASSPHRASE=pkssword export OM_TARGET=https://`terraform output -json | jq -r .ops_manager_dns.value` export OM_SKIP_SSL_VALIDATION=true om configure-authentication \ --username $OM_USERNAME \ --password $OM_PASSWORD \ --decryption-passphrase $OM_DECRYPTION_PASSPHRASE ``` ``` configuring internal userstore... waiting for configuration to complete... configuration complete ``` OpsManagerにアクセスするとログイン画面が表示されます。 ![image](https://user-images.githubusercontent.com/106908/51165638-47ef8380-18e4-11e9-876c-c651ce1615f6.png) 管理者ユーザーでログインできます。 ![image](https://user-images.githubusercontent.com/106908/51165671-648bbb80-18e4-11e9-87fa-b8c8ef284ff7.png) OpsManagerはデフォルトで自己署名のTLS証明書が使われています。自前の証明書(Let's encryptで取得したもの等)を使う場合は次のコマンドで設定できます。 この作業はオプションです。 ``` om update-ssl-certificate \ --certificate-pem="$(cat ~/path-to-letsencrypt/fullchain.pem)" \ --private-key-pem="$(cat ~/path-to-letsencrypt/privkey.pem)" ``` ``` Successfully applied custom SSL Certificate. Please allow about 1 min for the new certificate to take effect. ``` ![image](https://user-images.githubusercontent.com/106908/51166256-35764980-18e6-11e9-8699-b2748a726676.png) ### BOSH Directorの設定 PKSのControl Plane (API Server)やKubernetesのインストール、アップデート、死活監視、自動復旧を担うBOSH Directorをインストールするための設定を行います。 必要な情報はterraformのoutputに含まれているので、terraformのoutputからBOSH Directorを設定するためのYAMLを生成します。 ```yaml export SUBSCRIPTION_ID=$(terraform output -json | jq -r '.subscription_id.value') export TENANT_ID=$(terraform output -json | jq -r '.tenant_id.value') export CLIENT_ID=$(terraform output -json | jq -r '.client_id.value') export CLIENT_SECRET=$(terraform output -json | jq -r '.client_secret.value') export RESOURCE_GROUP_NAME=$(terraform output -json | jq -r '.pcf_resource_group_name.value') export BOSH_STORAGE_ACCOUNT_NAME=$(terraform output -json | jq -r '.bosh_root_storage_account.value') export DEPLOYMENTS_STORAGE_ACCOUNT_NAME=$(terraform output -json | jq -r '.wildcard_vm_storage_account.value') export DEFAULT_SECURITY_GROUP=$(terraform output -json | jq -r '.bosh_deployed_vms_security_group_name.value') export OPS_MANAGER_SSH_PUBLIC_KEY=$(terraform output -json | jq -r '.ops_manager_ssh_public_key.value' | sed 's/^/ /') export OPS_MANAGER_SSH_PRIVATE_KEY=$(terraform output -json | jq -r '.ops_manager_ssh_private_key.value' | sed 's/^/ /') export NETWORK_NAME=$(terraform output -json | jq -r '.network_name.value') export MANAGEMENT_SUBNET_NAME=$(terraform output -json | jq -r '.management_subnet_name.value') export MANAGEMENT_SUBNET_CIDRS=$(terraform output -json | jq -r '.management_subnet_cidrs.value[0]') export MANAGEMENT_SUBNET_GATEWAY=$(terraform output -json | jq -r '.management_subnet_gateway.value') export MANAGEMENT_RESERVED_IP_RANGES="$(echo $MANAGEMENT_SUBNET_CIDRS | sed 's|0/26$|1|g')-$(echo $MANAGEMENT_SUBNET_CIDRS | sed 's|0/26$|9|g')" export PKS_SUBNET_NAME=$(terraform output -json | jq -r '.pks_subnet_name.value') export PKS_SUBNET_CIDRS=$(terraform output -json | jq -r '.pks_subnet_cidrs.value[0]') export PKS_SUBNET_GATEWAY=$(terraform output -json | jq -r '.pks_subnet_gateway.value') export PKS_RESERVED_IP_RANGES="$(echo $PKS_SUBNET_CIDRS | sed 's|0/22$|1|g')-$(echo $PKS_SUBNET_CIDRS | sed 's|0/22$|9|g')" export SERVICES_SUBNET_NAME=$(terraform output -json | jq -r '.services_subnet_name.value') export SERVICES_SUBNET_CIDRS=$(terraform output -json | jq -r '.services_subnet_cidrs.value[0]') export SERVICES_SUBNET_GATEWAY=$(terraform output -json | jq -r '.services_subnet_gateway.value') export SERVICES_RESERVED_IP_RANGES="$(echo $SERVICES_SUBNET_CIDRS | sed 's|0/22$|1|g')-$(echo $SERVICES_SUBNET_CIDRS | sed 's|0/22$|9|g')" export OPS_MGR_TRUSTED_CERTS="" cat < config.yml networks-configuration: icmp_checks_enabled: false networks: - name: pks-infrastructure-network subnets: - iaas_identifier: $NETWORK_NAME/$MANAGEMENT_SUBNET_NAME cidr: $MANAGEMENT_SUBNET_CIDRS reserved_ip_ranges: $MANAGEMENT_RESERVED_IP_RANGES dns: "168.63.129.16" gateway: $MANAGEMENT_SUBNET_GATEWAY - name: pks-network subnets: - iaas_identifier: $NETWORK_NAME/$PKS_SUBNET_NAME cidr: $PKS_SUBNET_CIDRS reserved_ip_ranges: $PKS_RESERVED_IP_RANGES dns: "168.63.129.16" gateway: $PKS_SUBNET_GATEWAY - name: pks-services-network subnets: - iaas_identifier: $NETWORK_NAME/$SERVICES_SUBNET_NAME cidr: $SERVICES_SUBNET_CIDRS reserved_ip_ranges: $SERVICES_RESERVED_IP_RANGES dns: "168.63.129.16" gateway: $SERVICES_SUBNET_GATEWAY network-assignment: network: name: pks-infrastructure-network properties-configuration: iaas_configuration: subscription_id: $SUBSCRIPTION_ID tenant_id: $TENANT_ID client_id: $CLIENT_ID client_secret: $CLIENT_SECRET resource_group_name: $RESOURCE_GROUP_NAME bosh_storage_account_name: $BOSH_STORAGE_ACCOUNT_NAME cloud_storage_type: storage_accounts cloud_storage_type: managed_disks storage_account_type: Standard_LRS default_security_group: $DEFAULT_SECURITY_GROUP ssh_public_key: | $OPS_MANAGER_SSH_PUBLIC_KEY ssh_private_key: | $OPS_MANAGER_SSH_PRIVATE_KEY environment: AzureCloud director_configuration: ntp_servers_string: "0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org" resurrector_enabled: true post_deploy_enabled: true database_type: internal blobstore_type: local security_configuration: trusted_certificates: "$OPS_MGR_TRUSTED_CERTS" vm_password_type: generate syslog_configuration: {} resource-configuration: director: instance_type: id: automatic compilation: instance_type: id: automatic EOF ``` `om` CLIでこのYAMLを設定します。 ``` om configure-director \ --config config.yml ``` ``` started configuring director options for bosh tile finished configuring director options for bosh tile started configuring network options for bosh tile finished configuring network options for bosh tile started configuring network assignment options for bosh tile finished configuring network assignment options for bosh tile started configuring resource options for bosh tile applying resource configuration for the following jobs: compilation director finished configuring resource options for bosh tile ``` ![image](https://user-images.githubusercontent.com/106908/51167740-a3247480-18ea-11e9-9aaa-db9147117703.png) オレンジ色だった箇所が緑色になれば設定完了です。 ### AzureのManaged Identities作成 KubernetesのMaster, WorkerがAzureを操作する権限を制限するためにManaged Indentiesを作成します。 なぜかTerraformのテンプレートに含まれていないので、`az`コマンドで作成します。 Master用 ``` cat < pks_master_role.json { "Name": "PKS master", "IsCustom": true, "Description": "Permissions for PKS master", "Actions": [ "Microsoft.Network/*", "Microsoft.Compute/disks/*", "Microsoft.Compute/virtualMachines/write", "Microsoft.Compute/virtualMachines/read", "Microsoft.Storage/storageAccounts/*" ], "NotActions": [ ], "DataActions": [ ], "NotDataActions": [ ], "AssignableScopes": [ "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP_NAME}" ] } EOF az role definition create --role-definition pks_master_role.json az identity create -g ${RESOURCE_GROUP_NAME} -n pks-master az role assignment create \ -g ${RESOURCE_GROUP_NAME} \ --role "PKS master" \ --assignee-object-id `az identity list -g ${RESOURCE_GROUP_NAME} | jq -r '.[] | select(.name == "pks-master") | .principalId'` ``` > Managed Identity名が重複していたら`Name`を変更してください。企業アカウントを使っている場合は、重複する可能性があります。 Worker用 ``` cat < pks_worker_role.json { "Name": "PKS worker", "IsCustom": true, "Description": "Permissions for PKS worker", "Actions": [ "Microsoft.Storage/storageAccounts/*" ], "NotActions": [ ], "DataActions": [ ], "NotDataActions": [ ], "AssignableScopes": [ "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP_NAME}" ] } EOF az role definition create --role-definition pks_worker_role.json az identity create -g ${RESOURCE_GROUP_NAME} -n pks-worker az role assignment create \ -g ${RESOURCE_GROUP_NAME} \ --role "PKS worker" \ --assignee-object-id `az identity list -g ${RESOURCE_GROUP_NAME} | jq -r '.[] | select(.name == "pks-worker") | .principalId'` ``` ### PKSの設定 まずはPKSを[Pivotal Network](https://network.pivotal.io/products/pivotal-container-service)からダウンロードします。 PIVNET_TOKENはPivotal Networkの[Profileページ](https://network.pivotal.io/users/dashboard/edit-profile)から取得できます。 ``` PIVNET_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pivnet login --api-token=${PIVNET_TOKEN} ``` ``` Logged-in successfully ``` `pivnet` CLIでダウンロードします。ダウンロードしたいバージョンは`-r`で指定します。 `pivnet product-files`でダウンロード対象のファイル群を確認できます。 ``` pivnet product-files -p pivotal-container-service -r 1.3.0 ``` ``` +--------+---------------------------+----------------+---------------------+------------------------------------------------------------------+------------------------------------------------------------------------------------------+ | ID | NAME | FILE VERSION | FILE TYPE | SHA256 | AWS OBJECT KEY | +--------+---------------------------+----------------+---------------------+------------------------------------------------------------------+------------------------------------------------------------------------------------------+ | 292401 | PKS OSL 1.3.0 | 1.3.0 | Open Source License | | product-files/pivotal-container-service/PKS_OSL_1.3.0.txt | | 289735 | Pivotal Container Service | 1.3.0-build.38 | Software | 9bc9914b9e35014ba34d4a7bef91498f8ac76196fa78fa42ff71317a8657fc1b | product-files/pivotal-container-service/pivotal-container-service-1.3.0-build.38.pivotal | | 278453 | Kubectl 1.12.4 - Mac | 1.3.0-build.30 | Software | 4c76cb796344a10291157acc66fd3afc56f065663b15bf798b30a7a622731d16 | product-files/pivotal-container-service/kubectl-darwin-amd64-1.12.4 | | 278454 | Kubectl 1.12.4 - Linux | 1.3.0-build.30 | Software | 0258d3af3597a938fadc885268d11f8879baebd8ffe026d8ba416dab26d67e38 | product-files/pivotal-container-service/kubectl-linux-amd64-1.12.4 | | 278455 | Kubectl 1.12.4 - Windows | 1.3.0-build.30 | Software | 4eaadb13d9d84357e9820e05befb2df0a6fa8a8262cc8655daf42d43980056b1 | product-files/pivotal-container-service/kubectl-windows-amd64-1.12.4.exe | | 287865 | PKS CLI - Mac | 1.3.0-build.35 | Software | f015af7a359627a3b043e5f3ebfe0ba6bbfc576cc0beef57c77140949cc51e57 | product-files/pivotal-container-service/pks-darwin-amd64-1.3.0-build.126 | | 287866 | PKS CLI - Linux | 1.3.0-build.35 | Software | 5fc6e91d5df13fbdbaac1b4e574eac129386150b22a1b74e2952cdf17c6878da | product-files/pivotal-container-service/pks-linux-amd64-1.3.0-build.126 | | 287867 | PKS CLI - Windows | 1.3.0-build.35 | Software | a1dd279ab18082b01ad64ee07b4b6357ed574c675ce875475a4e0caf4f3cb290 | product-files/pivotal-container-service/pks-windows-amd64-1.3.0-build.126.exe | +--------+---------------------------+----------------+---------------------+------------------------------------------------------------------+------------------------------------------------------------------------------------------+ ``` `.pivotal`で終わるファイルがPKSの実体です。`pivnet donwload-product-files`コマンドでダウンロードできます。 ``` pivnet download-product-files -p pivotal-container-service -r 1.3.0 --glob=pivotal-container-service-*.pivotal --accept-eula ``` ``` 2019/01/17 12:51:55 Downloading 'pivotal-container-service-1.3.0-build.38.pivotal' to 'pivotal-container-service-1.3.0-build.38.pivotal' 4.01 GiB / 4.01 GiB [===========================================] 100.00% 6m41s 2019/01/17 12:58:37 Verifying SHA256 2019/01/17 12:58:52 Successfully verified SHA256 ``` ダウンロードしたファイルをOpsManagerにアップロードします。 ``` om upload-product -p ./pivotal-container-service-1.3.0-build.38.pivotal ``` ``` processing product beginning product upload to Ops Manager 4.01 GiB / 4.01 GiB [===========================================] 100.00% 6m50s 1m30s elapsed, waiting for response from Ops Manager... finished upload ``` アップロードされたプロダクトはOpsManagerの左側に表示されます。 ![image](https://user-images.githubusercontent.com/106908/51169218-afaacc00-18ee-11e9-9874-f3bb95de872b.png) アップロードされたプロダクトをステージングします。 ``` export FILENAME=`ls -t -n1 *.pivotal | awk 'NR==1 {print $1}'` export PRODUCT_NAME=`basename $FILENAME .pivotal | python -c 'print("-".join(raw_input().split("-")[:-2]))'` # pivotal-container-service export PRODUCT_VERSION=`basename $FILENAME .pivotal | python -c 'print("-".join(raw_input().split("-")[-2:]))'` # 1.3.0-build.35 om stage-product -p ${PRODUCT_NAME} -v ${PRODUCT_VERSION} ``` ``` staging pivotal-container-service 1.3.0-build.38 finished staging ``` PKSの設定画面が出ます。オレンジ色なので設定未完です。 ![image](https://user-images.githubusercontent.com/106908/51169525-7757bd80-18ef-11e9-8da1-698dc799134a.png) `Missing stemcell`と出ています。これはPKSが必要としているStemcell(Ubuntu VMのベースイメージ)のバージョンが用意されていないことを示します。 Stemcellは[Pivotal Network](https://network.pivotal.io/products/stemcells-ubuntu-xenial)からダウンロードできます。 ``` export STEMCELL_VERSION=`pivnet dependency-specifiers -p pivotal-container-service -r 1.3.0 --format=json | jq -r '.[] | select( .product.slug == "stemcells-ubuntu-xenial") | .specifier'` pivnet download-product-files -p stemcells-ubuntu-xenial -r ${STEMCELL_VERSION} --glob=*azure*.tgz --accept-eula ``` ``` 2019/01/15 18:10:23 Downloading 'bosh-stemcell-170.15-azure-hyperv-ubuntu-xenial-go_agent.tgz' to 'bosh-stemcell-170.15-azure-hyperv-ubuntu-xenial-go_agent.tgz' 499.69 MiB / 499.68 MiB [=========================================] 100.00% 59s 2019/01/15 18:11:29 Verifying SHA256 2019/01/15 18:11:33 Successfully verified SHA256 ``` `om` CLIでStemcellをOpsManagerにアップロードします。 ``` om upload-stemcell -s ./bosh-stemcell-*.tgz ``` ``` processing stemcell beginning stemcell upload to Ops Manager 499.68 MiB / 499.68 MiB [=========================================] 100.00% 58s 8s elapsed, waiting for response from Ops Manager... finished upload ``` `Missing stemcell`が消えます。 ![image](https://user-images.githubusercontent.com/106908/51170540-0cf44c80-18f2-11e9-8c45-5ca0730f6611.png) PKSを設定するためのYAMLファイルを生成します。 ```yaml # DNS名を使うことが前提 WILDCARD_DOMAIN=`terraform output -json | jq -r .ops_manager_dns.value | sed 's/pcf/*/g'` # PKS APIのTLS証明書を自己署名で作成する場合 CERTIFICATES=`om generate-certificate -d ${WILDCARD_DOMAIN}` export CERT_PEM=`echo $CERTIFICATES | jq -r '.certificate' | sed 's/^/ /'` export KEY_PEM=`echo $CERTIFICATES | jq -r '.key' | sed 's/^/ /'` # PKS APIのTLS証明書にLet's encrypt等を使う場合 # export CERT_PEM=`cat ~/path-to-letsencrypt/fullchain.pem | sed 's/^/ /'` # export KEY_PEM=`cat ~/path-to-letsencrypt/privkey.pem | sed 's/^/ /'` export API_HOSTNAME=`terraform output -json | jq -r .ops_manager_dns.value | sed 's/pcf/pks/g'` export VNET_NAME=`terraform output --json | jq -r '.network_name.value'` export PRIMARY_AVAILABILITY_SET=`echo ${VNET_NAME} | sed 's/-virtual-network/-pks-as/g'` export LOCATION=`grep location terraform.tfvars | sed -e 's/location = //g' -e 's/"//g' -e 's/ //g' | tr [:upper:] [:lower:]` export PKS_API_LB_NAME=`echo ${VNET_NAME} | sed 's/-virtual-network/-pks-lb/g'` cat < product.yml product-name: pivotal-container-service network-properties: network: name: pks-network other_availability_zones: - name: "null" service_network: name: pks-services-network singleton_availability_zone: name: "null" product-properties: .pivotal-container-service.pks_tls: value: cert_pem: | ${CERT_PEM} private_key_pem: | ${KEY_PEM} .properties.pks_api_hostname: value: ${API_HOSTNAME} .properties.plan1_selector: value: Plan Active .properties.plan1_selector.active.master_vm_type: value: Standard_F1s .properties.plan1_selector.active.master_instances: value: 1 .properties.plan1_selector.active.master_az_placement: value: - "null" .properties.plan1_selector.active.worker_vm_type: value: Standard_F2s .properties.plan1_selector.active.worker_instances: value: 1 .properties.plan1_selector.active.worker_az_placement: value: - "null" .properties.plan1_selector.active.allow_privileged_containers: value: true .properties.plan2_selector: value: Plan Active .properties.plan2_selector.active.master_vm_type: value: Standard_DS1_v2 .properties.plan2_selector.active.master_instances: value: 1 .properties.plan2_selector.active.master_az_placement: value: - "null" .properties.plan2_selector.active.worker_vm_type: value: Standard_DS2_v2 .properties.plan2_selector.active.worker_instances: value: 3 .properties.plan2_selector.active.worker_az_placement: value: - "null" .properties.plan2_selector.active.allow_privileged_containers: value: false .properties.plan3_selector: value: Plan Inactive .properties.telemetry_selector: value: disabled .properties.uaa_oidc: value: true .properties.cloud_provider: value: Azure .properties.cloud_provider.azure.subscription_id: value: ${SUBSCRIPTION_ID} .properties.cloud_provider.azure.location: value: ${LOCATION} .properties.cloud_provider.azure.tenant_id: value: ${TENANT_ID} .properties.cloud_provider.azure.resource_group_name: value: ${RESOURCE_GROUP_NAME} .properties.cloud_provider.azure.vnet_name: value: ${VNET_NAME} .properties.cloud_provider.azure.vnet_resource_group_name: value: ${RESOURCE_GROUP_NAME} .properties.cloud_provider.azure.default_security_group: value: ${DEFAULT_SECURITY_GROUP} .properties.cloud_provider.azure.primary_availability_set: value: ${PRIMARY_AVAILABILITY_SET} .properties.cloud_provider.azure.azure_master_managed_identity: value: pks-master .properties.cloud_provider.azure.azure_worker_managed_identity: value: pks-worker resource-config: pivotal-container-service: instances: automatic persistent_disk: size_mb: automatic instance_type: id: Standard_F2s internet_connected: false elb_names: - $PKS_API_LB_NAME errand-config: delete-all-clusters: pre-delete-state: true pks-nsx-t-precheck: post-deploy-state: false smoke-tests: post-deploy-state: false upgrade-all-service-instances: post-deploy-state: true wavefront-alert-creation: post-deploy-state: false wavefront-alert-deletion: pre-delete-state: false EOF ``` k8sクラスタを作るためのプランを3つまで作成できます。プランごとに、Master、WorkerのVM Type、インスタンス数、ディスクサイズを指定できます。 wokerのインスタンス数はk8sクラスタを作成するときに指定できますし、リサイズもできますが他の値はプラン毎に固定です。 好きな値を設定してください。 `om` CLIでYAMLを設定します。 ``` om configure-product \ --config product.yml ``` ``` configuring product... setting up network finished setting up network setting properties finished setting properties applying resource configuration for the following jobs: pivotal-container-service applying errand configuration for the following errands: delete-all-clusters pks-nsx-t-precheck smoke-tests upgrade-all-service-instances wavefront-alert-creation wavefront-alert-deletion finished configuring product ``` オレンジ色が緑色になれば設定完了です。 ![image](https://user-images.githubusercontent.com/106908/51178728-da088380-1906-11e9-8495-54dc67f74cf1.png) ### PKSのデプロイ 設定を適用してBOSH DirectorおよびPKSをインストールします。 ``` om apply-changes ``` ![image](https://user-images.githubusercontent.com/106908/51179095-f6f18680-1907-11e9-9efe-029b77d93ad8.png) 終わるまで待ちます。1時間くらいかかります... ![image](https://user-images.githubusercontent.com/106908/51191870-adfdfa00-1928-11e9-8cca-d9c87e9ccecd.png) ### k8sクラスタ作成 PKSがインストールできたらいよいよk8sクラスタを作成します。 PKSでは`pks` CLIでk8sクラスタを作成可能です。 `pks` CLIは[Pivotal Network](https://network.pivotal.io/products/pivotal-container-service)からダウンロードできます。 ``` pivnet download-product-files -p pivotal-container-service -r 1.3.0 --glob=pks-darwin-* --accept-eula ``` ``` 2019/01/15 17:36:16 Downloading 'pks-darwin-amd64-1.3.0-build.126' to 'pks-darwin-amd64-1.3.0-build.126' 27.99 MiB / 27.97 MiB [===========================================] 100.07% 25s 2019/01/15 17:36:47 Verifying SHA256 2019/01/15 17:36:48 Successfully verified SHA256 ``` `PATH`の通ったディレクトリにインストールしてください。 ``` install pks-darwin-amd64-* /usr/local/bin/pks ``` adminユーザーでログインします。 ``` export UAA_ADMIN_PASSWORD=`om credentials -p pivotal-container-service -c .properties.uaa_admin_password -t json | jq -r .secret` pks login -k -a ${API_HOSTNAME} -u admin -p ${UAA_ADMIN_PASSWORD} ``` k8sクラスタを作成する際にmasterのDNS名を事前に指定する必要があります。multi masterの場合はLBを作成して、そのDNS名かIPアドレスが必要です。 single masterの場合はpublic ipでも良いです。今回はsingle masterを前提として、Azureのpublic ipをDNS名付きで作成します。 DNS名は次のように作成および取得可能です。`CLUSTER_NAME`には好きな値を入れてください。 ``` CLUSTER_NAME=demo az network public-ip create -g ${RESOURCE_GROUP_NAME} --allocation-method Static -n ${CLUSTER_NAME} --dns-name ${CLUSTER_NAME}-pks HOSTNAME=`az network public-ip show -g ${RESOURCE_GROUP_NAME} -n ${CLUSTER_NAME} | jq -r .dnsSettings.fqdn` ``` `pks create-cluster`コマンドでk8sを作成します。`-p`でプランを指定できます。 ``` pks create-cluster ${CLUSTER_NAME} -e ${HOSTNAME} -p small --wait ``` 作成完了まで待ちます。Azureの場合は40分くらいかかります(泣) 最後に、PKSの一番ダメだと思う点なのですが、作成されたMasterにLBまたはIPをマッピングします。 PKS 1.3時点ではMaster用のLBが自動で設定されるのはvSphere + NSX-Tの環境のみです(泣)。[Feature Support by IaaS](https://docs.pivotal.io/runtimes/pks/1-3/release-notes.html#v1.3.0-iaas)の`Automatic Kubernetes Cluster API load balancer`を参照。 ここでは`pks` CLIと`az` CLIを組み合わせて先ほど払い出したIPアドレスをMaster VMにマッピングします。 ``` az network nic ip-config update \ -n ipconfig0 \ -g ${RESOURCE_GROUP_NAME} \ --public-ip-address ${CLUSTER_NAME} \ --nic-name $(az network nic list -g ${RESOURCE_GROUP_NAME} | jq -r ".[] | select(.ipConfigurations[0].privateIpAddress == $(pks cluster ${CLUSTER_NAME} --json | jq '.kubernetes_master_ips[0]')).name") ``` > ちなみにBOSHがMasterをrecreateした場合には手動でattachしたIP/LBはdettachされるため、再設定が必要です(泣泣) `~/.kube/config`を取得します。 ``` pks get-credentials ${CLUSTER_NAME} ``` `pks login`で使用したパスワードの再入力が求められます。 これで`kubectl`で作成したk8sクラスタにアクセス可能です。 ``` $ kubectl cluster-info Kubernetes master is running at https://tmaki-pks.japaneast.cloudapp.azure.com:8443 Heapster is running at https://tmaki-pks.japaneast.cloudapp.azure.com:8443/api/v1/namespaces/kube-system/services/heapster/proxy KubeDNS is running at https://tmaki-pks.japaneast.cloudapp.azure.com:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy kubernetes-dashboard is running at https://tmaki-pks.japaneast.cloudapp.azure.com:8443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy monitoring-influxdb is running at https://tmaki-pks.japaneast.cloudapp.azure.com:8443/api/v1/namespaces/kube-system/services/monitoring-influxdb/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. ``` ``` $ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME b1be3863-d0ee-45ed-a2c5-72135bb3db10 Ready 39m v1.12.4 10.0.16.11 Ubuntu 16.04.5 LTS 4.15.0-42-generic docker://18.6.1 ``` ``` $ kubectl get pod -o wide --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE kube-system heapster-85647cf566-shcfs 1/1 Running 0 34m 10.200.45.4 b1be3863-d0ee-45ed-a2c5-72135bb3db10 kube-system kube-dns-7559c96fc4-9s85s 3/3 Running 0 35m 10.200.45.2 b1be3863-d0ee-45ed-a2c5-72135bb3db10 kube-system kubernetes-dashboard-5f4b59b97f-nklmc 1/1 Running 0 34m 10.200.45.6 b1be3863-d0ee-45ed-a2c5-72135bb3db10 kube-system metrics-server-555d98886f-v8kms 1/1 Running 0 34m 10.200.45.3 b1be3863-d0ee-45ed-a2c5-72135bb3db10 kube-system monitoring-influxdb-cdcf4674-s9wg6 1/1 Running 0 34m 10.200.45.5 b1be3863-d0ee-45ed-a2c5-72135bb3db10 pks-system cert-generator-v0.11-cs8jt 0/1 Completed 0 34m 10.200.45.7 b1be3863-d0ee-45ed-a2c5-72135bb3db10 pks-system event-controller-6c77ddd949-wfl4d 2/2 Running 1 34m 10.200.45.10 b1be3863-d0ee-45ed-a2c5-72135bb3db10 pks-system fluent-bit-c7k5d 2/2 Running 0 34m 10.200.45.9 b1be3863-d0ee-45ed-a2c5-72135bb3db10 pks-system sink-controller-65595c498b-h72gr 1/1 Running 0 34m 10.200.45.8 b1be3863-d0ee-45ed-a2c5-72135bb3db10 pks-system telemetry-agent-559f9c8855-m6r8x 1/1 Running 0 28m 10.200.45.11 b1be3863-d0ee-45ed-a2c5-72135bb3db10 ``` Workerを3インスタンスにスケールアウトしてみます。 ``` pks resize ${CLUSTER_NAME} -n 3 --wait ``` ``` $ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME 6440e98f-f294-40fa-ba10-a902c6abb708 Ready 103m v1.12.4 10.0.16.13 Ubuntu 16.04.5 LTS 4.15.0-42-generic docker://18.6.1 a0d95747-ab5c-4f8d-9534-3bb750631602 Ready 98m v1.12.4 10.0.16.14 Ubuntu 16.04.5 LTS 4.15.0-42-generic docker://18.6.1 b1be3863-d0ee-45ed-a2c5-72135bb3db10 Ready 150m v1.12.4 10.0.16.11 Ubuntu 16.04.5 LTS 4.15.0-42-generic docker://18.6.1 ``` ### サンプルアプリのデプロイ [AKSのチュートリアル](https://docs.microsoft.com/azure/aks/tutorial-kubernetes-deploy-application)アプリをデプロイしてみます。 ``` git clone https://github.com/Azure-Samples/azure-voting-app-redis.git cd azure-voting-app-redis kubectl apply -f azure-vote-all-in-one-redis.yaml ``` ``` $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE azure-vote-back-746d4bc54b-vnngg 1/1 Running 0 3m4s 10.200.54.3 a0d95747-ab5c-4f8d-9534-3bb750631602 azure-vote-front-f747b5d4b-8t9qk 1/1 Running 0 3m4s 10.200.79.4 6440e98f-f294-40fa-ba10-a902c6abb708 ``` ロードバランサは作成しされるまでしばらく時間がかかります。`EXTERNAL-IP`に値が表示されればOKです。 ``` $ kubectl get service azure-vote-front -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR azure-vote-front LoadBalancer 10.100.200.210 40.81.221.230 80:30527/TCP 2m42s app=azure-vote-front ``` ![image](https://user-images.githubusercontent.com/106908/51314776-f4bc3300-1a93-11e9-9123-da37c37d1017.png) frontを5ポッドにスケールアウトします。 ``` kubectl scale --replicas=5 deployment/azure-vote-front ``` ``` $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE azure-vote-back-746d4bc54b-vnngg 1/1 Running 0 7m54s 10.200.54.3 a0d95747-ab5c-4f8d-9534-3bb750631602 azure-vote-front-f747b5d4b-6rzgc 1/1 Running 0 2m45s 10.200.54.4 a0d95747-ab5c-4f8d-9534-3bb750631602 azure-vote-front-f747b5d4b-8t9qk 1/1 Running 0 7m54s 10.200.79.4 6440e98f-f294-40fa-ba10-a902c6abb708 azure-vote-front-f747b5d4b-c6ngh 1/1 Running 0 2m45s 10.200.45.12 b1be3863-d0ee-45ed-a2c5-72135bb3db10 azure-vote-front-f747b5d4b-l6xg8 1/1 Running 0 2m45s 10.200.54.5 a0d95747-ab5c-4f8d-9534-3bb750631602 azure-vote-front-f747b5d4b-mrtvk 1/1 Running 0 2m45s 10.200.79.5 6440e98f-f294-40fa-ba10-a902c6abb708 ``` 確認したら削除します。 ``` kubectl delete -f azure-vote-all-in-one-redis.yaml ``` ### Persistent Volumeの使用 次にPersistent Volumeを使ってみます。PKSではデフォルトで`StorageClass`は特に設定されていないので、自分で設定します。 ```yaml cat < storageclass.yml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: standard annotations: storageclass.beta.kubernetes.io/is-default-class: "true" provisioner: kubernetes.io/azure-disk parameters: storageaccounttype: Standard_LRS kind: managed EOF ``` ``` kubectl apply -f storageclass.yml ``` ``` $ kubectl get storageclass NAME PROVISIONER AGE standard (default) kubernetes.io/azure-disk 5m54s ``` MySQLをデプロイします。 ``` kubectl create secret generic mysql-secret \ --from-literal=MYSQL_ROOT_PASSWORD=password \ --from-literal=MYSQL_USER=pksuser \ --from-literal MYSQL_PASSWORD=pkspassword \ --dry-run -o yaml > mysql-secret.yml kubectl apply -f mysql-secret.yml ``` ```yaml cat < mysql.yml apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: initContainers: - name: remove-lost-found image: busybox command: - sh - -c - | rm -fr /var/lib/mysql/lost+found volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql containers: - image: mysql:5.7 name: mysql env: - name: MYSQL_DATABASE value: demo - name: MYSQL_ROOT_PASSWORD value: password - name: MYSQL_USER value: pksuser - name: MYSQL_PASSWORD value: pkspassword ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pvc --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1G storageClassName: standard EOF ``` ``` kubectl apply -f mysql.yml ``` ``` $ kubectl get pod,pvc,pv NAME READY STATUS RESTARTS AGE pod/mysql-6b5f74849b-mp5h8 1/1 Running 0 2m27s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/mysql-pvc Bound pvc-84b12888-1a69-11e9-ac22-000d3a52962d 1Gi RWO standard 2m27s NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-84b12888-1a69-11e9-ac22-000d3a52962d 1Gi RWO Delete Bound default/mysql-pvc standard 2m14s ``` ``` $ kubectl exec $(kubectl get pod -l app=mysql -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}') -ti -- mysql -u pksuser -ppkspassword demo mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.24 MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> ``` 出来ました。 確認したら削除します。 ``` kubectl delete -f mysql.yml ``` k8sが作成したLBやDiskなどのリソースはPKSをアンインストールしても消えないため、 `kubectl`で削除する必要があります。 --- Azureでも普通にPKSが使えました。 本記事の内容をConcourseで自動化したいと思います。