コンテナ初学者の新人社員でk8sを勉強しています。
今回はAWSのEC2にMinikubeをインストールして、nginxのテストページが見れるまでの手順を記したいと思います。
開発環境
- AWS EC2 t3.small
今回、Minikubeを利用する環境として、EC2のt3.smallを選択しました。
2GB以上のメモリや20GB以上のディスクスペースがないとMinikubeをうまくインストールできないようです。
多少料金がかかってしまいます。試す場合は注意しましょう。
準備
EC2インスタンスを起動する手順までは省きます。私はやりなれているUbuntuをインストールしたEC2を選択しました。
以下のように入力して起動したEC2に接続します。
$ ssh -i test-key.pem ubuntu@xxx.xxx.xxx.xxx
test-key.pem はEC2を作成した際にダウンロードした鍵のファイル名です。
xxx.xxx.xxx.xxx はEC2のパブリックIPを指定します。
Dockerのインストール
無事EC2に接続できたらDockerをインストールしましょう。
ほぼ公式の手順通りです。
# Ubuntuのパッケージをアップデート
$ sudo apt-get update
# 必要なパッケージのインストール
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# Dockerの公式GPGキーの追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Dockerのダウンロードサイトをaptレポジトリに追加
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# Docker Engineのインストール
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
# バージョンが表示されればインストール成功
$ sudo docker --version
Minikubeのインストール
続いてMinikubeをインストールしましょう。
# minikubeのダウンロードと実行権限の付与
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
&& chmod +x minikube
# minikubeバイナリの移動
$ sudo mv minikube /usr/local/bin/
# バージョンが表示されればインストール成功
# minikube version
kubectlのインストール
Kubernetesはkubectlコマンドを使って操作するので、kubectlコマンドをインストールしていきます。
公式の手順通りです。
# 必要なパッケージのインストール
$ sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2
# kubectlのパッケージを追加
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
# kubectlのインストール
$ sudo apt-get update
$ sudo apt-get install -y kubectl
# バージョンが表示されればインストール成功
$ kubectl version --client
最後にMinikubeを起動します。
エラーがなければ無事起動できています。
$ sudo minikube start --vm-driver=none
・
・
・
💡 This can also be done automatically by setting the env var CHANGE_MINIKUBE_NONE_USER=true
🔎 Verifying Kubernetes components...
🌟 Enabled addons: storage-provisioner, default-storageclass
🏄 Done! kubectl is now configured to use "minikube" by default
マニフェストファイルの作成
kubectlを用いてリソースの操作をするわけですが、リソースの設定値が多いので、kubectlの引数で細かく設定するのはあまり現実的ではありません。
そのため、リソースの情報はファイルに記述しておいて、作成したファイルをkubectlに読み込ませるというやり方が一般的なようです。
リソースの情報を「マニフェスト」と呼び、それを記述したファイルのことを「マニフェストファイル」と呼びます。
マニフェストファイルはJSON形式またはYAML形式で記述するのですが、読みやすいYAML形式で記述されているものがほとんどです。
Pod作成
それでは nginx のPodを作っていきましょう。
Podのマニフェストファイルは以下のように記述しました。
apiVersion: v1
kind: Pod
metadata:
name: test-nginx
spec:
containers:
- name: my-nginx-container
image: nginx:latest
ports:
- containerPort: 80
Podをつくりたいので、kindにはPodと指定しておきます。
metadataには、Podの名前を指定します。test-nginxとしました。
specでは、Podの詳細情報を記します。
containerの項目では、nameにコンテナ名、imageにはイメージ名、portsではコンテナが使用するポート番号を指定します。
# Pod作成
$ kubectl create -f nginx.yaml
pod/test-nginx created
# Podの状態を確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
test-nginx 1/1 Running 0 8s
# Podの詳細情報の取得
$ kubectl describe pods my-pod
Name: test-nginx
Namespace: default
Priority: 0
Node: ip-10-0-1-23/10.0.1.23
Start Time: Sat, 14 Nov 2020 10:28:37 +0000
Labels: <none>
Annotations: <none>
Status: Running
IP: 172.17.0.3
IPs:
IP: 172.17.0.3
Containers:
my-nginx-container:
Container ID: docker://a580525cc1eb22f7a237b2d3424f8899ba04cf17ec71a1c2810c6d7e9700ebfc
Image: nginx:latest
Image ID: docker-pullable://nginx@sha256:aeade65e99e5d5e7ce162833636f692354c227ff438556e5f3ed0335b7cc2f1b
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sat, 14 Nov 2020 10:28:42 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5qpwm (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-5qpwm:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-5qpwm
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m16s default-scheduler Successfully assigned default/test-nginx to ip-10-0-1-23
Normal Pulling 2m16s kubelet Pulling image "nginx:latest"
Normal Pulled 2m13s kubelet Successfully pulled image "nginx:latest" in 3.237396456s
Normal Created 2m13s kubelet Created container my-nginx-container
Normal Started 2m12s kubelet Started container my-nginx-container
kubectl describe
でPodのIPアドレスは 172.17.0.3
だということがわかりました。
curlコマンドを実行してみると、nginxが起動していることがわかります。
ただこのままだとテストページを見ることができません。
$ curl 172.17.0.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
テストページの確認
今度はテストページが見れるようにするための設定をしていきましょう。
あまり意味はないですが、複数Podの起動も合わせてやっていきましょう。
Deplymentの作成
Deploymentを使って複数Podを作成できるようにします。
Deploymentのマニフェストファイルは以下のように記述しました。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deploymnet
spec:
replicas: 2
selector:
matchLabels:
app: my-nginx
template:
metadata:
labels:
app: my-nginx
spec:
containers:
- name: test-nginx
image: nginx:latest
ports:
- containerPort: 80
DeploymentのAPIGROUPはappsなので、apiVersionを apps/v1
とします。kubectl api-resources
と実行すると確認できます。
metadataでは、Deploymentの名前を指定します。
specでは、Deploymentの詳細情報を記述していきます。
ReplicaSetでは、レプリカ数を指定します。このファイルの場合、同じ構成のPodを2つ作成するという意味になります。
selectorでは、どのようなPodを作成するのかを指定します。app: my-nginxと指定しますが、すぐ下のtemplateで定義されたものを使用するという意味です。
templateで具体的なPodの情報を記述します。selectorで選択してもらえるようにapp: my-nginx と設定します。
それ以外は nginx.yaml
と同じように記述します。
Serviceの作成
次はServiceを使って外部からアクセスできるようにします。
Serviceのマニフェストファイルは以下のように記述しました。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
ports:
- nodePort: 30000
port: 8080
targetPort: 80
protocol: TCP
selector:
app: my-nginx
apiVersionでは、kubectl api-resources
で確認したところ空欄なのでv1
とします。
metadataでは、Serviceの名前を指定します。
specでは、Serviceの詳細を記述していきます。
typeはServiceの種類を指定します。ここでは、ノード(今回だとEC2)のIPアドレスを通じてアクセスできるNodePortとしました。試してないですが、ほかの種類にしてもできるかもしれません。
portsでは、ポートの設定を行います。
nodePortはノードのポート番号、portはServiceのポート番号、targetPortはPodのポート番号です。
ノードがポート30000で通信を待ち受け、そこからServiceのポート8080に転送、最後にPodのポート80に転送というような流れとなります。
Serviceを使ってnginxのテストページを確認する
DeploymentとService オブジェクトを用いて、nginxのテストページを確認していきます。
Serviceのポートは8080、ノードのポートには30000が割り当てられていることがわかります。
# Deploymentオブジェクトの作成
$ kubectl create -f deployment.yaml
deployment.apps/my-deploymnet created
# Serviceオブジェクトの作成
$ kubectl create -f service.yaml
service/nginx-service created
# Serviceの状態を確認
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
nginx-service NodePort 10.110.191.26 <none> 8080:30000/TCP 82s
まだやることがあります。
EC2のセキュリティグループの設定で30000ポートを許可してあげないとテストページが見れません。
※初めてやったときにここでつまりました笑
AWSにログインして、EC2 > セキュリティグループでEC2に割り当てたセキュリティグループ名を選択し、インバウンドルールを編集というボタンがあるのでそのボタンをクリックします。
ブラウザで xxx.xxx.xxx.xxx:30000
(xxx.xxx.xxx.xxxはEC2のパブリックIP)に接続するとnginxのテストページを確認できました。
感想
今回の検証を通して、Kubernetesの基本的な使い方をなんとなく知ることができました。
手を動かしたほうが、理解が進んだような気がします。
今度は以前やったBIND, Unboundのマニフェスト化に取り組んでいけたらと思います。