Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
18
Help us understand the problem. What is going on with this article?
@go_vargo

Kubernetes Sample APIServerの動かし方

概要・解説

Kubernetes Aggregated APIServerとは?

Kubernetesにはシステムコンポーネントとして、kube-apiserverがいますが、それとは別に独自に拡張したAggregated APIServerを配置することができます。

Custom ControllerのサンプルにSample Controllerがあるように、Custom APIServer(Aggregated APIServer)のサンプルとして公式リポジトリにSample APIServerがあります。

Sample Controllerの説明は下記で詳しく説明しているので、省略
https://nextpublishing.jp/book/11389.html

この記事は、そのSample APIServerの動かし方・遊び方についての記事です。

CRD(+Custom Controller)との違い

CRD + Custom Controllerを使ったOperatorが昨今のKubernetes界隈で流行っていますが、Aggregated APIServerはOperatorと比べると高い自由度を持つことができます。

CRDはある程度決められた枠組みの中で制作・使用することになりますが、APIServerはそれを超えた機能を実現できます。

Aggregated APIServerを使うことで何ができるのか? については
Programming Kubernetesの第8・9章に詳しくまとまっています

ただ、Aggregated APIServerを使わないと実現できないものはだいぶ限られます。
そのため、Kubernetesを拡張してなにかをしたい! という場合はほとんどCRD(+Custom Controller)の選択肢が主力になると思います。
実例も少ないため、Aggregated APIServerはマイナーといっていい存在です。

少なくとも日本語/英語含めて概要以外の記事が全くないので、この記事を書こうと思いました

Sample APIServerで遊ぶ

ここから本題です。Sample APIServerを動かす方法は二つあります。

  1. KubernetesクラスタにPodとしてSample APIServerをデプロイする
  2. Kubernetesクラスタに対して、etcdとSample APIServerをローカルプロセスとして動かす

この記事は2番目の方法の解説記事です。

ビルド

前提として、Golangのインストール・設定(Go Module含む)がされているものとします。
筆者の作業環境は下記です。下記のソフトウェアもインストール済みの前提で書いています。

  • macOS 10.14.5
  • Go 1.14.2
  • Minikube v1.11.0
  • etcd 3.3.11

Sample APIServerのソースをビルドします。

$ mkdir -p ~/go/src/k8s.io
$ git clone https://github.com/kubernetes/sample-apiserver.git
$ CGO_ENABLED=0 go build -a -o artifacts/simple-image/kube-sample-apiserver

準備する

Kubernetesクラスタを動かす

Kubernetesの拡張機能なので、当然Kubernetesクラスタが必要です。
今回はMinikubeを使って、ローカルクラスタを作ります。

Minikube Get Started!

$ minikube start --driver virtualbox

証明書を作る

Sample APIServerが利用する自己証明書を作成します。
1. CA証明書

$ openssl req -nodes -new -x509 -keyout ca.key -out ca.crt
Generating a 2048 bit RSA private key
...........................................................+++
........................................+++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) []:Shibuya
Organization Name (eg, company) []:Kubernetes
Organizational Unit Name (eg, section) []:CA
Common Name (eg, fully qualified host name) []:development
Email Address []:
$ openssl req -out client.csr -new -newkey rsa:4096 -nodes -keyout client.key -subj "/CN=development/O=system:masters"
Generating a 4096 bit RSA private key
..................++
...........................++
writing new private key to 'client.key'
-----
  1. Client証明書
$ openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
Signature ok
subject=/CN=development/O=system:masters
Getting CA Private Key
  1. curl用のp12形式
$ openssl pkcs12 -export -in ./client.crt -inkey ./client.key -out client.p12 -passout pass:password

Sample APIServerを起動する

etcdもローカルプロセスとして動かすため、インストールが必要です。
次のコマンドでetcdとSample APIServerを起動します。

$ etcd & ./artifacts/simple-image/kube-sample-apiserver \
  --secure-port 8443 --etcd-servers http://127.0.0.1:2379 --v=7 \
  --client-ca-file ca.crt --kubeconfig ~/.kube/config \
  --authentication-kubeconfig ~/.kube/config --authorization-kubeconfig ~/.kube/config

ログが出てきたら起動完了です。

APISericeを動かして遊ぶ

このSample APIServerではKind: FlunderというAPI Objectを扱います。
今回はローカルプロセスとして動かしているので、特に実行はしていませんが、通常はkind: APIServiceを登録してからCustom API Obejectを作成します。

以下はAPIServiceの参考です。

# https://github.com/kubernetes/sample-apiserver/blob/master/artifacts/example/apiservice.yaml
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: v1alpha1.wardle.example.com
spec:
  insecureSkipTLSVerify: true
  group: wardle.example.com
  groupPriorityMinimum: 1000
  versionPriority: 15
  service:
    name: api
    namespace: wardle
  version: v1alpha1

どんなAPIServiceが他にあるのかを見たい人は、kubectl get apiserviceで見てみると楽しいかもしれません。

httpieインストール

macOSでSample APIServerと疎通するために、brewでhttpieをインストールします。

$ brew install httpie

httpieでGET

Sample APIServerが動いているか確認するためにhttpieでGETリクエストを投げてみます。
まだ何もAPI Objectを作ってないので、空のリストが返ってきます。

$ http --verify=no --cert client.crt --cert-key client.key \
   https://localhost:8443/apis/wardle.example.com/v1alpha1/namespaces/default/flunders
HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Length: 187
Content-Type: application/json
Date: Sat, 13 Jun 2020 12:19:43 GMT

{
    "apiVersion": "wardle.example.com/v1alpha1",
    "items": [],
    "kind": "FlunderList",
    "metadata": {
        "resourceVersion": "2",
        "selfLink": "/apis/wardle.example.com/v1alpha1/namespaces/default/flunders"
    }
}

Sample APIServerをStandAloneで立てた状態でFlunder Objectを作るには、httpieを使ってPOSTリクエストを送ります。

$ echo '{ "apiVersion": "wardle.example.com/v1alpha1", "kind": "Flunder", "metadata": { "name": "my-first-flunder", "labels": { "sample-label": "true" } } }' | http --verify=no --cert client.crt --cert-key client.key https://localhost:8443/apis/wardle.example.com/v1alpha1/namespaces/default/flunders
HTTP/1.1 201 Created
Cache-Control: no-cache, private
Content-Length: 605
Content-Type: application/json
Date: Sat, 13 Jun 2020 12:26:49 GMT

{
    "apiVersion": "wardle.example.com/v1alpha1",
    "kind": "Flunder",
    "metadata": {
        "creationTimestamp": "2020-06-13T12:26:49Z",
        "labels": {
            "sample-label": "true"
        },
        "managedFields": [
            {
                "apiVersion": "wardle.example.com/v1alpha1",
                "fieldsType": "FieldsV1",
                "fieldsV1": {
                    "f:metadata": {
                        "f:labels": {
                            ".": {},
                            "f:sample-label": {}
                        }
                    }
                },
                "manager": "HTTPie",
                "operation": "Update",
                "time": "2020-06-13T12:26:49Z"
            }
        ],
        "name": "my-first-flunder",
        "namespace": "default",
        "resourceVersion": "3",
        "selfLink": "/apis/wardle.example.com/v1alpha1/namespaces/default/flunders/my-first-flunder",
        "uid": "2d323301-1447-4cd4-967d-bd07eac3a49f"
    },
    "spec": {},
    "status": {}
}

my-first-flunder Objectが作成できました。
あらためてGETすると、上記で作成したmy-first-flunderが返ってきます。

$ http --verify=no --cert client.crt --cert-key client.key \
   https://localhost:8443/apis/wardle.example.com/v1alpha1/namespaces/default/flunders
HTTP/1.1 200 OK
Cache-Control: no-cache, private
Content-Length: 731
Content-Type: application/json
Date: Sat, 13 Jun 2020 12:29:30 GMT

{
    "apiVersion": "wardle.example.com/v1alpha1",
    "items": [
        {
            "metadata": {
                "creationTimestamp": "2020-06-13T12:26:49Z",
                "labels": {
                    "sample-label": "true"
                },
                "managedFields": [
                    {
                        "apiVersion": "wardle.example.com/v1alpha1",
                        "fieldsType": "FieldsV1",
                        "fieldsV1": {
                            "f:metadata": {
                                "f:labels": {
                                    ".": {},
                                    "f:sample-label": {}
                                }
                            }
                        },
                        "manager": "HTTPie",
                        "operation": "Update",
                        "time": "2020-06-13T12:26:49Z"
                    }
                ],
                "name": "my-first-flunder",
                "namespace": "default",
                "resourceVersion": "3",
                "selfLink": "/apis/wardle.example.com/v1alpha1/namespaces/default/flunders/my-first-flunder",
                "uid": "2d323301-1447-4cd4-967d-bd07eac3a49f"
            },
            "spec": {},
            "status": {}
        }
    ],
$ http --verify=no --cert client.crt --cert-key client.key DELETE https://localhost:8443/apis/wardle.example.com/v1alpha1/namespaces/default/flunders/my-first-flunder

このFlunder Obejectが作られるとどうなるの!? と思ったかもしれませんが、特に何も起こりません。
Flunder Objectを作ったり、削除できたりするだけです。

あくまでサンプルということですね。

終わりに

以上がSample APIServerを動かすための動かし方・遊び方でした。
さらに詳しく知りたい方は、デバッガーを使ってどういう処理をしているのかを学ぶと良いでしょう(自分もまだやってませんが)。
kube-apiserverの処理をベースに、Aggredated APIServerが実装されているため、システムコンポーネントであるkube-apiserverに対する理解も深まるはずです。

以上

18
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
go_vargo
I love Cloud Native!

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
18
Help us understand the problem. What is going on with this article?