はじめに
kubernetesを勉強したい時にminikubeやkindなどをローカルPCに導入することで、気軽にkubernetesを試せる環境を手軽に構築することができます。
今回はkindを使って学習する際に、kubernetes上にサービス展開した時、そのサービスへの接続方法に困ることがあります。
ですので、kindの初回導入部分からサービスへの接続までをまとめていきます。
ここから導入して、kubernetesとは何かを体験しつつ、kubernetesに興味を持っていただけるきっかけになれば幸いです。
準備
kindとkubectlインストール
kubernetesの素であるkind本体と、kubernetesを操作するクライアントツールkubectlをインストールします。
brew install kind kubectl
詳しくは公式サイトを見てみてください。
kindクラスタを作成するためのマニフェストを用意します
まず、サービスを公開するためにはクラスタを作成する必要があります。
何も指定せずにクラスタを作成するコマンドで作成できますが、マニフェストと呼ばれる構成ファイルを作成することで、「こんなクラスタ」を作りたい!!を指定することができます。
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を作成します
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を対象にします。
- matchLabels:今回はkeyが
- 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を食い潰さないようにリミットを決めます。
- image:nginxの最新版である
- containers:nginx-containerという名前をつけます。
- metadata:どんな情報でも良いですが今回はkeyが
コマンド実行
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: 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のリソースを使用します。
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
というラベルを指定します。
- 今回はDeploymentでデプロイしたnginxの指定したいので、keyが
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)
間違いがあれば、コメントいただけると幸いです!
記事を読んでいただき、ありがとうございました!!