下面是一个示意图, 可帮助你调试 Kubernetes Deployment(你可以在此处下载它的 PDF 版本).
当你希望在 Kubernetes 中部署应用程序时, 你通常会定义三个组件:
一个 Deployment - 这是一份用于创建你的应用程序的 Pod 副本的 "食谱";
一个 Service - 一个内部负载均衡器, 用于将流量路由到内部的 Pod 上;
一个 Ingress - 描述如何流量应该如何从集群外部流入到集群内部的你的服务上.
下面让我们用示意图快速总结一下要点.
在 Kubernetes 中, 你的应用程序通过两层负载均衡器暴露服务: 内部的和外部的
内部的负载均衡器称为 Service, 而外部的负载均衡器称为 Ingress
Pod 不会直接部署. Deployment 会负责创建 Pod 并管理它们
假设你要部署一个简单的 "HelloWorld" 应用, 该应用的 YAML 文件的内容应该类似下面这样:
- // hello-world.YAML
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: my-deployment
- labels:
- track: canary
- spec:
- selector:
- matchLabels:
- any-name: my-App
- template:
- metadata:
- labels:
- any-name: my-App
- spec:
- containers:
- - name: cont1
- image: learnk8s/App:1.0.0
- ports:
- - containerPort: 8080
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: my-service
- spec:
- ports:
- - port: 80
- targetPort: 8080
- selector:
- name: App
- ---
- apiVersion: networking.k8s.io/v1beta1
- kind: Ingress
- metadata:
- name: my-ingress
- spec:
- rules:
- - http:
- paths:
- - backend:
- serviceName: App
- servicePort: 80
- path: /
这个定义很长, 组件之间的相互关系并不容易看出来.
例如:
什么时候应使用端口 80, 又是何时应使用端口 8080?
你是否应该为每个服务创建一个新端口以免它们相互冲突?
标签 (label) 名重要吗? 它们是否在每一处都应该是一样的?
在进行调试之前, 让我们回顾一下这三个组件是如何相互关联的.
让我们从 Deployment 和 Service 开始.
一. 连接 Deployment 和 Service
令人惊讶的消息是, Service 和 Deployment 之间根本没有连接.
事实是: Service 直接指向 Pod, 并完全跳过了 Deployment.
因此, 你应该注意的是 Pod 和 Service 之间的相互关系.
你应该记住三件事:
Service selector 应至少与 Pod 的一个标签匹配;
Service 的 targetPort 应与 Pod 中容器的 containerPort 匹配;
Service 的 port 可以是任何数字. 多个 Service 可以使用同一端口号, 因为它们被分配了不同的 IP 地址.
下面的图总结了如何连接端口:
考虑上面被一个服务暴露的 Pod
创建 Pod 时, 应为 Pod 中的每个容器定义 containerPort 端口
当创建一个 Service 时, 你可以定义 port 和 targetPort, 但是哪个用来连接容器呢?
targetPort 和 containerPort 应该始终保持匹配
如果容器暴露 3000 端口(containerPort), 那么 targetPort 应该匹配这一个端口号
再来看看 YAML, 标签和 ports/targetPort 应该匹配:
- // hello-world.YAML
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: my-deployment
- labels:
- track: canary
- spec:
- selector:
- matchLabels:
- any-name: my-App
- template:
- metadata:
- labels:
- any-name: my-App
- spec:
- containers:
- - name: cont1
- image: learnk8s/App:1.0.0
- ports:
- - containerPort: 8080
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: my-service
- spec:
- ports:
- - port: 80
- targetPort: 8080
- selector:
- any-name: my-App
那 deployment 顶部的 track: canary 标签呢?
它也应该匹配吗?
该标签属于 deployment,service 的选择器未使用它来路由流量.
换句话说, 你可以安全地删除它或为其分配其他值.
那 matchLabels 选择器呢?
它必须始终与 Pod 的标签匹配, 并且被 Deployment 用来跟踪 Pod.
假设你已经进行了所有正确的设置, 该如何测试它呢?
- // hello-world.YAML
- apiVersion: v1
- kind: Service
- metadata:
- targetPort: 8080
- selector:
- any-name: my-App
- ---
- apiVersion: networking.k8s.io/v1beta1
- kind: Ingress
- metadata:
- name: my-ingress
- spec:
- rules:
- - http:
- paths:
- - backend:
- $ kubectl get pods --all-namespaces
- NAMESPACE NAME READY STATUS
- kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
- kube-system etcd-minikube 1/1 Running
- kube-system kube-apiserver-minikube 1/1 Running
- kube-system kube-controller-manager-minikube 1/1 Running
- kube-system kube-proxy-zvf2h 1/1 Running
- kube-system kube-scheduler-minikube 1/1 Running
- kube-system nginx-ingress-controller-6fc5bcc 1/1 Running
- $ kubectl describe pod nginx-ingress-controller-6fc5bcc \
- --namespace kube-system \
- | grep Ports
- Ports: 80/TCP, 443/TCP, 18080/TCP
- $ kubectl get pods
- NAME READY STATUS RESTARTS AGE
- app1 0/1 ImagePullBackOff 0 47h
- app2 0/1 Error 0 47h
- app3-76f9fcd46b-xbv4k 1/1 Running 1 47h
- ImagePullBackoff
- ImageInspectError
- ErrImagePull
- ErrImageNeverPull
- RegistryUnavailable
- InvalidImageName
- CrashLoopBackOff
- RunContainerError
- KillContainerError
- VerifyNonRootError
- RunInitContainerError
- CreatePodSandboxError
- ConfigPodSandboxError
- KillPodSandboxError
- SetupNetworkError
- TeardownNetworkError
- $ kubectl get pods --all-namespaces
- NAMESPACE NAME READY STATUS
- kube-system coredns-5644d7b6d9-jn7cq 1/1 Running
- kube-system etcd-minikube 1/1 Running
- kube-system kube-apiserver-minikube 1/1 Running
- kube-system kube-controller-manager-minikube 1/1 Running
- kube-system kube-proxy-zvf2h 1/1 Running
- kube-system kube-scheduler-minikube 1/1 Running
- kube-system nginx-ingress-controller-6fc5bcc 1/1 Running
- # kubectl describe pod nginx-ingress-controller-6fc5bcc
- --namespace kube-system \
- | grep Ports
来源: http://www.tuicool.com/articles/MnaqQzE