前回は単一コンテナのアプリケーションを動かしたが、今回はコンテナ間でやり取りが発生するものを動かす。
流れとしては、クライアントからのリクエストをGATEWAY
サーバーで受け取り、SERVICE
サーバーにリクエストし、その結果を返すまで。
プログラムは以下の通り、環境変数TYPE
の値によって挙動を変えていて、同じイメージを使い回す。コードはここ。
var http = require('http');
var handleRequest = function(request, response) {
if(process.env.TYPE == "GATEWAY"){
console.log('Passed.');
var options = {
host: 'service',
port: 8080,
method: 'GET'
};
var req = http.request(options, function(res) {
data = ""
res.on('data', function (chunk) {
data+=chunk;
});
res.on('end', () => {
response.writeHead(200);
response.end(data);
});
});
req.on('error', function(e) {
response.writeHead(500)
response.end(e.message);
});
req.end();
}else{
console.log('Received.');
response.writeHead(200);
response.end('ok');
}
};
var www = http.createServer(handleRequest);
www.listen(8080);
これをContainer RegistryにPushする。
$ export PROJECT_ID="gcp-test-141011"
$ docker build -t gcr.io/$PROJECT_ID/multitest:v1 .
$ gcloud docker push gcr.io/$PROJECT_ID/multitest:v1
ローカルで試すためにminikubeを起動。コンテキストがminikubeに設定される。
$ minikube start
$ kubectl config current-context
minikube
minikubeでContainer Registryから取得できるようにsecretを作成する。 ローカルでビルドしたimageを使うこともできる。
ローカルでビルドしたimageをminikubeで使う - sambaiz-net
$ kubectl create secret docker-registry myregistrykey --docker-server=https://gcr.io --docker-username=oauth2accesstoken --docker-password="$(gcloud auth print-access-token)" --docker-email=***
まず、以下のservice_deployment.yaml
でDeploymentを作成する。
envのところで環境変数TYPE
をSERVICE
に設定した。
また、先ほど作成したsecretをimagePullSecrets
で指定し、
ローカルのminikube環境でContainer Registryから取得できるようにしている。
同様にgateway_deployment.yaml
でも作成する。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: service
labels:
app: service
spec:
replicas: 1
template:
metadata:
labels:
app: service
spec:
containers:
- name: service
image: gcr.io/gcp-test-141011/multitest:v1
resources:
requests:
cpu: 100m
memory: 100Mi
env:
- name: TYPE
value: SERVICE
ports:
- containerPort: 8080
imagePullSecrets:
- name: myregistrykey
$ kubectl create -f service_deployment.yaml
$ kubectl create -f gateway_deployment.yaml
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
gateway 1 1 1 1 8m
service 1 1 1 1 28m
次に、これを内部から呼べるようにするためのServiceを作成する。
apiVersion: v1
kind: Service
metadata:
name: service
labels:
app: service
spec:
ports:
- port: 8080
selector:
app: service
GATEWAY
の方は外に開くので、EXTERNAL IPが割り当てられるようにする。
ただ、minikubeではtype: LoadBalancer
に対応していないので代わりにtype: NodePort
を指定する。
apiVersion: v1
kind: Service
metadata:
name: gateway
labels:
app: gateway
spec:
# type: LoadBalancer
type: NodePort
ports:
- port: 8080
nodePort: 30002
selector:
app: gateway
$ kubectl create -f service_service.yaml
$ kubectl create -f gateway_service.yaml
$ kubectl get services
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gateway 10.0.0.176 <nodes> 8080/TCP 1h
service 10.0.0.111 <none> 8080/TCP 2d
GATEWAY
サーバーを越えてSERVICE
サーバーまで到達したことが確認できた。
$ curl 192.168.99.100:30002
ok
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
gateway-3043515563-a0tb5 1/1 Running 0 38m
service-2727435432-9glvb 1/1 Running 0 38m
$ kubectl logs service-2727435432-9glvb
Received.
一通り動いたのでこんなシェルスクリプトを書いた。
#!/bin/bash
context=`kubectl config current-context`
echo "${context}で実行します。よろしいですか[Y/N]"
read ANSWER
case $ANSWER in
"Y" ) :;;
* ) exit;;
esac
if [ $context = "minikube" ] ; then
kubectl create -f yaml/gateway_service_minikube.yaml
kubectl create -f yaml/service_deployment_minikube.yaml
kubectl create -f yaml/gateway_deployment_minikube.yaml
else
kubectl create -f yaml/gateway_service.yaml
kubectl create -f yaml/service_deployment.yaml
kubectl create -f yaml/gateway_deployment.yaml
fi
kubectl create -f yaml/service_service.yaml
これを実行するとこうなる。
$ gcloud container clusters create multi-container-app
$ kubectl config current-context
gke_gcp-test-141011_asia-east1-b_multi-container-app
$ sh create.sh
gke_gcp-test-141011_asia-east1-b_multi-container-appで実行します。よろしいですか[Y/N]
Y
service "gateway" created
deployment "service" created
deployment "gateway" created
service "service" created
$ kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gateway 10.83.254.5 104.199.206.147 8080/TCP 4m
service 10.83.255.118 <none> 8080/TCP 4m
$ curl 104.199.206.147:8080
ok