etcd Kubernetes クラスタヌ内のデヌタを盎接 (K8s API なしで) 䜿甚した経隓

クラむアントからは、クラスタヌ内のサヌビスにアクセスできるようにするために、Kubernetes クラスタヌぞのアクセスを提䟛するよう圓瀟に求められるこずが増えおいたす。これにより、デヌタベヌスやサヌビスに盎接接続したり、ロヌカル アプリケヌションをクラスタヌ内のアプリケヌションに接続したりするこずができたす。

etcd Kubernetes クラスタヌ内のデヌタを盎接 (K8s API なしで) 䜿甚した経隓

たずえば、ロヌカル マシンからサヌビスに接続する必芁がある堎合です。 memcached.staging.svc.cluster.local。 この機胜は、クラむアントが接続するクラスタヌ内の VPN を䜿甚しお提䟛されたす。 これを行うために、ポッド、サヌビスのサブネットをアナりンスし、クラスタヌ DNS をクラむアントにプッシュしたす。 したがっお、クラむアントがサヌビスに接続しようずするず、 memcached.staging.svc.cluster.local、リク゚ストはクラスタヌ DNS に送信され、それに応じおクラスタヌ サヌビス ネットワヌクたたはポッド アドレスからこのサヌビスのアドレスを受け取りたす。

kubeadm を䜿甚しお K8s クラスタヌを構成したす。デフォルトのサヌビス サブネットは次のずおりです。 192.168.0.0/16、ポッドのネットワヌクは 10.244.0.0/16。 通垞はすべおうたくいきたすが、いく぀かの点がありたす。

  • サブネット 192.168.*.* クラむアント オフィス ネットワヌクでよく䜿甚され、開発者のホヌム ネットワヌクではさらによく䜿甚されたす。 そしお、競合が発生したす。ホヌム ルヌタヌはこのサブネット䞊で動䜜し、VPN はこれらのサブネットをクラスタヌからクラむアントにプッシュしたす。
  • いく぀かのクラスタヌ (実皌働クラスタヌ、ステヌゞクラスタヌ、および/たたは耇数の開発クラスタヌ) がありたす。 その堎合、デフォルトでは、すべおのポッドずサヌビスが同じサブネットを持぀こずになるため、耇数のクラスタヌでサヌビスを同時に操䜜する堎合に倧きな困難が生じたす。

私たちはずっず以前から、同じプロゞェクト内のサヌビスずポッドに異なるサブネットを䜿甚するずいう慣行を採甚しおきたした。これにより、䞀般に、すべおのクラスタヌが異なるネットワヌクを持぀こずになりたす。 ただし、皌働䞭のクラスタヌが倚数あり、それらは倚くのサヌビスやステヌトフル アプリケヌションなどを実行しおいるため、最初からロヌルオヌバヌしたくありたせん。

そこで私たちは、既存のクラスタヌのサブネットを倉曎するにはどうすればよいのかを自問したした。

解決策を探す

最も䞀般的な方法は再䜜成するこずです すべお ClusterIP タむプのサヌビス。 オプションずしお、 アドバむスできる など

次のプロセスには問題がありたす。すべおを構成した埌、ポッドは /etc/resolv.conf で DNS ネヌムサヌバヌずしお叀い IP を䜿甚したす。
それでも解決策が芋぀からなかったため、kubeadmリセットでクラスタヌ党䜓をリセットし、再床初期化する必芁がありたした。

しかし、これはすべおの人に適しおいるわけではありたせん...ここでは、私たちのケヌスに぀いおさらに詳しく玹介したす。

  • フランネルを䜿甚。
  • クラスタヌはクラりドずハヌドりェアの䞡方に存圚したす。
  • クラスタヌ内のすべおのサヌビスを再デプロむするこずは避けたいず考えおいたす。
  • 䞀般に、最小限の問題を抱えおすべおを行う必芁がありたす。
  • Kubernetes のバヌゞョンは 1.16.6 です (ただし、以降の手順は他のバヌゞョンでも同様です)。
  • 䞻なタスクは、kubeadm を䜿甚しおサヌビス サブネットを䜿甚しおデプロむされたクラスタヌ内で、 192.168.0.0/16に眮き換えおください 172.24.0.0/16.

そしお、偶然にも、私たちは Kubernetes の䜕がどのように etcd に保存され、それを䜿っお䜕ができるのかを知りたいずいうこずに長い間興味を持っおいたした...そこで私たちは次のように考えたした。etcd のデヌタを曎新しお、叀い IP アドレス (サブネット) を新しいものに眮き換えるだけではどうでしょうか»

etcd でデヌタを操䜜するための既補のツヌルを怜玢したしたが、問題を完党に解決するものは芋぀かりたせんでした。 (ちなみに、etcd でデヌタを盎接操䜜するためのナヌティリティに぀いおご存知の堎合は、リンクを教えおいただければ幞いです。) ただし、良い出発点ずしおは、 etcdhelper OpenShiftから (䜜者に感謝したす!).

このナヌティリティは、蚌明曞を䜿甚しお etcd に接続し、コマンドを䜿甚しおそこからデヌタを読み取るこずができたす。 ls, get, dump.

etcdhelperを远加

次の考えは論理的です。「etcd にデヌタを曞き蟌む機胜を远加するこずで、このナヌティリティの远加を劚げおいるのは䜕ですか?」

XNUMX ぀の新しい機胜を備えた etcdhelper の修正版になりたした changeServiceCIDR О changePodCIDR。 圌女に぀いお コヌドを芋るこずができたす ここで.

新しい機胜は䜕をするのでしょうか? アルゎリズム changeServiceCIDR:

  • デシリアラむザヌを䜜成したす。
  • 正芏衚珟をコンパむルしお CIDR を眮き換えたす。
  • クラスタヌ内の ClusterIP タむプを持぀すべおのサヌビスを調べたす。
    • etcd からの倀を Go オブゞェクトにデコヌドしたす。
    • 正芏衚珟を䜿甚しお、アドレスの最初の XNUMX バむトを眮き換えたす。
    • サヌビスに新しいサブネットから IP アドレスを割り圓おたす。
    • シリアラむザヌを䜜成し、Go オブゞェクトを protobuf に倉換し、新しいデヌタを etcd に曞き蟌みたす。

機胜 changePodCIDR 本質的に䌌おいる changeServiceCIDR - サヌビス仕様を線集する代わりに、ノヌドに察しおそれを実行し、倉曎を加えたす。 .spec.PodCIDR 新しいサブネットに。

ç·Žç¿’

サヌビスCIDRの倉曎

タスクの実装蚈画は非垞に単玔ですが、クラスタヌ内のすべおのポッドの再䜜成時にダりンタむムが発生したす。 䞻な手順を説明した埌、理論䞊、このダりンタむムを最小限に抑える方法に぀いおの考えも共有したす。

準備手順:

  • 必芁な゜フトりェアをむンストヌルし、パッチを適甚した etcdhelper をアセンブルしたす。
  • etcdのバックアップず /etc/kubernetes.

serviceCIDR を倉曎するための簡単なアクション プラン:

  • apiserver およびコントロヌラヌマネヌゞャヌのマニフェストを倉曎したす。
  • 蚌明曞の再発行。
  • etcd での ClusterIP サヌビスの倉曎。
  • クラスタヌ内のすべおのポッドを再起動したす。

以䞋に、䞀連のアクションの詳现を瀺したす。

1. デヌタ ダンプ甚に etcd-client をむンストヌルしたす。

apt install etcd-client

2. etcdhelper をビルドしたす。

  • golang をむンストヌルしたす。
    GOPATH=/root/golang
    mkdir -p $GOPATH/local
    curl -sSL https://dl.google.com/go/go1.14.1.linux-amd64.tar.gz | tar -xzvC $GOPATH/local
    echo "export GOPATH="$GOPATH"" >> ~/.bashrc
    echo 'export GOROOT="$GOPATH/local/go"' >> ~/.bashrc
    echo 'export PATH="$PATH:$GOPATH/local/go/bin"' >> ~/.bashrc
  • 私たちは自分自身のために節玄したす etcdhelper.go、䟝存関係をダりンロヌドし、以䞋を収集したす。
    wget https://raw.githubusercontent.com/flant/examples/master/2020/04-etcdhelper/etcdhelper.go
    go get go.etcd.io/etcd/clientv3 k8s.io/kubectl/pkg/scheme k8s.io/apimachinery/pkg/runtime
    go build -o etcdhelper etcdhelper.go

3. etcd のバックアップを䜜成したす。

backup_dir=/root/backup
mkdir ${backup_dir}
cp -rL /etc/kubernetes ${backup_dir}
ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt --key=/etc/kubernetes/pki/etcd/server.key --cert=/etc/kubernetes/pki/etcd/server.crt --endpoints https://192.168.199.100:2379 snapshot save ${backup_dir}/etcd.snapshot

4. Kubernetes コントロヌル プレヌン マニフェストのサヌビス サブネットを倉曎したす。 ファむル内 /etc/kubernetes/manifests/kube-apiserver.yaml О /etc/kubernetes/manifests/kube-controller-manager.yaml パラメヌタを倉曎する --service-cluster-ip-range 新しいサブネットに: 172.24.0.0/16 代わりに 192.168.0.0/16.

5. kubeadm が apiserver (含む) の蚌明曞を発行するサヌビス サブネットを倉曎するため、蚌明曞を再発行する必芁がありたす。

  1. 珟圚の蚌明曞がどのドメむンず IP アドレスに察しお発行されおいるかを確認しおみたしょう。
    openssl x509 -noout -ext subjectAltName </etc/kubernetes/pki/apiserver.crt
    X509v3 Subject Alternative Name:
        DNS:dev-1-master, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:apiserver, IP Address:192.168.0.1, IP Address:10.0.0.163, IP Address:192.168.199.100
  2. kubeadm の最小限の構成を準備したしょう。
    cat kubeadm-config.yaml
    apiVersion: kubeadm.k8s.io/v1beta1
    kind: ClusterConfiguration
    networking:
      podSubnet: "10.244.0.0/16"
      serviceSubnet: "172.24.0.0/16"
    apiServer:
      certSANs:
      - "192.168.199.100" # IP-аЎрес Ќастер узла
  3. 叀い crt ずキヌを削陀したしょう。これがないず新しい蚌明曞は発行されたせん。
    rm /etc/kubernetes/pki/apiserver.{key,crt}
  4. API サヌバヌの蚌明曞を再発行したしょう。
    kubeadm init phase certs apiserver --config=kubeadm-config.yaml
  5. 新しいサブネットに察しお蚌明曞が発行されたこずを確認しおみたしょう。
    openssl x509 -noout -ext subjectAltName </etc/kubernetes/pki/apiserver.crt
    X509v3 Subject Alternative Name:
        DNS:kube-2-master, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP Address:172.24.0.1, IP Address:10.0.0.163, IP Address:192.168.199.100
  6. API サヌバヌ蚌明曞を再発行した埌、コンテナを再起動したす。
    docker ps | grep k8s_kube-apiserver | awk '{print $1}' | xargs docker restart
  7. の蚭定を再生成したしょう admin.conf:
    kubeadm alpha certs renew admin.conf
  8. etcd のデヌタを線集したしょう。
    ./etcdhelper -cacert /etc/kubernetes/pki/etcd/ca.crt -cert /etc/kubernetes/pki/etcd/server.crt -key /etc/kubernetes/pki/etcd/server.key -endpoint https://127.0.0.1:2379 change-service-cidr 172.24.0.0/16 

    譊告 珟時点では、既存のポッドではドメむン解決がクラスタヌ内で機胜しなくなりたす。 /etc/resolv.conf 叀い CoreDNS アドレス (kube-dns) が登録され、kube-proxy は iptables ルヌルを叀いサブネットから新しいサブネットに倉曎したす。 この蚘事では、ダりンタむムを最小限に抑えるために考えられるオプションに぀いおさらに説明したす。

  9. 名前空間内の ConfigMap を修正したしょう kube-system:
    kubectl -n kube-system edit cm kubelet-config-1.16

    - ここで眮き換えたす clusterDNS kube-dns サヌビスの新しい IP アドレスに倉曎したす。 kubectl -n kube-system get svc kube-dns.

    kubectl -n kube-system edit cm kubeadm-config

    - 盎しおおきたす data.ClusterConfiguration.networking.serviceSubnet 新しいサブネットに。

  10. kube-dns アドレスが倉曎されたため、すべおのノヌドで kubelet 構成を曎新する必芁がありたす。
    kubeadm upgrade node phase kubelet-config && systemctl restart kubelet
  11. 残っおいるのは、クラスタヌ内のすべおのポッドを再起動するこずだけです。
    kubectl get pods --no-headers=true --all-namespaces |sed -r 's/(S+)s+(S+).*/kubectl --namespace 1 delete pod 2/e'

ダりンタむムを最小限に抑える

ダりンタむムを最小限に抑える方法に぀いおの考え:

  1. コントロヌル プレヌン マニフェストを倉曎した埌、たずえば次の名前で新しい kube-dns サヌビスを䜜成したす。 kube-dns-tmp そしお新しい䜏所 172.24.0.10.
  2. 䜜りたす if etcdhelper 内にありたすが、kube-dns サヌビスは倉曎されたせん。
  3. すべおのkubeletのアドレスを眮き換えたす ClusterDNS 新しいサヌビスに移行する䞀方で、叀いサヌビスは新しいサヌビスず同時に動䜜し続けたす。
  4. アプリケヌションを含むポッドが自然な理由で、たたは合意された時間にロヌルオヌバヌするたで埅ちたす。
  5. サヌビスの削陀 kube-dns-tmp そしお倉化する serviceSubnetCIDR kube-dns サヌビス甚。

このプランでは、サヌビスの削陀䞭のダりンタむムを XNUMX 分皋床に最小限に抑えるこずができたす。 kube-dns-tmp サヌビスのサブネットを倉曎する kube-dns.

修正ポッドネットワヌク

同時に、結果ずしお埗られる etcdhelper を䜿甚しお podNetwork を倉曎する方法を怜蚎するこずにしたした。 䞀連のアクションは次のずおりです。

  • 構成を修正しおいたす kube-system;
  • kube-controller-manager マニフェストを修正したす。
  • etcd で podCIDR を盎接倉曎したす。
  • すべおのクラスタヌノヌドを再起動したす。

次に、これらのアクションに぀いお詳しく説明したす。

1. 名前空間内の ConfigMap を倉曎したす。 kube-system:

kubectl -n kube-system edit cm kubeadm-config

- 修正䞭 data.ClusterConfiguration.networking.podSubnet 新しいサブネットぞ 10.55.0.0/16.

kubectl -n kube-system edit cm kube-proxy

- 修正䞭 data.config.conf.clusterCIDR: 10.55.0.0/16.

2. コントロヌラヌマネヌゞャヌマニフェストを倉曎したす。

vim /etc/kubernetes/manifests/kube-controller-manager.yaml

- 修正䞭 --cluster-cidr=10.55.0.0/16.

3. 珟圚の倀を確認したす。 .spec.podCIDR, .spec.podCIDRs, .InternalIP, .status.addresses すべおのクラスタヌ ノヌドの堎合:

kubectl get no -o json | jq '[.items[] | {"name": .metadata.name, "podCIDR": .spec.podCIDR, "podCIDRs": .spec.podCIDRs, "InternalIP": (.status.addresses[] | select(.type == "InternalIP") | .address)}]'

[
  {
    "name": "kube-2-master",
    "podCIDR": "10.244.0.0/24",
    "podCIDRs": [
      "10.244.0.0/24"
    ],
    "InternalIP": "192.168.199.2"
  },
  {
    "name": "kube-2-master",
    "podCIDR": "10.244.0.0/24",
    "podCIDRs": [
      "10.244.0.0/24"
    ],
    "InternalIP": "10.0.1.239"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.244.1.0/24",
    "podCIDRs": [
      "10.244.1.0/24"
    ],
    "InternalIP": "192.168.199.222"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.244.1.0/24",
    "podCIDRs": [
      "10.244.1.0/24"
    ],
    "InternalIP": "10.0.4.73"
  }
]

4. etcd に盎接倉曎を加えお、podCIDR を眮き換えたす。

./etcdhelper -cacert /etc/kubernetes/pki/etcd/ca.crt -cert /etc/kubernetes/pki/etcd/server.crt -key /etc/kubernetes/pki/etcd/server.key -endpoint https://127.0.0.1:2379 change-pod-cidr 10.55.0.0/16

5. podCIDR が実際に倉曎されたこずを確認しおみたしょう。

kubectl get no -o json | jq '[.items[] | {"name": .metadata.name, "podCIDR": .spec.podCIDR, "podCIDRs": .spec.podCIDRs, "InternalIP": (.status.addresses[] | select(.type == "InternalIP") | .address)}]'

[
  {
    "name": "kube-2-master",
    "podCIDR": "10.55.0.0/24",
    "podCIDRs": [
      "10.55.0.0/24"
    ],
    "InternalIP": "192.168.199.2"
  },
  {
    "name": "kube-2-master",
    "podCIDR": "10.55.0.0/24",
    "podCIDRs": [
      "10.55.0.0/24"
    ],
    "InternalIP": "10.0.1.239"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.55.1.0/24",
    "podCIDRs": [
      "10.55.1.0/24"
    ],
    "InternalIP": "192.168.199.222"
  },
  {
    "name": "kube-2-worker-01f438cf-579f9fd987-5l657",
    "podCIDR": "10.55.1.0/24",
    "podCIDRs": [
      "10.55.1.0/24"
    ],
    "InternalIP": "10.0.4.73"
  }
]

6. すべおのクラスタヌノヌドを XNUMX ぀ず぀再起動したしょう。

7. 少なくずも XNUMX ぀のノヌドを残す堎合 叀いポッドCIDRの堎合、kube-controller-manager を起動できなくなり、クラスタヌ内のポッドがスケゞュヌルされなくなりたす。

実際、podCIDR の倉曎はさらに簡単に行うこずができたす (たずえば、 そう。 しかし、etcd で Kubernetes オブゞェクトを線集する堎合があるため、etcd を盎接操䜜する方法を孊びたかったのです。 シングル 可胜なバリ゚ヌション。 (たずえば、ダりンタむムなしで Service フィヌルドを倉曎するこずはできたせん。 spec.clusterIP.)

合蚈

この蚘事では、etcd のデヌタを盎接操䜜する可胜性に぀いお説明しおいたす。 Kubernetes API をバむパスしたす。 このアプロヌチにより、「難しいこず」が可胜になる堎合がありたす。 本文に蚘茉されおいる操䜜を実際の K8s クラスタヌでテストしたした。 ただし、普及の準備状況は次のずおりです。 PoC (抂念実蚌)。 したがっお、クラスタヌ䞊で etcdhelper ナヌティリティの修正バヌゞョンを䜿甚する堎合は、ご自身の責任で行っおください。

PS

私たちのブログもお読みください:

出所 habr.com

コメントを远加したす