Opensourcetechブログ

OpensourcetechによるNGINX/Kubernetes/Zabbix/Neo4j/Linuxなどオープンソース技術に関するブログです。

nginxコンテナ(Pod)のコンテンツ(index.html)をConfigMapで提供・更新する(kubernetes)


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が疎結合であるメリットですね!

Opensourcetech by Takahiro Kujirai