1.はじめに
別の記事でGKEにウェブサービスをデプロイする方法を紹介いたしました。
そのウェブサービスはどうやってアクセス元を認証するかのご質問がある方々がいると思います。
ウェブサービスに認証仕組みを追加する方法もありますが、手間がかかります。
本記事は GCP Cloud Endpoints を使うGKEのサービス間の認証方法を紹介いたします。
2.アーキテクチャー
早速ですが、想像しやすくするため、全体アーキテクチャーを先に見せます。
これから構築に行きます。
3.アプリケーションのフォルダ構成
application_folder
├── build
│ ├── cloudbuild.simplewebapp.yaml
│ └── simplewebapp.Dockerfile
├── deployment
│ └── simplewebapp.deployment.yaml
├── go.mod
├── go.sum
├── openapiv2
│ └── simple_webapp_endpoint.yaml
├── tools
│ ├── api
│ │ └── config
│ │ └── config.go
│ └── call_sercure_api.go
└── webapp
├── handler
│ └── simplewebapp_handler.go
└── simplewebapp.go
4.ウェブアプリケーション
下記の3つURLを提供します。
/index : Hello World を表示
/public : Public を表示
/private : Private を表示
詳細な処理はソースコードをご参照。
5.Cloud Endpoints
サービス間認証の場合、サービスアカウントを使う認証方法がお進められます。
サービスアカウントとアカウントJSONファイルの作成
gcloud iam service-accounts create service_account_001 --display-name "service account for authentication between services on gke"
gcloud iam service-accounts list
# サービス アカウント トークン作成者の役割を追加します
gcloud projects add-iam-policy-binding PROJECT_ID \
--member serviceAccount:SA_EMAIL_ADDRESS \
--role roles/serviceAccountTokenCreator
# 現在の作業ディレクトリにサービス アカウント キー ファイルを作成します。FILE_NAME は、キーファイルに使用する名前に置き換えます。デフォルトでは、gcloud JSON ファイルが作成されます。
gcloud iam service-accounts keys create FILE_NAME.json \
--iam-account SA_EMAIL_ADDRESS
Static IP作成
# Check static IP.
gcloud compute addresses list
# Create static IP.
gcloud compute addresses create simple-webapp-service-ip --region asia-northeast1
# Check static IP.
gcloud compute addresses list
> NAME ADDRESS/RANGE TYPE PURPOSE NETWORK REGION SUBNET STATUS
> simple-webapp-service-ip 35.243.84.30 EXTERNAL asia-northeast1 RESERVED
「35.243.84.30」のIPをメモして、下記のOpenAPI定義で使います。
Cloud Endpointsを作るため、OpenAPI定義を作成に行きます。
# [START swagger]
swagger: "2.0"
info:
description: "Simple Sercure Webapp API Endpoints"
version: 1.0.0
title: Simple Sercure Webapp
host: "simple-sercure-webapp.endpoints.PROJECT_ID.cloud.goog"
x-google-endpoints:
- name: "simple-sercure-webapp.endpoints.PROJECT_ID.cloud.goog"
target: "35.243.84.30"
tags:
- name: simple-webapp
description: Simple Sercure Webapp
# [END swagger]
consumes:
- "application/json"
- "text/html"
produces:
- "application/json"
- "text/html"
schemes:
- "http"
paths:
"/index":
get:
description: "index page"
operationId: "index"
produces:
- "text/html"
responses:
200:
description: "Success"
schema:
type: array
"/public":
get:
description: "public page"
operationId: "public"
produces:
- "text/html"
responses:
200:
description: "Success"
schema:
type: array
"/private":
get:
description: "private page"
operationId: "private"
produces:
- "text/html"
responses:
200:
description: "Success"
schema:
type: array
security:
- google_jwt: []
securityDefinitions:
# This section configures authentication using Google API Service Accounts
# to sign a json web token. This is mostly used for server-to-server
# communication.
google_jwt:
authorizationUrl: ""
flow: "implicit"
type: "oauth2"
# This must match the 'iss' field in the JWT.
x-google-issuer: "service_account_001@PROJECT_ID.iam.gserviceaccount.com"
# Update this with your service account's email address.
x-google-jwks_uri: "https://www.googleapis.com/robot/v1/metadata/x509/service_account_001@PROJECT_ID.iam.gserviceaccount.com"
PROJECT_IDはデプロイ先のProject IDを入れ替えてください。
「securityDefinitions」では認証方法を定義されます。今回はサービスアカウントを利用して認証させるとする。
認証対象のAPIは
- google_jwt: []
追加します。今回 /private のAPIのみ認証対象となります。
Cloud Endpoints にデプロイ
# deploy endpoints
gcloud endpoints services deploy openapiv2/simple_webapp_endpoint.yaml
デプロイ後の確認
6.Container Registryにイメージビルド
gcloud builds submit --config build/cloudbuild.simplewebapp.yaml
7.GKEにデプロイメントの定義
上記の構成図どおり、認証できるため「Extensible Service Proxy」を使います。
Extensible Service Proxy(ESP)は、OpenAPI または gRPC API バックエンドの前面で動作し、認証、モニタリング、ロギングなどの API 管理機能を提供する高パフォーマンスでスケーラブルなプロキシです。
apiVersion: v1
kind: Service
metadata:
name: simple-webapp-service
spec:
ports:
- port: 80
targetPort: 8081
protocol: TCP
name: http
selector:
app: simple-webapp
type: LoadBalancer
loadBalancerIP: "35.243.84.30"
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: simple-webapp
spec:
replicas: 2
template:
metadata:
labels:
app: simple-webapp
spec:
containers:
- name: esp
image: gcr.io/endpoints-release/endpoints-runtime:1
args: [
"--http_port", "8081",
"--backend", "127.0.0.1:8080",
"--service", "simple-sercure-webapp.endpoints.PROJECT_ID.cloud.goog",
"--rollout_strategy", "managed",
]
ports:
- containerPort: 8081
- name: simple-webapp
image: asia.gcr.io/PROJECT_ID/simple-webapp:latest
ports:
- containerPort: 8080
Endpoints のサービス名 「simple-sercure-webapp.endpoints.PROJECT_ID.cloud.goog」をESPのパラメタに指定する必要です。
GKEにデプロイ
kubectl apply -f deployment/simplewebapp.deployment.yaml
# デプロイ後のサービス情報確認
kubectl get services
> NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
> kubernetes ClusterIP 10.23.240.1 <none> 443/TCP 49d
> simple-webapp-service LoadBalancer 10.23.253.95 35.243.84.30 80:30169/TCP 18m
EXTERNAL-IP は指定された Static IP となっています。
GKEで確認
8.稼働確認
ブラウザでStatic IPを開いて確認してみます。
PrivateのURLを認証エラーとなりました。サービスアカウントのJWTトークンを使ってアクセスしないといけない。
JWTトークンを生成して、Private API をコールするツールを準備しました。
実施する前に、サービスアカウント情報を設定します。
package config
var (
Audience = "simple-sercure-webapp.endpoints.PROJECT_ID.cloud.goog"
ServiceAccountFile = "path_to/service_account_001.json"
ServiceAccountEmail = "service_account_001@PROJECT_ID.iam.gserviceaccount.com"
ApiUrl = "http://simple-sercure-webapp.endpoints.PROJECT_ID.cloud.goog/private"
RequestMethod = "GET"
RequestData = map[string]interface{}{}
)
Go〜
JWTトークンを使って、Private URLをアクセス出来ました。
最後までご覧いただき、ありがとうございます。