41
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

kubernetes REST API に外部から接続する

Last updated at Posted at 2017-09-29

kubernetes には kubectl というコマンドがあり普段のオペレーションはそちらでやることが多いと思いますが、サーバから kubernetes をコントロールしたいというニーズもあるとも思います。

kubernetes には REST API が用意されているのでそれにアクセスすれば良いんですが、どうやって認証すればいいのか迷ったのでメモを残しておきます。

認証

いくつかの認証方式が用意されています。

  • X509証明書
  • BASIC認証
  • TOKEN
  • Service Account
  • OpenID

今回は TOKEN 方式でやってみます。

トークン取得

トークンや証明書は Pod の中に入って /var/run/secrets/kubernetes.io/ にあります。手動で取るのはさすがにかったるいので、下記コマンドを叩きます。

$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') \
  | grep -E '^token' | cut -f2 -d':' | tr -d '\t')

これでトークンが取得できるはずです。

APIサーバのIP

次に curl で叩く先のIPアドレスを取得します。以下のコマンドで取得できるんですが、複数のクラスタを設定している場合は複数出てしまうので注意してください。

kubectl config view | grep server | cut -f 2- -d ":" | tr -d " "

GKE だとコントロールパネルの以下の部分で確認ができます。

gke.png

アクセスしてみる

TOKEN=$(kubectl describe secret $(kubectl get secrets | \
  grep default | cut -f1 -d ' ') | \
  grep -E '^token' | cut -f2 -d':' | tr -d '\t')

curl https://example.com/api/v1/namespaces/default/pods \
  --header "Authorization: Bearer $TOKEN" --insecure

これで Pod の一覧が取得できるはずです。最高ですね。あとは、REST API のリファレンスを見て kubernetes と仲良くなってください。なお、バージョンによって使える API と使えない API があるので注意してください。

kubectl proxy というやり方も

公式ではこちらをオススメしてます。

kubectl proxy --port=8080 &
$ curl http://localhost:8080/api/
{
  "versions": [
    "v1"
  ]
}

クライアントライブラリ

クライアントライブラリも各言語ごとにいくつかあります。

公式では Go と Python ですね。Rubyだと abonas/kubeclient あたりが良さそうです。

abonas/kubeclient

Rubyのgem abonas/kubeclient を使ってAPIにアクセスしてみます。前述したTOKENの取得ができていれば環境変数などにブチ込んで接続するだけです。

auth_options = {
  bearer_token: ENV['K8S_API_TOKEN']
}

client = Kubeclient::Client.new(
  "https://#{ENV['K8S_API_HOST']}/api/", 'v1', auth_options: auth_options
)

client.get_pods

ただ、これだけだとSSLでエラーが出ると思います。kubernetesは独自の証明書を使っているため、そのままだと接続できないからです。 実際にコマンドを実行しようとすると、 KubeException: SSL_connect returned=1 errno=0 state=error: certificate verify failed こんな感じのエラーが出ます。

証明書の設定

OpenSSL::SSL::VERIFY_NONE にする手もありますがオススメはしません。

まず、接続用の証明書を作ります。

openssl genrsa -aes128 2048 > client.key
openssl req -new -key client.key > client.csr
openssl x509 -in client.csr -days 365000 -req -signkey client.key > client.crt
openssl rsa -in client.key -out client.key

次にkubernetesの証明書を取得します。Podの中の /var/run/secrets/kubernetes.io/serviceaccount/ca.crt にあります。

最後に abonas/kubeclient で接続します。

auth_options = {
  bearer_token: ENV['K8S_API_TOKEN']
}

ssl_options = {
  client_cert: OpenSSL::X509::Certificate.new(File.read(Rails.root.join("secrets", "k8s_client.crt"))),
  client_key:  OpenSSL::PKey::RSA.new(File.read(Rails.root.join("secrets", "k8s_client.key"))),
  ca_file:     Rails.root.join("secrets", "k8s_ca.crt"),
  verify_ssl:  OpenSSL::SSL::VERIFY_PEER
}

client = Kubeclient::Client.new(
  "https://#{ENV['K8S_API_HOST']}/api/", 'v1',
  auth_options: auth_options,
  ssl_options: ssl_options
)

client.get_pods

以上で接続できるようになります。

41
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?