デフォルトでは、クラスタはプライベート エンドポイントを介してコントローラにアクセスでき、承認済みネットワークは VPC ネットワーク内で定義できます。
ただし、オンプレミス ネットワークまたは他の VPC ネットワークからコントローラにアクセスするには、追加のステップが必要です。これは、コントローラをホストする VPC ネットワークは Google が所有するものであり、他の VPC ネットワーク ピアリング接続、Cloud VPN、Cloud Interconnect 経由で接続されたリソースからアクセスできないためです。
オンプレミス、または Cloud VPN か Cloud Interconnect で接続された別の VPC ネットワークからコントローラにアクセスするには、VPC ネットワークから Google 所有の VPC ネットワークへのルート エクスポートを有効にします。
別の VPC ネットワーク、または別の VPC ネットワーク ピアリング(ハブアンドスポーク設計など)を介して接続されたオンプレミスからコントローラへのアクセスを有効にするには、承認済み IP アドレス空間にホストされたプロキシを作成する必要があります。これは、VPC ネットワーク ピアリングが推移的ではないためです。
このチュートリアルでは、GKE 限定公開クラスタ内でプロキシを構成する方法について説明します。
目標
- 外部アクセスを許可しない GKE 限定公開クラスタを作成する。
- Docker イメージを作成してデプロイし、プロキシを実行する。
- プロキシにアクセスする Kubernetes Service を作成する。
- プロキシへのアクセスをテストする。
費用
このチュートリアルでは、Google Cloud Platform の課金対象となる以下のコンポーネントを使用します。料金計算ツールを使用すると、予想使用量に基づいて費用の見積もりを作成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Google Kubernetes Engine APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Google Kubernetes Engine APIs.
環境設定
このチュートリアルでは、Cloud Shell を使用してコマンドを入力します。Cloud Shell では Google Cloud コンソールのコマンドラインにアクセスできます。また、Google Cloud で開発を行うために必要な Google Cloud CLI やその他のツールも含まれています。Cloud Shell は、Google Cloud コンソールの下部にウィンドウとして表示されます。初期化が完了するまでに数分かかることもありますが、ウィンドウはすぐに表示されます。
Cloud Shell を使用して環境を設定するには:
Google Cloud Console で Cloud Shell を開きます。
作成または選択したプロジェクトで作業していることを確認します。
[YOUR_PROJECT_ID]
は、Google Cloud プロジェクトに置き換えます。gcloud config set project [YOUR_PROJECT_ID] export PROJECT_ID=`gcloud config list --format="value(core.project)"`
デフォルトのコンピューティング ゾーンを設定します。このチュートリアルでは、
us-central1-c
に設定します。本番環境にデプロイする場合は、選択したリージョンにデプロイします。gcloud config set compute/region us-central1 gcloud config set compute/zone us-central1-c export REGION=us-central1 export ZONE=us-central1-c
VPC ネットワークとクライアント VM の作成
リソースをホストする VPC ネットワークとサブネットを作成します。
VPC ネットワークを作成します。
gcloud compute networks create k8s-proxy --subnet-mode=custom
新しく作成した VPC ネットワークにカスタム サブネットを作成します。
gcloud compute networks subnets create subnet-cluster \ --network=k8s-proxy --range=10.50.0.0/16
Kubernetes クラスタにリソースをデプロイするために使用するクライアント VM を作成します。
gcloud compute instances create --subnet=subnet-cluster \ --scopes cloud-platform proxy-temp
新しく作成したインスタンスの内部 IP アドレスを環境変数に保存します。
export CLIENT_IP=`gcloud compute instances describe proxy-temp \ --format="value(networkInterfaces[0].networkIP)"`
VPC ネットワークへの SSH アクセスを許可するファイアウォール ルールを作成します。
gcloud compute firewall-rules create k8s-proxy-ssh --network k8s-proxy \ --allow tcp:22
限定公開クラスタの作成
このチュートリアルで使用する限定公開クラスタを作成します。
使用したいクラスタがすでにある場合、クラスタの作成手順はスキップできますが、クライアント マシンに最初にアクセスする方法を構成する必要があります。
Cloud Shell で、クラスタを作成します。
gcloud container clusters create frobnitz \ --master-ipv4-cidr=172.16.0.64/28 \ --network k8s-proxy \ --subnetwork=subnet-cluster \ --enable-ip-alias \ --enable-private-nodes \ --enable-private-endpoint \ --master-authorized-networks $CLIENT_IP/32 \ --enable-master-authorized-networks
このコマンドは、
frobnitz
という名前の GKE 限定公開クラスタを作成し、クライアント マシンにのみアクセスを許可するようにmaster-authorized-networks
を設定します。
Docker イメージの作成
次の手順に沿って k8s-api-proxy,
という Kubernetes API プロキシ イメージを作成します。これは、Kubernetes API サーバーへの転送プロキシとして機能します。
Cloud Shell でディレクトリを作成し、そのディレクトリに移動します。
mkdir k8s-api-proxy && cd k8s-api-proxy
Dockerfile
を作成します。次の構成を使用して Alpine からコンテナを作成します。Alpine は、Privoxy プロキシを含む軽量のコンテナ ディストリビューションです。Dockerfile
は他にも、コンテナを初期化するため、curl
とjq
のインストール、必要な構成ファイルの追加、ポート 8118 の GKE 内部での公開、起動スクリプトの追加を行います。FROM alpine
RUN apk add -U curl privoxy jq && \ mv /etc/privoxy/templates /etc/privoxy-templates && \ rm -rf /var/cache/apk/* /etc/privoxy/* && \ mv /etc/privoxy-templates /etc/privoxy/templates ADD --chown=privoxy:privoxy config \ /etc/privoxy/ ADD --chown=privoxy:privoxy k8s-only.action \ /etc/privoxy/ ADD --chown=privoxy:privoxy k8s-rewrite-internal.filter \ /etc/privoxy/ ADD k8s-api-proxy.sh /
EXPOSE 8118/tcp
ENTRYPOINT ["./k8s-api-proxy.sh"]k8s-api-proxy
ディレクトリにconfig
ファイルを作成し、次の内容を追加します。#config directory confdir /etc/privoxy # Allow Kubernetes API access only actionsfile /etc/privoxy/k8s-only.action # Rewrite https://CLUSTER_IP to https://kubernetes.default filterfile /etc/privoxy/k8s-rewrite-internal.filter # Don't show the pod name in errors hostname k8s-privoxy # Bind to all interfaces, port :8118 listen-address :8118 # User cannot click-through a block enforce-blocks 1 # Allow more than one outbound connection tolerate-pipelining 1
同じディレクトリに
k8s-only.action
ファイルを作成し、次の内容を追加します。k8s-api-proxy.sh
が実行されると、CLUSTER_IP
が置き換えられます。# Block everything... {+block{Not Kubernetes}} /
# ... except the internal k8s endpoint, which you rewrite (see # k8s-rewrite-internal.filter). {+client-header-filter{k8s-rewrite-internal} -block{Kubernetes}} CLUSTER_IP/k8s-rewrite-internal.filter
ファイルを作成し、次の内容を追加します。k8s-api-proxy.sh
が実行されると、CLUSTER_IP
が置き換えられます。CLIENT-HEADER-FILTER: k8s-rewrite-internal\ Rewrite https://CLUSTER_IP/ to https://kubernetes.default/ s@(CONNECT) CLUSTER_IP:443\ (HTTP/\d\.\d)@$1 kubernetes.default:443 $2@ig
k8s-api-proxy.sh
ファイルを作成し、次の内容を追加します。#!/bin/sh set -o errexit set -o pipefail set -o nounset # Get the internal cluster IP export TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token) INTERNAL_IP=$(curl -H "Authorization: Bearer $TOKEN" -k -SsL https://kubernetes.default/api | jq -r '.serverAddressByClientCIDRs[0].serverAddress') # Replace CLUSTER_IP in the rewrite filter and action file sed -i "s/CLUSTER_IP/${INTERNAL_IP}/g"\ /etc/privoxy/k8s-rewrite-internal.filter sed -i "s/CLUSTER_IP/${INTERNAL_IP}/g"\ /etc/privoxy/k8s-only.action # Start Privoxy un-daemonized privoxy --no-daemon /etc/privoxy/config
k8s-api-proxy.sh
を実行可能にします。chmod +x k8s-api-proxy.sh
コンテナをビルドして、プロジェクトに push します。
docker build -t gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 . docker push gcr.io/$PROJECT_ID/k8s-api-proxy:0.1
イメージとサービスのデプロイ
Cloud Shell で、作成済みのクライアント VM にログインします。
gcloud compute ssh proxy-temp
kubectl
ツールをインストールします。sudo apt-get install kubectl
プロジェクト ID を環境変数として保存します。
export PROJECT_ID=`gcloud config list --format="value(core.project)"`
クラスタ認証情報を取得します。
gcloud container clusters get-credentials frobnitz \ --zone us-central1-c --internal-ip
作成したコンテナを公開する Kubernetes 環境を作成します。
kubectl run k8s-api-proxy \ --image=gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 \ --port=8118
内部ロードバランサの
ilb.yaml
ファイルを作成し、次の内容をコピーします。apiVersion: v1 kind: Service metadata: labels: run: k8s-api-proxy name: k8s-api-proxy namespace: default annotations: cloud.google.com/load-balancer-type: "Internal" spec: ports: - port: 8118 protocol: TCP targetPort: 8118 selector: run: k8s-api-proxy type: LoadBalancer
内部ロードバランサをデプロイします。
kubectl create -f ilb.yaml
サービスの IP アドレスを確認します。
kubectl get service/k8s-api-proxy
出力は次のようになります。外部 IP が表示されたら、プロキシの準備は完了です。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE k8s-api-proxy LoadBalancer 10.24.13.129 10.24.24.3 8118:30282/TCP 2m
この外部 IP アドレスはプロキシのアドレスです。
ILB の IP アドレスを環境変数として保存します。
export LB_IP=`kubectl get service/k8s-api-proxy \ -o jsonpath='{.status.loadBalancer.ingress[].ip}'`
クラスタのコントローラ IP アドレスを環境変数に保存します。
export CONTROLLER_IP=`gcloud container clusters describe frobnitz \ --zone=us-central1-c \ --format="get(privateClusterConfig.privateEndpoint)"`
プロキシ経由で Kubernetes API にアクセスして、プロキシが使用可能であることを確認します。
curl -k -x $LB_IP:8118 https://$CONTROLLER_IP/version
出力は次のようになります(出力は異なる場合があります)。{ "major": "1", "minor": "15+", "gitVersion": "v1.15.11-gke.5", "gitCommit": "a5bf731ea129336a3cf32c3375317b3a626919d7", "gitTreeState": "clean", "buildDate": "2020-03-31T02:49:49Z", "goVersion": "go1.12.17b4", "compiler": "gc", "platform": "linux/amd64" }
https_proxy
環境変数を HTTP(S) プロキシに設定して、kubectl
コマンドがどこからでも内部ロードバランサにアクセスできるようにします。export https_proxy=$LB_IP:8118
kubectl
コマンドを実行して、プロキシとhttps_proxy
変数をテストします。kubectl get pods
出力は次のようになります。これは、プロキシ経由で Kubernetes API に正常に接続されたことを意味します。
NAME READY STATUS RESTARTS AGE k8s-api-proxy-766c69dd45-mfqf4 1/1 Running 0 6m15s
クライアント VM を終了します。
exit
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
プロジェクトの削除
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
GKE クラスタの削除
プロジェクトを削除しない場合は、GKE クラスタを削除します。
gcloud container clusters delete frobnitz
次のステップ
- クラスタのセキュリティの強化を参照して、クラスタの保護を強化する。
- 限定公開の Google アクセスを参照して、パブリック IP を使用せずに Google サービスにアクセスする。
- Google Cloud に関するリファレンス アーキテクチャ、図、チュートリアル、ベスト プラクティスを確認する。Cloud Architecture Center を確認します。