10
6

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 1 year has passed since last update.

Craftsman SoftwareAdvent Calendar 2021

Day 14

初心者向けkind(kubernetes in docker)上のサービスへのアクセス方法

Last updated at Posted at 2021-12-13

はじめに

kubernetesを勉強したい時にminikubeやkindなどをローカルPCに導入することで、気軽にkubernetesを試せる環境を手軽に構築することができます。
今回はkindを使って学習する際に、kubernetes上にサービス展開した時、そのサービスへの接続方法に困ることがあります。
ですので、kindの初回導入部分からサービスへの接続までをまとめていきます。
ここから導入して、kubernetesとは何かを体験しつつ、kubernetesに興味を持っていただけるきっかけになれば幸いです。

準備

kindとkubectlインストール

kubernetesの素であるkind本体と、kubernetesを操作するクライアントツールkubectlをインストールします。

brew install kind kubectl

詳しくは公式サイトを見てみてください。

kindクラスタを作成するためのマニフェストを用意します

まず、サービスを公開するためにはクラスタを作成する必要があります。
何も指定せずにクラスタを作成するコマンドで作成できますが、マニフェストと呼ばれる構成ファイルを作成することで、「こんなクラスタ」を作りたい!!を指定することができます。

kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker

解説

  • kind: 作成するオブジェクトの種類です。今回はクラスタを作成するので、その種類を選択しています。
  • apiVersion: KubernetesAPIのバージョンを指定しますが、公式に書かれているバージョン「kind.x-k8s.io/v1alpha4」でよいです。
  • node:サービスが動作するpodがのる場所です
    • 今回はkubernetesの司令塔部分である、control-plane nodeと、
    • 通常のpodがのるworker nodeを2つ、計3つのnodeを作成します。

kindクラスタの作成

kind create cluster --config kind-config.yaml

nginxのpodを作成します

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: nginx-container
        image: nginx:latest
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"

解説

  • apiVersion:バージョンを指定します。ほぼ固定です。
  • kind: Deploymentを指定しています。これにすると、kubernetesが気を使って、出来るだけサービス断しないようにサービスリリースすることが出来るようになります。
  • metadata:オブジェクトを一意に特定するための情報で、このマニフェストの名前のようなものです。
  • spec:どんなサービスをどんな感じで作成したいか、希望を書くと、kubernetesが気を使ってその通りにしてくれます。
  • replicas:今回はpodを3つ立てたいと願います
  • selector:podを3つ立てたいが、どのようなものを立てたいかの条件を指定します。
    • matchLabels:今回はkeyがappでvalueがsample-appというラベルがついているpodを対象にします。
  • template:どんなpodを立てるかの詳細を記載します
    • metadata:どんな情報でも良いですが今回はkeyがappでvalueがsample-appというラベルにします。
      • ここの設定値とselectorのkeyとvalueが一致していない場合は、作成できないため、注意してください。
    • spec:podの構成を指定します。
      • containers:nginx-containerという名前をつけます。
        • image:nginxの最新版であるnginx:latestを指定します。こうするとdocker hubから最新のimageを取得できます。
        • resources:podがnodeを食い潰さないようにリミットを決めます。

コマンド実行
deployment.yamlを作成してデプロイします。

kubectl apply -f deployment.yaml

これで最新版のnginxが立ち上がりました。

接続方法その1 port-forward

一番手軽に接続できる方法だと思います。
kubectlを使って指定した単一podのサービスに接続します。

Podの状態を確認して表示したいpodを選びます

❯ kubectl get po   
NAME                                 READY   STATUS        RESTARTS   AGE
sample-deployment-75d79cf8cc-g6xhb   1/1     Running       0          21s
sample-deployment-75d79cf8cc-pp9jj   1/1     Running       0          29s
sample-deployment-75d79cf8cc-xl9tn   1/1     Running       0          37s

補足:replicas: 3を指定しているので、ちゃんとpodが3つできていることがわかります。

今回はnginxに接続します。

❯ kubectl port-forward sample-deployment-75d79cf8cc-g6xhb 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

別のターミナルを立ち上げcurlで接続します


❯ curl -i localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.21.4
Date: Wed, 08 Dec 2021 13:45:30 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Tue, 02 Nov 2021 14:49:22 GMT
Connection: keep-alive
ETag: "61814ff2-267"
Accept-Ranges: bytes

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

kubectl port-forwardのコマンドの説明は、以下になります。

kubectl port-forward [接続したPod名] [ブラウザで開く転送先ポート]:[nginxポートである転送元ポート]

今回はpodに対して接続しました。deploymentやserviceなどに対しても接続できますが、その際は接続先から一つのpodが選ばれて接続状態になります。
詳しくは公式Docのport-forwardにも例を見てみてください。

余談ですが、pod自体を操作したい場合は、このコマンドです。

kubectl exec -it sample-deployment-75d79cf8cc-g6xhb -- bash

接続方法その2 node port

次にServiceと呼ばれるkindの中の外部公開用node portを使用する方法です。
node portを使用するだけではkind(kubernetes in docker)の仕様上できないため、一つ手順が増えます。

準備

記事の最初に作成したkindのクラスタを作り直す必要があります。
まず、クラスタのyamlの最後に3行追加します。

kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
  extraPortMappings:
  - containerPort: 30080
    hostPort: 10080

解説

  • containerPortには、nodeportとして設定する予定のポートを指定します。
  • hostPortではブラウザでhttp://localhost:xxxxに接続したい際にxxxxの部分を指定します。80でも良いですが、色々被りそうなので、10080としています。

ちなみにnode portは30000-32767の範囲内のいずれかのポートを指定する必要がありますので、containerPortはその範囲内でお願いします。

クラスタを作り直します

記事通りにしているのであれば、クラスタを作り直す必要があるので、以下のコマンドを実行します。

# kind-kindクラスタを削除します。
kind delete cluster
# kind-kindクラスタを作成します。
kind create cluster --config kind-config.yaml
# nginxをデプロイします。
kubectl apply -f deployment.yaml

serviceを立ち上げます。

外部公開するにはserviceのリソースを使用します。

service.yaml
apiVersion: v1
kind: Service
metadata:
  name: sample-service
spec:
  type: NodePort
  ports:
  - name: "http-port"
    protocol: "TCP"
    port: 8080
    targetPort: 80
    nodePort: 30080
  selector:
    app: sample-app

解説

  • type: typeは色々ありますが、今回は外部公開するためにNodePortを指定します。
  • ports: nginxを表示するためのポートを指定します。
    • protocol:TCPを選択します。
    • port: cluster ipと呼ばれる箇所で、クラスタ内のpodたちが通信する際に使うポートを指定します。内部公開なので、今回は直接関係はないです。
    • targetPort:公開元のポートを指定します。nginxのデフォルトポートは80なので、80を指定します。
    • nodePort:クラスタ外からアクセスするためのポートを指定します。公開可能なポートのレンジを気にしつつ、30080を指定します。
  • selector:どのpodに対して公開するかの条件を指定します。
    • 今回はDeploymentでデプロイしたnginxの指定したいので、keyがappでvalueがsample-appというラベルを指定します。

service.yamlを作成して、以下のコマンドを実行します。

kubectl apply -f service.yaml

これで外部公開できました。本当かどうか確かめてみます。

curlで確認します。

curl -i localhost:10080

ブラウザでhttp://localhost:10080にアクセスしてもよいです。

念のために解説
ポイントとしては、nodeport30080に接続していないことです。
kindの仕様上30080では接続できないので、クラスタを作成した際に、extraPortMappingsに設定した、転送元であるcontainerPortにnodeportを指定して、転送先であるhostPortに10080を指定していますので、10080で接続すればよいです。

おわりに

いかがだったでしょうか。
色々割愛しているので、これは何?というものもあったかと思いますが、
面白そうと思っていただければ、その気になった部分を調べてみてはどうでしょうか。

またkubernetesには資格もあるので、資格取得にも挑戦してみても良いかと思います。
認定Kubernetes管理者 (CKA-JP)

間違いがあれば、コメントいただけると幸いです!

記事を読んでいただき、ありがとうございました!!

10
6
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
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?