LinuCエヴァンジェリストの鯨井貴博@opensourcetechです。
はじめに
今回は、こちらの記事で作成したkubernetesクラスター v1.26.00で、
nginxコンテナ(Pod)のコンテンツファイル(index.html)をConfigMapを使って提供、またコンテンツファイルの更新をやってみます。
実施する内容
以下のように進めていきます。
①コンテンツファイル index.html(ConfigMap)の作成
※Deploymentで指定する
②nginxコンテナ(Deployment)のデプロイ
③コンテナの公開(Service)
④クライアントからのアクセス
⑤コンテンツファイルの更新
①コンテンツファイル index.html(ConfigMap)の作成
まず、HTML/CSSでindex.htmlを作成します。
kubeuser@master01:~/configmap$ ls
current
kubeuser@master01:~/configmap$ ls current/
index.html
kubeuser@master01:~/configmap$ cat ./current/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: 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>
作成したindex.htmlを元に、ConfigMapを作成します。
kubeuser@master01:~/configmap$ kubectl create configmap index-dark --from-file ./current/index.html --dry-run=client -o yaml > configmap_dark.yaml
kubeuser@master01:~/configmap$ ls
configmap_dark.yaml current
kubeuser@master01:~/configmap$ cat configmap_dark.yaml
apiVersion: v1
data:
index.html: |
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: 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>
kind: ConfigMap
metadata:
creationTimestamp: null
name: index-dark
kubeuser@master01:~/configmap$ kubectl apply -f configmap_dark.yaml
configmap/index-dark created
kubeuser@master01:~/configmap$ kubectl get cm
NAME DATA AGE
index-dark 1 4s
kube-root-ca.crt 1 4d19h
②nginxコンテナ(Deployment)のデプロイ
続いて、作成したConfigMapを読み込むDeploymentを作成して、
nginxコンテナをデプロイします。
※replicas 1、nginxのバージョンは1.23.0としました。
まずDeploymentのyamlを作成。
kubeuser@master01:~/configmap$ vi deployment.yaml
kubeuser@master01:~/configmap$ cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.23.0
name: nginx
volumeMounts:
- name: index-volume
mountPath: /usr/share/nginx/html
volumes:
- name: index-volume
configMap:
name: index-dark
作成したyamlをデプロイします。
kubeuser@master01:~/configmap$ kubectl apply -f deployment.yaml deployment.apps/nginx created kubeuser@master01:~/configmap$ kubectl get all NAME READY STATUS RESTARTS AGE pod/nginx-59d7dcfd48-zl9zk 1/1 Running 0 23s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 4d19h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 23s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-59d7dcfd48 1 1 1 23s
③コンテナの公開(Service)
Serviceのyamlを作成します。
※type:LoadBalancerとしています。
※type:LoadBalancerに関しては、こちらを参照ください。
kubeuser@master01:~/configmap$ kubectl expose deployment nginx --port=80 --type=LoadBalancer --dry-run=client -o yaml > svc.yaml
kubeuser@master01:~/configmap$ cat svc.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
status:
loadBalancer: {}
yamlをデプロイします。
kubeuser@master01:~/configmap$ kubectl apply -f svc.yaml service/nginx created kubeuser@master01:~/configmap$ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 4d19h nginx LoadBalancer 10.1.231.71 192.168.1.51 80:30066/TCP 5s
④クライアントからのアクセス
クライアント(ブラウザ)からアクセスできました!

⑤コンテンツファイルの更新
次は、HPの更新などを想定した操作(index.htmlの入れ替え)をやってみます。
基本的には①と同じ手順で新しいコンテンツファイルを作成して、
②のDeployment用のyamlを編集してデプロイすればOKです。
"new"というディレクトリを更新用に使いました。
kubeuser@master01:~/configmap$ ls -R
.:
current new
./current:
index.html
./new:
index.html
kubeuser@master01:~/configmap$ cat ./new/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light; }
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>
ConfigMapの作成からデプロイ。
kubeuser@master01:~/configmap$ kubectl create configmap index-light --from-file ./new/index.html --dry-run=client -o yaml > configmap_light.yaml kubeuser@master01:~/configmap$ ls configmap_dark.yaml configmap_light.yaml current deployment.yaml new svc.yaml kubeuser@master01:~/configmap$ kubectl apply -f configmap_light.yaml configmap/index-light created kubeuser@master01:~/configmap$ kubectl get cm NAME DATA AGE index-dark 1 17m index-light 1 4s kube-root-ca.crt 1 4d19h
Deploymentのyaml(ConfigMapの箇所)を更新します。
kubeuser@master01:~/configmap$ vi deployment.yaml
kubeuser@master01:~/configmap$ cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx:1.23.0
name: nginx
volumeMounts:
- name: index-volume
mountPath: /usr/share/nginx/html
volumes:
- name: index-volume
configMap:
#name: index-dark
name: index-light
yamlをデプロイすると、既存のDeploymentが更新(Podの削除→再作成)されます。
kubeuser@master01:~/configmap$ kubectl apply -f deployment.yaml kudeployment.apps/nginx configured kubeuser@master01:~/configmap$ kubectl get pod -w NAME READY STATUS RESTARTS AGE nginx-59d7dcfd48-zl9zk 1/1 Terminating 0 87m nginx-7fffd76c68-phbbm 1/1 Running 0 3s nginx-59d7dcfd48-zl9zk 1/1 Terminating 0 87m nginx-59d7dcfd48-zl9zk 0/1 Terminating 0 87m nginx-59d7dcfd48-zl9zk 0/1 Terminating 0 87m nginx-59d7dcfd48-zl9zk 0/1 Terminating 0 87m kubeuser@master01:~/configmap$ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-7fffd76c68-phbbm 1/1 Running 0 12s
クライアント(ブラウザ)からアクセス(F5などをクリックして再読み込み)すると、
更新されたコンテンツが表示されます。

おわりに
今回やってみて、改めてkubernetesは様々なものをリソース(Deployment・ConfigMapなど)で定義するんだなぁと感じました。
仮想マシン(VM)などでWebサーバを作る場合は
OS・Webサーバソフトウェア・コンテンツが一体(密結合)となっていますが、
kubernetesの場合、Deployment(Pod)がWebサーバソフトウェア、
ConfigMapがコンテンツとそれぞれ独立(疎結合)になっています。
コンテンツファイルを更新する作業自体はどちらも似たような感覚を持ちましたが、実施している内容(挙動)は異なることを意識する必要がありますね。
なお、通常はDeployment配下のPodを冗長(Replicasを2以上)にするかと思うので、
仮想マシンのように全台で更新作業をしなくていいのはkubernetesが疎結合であるメリットですね!