LoginSignup
0
0

More than 1 year has passed since last update.

Angularの開発環境セットアップ とコンテナビルドとK8sデプロイ

Posted at

はじめに

Single Page Applicationのフレームワーク Angular をコンテナで実行するまでを勉強したので、備忘録として残しておく。

1. node.jsのバージョン管理ツール nvm のセットアップ

macOSで、node.jsのバージョンを切り替えられるように、nvmをインストールして、その上でnode.jsを動作させ、Angularのコマンドを利用する。nvmのセットアップは、参考リンクを読めば解るので、補足はしない。

2. 最新バージョンのnode.jsをインストール

バージョンの指定無しでインストールを実行すれば、その時点の最新バージョンのnodeがインストールされる。

Terminal
$ nvm install
$ node --version

3. TypsScript コマンドのインストール

TypeScriptのスニペットのテストを実施するために、TypeScript から JavaScript への変換コマンド tsc をインストールする。TypeScriptをブラウザ上で実行するときは、JavaScriptへ変換されたコードが実行される。TypeScriptからnode.jsのモジュールを利用するなどもあるので、TypeScriptで書いたコードが、JavaScriptに変換されたときの内容が解るtscコマンドは重要なデバックツールになる。

Terminal
$ npm install -g typescript

4. Angular のコマンドをインストール

Angularのコマンドをインストールする。このコマンドは、Angularのアプリケーション開発の足がかりとなるコードを生成する。また、JavaScriptへ変換するビルドを実施することができる。

Terminal
$ npm install -g @angular/cli

Angularの ngコマンドのオプションなどは、参考URLで解説されているので、ブックマークしておくと重宝する。

5. Angular のサンプルアプリを作成してみる

Anglularでアプリケーションを開発するときは、最初に、最小コードやディレクトリ構造をngコマンドで生成してから、足していくのが良い。次のコマンドは、SPAのコード TestAppの足場となるコードを生成してくれる。

Terminal
$ ng new TestApp
? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? SCSS   [ https://sass-lang.com/documentation/syntax#scss                ]
<中略>
✔ Packages installed successfully.
    Successfully initialized git.

以下はアプリケーションのディレクトリTestApp 以下に生成されたファイル群だ。アプリケーションのコードは、以下に付け足していく形で、開発を推進することができる。

Terminal
$ tree TestApp/
TestApp/
├── README.md
├── angular.json
├── karma.conf.js
├── package.json
├── src
│   ├── app
│   │   ├── app.component.html
│   │   ├── app.component.scss
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   └── app.module.ts
│   ├── assets
│   ├── environments
│   │   ├── environment.prod.ts
│   │   └── environment.ts
│   ├── favicon.ico
│   ├── index.html
│   ├── main.ts
│   ├── polyfills.ts
│   ├── styles.scss
│   └── test.ts
├── tsconfig.app.json
├── tsconfig.json
└── tsconfig.spec.json

4 directories, 20 files

参考URL:

6. Angular のテスト実行

上記のコマンド実行で、必要なコードを生成してくれるので、ディレクトリを移動して、'ng serve'を実行すると、HTTPサーバーが起動して、Angularのコードを、ブラウザ上で実行できる準備が整う。

Terminal
$ cd TestApp
$ ng serve

ターミナルにアクセスするべきURLは表示されるので、curlコマンドやブラウザを使って、動作や画面を確認することができる。

参考URL https://angular.io/cli/serve

7. コンテナのビルド準備

コンテナ化する場合でも 'ng serve' をWebサーバーとして利用することも出来なくはないが、本番用ではないため、脆弱性やパフォーマンスの懸念がある。そこで、Nginxのコンテンツとして、AngularのSPAをサーブする。そのためのDockerfileが以下だ。ここでのポイントは、ビルドとNginxのコンフィグの消去である。

Dockerfile
# Stage 1 ビルドステージ
FROM node:latest as node
WORKDIR /app
COPY ./TestApp /app
RUN npm install
RUN npm run build --prod  # TypeScriptからJavaScriptへのビルド

# Stage 2 Nginxとの統合
FROM nginx:alpine
RUN rm /etc/nginx/conf.d/default.conf  # コンフィグの消去
COPY --from=node /app/dist/test-app /usr/share/nginx/html

ビルドでは、TypeScriptのソースコードから、ブラウザで実行するためのJavaScriptのコードを生成する。生成されたJavaScriptのコートは人が読むためのコードではなく、ブラウザで実行するためのコードなので、名称が変更されるなどが実施される。

Nginxとの統合では、Kubernetesにデプロイすることを想定して、TLSのための証明書、コンフィグファイルを、それぞれ、Secret, ConfigMapで外部から与えられるようにするために、default.confを消去しておく。そして、conf.d 以下を外部のボリュームから提供できるようにする。

ビルドステージで生成されたコードは、ディレクトリ dist/test-appに作成されるので、そのディレクトリ以下を、Nginxのドキュメントルート以下に、コピーする。

8. コンテナのビルドとローカルテスト

ここからは、Dokcerコマンドの使い方になる。必要となるオプションとパラメーターの意味は以下になる。

Terminal
export TAG=1.0
docker build -t <レジストリURL>/<ユーザーID>/<コンテナイメージ名>:$TAG .

筆者のローカルのラボ環境に、コンテナレジストリでCNCF の Harborを立てている場合は、タグを初めから設定しておくと便利だ。

Terminal
export TAG=1.0
docker build -t harbor.labo.local/tkr/spa:$TAG .

ビルドが完了したら、実行してアクセステストを実施する。同様にオプションは以下である。

Terminal
docker run --rm --name spa -p <公開ポート>:<コンテナポート> -v <ホストの絶対パス>:<コンテナ上のマウント位置> <レジストリURL>/<ユーザーID>/<コンテナイメージ名>:$TAG

環境依存なので、参考程度に残しておく。 「-p」では、ポート番号はHTTPとHTTPSの両方のポートを開く。「-v」では、TLSのためのサーバー証明書と、Nginxのconf.d以下を、外部から与える。

Terminal
docker run --rm --name spa -p 5080:5080 -p 5443:5443 -v `pwd`/certs:/certs -v `pwd`/nginx:/etc/nginx/conf.d  harbor.labo.local/tkr/spa:$TAG

9. レジストリへ登録

Kubernetesでコンテナを実行するためには、コンテナをレジストリに登録しなければならない。以下は、レジストリに登録するには、アカウントを保有しており、そのアカウントでログインしていなければならない。この例では、コンテナレジストリ Harbor にログインしておき、登録するときのコマンド例だ。

Terminal
docker login -u tkr harbor.labo.local
docker push harbor.labo.local/tkr/spa:$TAG

10. Kubernetesへのデプロイ

アプリケーション専用の名前空間を作成しておき、公開用IPアドレスからDNSを登録するために、ロードバランサーをデプロイする。

Terminal
# 名前空間の作成
kubectl create ns spa

# ロードバランサーの設定、VIPの獲得
kubectl apply -f yamls/service.yaml -n spa

作業の前提として、以下の3点がある。特に、サーバー証明書のドメイン名が、DNS登録名と一致している昼用があるので、面倒だけど、外せない。

  • コンテナはレジストリへ登録しておく。
  • プライベートCAでサーバー証明書を作成しておく。
  • プライベートDNSにドメイン名を登録しておく。

TLS用のサーバー証明書は、Secret spa.tlsに保存、そして、 Nginxのコンフィルは、Configmap nginx-configへ保存する。

Terminal
# サーバー証明書をデプロイ
kubectl create secret tls spa.tls \
  --cert=certs/tls.crt \
  --key=certs/tls.key \
  -n spa

# Nginxの設定ファイルをデプロイ
kubectl create configmap nginx-config --from-file=nginx -n spa

最後にKubernetesへデプロイする。

Terminal
# コンテナのデプロイ、ロードバランサーの設定
kubectl apply -k yamls -n spa

これで、kubectl get po -n spakubectl get svc -n spa で確認すれば良い。

11. プロジェクトのファイル構成

コンテナやKubernetesのYAMLなどを一箇所に集約して、プロジェクト用のディレクトリを作成しておくとと便利だ。nginx と yamlsの部分の内容は、後述する。

$ tree angular-apl
angular-apl
├── Dockerfile
├── README.md
├── TestApp
│   ├── README.md
│  <以下省略 前述に同じため>
│  
├── certs
│   ├── tls.crt
│   └── tls.key
├── nginx
│   ├── default.conf
│   └── ssl-server.conf
└── yamls
    ├── deployment.yaml
    ├── kustomization.yaml
    └── service.yaml

12. Nginxのコンフィルファイル

'/etc/nginx/conf.d' に配置する HTTPの設定ファイルである。 OpenShift環境へのデプロイも考慮して、特権ポートを避ける設定にする。

default.conf
server {
    listen       5080;
    server_name  spa.labo.local;
    location / {        
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

こちらは、TLSで暗号化するWebサーバーの設定である。証明書と鍵は/certsの下にマウントする想定だ。

ssl-server.conf
server {
    listen 5443 ssl http2;
    #listen [::]:5443 ssl http2;
    server_name         spa.labo.local;
    root                /usr/share/nginx/html;
    ssl_certificate     /certs/tls.crt;
    ssl_certificate_key /certs/tls.key;
    ssl_session_timeout 1d;
    ssl_session_cache   shared:SharedNixCraftSSL:10m; 
    ssl_session_tickets off;
    ssl_protocols       TLSv1.3;
    ssl_prefer_server_ciphers off;
}

13. Kubernetes の YAMLファイル

ロードバランサーのIPアドレスは、アサインされるので、先にデプロイしておいて、IPアドレスをDNSへ登録するのが良いと思う。クラウドやKubernetesクラスタの構成により変わるので、参考程度にみて欲しい。

service.yaml
apiVersion: v1
kind: Service
metadata:
  name: spa
spec:
  selector:
    app: spa
    group: spa-group
  ports:
  - name: https
    protocol: TCP
    port: 443
    targetPort: 5443
  - name: http
    protocol: TCP
    port: 80
    targetPort: 5080
  type: LoadBalancer

予めレジストリへ登録しておいたコンテナ harbor.labo.local/tkr/spa:1.0 を指定して、
ConfigMapとSecretをボリュームとしてマウントする。

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spa
spec:
  replicas: 1
  selector:
    matchLabels:
      app: spa
      group: spa-group
  template:
    metadata:
      labels:
        app: spa
        group: spa-group
    spec:
      #imagePullSecrets:
      #- name: regcred
      containers:
      - name: spa
        image: harbor.labo.local/tkr/spa:1.0
        imagePullPolicy: Always
        volumeMounts:
        - name: tls
          mountPath: /certs
        - name: config
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: tls
        secret:
          secretName: spa.tls
      - name: config
        configMap:
          name: nginx-config

さらにYAMLファイルが増える場合は、適用の順序が保証されるので、作成しておくと便利だ。

kustomization.yaml
resources:
- service.yaml
- deployment.yaml

以上

0
0
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
0
0