Docker-Compose转K8s部署至GKE后无法访问外部IP排查
我用kompose convert -f docker-compose.yml -o kubernetes.yml将Docker Compose配置转换为Kubernetes配置,在本地Minikube环境执行kubectl apply -f Kubernetes.yml后,能通过LoadBalancer IP正常访问服务,但部署到GKE后,服务的外部IP无法连接。
执行kubectl get svc得到以下输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend ClusterIP 10.32.129.17 <none> 8000/TCP 42m cleverstack-auth-service LoadBalancer 10.32.131.62 34.134.47.16 8080:30295/TCP 42m kubernetes ClusterIP 10.32.128.1 <none> 443/TCP 43m proxy ClusterIP 10.32.130.232 <none> 8080/TCP 42m redis ClusterIP 10.32.131.143 <none> 6379/TCP 42m
尝试访问34.134.47.16:8080无法连接,相关Kubernetes配置如下:
apiVersion: v1 kind: Service metadata: name: cleverstack-auth-service annotations: external-dns.alpha.kubernetes.io/hostname: localhost spec: selector: io.kompose.service: proxy type: LoadBalancer ports: - protocol: "TCP" port: 8080 targetPort: 8080 --- apiVersion: v1 items: - apiVersion: v1 kind: Service metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: backend name: backend spec: ports: - name: "8000" port: 8000 targetPort: 8000 selector: io.kompose.service: backend status: loadBalancer: {} - apiVersion: v1 kind: Service metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: proxy name: proxy spec: ports: - name: "80" port: 80 targetPort: 8080 selector: io.kompose.service: proxy status: loadBalancer: {} - apiVersion: v1 kind: Service metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: redis name: redis spec: ports: - name: "6379" port: 6379 targetPort: 6379 selector: io.kompose.service: redis status: loadBalancer: {} - apiVersion: apps/v1 kind: Deployment metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: backend name: backend spec: replicas: 1 selector: matchLabels: io.kompose.service: backend strategy: type: Recreate template: metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.network/cs-network: "true" io.kompose.service: backend spec: containers: - args: - gunicorn - cleverstack.wsgi:application - --bind - 0.0.0.0:8000 - --env - DJANGO_SETTINGS_MODULE=cleverstack.settings env: - name: DEBUG value: "True" image: asia.gcr.io/project/docker-image:latest name: cleverstack-auth-backend ports: - containerPort: 8000 resources: {} volumeMounts: - mountPath: /home/cs-user/cs-backend/static name: static-volume - mountPath: /home/cs-user/cs-backend/media name: media-volume restartPolicy: Always volumes: - name: static-volume persistentVolumeClaim: claimName: static-volume - name: media-volume persistentVolumeClaim: claimName: media-volume status: {} - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null labels: io.kompose.service: static-volume name: static-volume spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Mi status: {} - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null labels: io.kompose.service: media-volume name: media-volume spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Mi status: {} - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: creationTimestamp: null name: cs-network spec: ingress: - from: - podSelector: matchLabels: io.kompose.network/cs-network: "true" podSelector: matchLabels: io.kompose.network/cs-network: "true" - apiVersion: apps/v1 kind: Deployment metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: celery name: celery spec: replicas: 1 selector: matchLabels: io.kompose.service: celery strategy: type: Recreate template: metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.network/cs-network: "true" io.kompose.service: celery spec: containers: - args: - celery - -A - cleverstack - worker - -l - info env: - name: DEBUG value: "True" image: asia.gcr.io/project/docker-image:latest name: celery resources: {} volumeMounts: - mountPath: /home/cs-user/cs-celery name: celery-volume restartPolicy: Always volumes: - name: celery-volume persistentVolumeClaim: claimName: celery-volume status: {} - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null labels: io.kompose.service: celery-volume name: celery-volume spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Mi status: {} - apiVersion: apps/v1 kind: Deployment metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: celery-beat name: celery-beat spec: replicas: 1 selector: matchLabels: io.kompose.service: celery-beat strategy: type: Recreate template: metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.network/cs-network: "true" io.kompose.service: celery-beat spec: containers: - args: - celery - -A - cleverstack - worker - -l - info env: - name: DEBUG value: "True" image: asia.gcr.io/project/docker-image:latest name: celery-beat resources: {} volumeMounts: - mountPath: /home/cs-user/cs-celery_beat name: celery-beat-volume restartPolicy: Always volumes: - name: celery-beat-volume persistentVolumeClaim: claimName: celery-beat-volume status: {} - apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null labels: io.kompose.service: celery-beat-volume name: celery-beat-volume spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Mi status: {} - apiVersion: apps/v1 kind: Deployment metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: proxy name: proxy spec: replicas: 1 selector: matchLabels: io.kompose.service: proxy strategy: {} template: metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.network/cs-network: "true" io.kompose.service: proxy spec: containers: - image: asia.gcr.io/project/docker-image:latest name: cleverstack-auth-proxy ports: - containerPort: 8080 resources: {} restartPolicy: Always status: {} - apiVersion: apps/v1 kind: Deployment metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.service: redis name: redis spec: replicas: 1 selector: matchLabels: io.kompose.service: redis strategy: {} template: metadata: annotations: kompose.cmd: kompose convert -f docker-compose.yml -o kubernetes1.yml kompose.version: 1.27.0 (HEAD) creationTimestamp: null labels: io.kompose.network/cs-network: "true" io.kompose.service: redis spec: containers: - args: - redis-server image: redis name: redis ports: - containerPort: 6379 resources: {} restartPolicy: Always status: {} kind: List metadata: {}
1. 网络策略拦截外部流量
你的配置中存在cs-network网络策略,规则为仅允许带有io.kompose.network/cs-network: "true"标签的Pod访问同标签Pod。GKE的LoadBalancer流量属于集群外部流量,不会携带该标签,因此被策略拦截。
解决方式:
- 修改网络策略,添加允许外部流量访问8080端口的规则:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: cs-network spec: ingress: # 保留原有内部Pod间访问规则 - from: - podSelector: matchLabels: io.kompose.network/cs-network: "true" # 添加允许外部访问8080端口的规则 - from: - ipBlock: cidr: 0.0.0.0/0 ports: - protocol: TCP port: 8080 podSelector: matchLabels: io.kompose.network/cs-network: "true"
- 或者直接删除该网络策略(如果不需要内部流量限制):
kubectl delete networkpolicy cs-network
2. 检查Proxy Pod运行状态
确认proxy Deployment的Pod是否正常启动:
kubectl get pods -l io.kompose.service=proxy
如果Pod处于异常状态(如CrashLoopBackOff、Pending),查看日志排查问题:
kubectl logs <proxy-pod-name>
重点检查镜像拉取是否正常(确认asia.gcr.io/project/docker-image:latest存在,且GKE节点有权限访问该镜像仓库)。
3. 验证内部服务连通性
通过端口转发测试集群内部是否能访问proxy服务:
kubectl port-forward svc/proxy 8080:80
访问localhost:8080,如果能正常访问,说明内部服务无问题,故障点在外部流量的网络策略或GKE防火墙规则。
4. 检查GKE防火墙规则
GKE会自动为LoadBalancer服务创建防火墙规则,若规则缺失可手动添加:
- 查看集群节点标签:
gcloud container clusters describe <cluster-name> --zone <zone> | grep nodeTaints
节点标签格式通常为gke-<cluster-name>-<hash>-node
2. 创建允许8080端口的防火墙规则:
gcloud compute firewall-rules create allow-lb-8080 \ --allow tcp:8080 \ --source-ranges 0.0.0.0/0 \ --target-tags <cluster-node-tags>
内容的提问来源于stack exchange,提问作者Sujayeendra G

