参考:https://kubernetes.io/zh/docs/tasks/debug-application-cluster/debug-service/
对于新安装的 Kubernetes,经常出现的问题是 Service 无法正常运行。 你已经通过 Deployment(或其他工作负载控制器)运行了 Pod,并创建 Service ,但是 当你尝试访问它时,没有任何响应。此文档有望对你有所帮助并找出问题所在。
在 Pod 中运行命令对于这里的许多步骤,你可能希望知道运行在集群中的 Pod 看起来是什么样的。 最简单的方法是运行一个交互式的 busybox Pod:
kubectl run -it --rm --restart=Never busybox --image=gcr.io/google-containers/busybox sh说明: 如果没有看到命令提示符,请按回车。
如果你已经有了你想使用的正在运行的 Pod,则可以运行以下命令去进入:
kubectl exec <POD-NAME> -c <CONTAINER-NAME> -- <COMMAND> 设置为了完成本次实践的任务,我们先运行几个 Pod。 由于你可能正在调试自己的 Service,所以,你可以使用自己的信息进行替换, 或者你也可以跟着教程并开始下面的步骤来获得第二个数据点。
kubectl create deployment hostnames --image=k8s.gcr.io/serve_hostname deployment.apps/hostnames createdkubectl 命令将打印创建或变更的资源的类型和名称,它们可以在后续命令中使用。 让我们将这个 deployment 的副本数扩至 3。
kubectl scale deployment hostnames --replicas=3 deployment.apps/hostnames scaled请注意这与你使用以下 YAML 方式启动 Deployment 类似:
apiVersion: apps/v1 kind: Deployment metadata: labels: app: hostnames name: hostnames spec: selector: matchLabels: app: hostnames replicas: 3 template: metadata: labels: app: hostnames spec: containers: - name: hostnames image: k8s.gcr.io/serve_hostname"app" 标签是 kubectl create deployment 根据 Deployment 名称自动设置的。
确认你的 Pods 是运行状态:
kubectl get pods -l app=hostnames NAME READY STATUS RESTARTS AGE hostnames-632524106-bbpiw 1/1 Running 0 2m hostnames-632524106-ly40y 1/1 Running 0 2m hostnames-632524106-tlaok 1/1 Running 0 2m你还可以确认你的 Pod 是否正在提供服务。你可以获取 Pod IP 地址列表并直接对其进行测试。
kubectl get pods -l app=hostnames \ -o go-template=\'{{range .items}}{{.status.podIP}}{{"\n"}}{{end}}\' 10.244.0.5 10.244.0.6 10.244.0.7用于本教程的示例容器通过 HTTP 在端口 9376 上提供其自己的主机名, 但是如果要调试自己的应用程序,则需要使用你的 Pod 正在侦听的端口号。
在 Pod 内运行:
for ep in 10.244.0.5:9376 10.244.0.6:9376 10.244.0.7:9376; do wget -qO- $ep done输出类似这样:
hostnames-632524106-bbpiw hostnames-632524106-ly40y hostnames-632524106-tlaok如果此时你没有收到期望的响应,则你的 Pod 状态可能不健康,或者可能没有在你认为正确的端口上进行监听。 你可能会发现 kubectl logs 命令对于查看正在发生的事情很有用, 或者你可能需要通过kubectl exec 直接进入 Pod 中并从那里进行调试。
假设到目前为止一切都已按计划进行,那么你可以开始调查为何你的 Service 无法正常工作。
Service 是否存在?细心的读者会注意到我们实际上尚未创建 Service -这是有意而为之。 这一步有时会被遗忘,这是首先要检查的步骤。
那么,如果我尝试访问不存在的 Service 会怎样? 假设你有另一个 Pod 通过名称匹配到 Service ,你将得到类似结果:
wget -O- hostnames Resolving hostnames (hostnames)... failed: Name or service not known. wget: unable to resolve host address \'hostnames\'首先要检查的是该 Service 是否真实存在:
kubectl get svc hostnames No resources found. Error from server (NotFound): services "hostnames" not found让我们创建 Service。 和以前一样,在这次实践中 - 你可以在此处使用自己的 Service 的内容。
kubectl expose deployment hostnames --port=80 --target-port=9376 service/hostnames exposed重新运行查询命令:
kubectl get svc hostnames NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hostnames ClusterIP 10.0.1.175 <none> 80/TCP 5s现在你知道了 Service 确实存在。
同前,此步骤效果与通过 YAML 方式启动 \'Service\' 一样:
apiVersion: v1 kind: Service metadata: name: hostnames spec: selector: app: hostnames ports: - name: default protocol: TCP port: 80 targetPort: 9376为了突出配置范围的完整性,你在此处创建的 Service 使用的端口号与 Pods 不同。 对于许多真实的 Service,这些值可以是相同的。
Service 是否可通过 DNS 名字访问?通常客户端通过 DNS 名称来匹配到 Service。
从相同命名空间下的 Pod 中运行以下命令:
nslookup hostnames Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local Name: hostnames Address 1: 10.0.1.175 hostnames.default.svc.cluster.local