12

.NET Core + Kubernetes:Pod | Beck's Blog

 4 years ago
source link: http://beckjin.com/2020/04/12/aspnet-k8s-pod/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

.NET Core + Kubernetes:快速体验 文章中,已经实现将一个 .NET Core API 服务部署在 Kubernetes 集群中,接下来将逐步了解 Kubernetes 中各核心模块。首先当然是 Pod,我相信 Pod 是在接触 Kubernetes 时听到较多的一个词语,Pod 到底是什么?和容器之间有怎样的关系?本文将继续通过对 .NET Core 服务的部署来了解更多关于 Pod 的知识。

为什么需要 Pod

Pod 从表现上来看更像一台虚拟机,容器则是运行在这台虚拟机中的一个个程序进程,如下图(Infra 容器是 Pod 实现中使用的一个中间容器):

pod.png

在现实的容器调度中,会存在容器间的强依赖情况,也就是多个容器需要运行在同一台机器上,这时如果从容器层面来调度,当机器资源只能满足部分容器被编排时,这时候就傻逼了,要么容器运行不正常,要么通过其他手段使容器重新被正确编排。所以面对这样的场景,以容器为单位来编排就可能存在问题,所以在 Kubernetes 中提出了 Pod 的概念,Pod 是一组容器的集合,以 Pod 为单位(如 CPU、内存等资源定义)来编排就显得更为合理。当然在实际情况下,一个 Pod 下一个容器还是比较常见的使用方式。

创建 Pod

下面依然使用之前制作的 .NET Core API 服务的镜像 (beckjin/k8sdemo:1.0.0) 在 Kubernetes 中创建 Pod 来演示。

  1. 创建 k8sdemo-pod.yaml 配置文件,定义一个较简单的 Pod,当然配置字段远不止以下这些。另外从 containers 字段也可以看出 Pod 支持多容器。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    apiVersion: v1  # 版本号
    kind: Pod # 资源类型
    metadata: # meta 信息
    name: k8sdemo
    spec:
    containers: # 容器字段
    - name: k8sdemo # 容器名称
    image: beckjin/k8sdemo:1.0.0 # 镜像
    ports:
    - containerPort: 80 # 容器暴露的端口
    imagePullPolicy: IfNotPresent # 如果镜像不存在则拉取
  2. 创建 Pod,kubectl apply -f k8sdemo-pod.yaml

  3. 查看 Pod 状态,kubectl get pods,Running 代表启动已成功

    pods.png

Pod 外部访问

Pod 启动后默认是无法直接访问的,有以下几种方式可以设置支持外部访问,这里暂介绍前两种方式,其他的涉及 Kubernetes 中更多的模块内容,后面会逐步涉及。

  1. hostNetwork
  2. hostPort
  3. NodePort
  4. LoadBalancer
  5. Ingress

hostNetwork

在配置文件 spec 字段下添加 hostNetwork: true,这种情况下主机上监听的端口与容器暴露的端口一样。

1
2
3
4
spec:
hostNetwork: true
containers:
...

hostPort

在配置文件 ports 字段下添加 hostPort: 自定义端口

1
2
3
ports:
- containerPort: 80
hostPort: 8888

以上两种方式任选一种进行测试即可(以下截图是基于 hostNetwork 方式),修改后重启 Pod kubectl apply --force -f k8sdemo-pod.yaml,然后通过 kubectl get pods,svc -o wide 查看 Pod 所在的主机IP。

podWide.png

api.png

Pod 几个重要字段

nodeSelector

nodeSelector 字段可根据指定的 lable 过滤符合条件的节点,如下给 k8s-node2 这个节点添加了 lable : tag=main

1
kubectl label nodes k8s-node2 tag=main

配置文件如下调整后,重启 Pod 就会移到 k8s-node2 节点上运行。

1
2
3
4
5
spec:
containers:
...
nodeSelector:
tag: main

nodeSelector.png

hostAliases

如果需要给运行在 Pod 增加一些域名的解析(例如宿主机的主机名),但又不想动 DNS 模块,则可以通过 hostAliases 字段来配置。

1
2
3
4
5
6
7
spec:
containers:
...
hostAliases:
- ip: "10.10.22.22"
hostnames:
- "www.test.com"

hostAliases.png

lifecycle

lifecycle 字段可设置在容器状态发生变化时触发一些动作。使用方式如下:

1
2
3
4
5
6
7
8
9
10
11
spec:
containers:
- name: k8sdemo
...
lifecycle:
postStart:
exec:
command: ["echo start"]
preStop:
exec:
command: ["echo stop"]

livenessProbe

livenessProbe 字段可设置健康检查需要执行的命令或 HTTP/TCP 请求。以下设置通过发起 HTTP 请求方式,根据 /healthz 接口返回状态来判断服务是否正常,目前肯定是失败,因为接口本身就 404。

1
2
3
4
5
6
7
8
9
10
11
spec:
containers:
- name: k8sdemo
...
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 1

由于 Pod 默认自带恢复机制,也就是 spec.restartPolicy 字段的默认值是 Always,所以当健康检查失败就会触发自动恢复机制,这个字段值还支持 OnFailure(异常时才自动重启) 和 Never(永不重启),实际使用中,需要根据场景设置合理的恢复策略。

livenessProbe.png

但需要注意 Pod 的恢复永远都发生在当前节点,并不会移到其他节点,这也就意味着如果该 Pod 所在的机器宕机了,这个 Pod 就彻底挂了。至于如何处理这个问题,在后面 Deployment 控制器部分将会介绍。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK