k8s環境ハンズオン webアプリケーション構築実践編
本セクションではminikubeの中に三層アプリを構築してきます。
- デバッグ用イメージ作成
- DBサーバーのイメージ作成
- DBサーバーの構築(ストレージ)
- DBサーバーの構築(Pod)
- DBサーバーの構築(Pod+Secret)
- DBサーバーの構築(StatefulSet)
- DBサーバーの構築(HeadlessService)
- DBサーバーの構築(初期化)
- APサーバーのイメージ作成
- APサーバーの構築(Pod+Secret)
- APサーバーの構築(Deployment)
- APサーバーの構築(Service)
- WEBサーバーのイメージ作成
- WEBサーバーの構築(Pod)
- WEBサーバーの構築(Pod+ConfigMap)
- WEBサーバーの構築(Deployment)
- WEBサーバーの構築(Service)
- Webアプリケーションの公開(Ingress)
作成するアプリ
minikubeの中に三層アプリを構築
web→ap→db→localstorage
デバッグ用イメージ作成
実装
- 以下の3ファイルを作成
mongodb-org-4.0.repo
Dockerfile
debug-pod.yml
確認
Docker
1. Dockerで作成したイメージを実行
2. 実行中コンテナに入る
3. 必要なコマンドが実行可能なことを確認
Kubernetes
1. Podを作成
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
FROM centos:7
COPY . /tmp/debug
RUN \
# Install MongoDB shell, tools.
mv /tmp/debug/mongodb-org-4.0.repo /etc/yum.repos.d; \
yum install -y mongodb-org-shell-4.0.5 mongodb-org-tools-4.0.5; \
# Install ip , ifconfig command.
yum install -y iproute net-tools; \
# Install jq
curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64; \
chmod +x /usr/local/bin/jq; \
# Delete cache files.
yum clean all;
apiVersion: v1
kind: Pod
metadata:
name: debug
namespace: default
spec:
containers:
- name: debug
image: debug
imagePullPolicy: Never
command:
- "sh"
- "-c"
args:
- |
while true
do
sleep 5
done
上記3ファイルをvmにうつし、ビルドコマンド実行
(dockerfileにビルド申請を投げかける)
docker build -t debug .
debugイメージの確認
docker image ls
debugイメージを実行する
docker run -it debug sh
入り込んだコンテナで下記のコマンドでipを確認
ip;mongo;ifconfig;
mongodbが正しく動いている確認したら
コンテナを削除する。
docker container prune
続いてk8sで動作させるマニフェストファイルapplyする
kubectl apply -f debug-pod.yml
# 動作確認
kubectl get pod
中に入って動作確認する
kubectl exec -it debug sh
ip;mongo;ifconfig;
exit;
# 動作確認
kubectl get pod
DBサーバーのイメージ作成
実装
- 以下の3ファイルを作成
.dockerignore
docker-entrypoint.sh
Dockerfile
確認
- Dockerで作成したイメージを実行
- 実行中コンテナに入る
- MongoDBに接続できることを確認
**/.git
**/.DS_Store
**/node_modules
# ! /bin/sh
INIT_FLAG_FILE=/data/db/init-completed
INIT_LOG_FILE=/data/db/init-mongod.log
start_mongod_as_daemon() {
echo
echo "> start mongod ..."
echo
mongod \
--fork \
--logpath ${INIT_LOG_FILE} \
--quiet \
--bind_ip 127.0.0.1 \
--smallfiles;
}
create_user() {
echo
echo "> create user ..."
echo
if [ ! "$MONGO_INITDB_ROOT_USERNAME" ] || [ ! "$MONGO_INITDB_ROOT_PASSWORD" ]; then
return
fi
mongo "${MONGO_INITDB_DATABASE}" <<-EOS
db.createUser({
user: "${MONGO_INITDB_ROOT_USERNAME}",
pwd: "${MONGO_INITDB_ROOT_PASSWORD}",
roles: [{ role: "root", db: "${MONGO_INITDB_DATABASE:-admin}"}]
})
EOS
}
create_initialize_flag() {
echo
echo "> create initialize flag file ..."
echo
cat <<-EOF > "${INIT_FLAG_FILE}"
[$(date +%Y-%m-%dT%H:%M:%S.%3N)] Initialize scripts if finigshed.
EOF
}
stop_mongod() {
echo
echo "> stop mongod ..."
echo
mongod --shutdown
}
if [ ! -e ${INIT_LOG_FILE} ]; then
echo
echo "--- Initialize MongoDB ---"
echo
start_mongod_as_daemon
create_user
create_initialize_flag
stop_mongod
fi
exec "$@"
FROM alpine:3.9
COPY docker-entrypoint.sh /usr/local/bin
RUN \
adduser -g mongodb -DH -u 1000 mongodb; \
apk --no-cache add mongodb=4.0.5-r0; \
chmod +x /usr/local/bin/docker-entrypoint.sh; \
mkdir -p /data/db; \
chown -R mongodb:mongodb /data/db;
VOLUME /data/db
EXPOSE 27017
ENTRYPOINT [ "docker-entrypoint.sh" ]
CMD [ "mongod" ]
セットしたdockerfileをビルドする。
docker build -t weblog-db:v1.0.0 .
dockerをデーモン起動する。
docker run -d weblog-db:v1.0.0
起動しているかコンテナ一覧確認
[root@localhost ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46aa0fa9b017 2d3813851e87 "kube-scheduler --bi…" About a minute ago Up About a minute k8s_kube-scheduler_kube-scheduler-minikube_kube-system_31d9ee8b7fb12e797dc981a8686f6b2b_6
88649a10f187 weblog-db:v1.0.0 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 27017/tcp gifted_spence
コンテナの中に入ってmongodbが動作しているか確認
docker exec -it gifted_spence sh
mongodbが正しく動いている確認
show dbs
dockerコンテナ停止して削除
[root@localhost ~]# docker stop gifted_spence
gifted_spence
[root@localhost ~]# docker system prune
DBサーバーの構築(ストレージ)
実装
- 以下のファイルを作成
weblog-db-storage.yml
確認
※必要なフォルダが作成されていること
- PersistentVolume、PersistentVolumeClaimを作成
- 作成したリソースを確認
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/storage"
type: Directory
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: storage-claim
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
DBサーバーの構築(Pod)
実装
- 以下のファイルを作成
weblog-db-pod.yml
確認
※必要なフォルダが作成されていること
※作成されたフォルダは空であること
- PersistentVolume, PersistentVolumeClaim, Podを作成
- MongoDBのファイルが作成されていることを確認
- 作成したPodへ入る
- MongoDBへ接続確認
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/storage"
type: Directory
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: storage-claim
labels:
app: weblog
type: storage
spec:
storageClassName: slow
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: mongodb
namespace: default
labels:
app: weblog
type: database
spec:
containers:
- name: mongodb
image: weblog-db:v1.0.0
imagePullPolicy: Never
command:
- "mongod"
- "--bind_ip_all"
volumeMounts:
- mountPath: /data/db
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: storage-claim
DBサーバーの構築(Pod+Secret)
実装
- keyfile(ランダム文字列)を作成
- Secretリソースを作成
- SecretリソースのYAMLを取得
- weblog-db-pod.ymlへマージ
- Secretリソースを削除
確認
※必要なフォルダが作成されていること
※作成されたフォルダは空であること
- PersistentVolume, Pod, Secretを作成
- 作成したPodへ入る
- MongoDBへ接続
- 設定したユーザー名/パスワードで認証
- DB一覧を表示
DFCytNO0mwawyBs25EOwptvC1TicPzI39KkojjhfE7HeR/VvryeNwqdOvOwiZ9jP/pIWIeYUYiktZXfXhOOlyMBEwUCGr+umbmEeududNy4hQCsVe0YOSlX07Xqa//o+mz4Z8pEchN0wUahqpHD5ieFyoMNIVaEcFPF43+3vZovw7M4xaY+xhhnW5etgm/c2g9GaGlJ4aXPXJbHQTylscnivBrmWiIY+JAPc+oFGJL5I3OCiSR1d66gG99ysof76Rtx0MvYgWdX9rSe16odaI3IWtmhI2CLbWpS994nYcWTCbtor3fMC1cs8nNRWy1un+JbbPooMqiRObxRncHap2X+pOKtjYPg+YKX1Htf+XyaH7DrFdZMnsVbAtAgV6Cf67IZym65p8LjjFkhZTbn5ZMgjQinwerkB+QC5hmaQQhAu6z5te+kPrsQg4PQ/JCRL7vweZEzddwlCo8NYGUJXaSG0Lg2k7wDx9oHLTuA/Telit2VrfgRbU6Y6f6FEOczjKnHKgHT09RJa56wdihgHreyWbVCC7BfdFJ2zRj1fG5YEgpkA3pgMsuvUDi6Ai6tNVe3O3jAqCmXghpFbryi9XYgtDsQkpGPRUZyLvNBj5k8qBoiYkiHPWvyIbyB9SX0pcyP10R8zR0TB8pXUZb3Xh1p4VDMTtg5u8Wwf56pIrWe3KYj20P2wWyQ3glDo5GMJxUdoubTxOun2+V0J6Oc0dKlmweqEjAbakJiDdyvty2OggnbgRSNYZInNKVR9nbnPUE/kCSMbNeE5hVVFC0zx6FKHkdxiZFEv8bP/LR4hY49OEZa9vuPRBn2LqflucO7wm5OnD8mN3PY8LlpN6SWCUTGJ2qfwm36vjRKpHxnFH6IcyDVwmbPulCMEnfnL5rKJ/4bZGiE1SQobQGYD/Gbq1UFWok0FMfTFV1wetQfVv32SISJ6PUJM2iThBJWDPNVTmKf28Dlq2NaLFMd1ugKxAWP2fN9YOgw6ZuiiRB/6UbIM7Ms2FWfytGp2oYcy94XP
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/storage"
type: Directory
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: storage-claim
labels:
app: weblog
type: storage
spec:
storageClassName: slow
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
namespace: default
labels:
app: weblog
type: database
type: Opaque
data:
root_username: YWRtaW4=
root_password: UGFzc3cwcmQ=
keyfile: REZDeXROTzBtd2F3eUJzMjVFT3dwdHZDMVRpY1B6STM5S2tvampoZkU3SGVSL1Z2cnllTndxZE92T3dpWjlqUC9wSVdJZVlVWWlrdFpYZlhoT09seU1CRXdVQ0dyK3VtYm1FZXVkdWROeTRoUUNzVmUwWU9TbFgwN1hxYS8vbyttejRaOHBFY2hOMHdVYWhxcEhENWllRnlvTU5JVmFFY0ZQRjQzKzN2Wm92dzdNNHhhWSt4aGhuVzVldGdtL2MyZzlHYUdsSjRhWFBYSmJIUVR5bHNjbml2QnJtV2lJWStKQVBjK29GR0pMNUkzT0NpU1IxZDY2Z0c5OXlzb2Y3NlJ0eDBNdllnV2RYOXJTZTE2b2RhSTNJV3RtaEkyQ0xiV3BTOTk0blljV1RDYnRvcjNmTUMxY3M4bk5SV3kxdW4rSmJiUG9vTXFpUk9ieFJuY0hhcDJYK3BPS3RqWVBnK1lLWDFIdGYrWHlhSDdEckZkWk1uc1ZiQXRBZ1Y2Q2Y2N0laeW02NXA4TGpqRmtoWlRibjVaTWdqUWlud2Vya0IrUUM1aG1hUVFoQXU2ejV0ZStrUHJzUWc0UFEvSkNSTDd2d2VaRXpkZHdsQ284TllHVUpYYVNHMExnMms3d0R4OW9ITFR1QS9UZWxpdDJWcmZnUmJVNlk2ZjZGRU9jempLbkhLZ0hUMDlSSmE1NndkaWhnSHJleVdiVkNDN0JmZEZKMnpSajFmRzVZRWdwa0EzcGdNc3V2VURpNkFpNnROVmUzTzNqQXFDbVhnaHBGYnJ5aTlYWWd0RHNRa3BHUFJVWnlMdk5CajVrOHFCb2lZa2lIUFd2eUlieUI5U1gwcGN5UDEwUjh6UjBUQjhwWFVaYjNYaDFwNFZETVR0ZzV1OFd3ZjU2cElyV2UzS1lqMjBQMndXeVEzZ2xEbzVHTUp4VWRvdWJUeE91bjIrVjBKNk9jMGRLbG13ZXFFakFiYWtKaURkeXZ0eTJPZ2duYmdSU05ZWkluTktWUjluYm5QVUUva0NTTWJOZUU1aFZWRkMweng2RktIa2R4aVpGRXY4YlAvTFI0aFk0OU9FWmE5dnVQUkJuMkxxZmx1Y083d201T25EOG1OM1BZOExscE42U1dDVVRHSjJxZndtMzZ2alJLcEh4bkZINkljeURWd21iUHVsQ01FbmZuTDVyS0ovNGJaR2lFMVNRb2JRR1lEL0dicTFVRldvazBGTWZURlYxd2V0UWZWdjMyU0lTSjZQVUpNMmlUaEJKV0RQTlZUbUtmMjhEbHEyTmFMRk1kMXVnS3hBV1AyZk45WU9ndzZadWlpUkIvNlViSU03TXMyRldmeXRHcDJvWWN5OTRYUAo=
---
apiVersion: v1
kind: Pod
metadata:
name: mongodb
namespace: default
labels:
app: weblog
type: database
spec:
containers:
- name: mongodb
image: weblog-db:v1.0.0
imagePullPolicy: Never
args:
- "mongod"
- "--auth"
- "--bind_ip_all"
env:
- name: "MONGO_INITDB_ROOT_USERNAME"
valueFrom:
secretKeyRef:
name: mongo-secret
key: root_username
- name: "MONGO_INITDB_ROOT_PASSWORD"
valueFrom:
secretKeyRef:
name: mongo-secret
key: root_password
- name: "MONGO_INITDB_DATABASE"
value: "admin"
volumeMounts:
- mountPath: /data/db
name: storage
- mountPath: /home/mongodb
name: secret
volumes:
- name: storage
persistentVolumeClaim:
claimName: storage-claim
- name: secret
secret:
secretName: mongo-secret
items:
- key: keyfile
path: keyfile
mode: 0700
DBサーバーの構築(StatefulSet)
実装
- 以下のファイルを作成
weblog-db-statefulset.yml
確認
※必要なフォルダが作成されていること
※作成されたフォルダは空であること
- PersistentVolume, Secret, StatefulSetを作成
- 作成したPodへ入る
- MongoDBへ接続
- 設定したユーザー名/パスワードで認証
- DB一覧を表示
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume-0
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/pv0000"
type: Directory
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume-1
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/pv0001"
type: Directory
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume-2
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/pv0002"
type: Directory
---
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
namespace: default
labels:
app: weblog
type: database
type: Opaque
data:
root_username: YWRtaW4=
root_password: UGFzc3cwcmQ=
keyfile: REZDeXROTzBtd2F3eUJzMjVFT3dwdHZDMVRpY1B6STM5S2tvampoZkU3SGVSL1Z2cnllTndxZE92T3dpWjlqUC9wSVdJZVlVWWlrdFpYZlhoT09seU1CRXdVQ0dyK3VtYm1FZXVkdWROeTRoUUNzVmUwWU9TbFgwN1hxYS8vbyttejRaOHBFY2hOMHdVYWhxcEhENWllRnlvTU5JVmFFY0ZQRjQzKzN2Wm92dzdNNHhhWSt4aGhuVzVldGdtL2MyZzlHYUdsSjRhWFBYSmJIUVR5bHNjbml2QnJtV2lJWStKQVBjK29GR0pMNUkzT0NpU1IxZDY2Z0c5OXlzb2Y3NlJ0eDBNdllnV2RYOXJTZTE2b2RhSTNJV3RtaEkyQ0xiV3BTOTk0blljV1RDYnRvcjNmTUMxY3M4bk5SV3kxdW4rSmJiUG9vTXFpUk9ieFJuY0hhcDJYK3BPS3RqWVBnK1lLWDFIdGYrWHlhSDdEckZkWk1uc1ZiQXRBZ1Y2Q2Y2N0laeW02NXA4TGpqRmtoWlRibjVaTWdqUWlud2Vya0IrUUM1aG1hUVFoQXU2ejV0ZStrUHJzUWc0UFEvSkNSTDd2d2VaRXpkZHdsQ284TllHVUpYYVNHMExnMms3d0R4OW9ITFR1QS9UZWxpdDJWcmZnUmJVNlk2ZjZGRU9jempLbkhLZ0hUMDlSSmE1NndkaWhnSHJleVdiVkNDN0JmZEZKMnpSajFmRzVZRWdwa0EzcGdNc3V2VURpNkFpNnROVmUzTzNqQXFDbVhnaHBGYnJ5aTlYWWd0RHNRa3BHUFJVWnlMdk5CajVrOHFCb2lZa2lIUFd2eUlieUI5U1gwcGN5UDEwUjh6UjBUQjhwWFVaYjNYaDFwNFZETVR0ZzV1OFd3ZjU2cElyV2UzS1lqMjBQMndXeVEzZ2xEbzVHTUp4VWRvdWJUeE91bjIrVjBKNk9jMGRLbG13ZXFFakFiYWtKaURkeXZ0eTJPZ2duYmdSU05ZWkluTktWUjluYm5QVUUva0NTTWJOZUU1aFZWRkMweng2RktIa2R4aVpGRXY4YlAvTFI0aFk0OU9FWmE5dnVQUkJuMkxxZmx1Y083d201T25EOG1OM1BZOExscE42U1dDVVRHSjJxZndtMzZ2alJLcEh4bkZINkljeURWd21iUHVsQ01FbmZuTDVyS0ovNGJaR2lFMVNRb2JRR1lEL0dicTFVRldvazBGTWZURlYxd2V0UWZWdjMyU0lTSjZQVUpNMmlUaEJKV0RQTlZUbUtmMjhEbHEyTmFMRk1kMXVnS3hBV1AyZk45WU9ndzZadWlpUkIvNlViSU03TXMyRldmeXRHcDJvWWN5OTRYUAo=
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo
namespace: default
labels:
app: weblog
type: database
spec:
selector:
matchLabels:
app: weblog
type: database
serviceName: db-svc
replicas: 3
template:
metadata:
name: mongodb
namespace: default
labels:
app: weblog
type: database
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongodb
image: weblog-db:v1.0.0
imagePullPolicy: Never
args:
- "mongod"
- "--auth"
- "--clusterAuthMode=keyFile"
- "--keyFile=/home/mongodb/keyfile"
- "--replSet=rs0"
- "--bind_ip_all"
env:
- name: "MONGO_INITDB_ROOT_USERNAME"
valueFrom:
secretKeyRef:
name: mongo-secret
key: root_username
- name: "MONGO_INITDB_ROOT_PASSWORD"
valueFrom:
secretKeyRef:
name: mongo-secret
key: root_password
- name: "MONGO_INITDB_DATABASE"
value: "admin"
volumeMounts:
- mountPath: /data/db
name: storage
- mountPath: /home/mongodb
name: secret
volumes:
- name: secret
secret:
secretName: mongo-secret
items:
- key: keyfile
path: keyfile
mode: 0700
volumeClaimTemplates:
- metadata:
name: storage
spec:
storageClassName: slow
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
DBサーバーの構築(HeadlessService)
実装
- 以下のファイルを作成
weblog-db-fullset.yml
確認
※必要なフォルダが作成されていること
※作成されたフォルダは空であること
- PersistentVolume, Secret, StatefulSet, Serviceを作成
- 作成したPodへ入る
- MongoDBを初期化
- レプリカセット構築できていることを確認
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume-0
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/pv0000"
type: Directory
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume-1
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/pv0001"
type: Directory
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: storage-volume-2
namespace: default
labels:
app: weblog
type: storage
spec:
storageClassName: slow
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
hostPath:
path: "/data/pv0002"
type: Directory
---
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
namespace: default
labels:
app: weblog
type: database
type: Opaque
data:
root_username: YWRtaW4=
root_password: UGFzc3cwcmQ=
keyfile: REZDeXROTzBtd2F3eUJzMjVFT3dwdHZDMVRpY1B6STM5S2tvampoZkU3SGVSL1Z2cnllTndxZE92T3dpWjlqUC9wSVdJZVlVWWlrdFpYZlhoT09seU1CRXdVQ0dyK3VtYm1FZXVkdWROeTRoUUNzVmUwWU9TbFgwN1hxYS8vbyttejRaOHBFY2hOMHdVYWhxcEhENWllRnlvTU5JVmFFY0ZQRjQzKzN2Wm92dzdNNHhhWSt4aGhuVzVldGdtL2MyZzlHYUdsSjRhWFBYSmJIUVR5bHNjbml2QnJtV2lJWStKQVBjK29GR0pMNUkzT0NpU1IxZDY2Z0c5OXlzb2Y3NlJ0eDBNdllnV2RYOXJTZTE2b2RhSTNJV3RtaEkyQ0xiV3BTOTk0blljV1RDYnRvcjNmTUMxY3M4bk5SV3kxdW4rSmJiUG9vTXFpUk9ieFJuY0hhcDJYK3BPS3RqWVBnK1lLWDFIdGYrWHlhSDdEckZkWk1uc1ZiQXRBZ1Y2Q2Y2N0laeW02NXA4TGpqRmtoWlRibjVaTWdqUWlud2Vya0IrUUM1aG1hUVFoQXU2ejV0ZStrUHJzUWc0UFEvSkNSTDd2d2VaRXpkZHdsQ284TllHVUpYYVNHMExnMms3d0R4OW9ITFR1QS9UZWxpdDJWcmZnUmJVNlk2ZjZGRU9jempLbkhLZ0hUMDlSSmE1NndkaWhnSHJleVdiVkNDN0JmZEZKMnpSajFmRzVZRWdwa0EzcGdNc3V2VURpNkFpNnROVmUzTzNqQXFDbVhnaHBGYnJ5aTlYWWd0RHNRa3BHUFJVWnlMdk5CajVrOHFCb2lZa2lIUFd2eUlieUI5U1gwcGN5UDEwUjh6UjBUQjhwWFVaYjNYaDFwNFZETVR0ZzV1OFd3ZjU2cElyV2UzS1lqMjBQMndXeVEzZ2xEbzVHTUp4VWRvdWJUeE91bjIrVjBKNk9jMGRLbG13ZXFFakFiYWtKaURkeXZ0eTJPZ2duYmdSU05ZWkluTktWUjluYm5QVUUva0NTTWJOZUU1aFZWRkMweng2RktIa2R4aVpGRXY4YlAvTFI0aFk0OU9FWmE5dnVQUkJuMkxxZmx1Y083d201T25EOG1OM1BZOExscE42U1dDVVRHSjJxZndtMzZ2alJLcEh4bkZINkljeURWd21iUHVsQ01FbmZuTDVyS0ovNGJaR2lFMVNRb2JRR1lEL0dicTFVRldvazBGTWZURlYxd2V0UWZWdjMyU0lTSjZQVUpNMmlUaEJKV0RQTlZUbUtmMjhEbHEyTmFMRk1kMXVnS3hBV1AyZk45WU9ndzZadWlpUkIvNlViSU03TXMyRldmeXRHcDJvWWN5OTRYUAo=
---
apiVersion: v1
kind: Service
metadata:
name: db-svc
namespace: default
labels:
app: weblog
type: database
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
app: weblog
type: database
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo
namespace: default
labels:
app: weblog
type: database
spec:
selector:
matchLabels:
app: weblog
type: database
serviceName: db-svc
replicas: 3
template:
metadata:
name: mongodb
namespace: default
labels:
app: weblog
type: database
spec:
terminationGracePeriodSeconds: 10
containers:
- name: mongodb
image: weblog-db:v1.0.0
imagePullPolicy: Never
args:
- "mongod"
- "--auth"
- "--clusterAuthMode=keyFile"
- "--keyFile=/home/mongodb/keyfile"
- "--replSet=rs0"
- "--bind_ip_all"
env:
- name: "MONGO_INITDB_ROOT_USERNAME"
valueFrom:
secretKeyRef:
name: mongo-secret
key: root_username
- name: "MONGO_INITDB_ROOT_PASSWORD"
valueFrom:
secretKeyRef:
name: mongo-secret
key: root_password
- name: "MONGO_INITDB_DATABASE"
value: "admin"
volumeMounts:
- mountPath: /data/db
name: storage
- mountPath: /home/mongodb
name: secret
volumes:
- name: secret
secret:
secretName: mongo-secret
items:
- key: keyfile
path: keyfile
mode: 0700
volumeClaimTemplates:
- metadata:
name: storage
spec:
storageClassName: slow
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
DBサーバーの構築(初期化)
- デバッグ用Podを起動
- 初期化スクリプトをデバッグ用Podへコピー
- デバッグ用Podへ入る
- MongoDBへ接続してプライマリを確認して切断
- 初期化スクリプトを修正(必要であれば)
- 初期化スクリプトを実行
- いずれかのMongoDBに接続してデータが入ったことを確認
// use weblog
db.createUser({
user: "user",
pwd: "welcome",
roles: [{
role: "readWrite", db: "weblog"
}]
})
db.posts.drop();
db.users.drop();
db.privileges.drop();
# Create user
mongo mongodb://mongo-0.db-svc:27017/weblog -u admin -p Passw0rd --authenticationDatabase admin ./adduser.js
# Create collection & insert initial data
mongo mongodb://mongo-0.db-svc:27017/weblog -u admin -p Passw0rd --authenticationDatabase admin ./insert.js
//
// posts table
//
db.posts.createIndex({ url: 1 }, { unique: true, background: true });
db.posts.insertMany([{
url: "/2017/05/hello-nodejs.html",
published: new Date(2017, 4, 2),
updated: new Date(2017, 4, 2),
title: "ようこそ Node.js の世界へ",
content: "Node.js は おもしろい!",
keywords: ["Node.js"],
authors: ["Yuta Sato"]
}, {
url: "/2017/06/nodejs-basic.html",
published: new Date(2017, 5, 12),
updated: new Date(2017, 5, 12),
title: "Node.js の 基本",
content: "ちょっと難しくなってきた!?",
keywords: ["Node.js"],
authors: ["Yuta Sato"]
}, {
url: "/2017/07/advanced-nodejs.html",
published: new Date(2017, 7, 8),
updated: new Date(2017, 7, 8),
title: "Node.js 応用",
content: "Node.js で Excel ファイルが触れるなんて!!",
keywords: ["Node.js"],
authors: ["Yuta Sato"]
}]);
//
// users table
//
db.users.createIndex({ email: 1 }, { unique: true, background: true });
db.users.insertMany([{
email: "yuta.sato@sample.com",
name: "Yuta Sato",
password: "77d1fb804f4e1e6059377122046c95de5e567cb9fd374639cb96e7f5cc07dba1", //"qwerty", // "77d1fb804f4e1e6059377122046c95de5e567cb9fd374639cb96e7f5cc07dba1"
role: "owner"
}]);
//
// privileges table
//
db.privileges.createIndex({ role: 1 }, { unique: true, background: true });
db.privileges.insertMany([
{ role: "default", permissions: ["read"] },
{ role: "owner", permissions: ["readWrite"] }
]);
APサーバーのイメージ作成
実装
-
以下のファイルを作成
ROOT
│
│ .dockerignore
│ docker-entrypoint.sh
│ Dockerfile
│
│ --- 以下は Node.js アプリ Application フォルダに配置---
│ app.js
│ package.json
│ yarn.lock
│
├─ api
├─ config
├─ lib
├─ log
├─ public
├─ routes
└─ views
確認
※DBサーバーが起動して初期化まで済んでいること
- MongoDBのプライマリを確認
- MongoDBに対するService, Endpointsを作成(kubectl apply)
- Dockerで作成したイメージを実行(docker run)
- 作成したNode.jsアプリケーションコンテナへ接続(curl)
- MongoDB接続用Service, Endpointsを削除(kubectl delete)
APサーバーの構築(Pod+Secret)
実装
- 以下のファイルを作成
weblog-app-pod.yml
確認
※DBサーバーが起動して初期化まで済んでいること
- Secret, Podを作成(kubectl apply)
- デバッグPodを作成して入る(kubectl exec)
- APサーバーPodへ接続確認(curl)
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
namespace: default
labels:
app: weblog
type: database
type: Opaque
data:
root_username: YWRtaW4=
root_password: UGFzc3cwcmQ=
weblog_username: dXNlcg== # user
weblog_password: d2VsY29tZQ== # welcome
keyfile: REZDeXROTzBtd2F3eUJzMjVFT3dwdHZDMVRpY1B6STM5S2tvampoZkU3SGVSL1Z2cnllTndxZE92T3dpWjlqUC9wSVdJZVlVWWlrdFpYZlhoT09seU1CRXdVQ0dyK3VtYm1FZXVkdWROeTRoUUNzVmUwWU9TbFgwN1hxYS8vbyttejRaOHBFY2hOMHdVYWhxcEhENWllRnlvTU5JVmFFY0ZQRjQzKzN2Wm92dzdNNHhhWSt4aGhuVzVldGdtL2MyZzlHYUdsSjRhWFBYSmJIUVR5bHNjbml2QnJtV2lJWStKQVBjK29GR0pMNUkzT0NpU1IxZDY2Z0c5OXlzb2Y3NlJ0eDBNdllnV2RYOXJTZTE2b2RhSTNJV3RtaEkyQ0xiV3BTOTk0blljV1RDYnRvcjNmTUMxY3M4bk5SV3kxdW4rSmJiUG9vTXFpUk9ieFJuY0hhcDJYK3BPS3RqWVBnK1lLWDFIdGYrWHlhSDdEckZkWk1uc1ZiQXRBZ1Y2Q2Y2N0laeW02NXA4TGpqRmtoWlRibjVaTWdqUWlud2Vya0IrUUM1aG1hUVFoQXU2ejV0ZStrUHJzUWc0UFEvSkNSTDd2d2VaRXpkZHdsQ284TllHVUpYYVNHMExnMms3d0R4OW9ITFR1QS9UZWxpdDJWcmZnUmJVNlk2ZjZGRU9jempLbkhLZ0hUMDlSSmE1NndkaWhnSHJleVdiVkNDN0JmZEZKMnpSajFmRzVZRWdwa0EzcGdNc3V2VURpNkFpNnROVmUzTzNqQXFDbVhnaHBGYnJ5aTlYWWd0RHNRa3BHUFJVWnlMdk5CajVrOHFCb2lZa2lIUFd2eUlieUI5U1gwcGN5UDEwUjh6UjBUQjhwWFVaYjNYaDFwNFZETVR0ZzV1OFd3ZjU2cElyV2UzS1lqMjBQMndXeVEzZ2xEbzVHTUp4VWRvdWJUeE91bjIrVjBKNk9jMGRLbG13ZXFFakFiYWtKaURkeXZ0eTJPZ2duYmdSU05ZWkluTktWUjluYm5QVUUva0NTTWJOZUU1aFZWRkMweng2RktIa2R4aVpGRXY4YlAvTFI0aFk0OU9FWmE5dnVQUkJuMkxxZmx1Y083d201T25EOG1OM1BZOExscE42U1dDVVRHSjJxZndtMzZ2alJLcEh4bkZINkljeURWd21iUHVsQ01FbmZuTDVyS0ovNGJaR2lFMVNRb2JRR1lEL0dicTFVRldvazBGTWZURlYxd2V0UWZWdjMyU0lTSjZQVUpNMmlUaEJKV0RQTlZUbUtmMjhEbHEyTmFMRk1kMXVnS3hBV1AyZk45WU9ndzZadWlpUkIvNlViSU03TXMyRldmeXRHcDJvWWN5OTRYUAo=
---
apiVersion: v1
kind: Pod
metadata:
name: nodeapp
namespace: default
labels:
app: weblog
type: application
spec:
containers:
- name: node
image: weblog-app:v1.0.0
imagePullPolicy: Never
ports:
- containerPort: 3000
env:
- name: "MONGODB_USERNAME"
valueFrom:
secretKeyRef:
name: mongo-secret
key: weblog_username
- name: "MONGODB_PASSWORD"
valueFrom:
secretKeyRef:
name: mongo-secret
key: weblog_password
- name: "MONGODB_HOSTS"
value: "mongo-0.db-svc:27017,mongo-1.db-svc:27017,mongo-2.db-svc:27017,"
- name: "MONGODB_DATABASE"
value: "weblog"
- name: "MONGODB_REPLICASET"
value: "rs0"
APサーバーの構築(Deployment)
実装
- 以下のファイルを作成
weblog-app-deployment.yml
確認
※DBサーバーが起動して初期化まで済んでいること
- Secret, Deploymentを作成(kubectl apply)
- デバッグPodを作成して入る(kubectl exec)
- APサーバーPodへ接続確認(curl)
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
namespace: default
labels:
app: weblog
type: database
type: Opaque
data:
root_username: YWRtaW4=
root_password: UGFzc3cwcmQ=
weblog_username: dXNlcg== # user
weblog_password: d2VsY29tZQ== # welcome
keyfile: REZDeXROTzBtd2F3eUJzMjVFT3dwdHZDMVRpY1B6STM5S2tvampoZkU3SGVSL1Z2cnllTndxZE92T3dpWjlqUC9wSVdJZVlVWWlrdFpYZlhoT09seU1CRXdVQ0dyK3VtYm1FZXVkdWROeTRoUUNzVmUwWU9TbFgwN1hxYS8vbyttejRaOHBFY2hOMHdVYWhxcEhENWllRnlvTU5JVmFFY0ZQRjQzKzN2Wm92dzdNNHhhWSt4aGhuVzVldGdtL2MyZzlHYUdsSjRhWFBYSmJIUVR5bHNjbml2QnJtV2lJWStKQVBjK29GR0pMNUkzT0NpU1IxZDY2Z0c5OXlzb2Y3NlJ0eDBNdllnV2RYOXJTZTE2b2RhSTNJV3RtaEkyQ0xiV3BTOTk0blljV1RDYnRvcjNmTUMxY3M4bk5SV3kxdW4rSmJiUG9vTXFpUk9ieFJuY0hhcDJYK3BPS3RqWVBnK1lLWDFIdGYrWHlhSDdEckZkWk1uc1ZiQXRBZ1Y2Q2Y2N0laeW02NXA4TGpqRmtoWlRibjVaTWdqUWlud2Vya0IrUUM1aG1hUVFoQXU2ejV0ZStrUHJzUWc0UFEvSkNSTDd2d2VaRXpkZHdsQ284TllHVUpYYVNHMExnMms3d0R4OW9ITFR1QS9UZWxpdDJWcmZnUmJVNlk2ZjZGRU9jempLbkhLZ0hUMDlSSmE1NndkaWhnSHJleVdiVkNDN0JmZEZKMnpSajFmRzVZRWdwa0EzcGdNc3V2VURpNkFpNnROVmUzTzNqQXFDbVhnaHBGYnJ5aTlYWWd0RHNRa3BHUFJVWnlMdk5CajVrOHFCb2lZa2lIUFd2eUlieUI5U1gwcGN5UDEwUjh6UjBUQjhwWFVaYjNYaDFwNFZETVR0ZzV1OFd3ZjU2cElyV2UzS1lqMjBQMndXeVEzZ2xEbzVHTUp4VWRvdWJUeE91bjIrVjBKNk9jMGRLbG13ZXFFakFiYWtKaURkeXZ0eTJPZ2duYmdSU05ZWkluTktWUjluYm5QVUUva0NTTWJOZUU1aFZWRkMweng2RktIa2R4aVpGRXY4YlAvTFI0aFk0OU9FWmE5dnVQUkJuMkxxZmx1Y083d201T25EOG1OM1BZOExscE42U1dDVVRHSjJxZndtMzZ2alJLcEh4bkZINkljeURWd21iUHVsQ01FbmZuTDVyS0ovNGJaR2lFMVNRb2JRR1lEL0dicTFVRldvazBGTWZURlYxd2V0UWZWdjMyU0lTSjZQVUpNMmlUaEJKV0RQTlZUbUtmMjhEbHEyTmFMRk1kMXVnS3hBV1AyZk45WU9ndzZadWlpUkIvNlViSU03TXMyRldmeXRHcDJvWWN5OTRYUAo=
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
namespace: default
labels:
app: weblog
type: application
spec:
replicas: 3
selector:
matchLabels:
app: weblog
type: application
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
revisionHistoryLimit: 14
template:
metadata:
name: nodeapp
namespace: default
labels:
app: weblog
type: application
spec:
containers:
- name: node
image: weblog-app:v1.0.0
imagePullPolicy: Never
ports:
- containerPort: 3000
env:
- name: "MONGODB_USERNAME"
valueFrom:
secretKeyRef:
name: mongo-secret
key: weblog_username
- name: "MONGODB_PASSWORD"
valueFrom:
secretKeyRef:
name: mongo-secret
key: weblog_password
- name: "MONGODB_HOSTS"
value: "mongo-0.db-svc:27017,mongo-1.db-svc:27017,mongo-2.db-svc:27017,"
- name: "MONGODB_DATABASE"
value: "weblog"
- name: "MONGODB_REPLICASET"
value: "rs0"
APサーバーの構築(Service)
実装
- 以下のファイルを作成
weblog-app-fullset.yml
確認
※DBサーバーが起動して初期化まで済んでいること
- Secret, Deployment, Serviceを作成(kubectl apply)
- デバッグPodを作成して入る(kubectl exec)
- APサーバーへService経由で接続(curl)
- APサーバーのいずれかにログ出力されていることを確認
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
namespace: default
labels:
app: weblog
type: database
type: Opaque
data:
root_username: YWRtaW4=
root_password: UGFzc3cwcmQ=
weblog_username: dXNlcg== # user
weblog_password: d2VsY29tZQ== # welcome
keyfile: REZDeXROTzBtd2F3eUJzMjVFT3dwdHZDMVRpY1B6STM5S2tvampoZkU3SGVSL1Z2cnllTndxZE92T3dpWjlqUC9wSVdJZVlVWWlrdFpYZlhoT09seU1CRXdVQ0dyK3VtYm1FZXVkdWROeTRoUUNzVmUwWU9TbFgwN1hxYS8vbyttejRaOHBFY2hOMHdVYWhxcEhENWllRnlvTU5JVmFFY0ZQRjQzKzN2Wm92dzdNNHhhWSt4aGhuVzVldGdtL2MyZzlHYUdsSjRhWFBYSmJIUVR5bHNjbml2QnJtV2lJWStKQVBjK29GR0pMNUkzT0NpU1IxZDY2Z0c5OXlzb2Y3NlJ0eDBNdllnV2RYOXJTZTE2b2RhSTNJV3RtaEkyQ0xiV3BTOTk0blljV1RDYnRvcjNmTUMxY3M4bk5SV3kxdW4rSmJiUG9vTXFpUk9ieFJuY0hhcDJYK3BPS3RqWVBnK1lLWDFIdGYrWHlhSDdEckZkWk1uc1ZiQXRBZ1Y2Q2Y2N0laeW02NXA4TGpqRmtoWlRibjVaTWdqUWlud2Vya0IrUUM1aG1hUVFoQXU2ejV0ZStrUHJzUWc0UFEvSkNSTDd2d2VaRXpkZHdsQ284TllHVUpYYVNHMExnMms3d0R4OW9ITFR1QS9UZWxpdDJWcmZnUmJVNlk2ZjZGRU9jempLbkhLZ0hUMDlSSmE1NndkaWhnSHJleVdiVkNDN0JmZEZKMnpSajFmRzVZRWdwa0EzcGdNc3V2VURpNkFpNnROVmUzTzNqQXFDbVhnaHBGYnJ5aTlYWWd0RHNRa3BHUFJVWnlMdk5CajVrOHFCb2lZa2lIUFd2eUlieUI5U1gwcGN5UDEwUjh6UjBUQjhwWFVaYjNYaDFwNFZETVR0ZzV1OFd3ZjU2cElyV2UzS1lqMjBQMndXeVEzZ2xEbzVHTUp4VWRvdWJUeE91bjIrVjBKNk9jMGRLbG13ZXFFakFiYWtKaURkeXZ0eTJPZ2duYmdSU05ZWkluTktWUjluYm5QVUUva0NTTWJOZUU1aFZWRkMweng2RktIa2R4aVpGRXY4YlAvTFI0aFk0OU9FWmE5dnVQUkJuMkxxZmx1Y083d201T25EOG1OM1BZOExscE42U1dDVVRHSjJxZndtMzZ2alJLcEh4bkZINkljeURWd21iUHVsQ01FbmZuTDVyS0ovNGJaR2lFMVNRb2JRR1lEL0dicTFVRldvazBGTWZURlYxd2V0UWZWdjMyU0lTSjZQVUpNMmlUaEJKV0RQTlZUbUtmMjhEbHEyTmFMRk1kMXVnS3hBV1AyZk45WU9ndzZadWlpUkIvNlViSU03TXMyRldmeXRHcDJvWWN5OTRYUAo=
---
apiVersion: v1
kind: Service
metadata:
name: app-svc
namespace: default
labels:
app: weblog
type: application
spec:
ports:
- port: 3000
targetPort: 3000
selector:
app: weblog
type: application
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
namespace: default
labels:
app: weblog
type: application
spec:
replicas: 3
selector:
matchLabels:
app: weblog
type: application
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
revisionHistoryLimit: 14
template:
metadata:
name: nodeapp
namespace: default
labels:
app: weblog
type: application
spec:
containers:
- name: node
image: weblog-app:v1.0.0
imagePullPolicy: Never
ports:
- containerPort: 3000
env:
- name: "MONGODB_USERNAME"
valueFrom:
secretKeyRef:
name: mongo-secret
key: weblog_username
- name: "MONGODB_PASSWORD"
valueFrom:
secretKeyRef:
name: mongo-secret
key: weblog_password
- name: "MONGODB_HOSTS"
value: "mongo-0.db-svc:27017,mongo-1.db-svc:27017,mongo-2.db-svc:27017,"
- name: "MONGODB_DATABASE"
value: "weblog"
- name: "MONGODB_REPLICASET"
value: "rs0"
WEBサーバーのイメージ作成
実装
- 以下のファイルを作成
ROOT
docker-entrypoint.sh
Dockerfile
※nginx.confは添付を利用
確認
※Kubernetes上でDBサーバーとAPサーバーが起動していること
- APサーバーへアクセスするServiceを作成
- Webサーバーコンテナ起動
- 外部からブラウザでアクセスして画面確認
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server_tokens off;
proxy_cache_path /var/cache/nginx keys_zone=STATIC:10m max_size=1g inactive=10d;
proxy_temp_path /var/cache/nginx/tmp;
server {
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://${APPLICATION_HOST}/;
}
location /public/ {
proxy_pass http://${APPLICATION_HOST}/public/;
proxy_ignore_headers Cache-Control Expires;
proxy_buffering on;
proxy_cache STATIC;
proxy_cache_valid any 10d;
add_header X-Nginx-Cache $upstream_cache_status;
}
}
# include /etc/nginx/conf.d/*.conf;
}
# ! /bin/sh
envsubst '$$APPLICATION_HOST' \
< /home/nginx/nginx.conf \
> /etc/nginx/nginx.conf
exec "$@"
FROM nginx:1.17.2-alpine
COPY . /home/nginx
RUN cd /home/nginx; \
mv docker-entrypoint.sh /usr/local/bin; \
chmod +x /usr/local/bin/docker-entrypoint.sh;
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]
weblog-app-service.yml
apiVersion: v1
kind: Service
metadata:
name: nodeapp
namespace: default
labels:
env: study
spec:
type: NodePort
selector:
app: weblog
type: application
ports:
- port: 3000
targetPort: 3000
nodePort: 30000
WEBサーバーの構築(Pod)
実装
- 以下のファイルを作成
weblog-web-pod.yml
確認
※DBサーバーが起動して初期化まで済んでいること
※APサーバーが起動していること
- ConfigMap, Deployment, Serviceを作成(kubectl apply)
- 作成したWebサーバーPodのIPアドレスを確認(kubectl get)
- デバッグPodを作成して入る(kubectl exec)
- Webサーバーへ接続(curl)
- 接続したWebサーバーにアクセスログがあることを確認
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: weblog
type: frontend
spec:
containers:
- name: nginx
image: weblog-web:v1.0.0
imagePullPolicy: Never
ports:
- containerPort: 80
env:
- name: "APPLICATION_HOST"
value: "app-svc:3000"
WEBサーバーの構築(Pod+ConfigMap)
実装
- 以下のファイルを作成
weblog-web-pod+configmap.yml
確認
※DBサーバーが起動して初期化まで済んでいること
※APサーバーが起動していること
- ConfigMap, Podを作成(kubectl apply)
- WebサーバーPodに入ってConfigMapを利用していることを確認(kubectl exec)
- WebサーバーPodのIPアドレスを確認(kubectl get)
- デバッグPodを作成して入る(kubectl exec)
- WebサーバーPodへ接続確認(curl)
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
labels:
app: weblog
type: frontend
data:
nginx.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server_tokens off;
proxy_cache_path /var/cache/nginx keys_zone=STATIC:10m max_size=1g inactive=10d;
proxy_temp_path /var/cache/nginx/tmp;
server {
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://${APPLICATION_HOST}/;
}
location /public/ {
proxy_pass http://${APPLICATION_HOST}/public/;
proxy_ignore_headers Cache-Control Expires;
proxy_buffering on;
proxy_cache STATIC;
proxy_cache_valid any 10d;
add_header X-Nginx-Cache $upstream_cache_status;
}
}
# include /etc/nginx/conf.d/*.conf;
# ConfigMap
}
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: weblog
type: frontend
spec:
containers:
- name: nginx
image: weblog-web:v1.0.0
imagePullPolicy: Never
ports:
- containerPort: 80
env:
- name: "APPLICATION_HOST"
value: "app-svc:3000"
volumeMounts:
- name: config-volume
mountPath: /home/nginx
volumes:
- name: config-volume
configMap:
name: nginx-config
WEBサーバーの構築(Deployment)
実装
- 以下のファイルを作成
weblog-web-deployment.yml
確認
※DBサーバーが起動して初期化まで済んでいること
※APサーバーが起動していること
- ConfigMap, Deploymentを作成(kubectl apply)
- WebサーバーPodのIPアドレスを確認(kubectl get)
- デバッグPodを作成して入る(kubectl exec)
- WebサーバーPodいずれかへ接続確認(curl)
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
labels:
app: weblog
type: frontend
data:
nginx.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server_tokens off;
proxy_cache_path /var/cache/nginx keys_zone=STATIC:10m max_size=1g inactive=10d;
proxy_temp_path /var/cache/nginx/tmp;
server {
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://${APPLICATION_HOST}/;
}
location /public/ {
proxy_pass http://${APPLICATION_HOST}/public/;
proxy_ignore_headers Cache-Control Expires;
proxy_buffering on;
proxy_cache STATIC;
proxy_cache_valid any 10d;
add_header X-Nginx-Cache $upstream_cache_status;
}
}
# include /etc/nginx/conf.d/*.conf;
# ConfigMap
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
labels:
app: weblog
type: frontend
spec:
replicas: 3
selector:
matchLabels:
app: weblog
type: frontend
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
revisionHistoryLimit: 14
template:
metadata:
name: nginx
namespace: default
labels:
app: weblog
type: frontend
spec:
containers:
- name: nginx
image: weblog-web:v1.0.0
imagePullPolicy: Never
ports:
- containerPort: 80
env:
- name: "APPLICATION_HOST"
value: "app-svc:3000"
volumeMounts:
- name: config-volume
mountPath: /home/nginx
volumes:
- name: config-volume
configMap:
name: nginx-config
WEBサーバーの構築(Service)
実装
- 以下のファイルを作成
weblog-web-fullset.yml
確認
※DBサーバーが起動して初期化まで済んでいること
※APサーバーが起動していること
- ConfigMap, Deploymentを作成(kubectl apply)
- デバッグPodを作成して入る(kubectl exec)
- WebサーバーServiceへ接続確認(curl)
apiVersion: v1
kind: Service
metadata:
name: web-svc
namespace: default
labels:
app: weblog
type: frontend
spec:
ports:
- port: 80
targetPort: 80
selector:
app: weblog
type: frontend
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: default
labels:
app: weblog
type: frontend
data:
nginx.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server_tokens off;
proxy_cache_path /var/cache/nginx keys_zone=STATIC:10m max_size=1g inactive=10d;
proxy_temp_path /var/cache/nginx/tmp;
server {
listen 80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://${APPLICATION_HOST}/;
}
location /public/ {
proxy_pass http://${APPLICATION_HOST}/public/;
proxy_ignore_headers Cache-Control Expires;
proxy_buffering on;
proxy_cache STATIC;
proxy_cache_valid any 10d;
add_header X-Nginx-Cache $upstream_cache_status;
}
}
# include /etc/nginx/conf.d/*.conf;
# ConfigMap
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: default
labels:
app: weblog
type: frontend
spec:
replicas: 3
selector:
matchLabels:
app: weblog
type: frontend
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
revisionHistoryLimit: 14
template:
metadata:
name: nginx
namespace: default
labels:
app: weblog
type: frontend
spec:
containers:
- name: nginx
image: weblog-web:v1.0.0
imagePullPolicy: Never
ports:
- containerPort: 80
env:
- name: "APPLICATION_HOST"
value: "app-svc:3000"
volumeMounts:
- name: config-volume
mountPath: /home/nginx
volumes:
- name: config-volume
configMap:
name: nginx-config
Webアプリケーションの公開(Ingress)
実装
- 以下のファイルを作成
weblog-ingress.yml
確認
※DBサーバーが起動して初期化まで済んでいること
※APサーバーが起動していること
※Webサーバーが起動していること
- Ingressを作成(kubectl apply)
- minikubeへ接続確認(ブラウザ)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: entrypoint
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
labels:
app: weblog
type: entrypoint
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: web-svc
servicePort: 80