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. 【scikit-learn基础】--『预处理』之 正则化

    数据的预处理是数据分析,或者机器学习训练前的重要步骤.通过数据预处理,可以 提高数据质量,处理数据的缺失值.异常值和重复值等问题,增加数据的准确性和可靠性 整合不同数据,数据的来源和结构可能多种多样, ...

  2. ez_curl【代码审计】

    ez_curl[代码审计][难度:4] 题目描述 代码审计类题目,附上代码: <?php highlight_file(__FILE__); $url = 'http://back-end:30 ...

  3. 【内核】ELF 文件执行流程

    # ELF 文件分类 Linux中,ELF文件全称为:Executable and Linkable Format,主要有三种形式,分别是: 可执行文件 动态库文件(共享文件 .so) 目标文件(可重 ...

  4. 华企盾科技:智能AI自动化研判分析服务系统概述

    由中企网安全资子公司北京华企盾科技有限责任公司开发的<智能AI自动化研判分析服务系统>,获得国家版权局颁发的计算机软件著作权登记证书. 智能AI自动化研判分析服务系统是基于人工智能.大数据 ...

  5. Git 的底层原理

    前言 ​ 基于 Git 的使用,已经在前文有过相关的介绍,使用 Git 用作日常的开发基本上是足够的.现在,本文将详细介绍一些有关 Git 的实现原理. 底层命令与上层命令 ​ 一般情况下,正常使用的 ...

  6. 新版的Django中的path不能使用正则表达式

    新版的path 虽然 取代了 之前的url,但是在写路由的时候不能在路由中直接写正则表达式,不然会找不到页面. 解决方法使用 re_path from django.urls import re_pa ...

  7. 在Docker上面安装/启动、运行、挂载MySQL5.7

    下载文档请看:https://hub.docker.com/r/mysql/mysql-server 一.下载镜像 执行命令: docker pull mysql/mysql-server:5.7 查 ...

  8. 神经网络入门篇:详解为什么需要非线性激活函数?(why need a nonlinear activation function?)

    为什么需要非线性激活函数? 为什么神经网络需要非线性激活函数?事实证明:要让的神经网络能够计算出有趣的函数,必须使用非线性激活函数,证明如下: 这是神经网络正向传播的方程,现在去掉函数\(g\),然后 ...

  9. 一文详解kube-apiserver认证鉴权能力

    本文分享自华为云社区<kube-apiserver认证鉴权能力>,作者: 可以交个朋友. HTTPS为什么要进行身份验证 首先不管是kubectl还是API调用都是通过HTTPS访问kub ...

  10. 云图说|应用魔方AppCube:揭秘码农防脱神器

    摘要: 应用魔方(AppCube)是华为云为行业客户.合作伙伴.开发者量身打造的一款低代码开发平台.通过AppCube可轻松构建专业级应用,创新随心所欲,敏捷超乎想象. 本文分享自华为云社区<云 ...