840 字
4 分钟
gke-apiproxy
制作镜像与部署代理(来自 Google Cloud 文档摘录与整理)
本文件整理自 Google Cloud 文档(归档页面)“Creating GKE private clusters with network proxies for controller access” 的 Creating the Docker image 和 Deploying the image and Service 两个部分,便于笔记与直接复用。 原始页面: https://cloud.google.com/kubernetes-engine/docs/archive/creating-kubernetes-engine-private-clusters-with-net-proxies
目标(Objectives)
- Create a GKE private cluster with no external access.
- Create and deploy a Docker image to run the proxy.
- Create a Kubernetes Service to access the proxy.
- Test access to the proxy.
一、制作 Docker 镜像(Creating the Docker image)
使用下面步骤构建一个名为 k8s-api-proxy 的 Kubernetes API 代理镜像(作为到 Kubernetes API server 的正向代理)。
- 在 Cloud Shell 中创建目录并进入:
mkdir k8s-api-proxy && cd k8s-api-proxy- 创建
Dockerfile。下面示例以 Alpine 为基础,安装privoxy、curl、jq,并添加配置文件与启动脚本,暴露端口 8118:
FROM alpineRUN 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/templatesADD --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/tcpENTRYPOINT ["./k8s-api-proxy.sh"]- 在
k8s-api-proxy目录中创建config文件,内容示例:
#config directoryconfdir /etc/privoxy# Allow Kubernetes API access onlyactionsfile /etc/privoxy/k8s-only.action# Rewrite https://CLUSTER_IP to https://kubernetes.defaultfilterfile /etc/privoxy/k8s-rewrite-internal.filter# Don't show the pod name in errorshostname k8s-privoxy# Bind to all interfaces, port :8118listen-address :8118# User cannot click-through a blockenforce-blocks 1# Allow more than one outbound connectiontolerate-pipelining 1- 创建
k8s-only.action(运行时会由脚本替换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(运行时会由脚本替换CLUSTER_IP):
CLIENT-HEADER-FILTER: k8s-rewrite-internal# Rewrite https://CLUSTER_IP to https://kubernetes.defaults@(CONNECT) CLUSTER_IP:443(HTTP/\d\.\d)@$1 kubernetes.default:443 $2@ig- 创建启动脚本
k8s-api-proxy.sh,脚本会读取 ServiceAccount token 获取集群内部 API 地址并替换CLUSTER_IP,然后以非守护进程方式启动 privoxy:
#!/bin/shset -o errexitset -o pipefailset -o nounset
# 获取集群内部 IPexport 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')
# 替换 CLUSTER_IPsed -i "s/CLUSTER_IP/${INTERNAL_IP}/g" /etc/privoxy/k8s-rewrite-internal.filtersed -i "s/CLUSTER_IP/${INTERNAL_IP}/g" /etc/privoxy/k8s-only.action
# 启动 Privoxy(非守护进程模式)privoxy --no-daemon /etc/privoxy/config- 赋予脚本执行权限并构建/推送镜像:
chmod +x k8s-api-proxy.sh
docker build -t gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 .docker push gcr.io/$PROJECT_ID/k8s-api-proxy:0.1备注:文档中说明为了教程简便,没有为 Kubernetes API server 或代理配置/验证证书。生产环境请正确安装与验证 TLS 证书。
二、部署镜像与 Service(Deploying the image and Service)
- 在 Cloud Shell 中 SSH 登录到之前创建的 client VM:
gcloud compute ssh proxy-temp- 安装
kubectl:
sudo apt-get install kubectl- 将项目 ID 保存为环境变量:
export PROJECT_ID=$(gcloud config list --format="value(core.project)")- 获取集群凭证(使用内部 IP):
gcloud container clusters get-credentials frobnitz \ --zone us-central1-c --internal-ip- 创建一个 Deployment 来运行你构建的镜像:
kubectl run k8s-api-proxy \ --image=gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 \ --port=8118- 创建
ilb.yaml(Internal Load Balancer Service):
apiVersion: v1kind: Servicemetadata: 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- 部署 Internal LB Service:
kubectl create -f ilb.yaml- 检查 Service 并等待分配 IP:
kubectl get service/k8s-api-proxy示例输出(当看到 External IP 时代理已准备好):
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEk8s-api-proxy LoadBalancer 10.24.13.129 10.24.24.3 8118:30282/TCP 2m- 保存 ILB IP 至环境变量:
export LB_IP=$(kubectl get service/k8s-api-proxy -o jsonpath='{.status.loadBalancer.ingress[].ip}')- 保存集群 Controller 的私有端点 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", ...}- 若需要让
kubectl命令都走该代理,可临时设置环境变量(完成后记得unset https_proxy):
export https_proxy=$LB_IP:8118kubectl get pods三、清理(简要)
# 删除 GKE 集群(示例)gcloud container clusters delete frobnitz参考来源
- Google Cloud — Creating GKE private clusters with network proxies for controller access(归档页面)
https://cloud.google.com/kubernetes-engine/docs/archive/creating-kubernetes-engine-private-clusters-with-net-proxies
gke-apiproxy
https://blog.debugmy.com/posts/gke-apiproxy/