1. kubernetes 整体架构

kubernetes 由 master 节点和工作节点组成。其中,master 节点的组件有 APIServer,scheduler 和 controller-manager。APIServer 是系统管理指令的统一入口,scheduler 负责调度 Pod 到合适的工作节点上,controller-manager 是一组资源控制器,负责控制管理对应的资源,如 replication 等。工作节点的组件有 kubelet 和 kube-proxy。kubelet 负责创建,管理,维护 pod,kube-proxy 负责将访问 service 的流量转发到对应的 endpoint 上。

kubernetes 的整体架构图如下所示:

了解了整体架构图,那么各个组件是如何协同工作的呢。这里以创建 pod 为例查看各组件的协作流程,流程图如下:

主要有如下几步:

  1. 用户调用 REST API 请求创建 pod,APIServer 响应 API 请求,并进行一系列验证操作,包括认证,授权和资源配置等,验证通过后,APIServer 调用 etcd 在后台数据库建立 Pod 资源对象。
  2. scheduler 定期调用 APIServer 的 kubernetes API 接口查看系统中可用的工作节点列表和待调度 Pod,使用调度策略为待调度 Pod 选择合适的工作节点,这个过程称为绑定(bind)。
  3. 绑定成功后,scheduler 调用 APIServer 在 etcd 中创建 binding 对象,该对象描述了工作节点上绑定运行的所有 pod 信息。

1.1 APIServer 概述

APIServer 作为统一接口,负责管理各组件的通信,是 kubernetes 集群的核心。对资源的增删改查操作都将通过 APIServer 传递到后台 etcd 数据库,使用 curl 工具可以很容易的获取到 APIServer 的 API 响应信息。

1.1.1 Kubernetes APIServer 组件

查看环境上运行的 APIServer:

[root@chunqiu ~ (Master)]# kubectl get pods -o wide -n kube-system | grep api
kube-apiserver-chunqiu-0 1/1 Running 1 70d 172.17.66.2 chunqiu-0 <none> <none>
kube-apiserver-chunqiu-1 1/1 Running 1 70d 172.17.66.3 chunqiu-1 <none> <none>
kube-apiserver-chunqiu-2 1/1 Running 1 70d 172.17.66.4 chunqiu-2 <none> <none> [root@chunqiu ~ (Master)]# kubectl get service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 70d <none> [root@chunqiu ~ (Master)]# kubectl describe service kubernetes
Name: kubernetes
Namespace: default
Labels: component=apiserver
provider=kubernetes
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP: 10.254.0.1
Port: https 443/TCP
TargetPort: 8443/TCP
Endpoints: 172.17.66.2:8443,172.17.66.3:8443,172.17.66.4:8443
Session Affinity: None
Events: <none>

当前环境为 master 和工作节点共用模式,可以看到每台节点上都以 pod 形式运行了 APIServer,并且它们与 kubernetes service 进行了绑定。

集群内的 APIServer 部署知道了,那 APIServer 的配置文件又是怎样的呢?查看组件的配置文件能更好的理解组件的整体结构:

[root@chunqiu ~ (Master)]# kubectl describe pods kube-apiserver-chunqiu-0 -n kube-system
Priority: 2000001000
Priority Class Name: system-node-critical
Status: Running
IP: 172.17.66.2
Containers:
kube-apiserver:
Image: bcmt-registry:5000/k8s.gcr.io/kube-apiserver-amd64:v1.19.5
Port: 8443/TCP
Host Port: 8443/TCP
Command:
/usr/local/bin/kube-apiserver
--default-not-ready-toleration-seconds=180
--default-unreachable-toleration-seconds=180
--bind-address=172.17.66.2
--etcd-servers=https://172.17.66.2:2379
--etcd-cafile=/etc/etcd/ssl/ca.pem
--etcd-certfile=/etc/etcd/ssl/etcd-client.pem
--etcd-keyfile=/etc/etcd/ssl/etcd-client-key.pem
--allow-privileged=true
--service-cluster-ip-range=10.254.0.0/16
--secure-port=8443
--insecure-port=0
--anonymous-auth=false
--authorization-mode=Node,RBAC
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount...
--kubelet-certificate-authority=/etc/kubernetes/ssl/ca.pem
--kubelet-client-certificate=/etc/kubernetes/ssl/cluster-admin.pem
--kubelet-client-key=/etc/kubernetes/ssl/cluster-admin-key.pem
...

省略了部分参数,主要配置参数及命令如下:

参数 描述
/usr/local/bin/kube-apiserver image 中包含的启动 apiserver 命令
bind-address apiserver 安全端口绑定的 ip 地址,用于接受安全连接
etcd-servers,etcd-cafile,etcd-certfile,etcd-keyfile 访问 etcd 需要的信息
allow-privileged 是否运行容器以特权模式运行
service-cluster-ip-range 绑定 service 的 ip 范围(kubernetes service 的 cluster ip 为 10.254.0.1)
secure-port 安全端口,通过安全 ip 加安全端口的方式可以访问到 apiserver
insecure-port 非安全端口,用于接受非安全连接,0 表示不启用非安全端口
enable-admission-plugins admission controller 的插件
kubelet-certificate-authority,kubelet-client-certificate,kubelet-client-key 访问 apiserver 的认证信息

介绍了 APIServer 配置信息,接下来使用 curl 调用 APIServer API 看看请求结果。

1.1.2 Kubernetes API

为了兼容旧版本的同时升级新版本 API,Kubernetes 提供了多版本 API 的支持,每个版本的 API 通过一个版本号路径前缀进行区分,如 /api/v1beta1 等。通过 kubectl api-version 命令可以查看当前 kubernetes 的版本信息:

[root@chunqiu ~ (Master)]# kubectl api-versions | grep v1
networking.k8s.io/v1
networking.k8s.io/v1beta1
...

可以看到资源 networking 包含不同的 APIVersion,其中 v1beta1 表示不建议使用(Deprecated)版本。关于版本发布及管理信息可看这里

kubernetes 使用 API Groups 对 API 进行标识,API Groups 分为两种:

  1. Core Groups(核心组)是 Kubernetes 最核心的 API,其特点是没有“组”的概念,例如 “v1” 即表示核心组 apiVersion: v1。
  2. 具有分组信息的 API,以 /api/$GROUP_NAME/$VERSION/ URL 路径进行标识,如 apiVersion: apps/v1。

    关于 API 详细信息可参考这里

以 pod 为例,查看 pod 的基本 API 接口:

资源类型 方法 说明 备注
PODS GET /api/v1/pods 获取 pod 列表
POST /api/v1/pods 创建 pod 列表
GET /api/v1/namespaces/{namespace}/pods 获取 Namespace 下的 pod 列表
POST /api/v1/namespaces/{namespace}/pods 在 Namespace 下创建 pod
DELETE /api/v1/namespaces/{namespace}/pods/ 删除 Namespace 下的 pod 对象
GET /api/v1/namespaces/{namespace}/pods/ 获取 Namespace 下的 pod 对象
PATCH /api/v1/namespaces/{namespace}/pods/ 部分更新某个 Namespace 下的 pod 对象
PUT /api/v1/namespaces/{namespace}/pods/ 替换某个 Namespace 下的 pod 对象

使用 curl 工具 curl pod 的 API:

[root@chunqiu ~ (Master)]# curl https://172.17.66.2:8443/api/v1/namespaces/ci/pods/ --cacert /etc/kubernetes/ssl/ca.pem \
--key /etc/kubernetes/ssl/cluster-admin-key.pem --cert /etc/kubernetes/ssl/cluster-admin.pem
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces/ci/pods/",
"resourceVersion": "42384766"
},
"items": [
{
"metadata": {
"name": "chunqiu-0",
"generateName": "chunqiu-",
"namespace": "ci",
"selfLink": "/api/v1/namespaces/ci/pods/chunqiu-0",
"uid": "36793f0c-9bf9-4bec-b46e-66f5945d3889",
"resourceVersion": "42378305",
"creationTimestamp": "2021-06-09T03:18:00Z",
...

curl 获取到 Namespace ci 下的 pod 列表。类似的,获取 apiVersion: apps/v1 的 statefulset 资源列表如下:

[root@chunqiu ~ (Master)]# curl https://172.17.66.2:8443/apis/apps/v1/namespaces/ci/statefulsets/ --cacert /etc/kubernetes/ssl/ca.pem \
--key /etc/kubernetes/ssl/cluster-admin-key.pem --cert /etc/kubernetes/ssl/cluster-admin.pem
{
"kind": "StatefulSetList",
"apiVersion": "apps/v1",
"metadata": {
"selfLink": "/apis/apps/v1/namespaces/ci/statefulsets/",
"resourceVersion": "42392636"
},
"items": [
{
"metadata": {
"name": "chunqiu",
"namespace": "ci",
"selfLink": "/apis/apps/v1/namespaces/ci/statefulsets/chunqiu",
"uid": "0e00ffab-e504-43bf-bcd6-713359a2cfde",
"resourceVersion": "42392038",
"generation": 1,
"creationTimestamp": "2021-06-09T03:40:55Z",
"labels": {
"app.kubernetes.io/managed-by": "Helm"
},
...

对资源对象的操作除了增删改查外,Kubernetes 还提供另外一种资源操作类型 WATCH,WATCH 返回一连串 JSON 对象,该对象记录了某个给定资源对象的变化情况。如对 pod 的 WATCH 操作:

资源类型 类型 方法 URL Path 说明
PODS WATCH GET /api/v1/watch/pods 监听所有 pod 变化
POST /api/v1/watch/namespaces/{namespace}/pods 监听某个 Namespace 下所有 pod 的变化

调用 WATCH API 监听 pod 变化情况:

[root@chunqiu ~ (Master)]# curl https://172.17.66.2:8443/api/v1/watch/pods/ --cacert /etc/kubernetes/ssl/ca.pem\
--key /etc/kubernetes/ssl/cluster-admin-key.pem --cert /etc/kubernetes/ssl/cluster-admin.pem
{"type":"ADDED","object":{"kind":"Pod","apiVersion":"v1"
... # 删除 pod
{"type":"MODIFIED","object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"chunqiu-0","generateName":"chunqiu-...
...

可以看到 WATCH API 始终处于监控当前 pod 变化状态,使用 kubectl 删除某个 pod,WATCH API 监听到该 pod 的变化情况。

1.2 etcd 概述

那么 APIServer 介绍完了吗?并没有,离开 etcd 的 APIServer 是不完整的。介绍 etcd 之前,先看下 APIServer 的拓扑结构:

用户请求通过认证授权之后访问 APIServer,APIServer 会进一步调用 admission controller 对用户请求进行进一步资源审核,审核由多维度资源插件完成(APIServer 配置参数的 enable-admission-plugins 参数定义了所需资源审核插件),通过审核后 APIServer 会根据 REST API 调用在后台 etcd 进行实际的增删改查操作。

Kubernetes 的资源存储路径都以 /registry 开始的:

[root@chunqiu ~ (Master)]# etcdctl --endpoints=https://172.17.66.2:2379 --cacert /etc/etcd/ssl/ca.pem \
--key /etc/etcd/ssl/etcd-key.pem --cert /etc/etcd/ssl/etcd.pem get /registry/ --prefix --keys-only=true
/registry/apiextensions.k8s.io/customresourcedefinitions/brhooks.cbur.csf.chunqiu.com /registry/apiextensions.k8s.io/customresourcedefinitions/brpolices.cbur.bcmt.local
...

构造场景使用 DELETE 方法删除 pod,查看 etcd 中该 pod 的资源变化情况:

  1. 默认 namespace 下创建 pod,查看 pod 在 etcd 存储情况。
[root@chunqiu ~ (Master)]# kubectl get pods
NAME READY STATUS RESTARTS AGE
etcdtester 0/1 ImagePullBackOff 0 100s [root@chunqiu ~ (Master)]# etcdctl --endpoints=https://172.17.66.2:2379 --cacert /etc/etcd/ssl/ca.pem \
--key /etc/etcd/ssl/etcd-key.pem --cert /etc/etcd/ssl/etcd.pem get /registry/pods/default/etcdtester --prefix --keys-only=true
/registry/pods/default/etcdtester
  1. 开启 WATCH 监听默认 namespace 下 pod 变化情况。
[root@chunqiu ~ (Master)]# curl https://172.17.66.2:8443/api/v1/watch/namespaces/default/pods/ --cacert /etc/kubernetes/ssl/ca.pem \
--key /etc/kubernetes/ssl/cluster-admin-key.pem --cert /etc/kubernetes/ssl/cluster-admin.pem
{"type":"ADDED","object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"etcdtester"...
  1. 调用 APIServer 的 DELETE 方法删除 pod,查看 etcd 中 pod 变化情况:
# DELETE pod
[root@chunqiu ~ (Master)]# curl -X DELETE https://172.17.66.2:8443/api/v1/namespaces/default/pods/etcdtester --cacert /etc/kubernetes/ssl/ca.pem \
--key /etc/kubernetes/ssl/cluster-admin-key.pem --cert /etc/kubernetes/ssl/cluster-admin.pem
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "etcdtester",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/pods/etcdtester",
... # WATCH 监听 pod
[root@chunqiu ~ (Master)]# curl https://172.17.66.2:8443/api/v1/watch/namespaces/default/pods/ --cacert /etc/kubernetes/ssl/ca.pem \
--key /etc/kubernetes/ssl/cluster-admin-key.pem --cert /etc/kubernetes/ssl/cluster-admin.pem
{"type":"ADDED","object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"etcdtester"... {"type":"MODIFIED","object":{"kind":"Pod","apiVersion":"v1","metadata":{"name":"etcdtester"... # etcd 查看 pod
[root@chunqiu ~ (Master)]# etcdctl --endpoints=https://172.17.66.2:2379 --cacert /etc/etcd/ssl/ca.pem \
--key /etc/etcd/ssl/etcd-key.pem --cert /etc/etcd/ssl/etcd.pem get /registry/pods/default/etcdtester --prefix --keys-only=true

可以看到,删除 pod 后 WATCH 监听到 pod 变化,etcd 更新 pod 资源对象。

Kubernetes APIServer 最佳实践的更多相关文章

  1. Kubernetes YAML最佳实践和策略

    Kubernetes工作负载最常用YAML格式的文件来定义. YAML的问题之一就是很难描述清单文件之间的约束或关系. 如果你希望检查是否已从受信任的注册表中提取部署到群集中的所有映像,该怎么办? 如 ...

  2. Kubernetes Deployment 最佳实践

    零.示例 首先给出一个 Deployment+HPA+ PodDisruptionBudget 的完整 demo,后面再详细介绍其中的每一个部分: apiVersion: apps/v1 kind: ...

  3. Aggregated APIServer 构建云原生应用最佳实践

    作者 张鹏,腾讯云容器产品工程师,拥有多年云原生项目开发落地经验.目前主要负责腾讯云 TKE 云原生 AI 产品的开发工作. 谢远东,腾讯高级工程师,Kubeflow Member.Fluid(CNC ...

  4. Kubernetes生产环境最佳实践

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 众所周知,Kubernetes很难! 以下是在生产中使用 ...

  5. 生产环境容器落地最佳实践 --JFrog 内部K8s落地旅程

    引言 Kubernetes已经成为市场上事实上领先的编配工具,不仅对技术公司如此,对所有公司都是如此,因为它允许您快速且可预测地部署应用程序.动态地伸缩应用程序.无缝地推出新特性,同时有效地利用硬件资 ...

  6. Kubernetes最佳实践之腾讯云TKE 集群组建

    作者陈鹏,腾讯工程师,负责腾讯云 TKE 的售中.售后的技术支持,根据客户需求输出合理技术方案与最佳实践,为客户业务保驾护航.使用 TKE 来组建 Kubernetes 集群时,会面对各种配置选项,本 ...

  7. Kubernetes集群的监控报警策略最佳实践

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79652064 本文为Kub ...

  8. Kubernetes日志的6个最佳实践

    本文转自Rancher Labs Kubernetes可以帮助管理部署在Pod中的上百个容器的生命周期.它是高度分布式的并且各个部分是动态的.一个已经实现的Kubernetes环境通常涉及带有集群和节 ...

  9. 可能是Asp.net Core On host、 docker、kubernetes(K8s) 配置读取的最佳实践

    写在前面 为了不违反广告法,我竭尽全力,不过"最佳实践"确是标题党无疑,如果硬要说的话 只能是个人最佳实践. 问题引出 ​ 可能很多新手都会遇到同样的问题:我要我的Asp.net ...

  10. 验证Kubernetes YAML的最佳实践和策略

    本文来自Rancher Labs Kubernetes工作负载最常见的定义是YAML格式的文件.使用YAML所面临的挑战之一是,它相当难以表达manifest文件之间的约束或关系. 如果你想检查所有部 ...

随机推荐

  1. cmd命令根据端口号杀进程

    1.根据端口查到进程pid netstat –ano|findstr 端口号 1 2.使用taskkill命令杀死进程 taskkill /pid pid 1 温馨提醒: 1.执行完第一步后,命令行显 ...

  2. javaScript正则截取自定义标签-javascript-zheng-ze-jie-qu-zi-ding-yi-biao-qian

    title: javaScript正则截取自定义标签 date: 2021-12-29 17:31:48.448 updated: 2021-12-29 17:31:48.448 url: https ...

  3. Rust 学习笔记

    rust 学习梳理 数据类型 基于已明确的类型,Rust会推断剩下大部分类型.基于类型推断Rust具备了与动态类型语言近似的易读性,并仍能在编译期捕获类型错误. 函数可以是泛型的:单个函数ujiu可以 ...

  4. JavaFx之TableView表格添加按钮删除行(二十二)

    JavaFx之TableView表格添加按钮删除行(二十二) JavaFx之TableView添加按钮 JavaFx之TableView删除行 编写一个xml <?xml version=&qu ...

  5. 2023-11-29:用go语言,给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。 需保证 返回结果的字典序最小。 要求不能打乱其他字符的相对位置)。 输入:s = “cba

    2023-11-29:用go语言,给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次. 需保证 返回结果的字典序最小. 要求不能打乱其他字符的相对位置). 输入:s = &quo ...

  6. 4大焕新,华为云CCE带你感受容器化上云体验

    本文分享自华为云社区<华为云CCE邀您共同打造最佳容器化上云体验>,作者:云容器大未来 . 在容器化日益成为中大型企业上云主流选择的情况下,容器服务如何能帮助用户更简单快捷的上云.高效可信 ...

  7. 2022 IDC中国未来企业大奖优秀奖颁布,华为云数据库助力德邦快递获奖

    摘要:华为云数据库助力德邦快递打造的"基于数智融合的一站式物流供应链平台"项目从500多个项目中脱颖而出,荣获2022 IDC中国未来企业大奖优秀奖"未来智能领军者&qu ...

  8. 带你认识大模型训练关键算法:分布式训练Allreduce算法

    摘要:现在的模型以及其参数愈加复杂,仅仅一两张的卡已经无法满足现如今训练规模的要求,分布式训练应运而生. 本文分享自华为云社区<分布式训练Allreduce算法>,原文作者:我抽签必中. ...

  9. maptalks点线面图形样式设置经验总结

    个人偏好使用mapbox,但是架不住人多,被使用maptalks,然而的文档非常感人,让人泪崩三千里-- maptalks图形样式设置,通过symbol设置 设置symbol的,可以直接在 图形(Ma ...

  10. iOS代码安全加固利器:深入探讨字符串和代码混淆器的作用

    ​ 在网上搜"代码混淆"关键词,可以看到n多教程.包括本篇博客,大部分重要内容也是从网上各位大神的博客里面看到然后摘取和总结出来的.虽然网上都有,但是对于我个人来说,很难找到一篇博 ...