前回のTelepresence2でAWS ElastiCacheエンドポイントのようなプライベートIPアドレスに接続するで挙げた課題をなんとかする方法を見つけたのでメモ。

課題は認証情報を更新するときに

aws eks update-kubeconfig --name my-cluster

を叩いてconfigに手で書き加えた設定が消えてしまうことでした。 これをどう解決するかというと、タイトル通り認証情報とエンドポイントのみを書き換えます。

書き換えは以下のようにzsh functionでやります。

function k-update(){
  clusterName="my-cluster"
  awsID="*****"
  region="ap-northeast-1"
  clusterARN="arn:aws:eks:${region}:${awsID}:cluster/${clusterName}"
  kubeConfig=$(aws eks update-kubeconfig --name ${clusterName} --profile prd-admin --dry-run | base64)

  # 認証情報取得
  jsonPathStringAuth="{.clusters[?(@.name == \"$clusterARN\")].cluster.certificate-authority-data}"
  crt=$(kubectl --kubeconfig <(echo "${kubeConfig}" | base64 -d ) config view --raw -o jsonpath="${jsonPathStringAuth}")

  # EKSエンドポイント取得
  jsonPathStringServer="{.clusters[?(@.name == \"$clusterARN\")].cluster.server}"
  server=$(kubectl --kubeconfig <(echo "${kubeConfig}" | base64 -d ) config view --raw -o jsonpath="${jsonPathStringServer}")

  current=$(kubectl config get-clusters | grep ${clusterARN})
  if [ "${current}" = "" ]; then
      KUBECONFIG=~/.kube/config:<(echo "${kubeConfig}" | base64 -d ) kubectl config view --raw >| ~/.kube/config
      echo "new cluster ${clusterName} added to kubeconfig."
      return
  fi

  kubectl config set "clusters.${clusterARN}.certificate-authority-data" "${crt}"
  kubectl config set "clusters.${clusterARN}.server" "${server}"
  kubectl config use-context $clusterARN
}

これは何をやっているかというと、以下のようなことをしています。

  1. aws eks update-kubeconfig を --dry-run をつけて実行することで標準出力のみに出力
  2. シェルのプロセス置換を利用してkubectl がdry-run結果(認証情報更新済み)をconfigとして使用するようにし、認証情報 certificate-authority-data と エンドポイント server を取り出す。
  3. 新しいクラスターの場合はそのままdry-run結果を~/.kube/configに保存
  4. 既に設定が存在するクラスターの場合は認証情報 certificate-authority-dataserverdry-run結果(認証情報更新済み)のものに更新
  5. Current contextの切り替え

これで k-update を叩くことで認証情報とエンドポイントが更新され、手で書き加えた設定も消えないということになります。