Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deploy & Manage Kubernetes on SakuraCloud

Naoki Kanazawa
November 05, 2019
5k

Deploy & Manage Kubernetes on SakuraCloud

Naoki Kanazawa

November 05, 2019
Tweet

Transcript

  1. 今日話すこと • さくら内での事例紹介 ◦ 新サービスのインフラに Kubernetesを導入した話 • さくらのクラウドにkubernetesをデプロイする ◦ ざっくりした流れと、コツなど

    • この2つの話をしながらさくらのクラウドに kubernetesを乗せる時のコツ?を紹介します (さくらのクラウド側の tipsがメインになりそう) 3
  2. どこに導入したの? (ΦωΦ) • とある新規サービスの 「Cpanel and API Team」チーム ◦ コンパネ・APIのインフラにKubernetesを導入した

    • メンバー ◦ API開発 ▪ @chibiegg ▪ @amaya382 ▪ @asya_aoi1049 ▪ もう一人 ◦ 監視 / Manifest管理 ▪ @kameneko1004 ◦ Kubernetes管理 ▪ わたし 6
  3. アーキテクチャ > v2 9 物理側 バックボーン さくらのクラウド VPN VPN Authn

    Proxy Secure Proxy RProxy ⇆ worker etcd master worker RProxy ⇆ internet hybrid 接続 ストレージ バックエンド etcd x5 master x3 worker xN台~ プロクシ側で完結する アプリケーションだけ こっちに置くなど internet
  4. アーキテクチャ > v3 10 物理側 バックボーン さくらのクラウド VPN VPN Authn

    Proxy Secure Proxy RProxy ⇆ worker etcd master worker RProxy ⇆ internet hybrid 接続 ストレージ バックエンド internet 物理にまたがった構 成をやめた 4core/8G or 4core/16G くらいのスペックを 横に並べている 物理とまたがった構成を解除 ライフサイクルが異なる - RProxyは1度建てたらほぼその まま運用できる - k8sは数ヶ月ごとに Upgrade etcd x5 master x3 worker x7~
  5. CNI • Calicoを採用 ◦ L3ピュアでの通信 (BGP) ◦ NetworkPolicyが使える ◦ 物理側NWとは

    CrossSubnet Modeの IPIPトンネルでカプセリング • CrossSubnet ◦ 同セグメント内のPod通信は直接ルーティングし、別セグメントなら IPIPでカプセリング ◦ セグメント間のルータが BGPを喋れるなら必要ない ◦ よしなにカプセリングしたりさせなかったり 12
  6. Calico - Cross Subnet 13 物理側 さくらのクラウド RProxy ⇆ worker

    etcd master worker RProxy ⇆ internet hybrid 接続 ストレージ バックエンド このNWをまたがった部分の Pod間通信の話
  7. Calico - Cross Subnet 14 物理 さくらのクラウド ⇆ worker 3

    worker 1 worker 2 ⇆ hybrid 接続 worker 5 worker 4 Host subnet 192.168.0.0/24 Host subnet 192.168.99.0/24 .21 .22 .23 .200 .31 .32 .200 10.0.65.0/26 10.0.66.0/26 10.0.67.0/26 10.0.70.0/26 10.0.71.0/26 Cluster Subnet (pod CIDR)
  8. Calico - Cross Subnet 15 物理 さくらのクラウド ⇆ worker 3

    worker 1 worker 2 ⇆ hybrid 接続 worker 5 worker 4 192.168.0.0/24 192.168.99.0/24 .21 .22 .23 .200 .31 .32 .200 10.0.65.0/26 10.0.66.0/26 10.0.67.0/26 10.0.70.0/26 10.0.71.0/26 Cluster Subnet (pod CIDR) Nodeが同じSubnet内に いる場合は、その上の Pod間通信はBGPで直接 ルーティングされる こっちも同じ
  9. Calico - Cross Subnet 16 物理 さくらのクラウド ⇆ worker 3

    worker 1 worker 2 ⇆ hybrid 接続 worker 5 worker 4 192.168.0.0/24 192.168.99.0/24 .21 .22 .23 .200 .31 .32 .200 10.0.65.0/26 10.0.66.0/26 10.0.67.0/26 10.0.70.0/26 10.0.71.0/26 Nodeが異なるSubnetに いる場合は、その上の Pod間通信はIPIPでカプ セリングされる Cluster Subnet (pod CIDR) ここらへんにいるルータに各ホ ストとPodNetworkのルーティン グを追加しなくて済む (BGPを喋れない場合も)
  10. ユーザ管理 (kubectl を叩く人) • クライアント証明書認証 ◦ kubespray(kubeadm)などで構築するとデフォルトで用意される kubeconfig はこれ ◦

    CRL(証明書失効リスト)をkube-apiserverに持たせることが現状不可 ▪ https://github.com/kubernetes/kubernetes/issues/18982 • ServiceAccount ◦ 一応 ServiceAccount はあくまでアプリケーション用 ◦ ユーザ単位で作成・削除は出来る ◦ 人が増えまくると管理が大変になるらしい • oidc (OpenID Connect) 認証 ◦ keycloakなどでかぶせればAD認証が可能になる ◦ kubeloginなどのツールと合わせて使う 18
  11. ざっくりと流れ 20 • デプロイ ◦ サーバの展開 (Terraform) ◦ Dynamic Inventoryを実装

    ◦ サーバの初期設定 (Ansible) ◦ Kubernetes cluster をデプロイ (kubespray) • おまけ ◦ Cluster Upgrade
  12. 今回のお話で出てくる構成(雑) 23 さくらのクラウド master node x n台 - kubelet -

    kube-apiserver - kube-scheduler - kube-controller-manager worker node x n台 - kube-apiserver - kube-scheduler - kube-controller-manager etcd node x n台 - etcd スイッチ
  13. デプロイ > サーバの展開 25 • terraformで行う ◦ https://github.com/naoki912/example-sacloud-kubernetes/tree/master/terraform • ゴール

    ◦ Switchを作成できる ◦ サーバを作成できる ◦ 後述するDynamic Inventoryで使うタグを設定する • やること ◦ terraformを書く!
  14. デプロイ > サーバの初期設定 • Ansibleで行う ◦ https://github.com/naoki912/example-sacloud-kubernetes/tree/master/ansible • ゴール ◦

    kubesprayを流し込める状態にする • やること ◦ nfs-common をインストール ▪ PVにNFSアプライアンスを使う場合 ◦ IPv4 Forwarding の設定 ◦ DSRの設定 ▪ type LoadBalancer (sakura-cloud-controller-manager) を使う場合 ◦ swapの無効化 26
  15. デプロイ > サーバの初期設定 > swap無効化のコツ • systemd が動いているOSでのswap無効化のコツ ◦ systemdが勝手にswapパーティションを見つけてきて有効にしてしまう

    • 通常なら ◦ swapoff ◦ fstabからswapを削除 • systemd ◦ *.swap をmask • Ubuntuアーカイブなら dev-vda2.swap を決め打ちでmaskしてok ◦ 多分これが一番早いと思います 27 - name: mask swap systemd: name: dev-vda2.swap masked: yes $ sudo systemctl mask dev-vda2.swap
  16. デプロイ > サーバの初期設定 > DSR • type LoadBalancer を使う場合は設定する ◦

    sakura-cloud-controller-manager はLBアプライアンスを使用している ◦ https://github.com/sacloud/sakura-cloud-controller-manager • https://manual.sakura.ad.jp/cloud/network/load-balancer.html#id15 • https://github.com/naoki912/example-sacloud-kubernetes/blob/079b15baa11e51e808a1be0a5da4cd9bacc22417/ans ible/roles/kubespray_pre/tasks/main.yml#L19-L34 28
  17. デプロイ > kubespray 29 • https://github.com/kubernetes-sigs/kubespray ◦ Ansible + kubeadm

    ◦ etcd含めHAクラスタをサポート ◦ dockerのインストールから面倒を見てくれる ◦ kube-apiserverの前段のLBを用意しなくて済む ▪ kube-apiserverへリバプロするNginxのStaticPodがnode上に展開される worker master kubelet Nginx StaticPod kube-apiserver upstream kube_apiserver { server 192.168.0.9:6443; server 192.168.0.10:6443; } server { listen 127.0.0.1:6443; proxy_pass kube_apiserver; } # /etc/kubernetes/kubelet.conf apiVersion: v1 clusters: - cluster: certificate-authority-data: XXXX server: https://localhost:6443 name: default-cluster master kube-apiserver
  18. デプロイ > kubespray > つらいとこ • playbookの実行に時間がかかる (1時間くらい) ◦ スケールアウトに時間がかかる

    • アップグレード時はけっこうバグを踏むのでちゃんと検証しよう • 設定変更やスケール時はクラスタを破壊しないように注意 ◦ ミスって別バージョンの etcdのkubesprayを流すとクラスタが破壊される可能性 ◦ etcdのマイナーバージョンが変わるタイミングでダウングレードしちゃって止まるとか 30
  19. デプロイ > kubespray > 対象 32 32 さくらのクラウド ⇆ worker

    etcd master internet type LB worker etcd master
  20. デプロイ > kubespray > 対象 33 vm ⇆ vm vm

    kubespray 実行マシン vm vm vm
  21. デプロイ > kubespray > 対象 34 ⇆ etcd - docker

    - etcd etcd - docker - etcd kubespray 実行マシン master - docker - kubelet - kube-apiserver - kube-scheduler - kube-controller-manager master - docker - kubelet - kube-apiserver - kube-scheduler - kube-controller-manager worker - docker - kubelet - nginx (StaticPod) worker - docker - kubelet - nginx (StaticPod)
  22. デプロイ > kubespray > kubesprayの設定 > 実行環境 • pyenv を利用する

    (環境を切り替えられれば他のものでok) • pythonのバージョンは何でも良い • ansibleのバージョンは requirements.txt で必ず合わせる ◦ 最新バージョンのansibleで実行するとコケる (kubespray v2.8) 36 $ pyenv virtualenv 3.7.2 kubespray-v2.10.4 $ pyenv activate kubespray-v2.10.4 $ pyenv exec pip install -r requirements.txt
  23. デプロイ > kubespray > kubesprayの設定 > project tree • kubespray

    の group_vars に直接書き込まない! • group_varsはsampleのsymlinkを張る (中身は触らない) • 設定変更はextra_varsで渡す ◦ 変更する変数だけ定義する ◦ 設定はgit管理 • 何を変更したか分かるように 37 . (project root) ├── credentials/ │ ├── dev.kubeadm_certificate_key.creds │ ├── dev.kube_encrypt_token.creds │ ├── lab.kube_encrypt_token.creds │ ├── prd.kube_encrypt_token.creds │ └── stg.kube_encrypt_token.creds ├── extra_vars_all.yml ├── inventory/ │ ├── credentials -> ../credentials │ ├── group_vars -> ../kubespray/inventory/sample/group_vars │ ├── inventory.py* │ ├── dev.ini │ └── prd.ini ├── kubespray/ -> git submodule ├── .python-version └── README.md extra_varsに設定されている変数は group_varsを上書きしてくれる 設定項目が多いので group_varsを直接編集すると何を変更したか 分からなくなる Dynamic Inventory については後述
  24. デプロイ > kubespray > kubesprayの設定 > option • ほぼほぼデフォルトのままで問題ない 38

    # https://github.com/naoki912/example-sacloud-kubernetes/blob/master/kubespray/extra_vars_all.yml etcd_memory_limit: "2048M" # WARNING: BUG # https://github.com/kubernetes-sigs/kubespray/issues/4917 # https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/configuration.md#--quota-backend-bytes etcd_quota_backend_bytes: "0" # クラスタの使用目的によっては無効化 podsecuritypolicy_enabled: false # dashboardを無効化 dashboard_enabled: false # group_vars/k8s-cluster/addons.yml # 使いたいものがある場合 helm_enabled: false registry_enabled: false ...
  25. デプロイ > kubespray > kubesprayの設定 > option • etcdの暗号化をする場合は必要に応じてsecretを置くディレクトリも調整 39

    ## Encrypting Secret Data at Rest (experimental) kube_encrypt_secret_data: true # example: inventory/credentials/dev.kube_encrypt_token.creds kube_encrypt_token: "{{ lookup('password', credentials_dir + '/' + env + '.kube_encrypt_token.creds length=32 chars=ascii_letters,digits') }}"
  26. デプロイ > kubespray > upgrade 40 • リリースノートとgroup_varsのdiffを見ておく ◦ デフォルトのパラメータが変わることがある

    • 必ず検証 ◦ 検証環境に本番と同じようにアプリケーションをデプロイした状態で行う
  27. デプロイ > kubespray > kubesprayバグ集 • v2.8.3(v1.12.5) -> v2.9.0(v1.13.5) ◦

    「calicoが壊れてworkerが全てNotReadyになる」 ◦ nodelocaldns がデフォルトで有効になったタイミングだったはず • v2.10.4(v1.14.3) -> v2.11.0(v1.15.3) ◦ 「デフォルト定義の etcd_quota_backend_bytes: "2G" でetcdの起動に失敗する」 ◦ ロールバックしようとして前のバージョンの playbookを流すとetcdがクラッシュ ▪ etcdのマイナーバージョンが切り替わったタイミングだった 41
  28. 事前準備 > Dynamic Inventory > group by どれ...? • さくらのクラウドのサーバにはタグを付けることが出来る

    ◦ そのタグ(server_tags)をベースにgroupを生成 • タグはterraformなどで構築する時に設定すればok 44 ↓これ
  29. @with_sacloud_inventory @with_kubespray_inventory @cluster=example @instance-type=large k8s-cluster kube-master @sshconfig @ssh_user=ubuntu @ssh_bastion_group=group1 server_tags

    事前準備 > Dynamic Inventory > group • server_tagsから生成する 45 # 手で書くなら [kube-master] node1 node2 [etcd] node1 node2 node3 [kube-node] node2 node3 node4 node5 node6 # Dynamic Inventory # 実際にはjsonを吐く [@cluster=example] node1 node2 ... [kube-master] node1 [kube-node] node2 [@instance-type=large] node2 ... [@sshconfig] [@ssh_user=ubuntu] [@with_kubespray_inventory] [@with_sacloud_inventory] この server_tags から生成する # Dynamic Inventory { "@cluster=example": { "hosts": [ "server-01", "server-02", "server-03" ] }, "kube-master": { "hosts": [ "server-01", "server-02" ] }, "etcd": { "hosts": [ "server-01" ] }, "kube-node": { "hosts": [ "server-02", "server-03" ] } }
  30. @with_sacloud_inventory @with_kubespray_inventory @cluster=example @instance-type=large k8s-cluster kube-master @sshconfig @ssh_user=ubuntu @ssh_bastion_group=group1 server_tags

    事前準備 > Dynamic Inventory > group • groupは3種類の使い方をする ◦ filter ▪ 複数クラスタを巻き込まないように対象のクラスタのみに filter ◦ kubesprayが使用するgroup ▪ kube-master, kube-node, etcd, k8s-cluster(kube-master, kube-node) ◦ nodeごとに設定したい変数などがある場合に使う group ▪ @instance-type= 46
  31. @with_sacloud_inventory @with_kubespray_inventory @cluster=example @instance-type=large k8s-cluster kube-master @sshconfig @ssh_user=ubuntu @ssh_bastion_group=group1 server_tags

    事前準備 > Dynamic Inventory > group > filter • 同じzoneに複数k8sが存在する場合は必須 • どのクラスタに対してkubesprayを実行するか判断 47 クラスタA クラスタB node node node node node node node node tag @cluster=a tag @cluster=b 「@cluster=b」 のみplaybookを実行 (タグに「@cluster=b」が 設定されていないサーバ をinventoryに含めない)
  32. @with_sacloud_inventory @with_kubespray_inventory @cluster=example @instance-type=large k8s-cluster kube-master @sshconfig @ssh_user=ubuntu @ssh_bastion_group=group1 server_tags

    事前準備 > Dynamic Inventory > group > kubespray用 • kubesprayが利用するgroup ◦ ↓の4種類のgroupを見てnodeをデプロイする ◦ kube-master, kube-node, etcd, (k8s-cluster) ◦ 同じサーバに「etcd, kube-master」などのgroupを割り当てれば同居可能 48
  33. @with_sacloud_inventory @with_kubespray_inventory @cluster=example @instance-type=large k8s-cluster kube-master @sshconfig @ssh_user=ubuntu @ssh_bastion_group=group1 server_tags

    事前準備 > Dynamic Inventory > group > 特殊な設定用 • 一部のnodeのみ特殊な設定を入れたい時に利用する • inventoryのgroupにkubesprayで使う変数を設定する ◦ 「@instance-type=」groupに「node_labels」変数を設定するなど 49 # inventory/dev-hosts.ini [@instance-type=large:vars] node_labels={"beta.kubernetes.io/instance-type":"large"} # groupに対してvarsを設定する [test_group:vars] key=value
  34. @with_sacloud_inventory @with_kubespray_inventory @cluster=example @instance-type=large k8s-cluster kube-master @sshconfig @ssh_user=ubuntu @ssh_bastion_group=group1 server_tags

    事前準備 > Dynamic Inventory > 実装 50 • https://github.com/naoki912/example-sacloud-kubernetes/blob/master/kubesp ray/inventory/kube_sacloud_inventory.py • https://github.com/naoki912/example-sacloud-kubernetes/blob/master/ansible /sacloud_inventory.py # kubespray実行イメージ # 環境変数でprofileとclusterを渡す $ USACLOUD_PROFILE=dev \ CLUSTER=@cluster=example \ ansible-playbook \ -i inventory/inventory.py \ -i inventory/prd.ini \ -e '@extra_vars_all.yml' \ --become --ask-pass --ask-become-pass \ kubespray/cluster.yml
  35. そのた - うちのチームの過去の資料 • Kubernetesって何ができるの?どうなってるの? ◦ https://speakerdeck.com/amaya382/kubernetestutehe-gadekirufalse-dounatuterufalse • Kubernetesを最大限に活かすためのGitOps入門 ◦

    https://speakerdeck.com/amaya382/kuberneteswozui-da-xian-nihuo-kasutamefalsegitopsru-men • GitOpsでも秘匿情報をバッチリ扱う方法、SealedSecretとは? / How to manage credentials on GitOps ◦ https://speakerdeck.com/amaya382/how-to-manage-credentials-on-gitops • Kubernetes,Prometheusをやってみて辛い,辛かった話 / Prometheus's Experience ◦ https://speakerdeck.com/takumanakagame/prometheuss-experience • Prometheusを始めよう / Introduction Prometheus ja ◦ https://speakerdeck.com/takumanakagame/introduction-prometheus-ja 53