如何让K8S内部Rest API通过外部域名访问Keycloak并给Nginx Service加主机名
你完全可以给Nginx Service绑定额外的主机名,不用依赖静态IP配置,下面是几种实用的实现方式:
方案1:CoreDNS自定义域名映射(最推荐)
Kubernetes集群默认用CoreDNS做内部DNS解析,你可以通过配置CoreDNS,把想要的外部主机名直接映射到Nginx Service的内部地址,这样Rest API Pod无需任何额外配置,就能通过外部URL访问Keycloak。
具体步骤:
- 创建一个CoreDNS自定义配置的ConfigMap:
apiVersion: v1 kind: ConfigMap metadata: name: coredns-custom namespace: kube-system data: # 替换成你想要的外部主机名 external-keycloak.yourdomain.com: | # 用CNAME指向Nginx Service的内部域名(无需硬编码IP) external-keycloak.yourdomain.com IN CNAME nginx-service.default.svc.cluster.local.
这里的nginx-service.default.svc.cluster.local是你Nginx Service的内部默认域名,格式为[Service名称].[命名空间].svc.cluster.local,替换成你实际的Service信息即可。
- 重启CoreDNS Pod让配置生效:
kubectl rollout restart deployment coredns -n kube-system
配置完成后,Rest API Pod里直接使用external-keycloak.yourdomain.com这个主机名,CoreDNS会自动把它解析到Nginx Service的ClusterIP,就算Service IP变化也不用修改配置。
方案2:创建额外的Service指向Nginx Pod
你可以新建一个ClusterIP Service,和原Nginx Service关联同一个Pod集合,这个新Service的内部域名就是你想要的“额外主机名”:
具体步骤:
- 编写新的Service配置文件:
apiVersion: v1 kind: Service metadata: # 这个名称就是新的内部主机名前缀 name: external-keycloak-proxy namespace: default spec: # 匹配Nginx Pod的标签 selector: app: nginx-proxy ports: - port: 80 targetPort: 80 # 匹配Nginx Pod的端口 type: ClusterIP
- 应用配置:
kubectl apply -f your-service-file.yaml
之后,Rest API Pod可以通过external-keycloak-proxy.default.svc.cluster.local这个内部域名访问Nginx Service,如果需要对应外部URL,还是得结合方案1的CoreDNS映射。
方案3:动态配置HostAlias(替代静态IP)
如果你想继续用HostAlias的方式,但不想硬编码IP,可以用初始化容器动态获取Nginx Service的IP,自动注入到Pod的/etc/hosts里:
具体步骤:
- 编写Rest API Pod的配置文件,加入初始化容器:
apiVersion: v1 kind: Pod metadata: name: rest-api-pod spec: # 给初始化容器授予获取Service的权限(需要提前创建对应的ServiceAccount和Role) serviceAccountName: service-reader initContainers: - name: set-host-alias image: busybox:1.35 command: - sh - -c - "echo $(kubectl get service nginx-service -o jsonpath='{.spec.clusterIP}') external-keycloak.yourdomain.com >> /etc/hosts.d/hosts" volumeMounts: - name: hosts mountPath: /etc/hosts.d containers: - name: rest-api image: your-rest-api-image volumeMounts: - name: hosts mountPath: /etc/hosts subPath: hosts volumes: - name: hosts emptyDir: {}
- 创建对应的ServiceAccount和Role,让初始化容器能执行
kubectl get service命令:
# ServiceAccount apiVersion: v1 kind: ServiceAccount metadata: name: service-reader namespace: default # Role apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: service-reader-role namespace: default rules: - apiGroups: [""] resources: ["services"] verbs: ["get", "list"] # RoleBinding apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: service-reader-binding namespace: default subjects: - kind: ServiceAccount name: service-reader roleRef: kind: Role name: service-reader-role apiGroup: rbac.authorization.k8s.io
- 应用所有配置:
kubectl apply -f service-account.yaml kubectl apply -f rest-api-pod.yaml
这个方法能自动获取Nginx Service的IP,无需手动配置,但步骤相对繁琐,不如方案1简洁。
内容的提问来源于stack exchange,提问作者Saveriu CIANELLI

