关于 Kubernetes中kube-apiserver的一些笔记

2023-10-30 00:32

本文主要是介绍关于 Kubernetes中kube-apiserver的一些笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面


  • 学习K8s,简单整理下
  • 官网很详细,小伙伴系统学习可以到官网
  • https://kubernetes.io/zh/docs/tasks/administer-cluster/access-cluster-api/

年轻游侠儿泪眼模糊,凄然一笑,站起身,拿木剑对准墙壁,狠狠折断。

此后江湖再无温华的消息,这名才出江湖便已名动天下的木剑游侠儿,一夜之间,以最决然的苍凉姿态,离开了江湖。

刺骨大雪中,他最后对自己说了一句。

“不练剑了。” ——烽火戏诸侯《雪中悍刀行》


Kubernetes API Server原理分析

官网很详细,小伙伴系统学习可以到官网:https://kubernetes.io/zh/docs/tasks/administer-cluster/access-cluster-api/

Kubernetes API Server的核心功能是提供了Kubernetes各类资源对象(如Pod,RC, Service等)的增、删、改、查及Watch等HTTP Rest接口,成为集群内各个功能模块之间数据交互和通信的中心枢纽,是整个系统的数据总线和数据中心。除此之外,它还有以下一些功能特性。

(1)是集群管理的API入口。

(2)是资源配额控制的入口。

(3)提供了完备的集群安全机制。

理论概述

Kubernetes API Server通过一个名为kube-apiserver的进程提供服务,该进程运行在Master节点上,如果小伙伴使用二进制方式安装k8s,会发现,kube-apiserver是docker之后第一个要启动的服务

旧版本中kube-apiserver进程在本机的8080端口(对应参数-insecure-port)提供REST服务。

新版本中启动HTTPS安全端口(--secure-port=6443)来启动安全机制,加强REST API访问的安全性。这里需要说明的是,好像是从1.20开始就不支持了,在apiserver配置文件里添加 --insecure-port=8080会导致启动不了,所以不在支持直接http的方式访问(可以用代理)

在高版本的环境中,有时候环境起不来,会报错说6443端口没有开放

通常我们可以通过命令行工具kubectl来与Kubernetes API Server交互,它们之间的接口是REST调用。

使用 kubectl 代理

如果我们只想对外暴露部分REST服务,则可以在Master或其他任何节点上通过运行kubect proxy进程启动一个内部代理来实现。

┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl proxy --port=8080 &
[1] 43454
┌──[root@vms81.liruilongs.github.io]-[~]
└─$Starting to serve on 127.0.0.1:8080┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl http://localhost:8080/api/ > kubeapi% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100   185  100   185    0     0   2863      0 --:--:-- --:--:-- --:--:--  2936
┌──[root@vms81.liruilongs.github.io]-[~]
└─$head -20 kubeapi
{"kind": "APIVersions","versions": ["v1"],"serverAddressByClientCIDRs": [{"clientCIDR": "0.0.0.0/0","serverAddress": "192.168.26.81:6443"}]
}┌──[root@vms81.liruilongs.github.io]-[~]
└─$jobs
[1]+  Running                 kubectl proxy --port=8080 &
┌──[root@vms81.liruilongs.github.io]-[~]
└─$fg
kubectl proxy --port=8080
^C

当然,我们也可以拒绝访问某一资源,比如pod

┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl proxy  --reject-paths="^/api/v1/pod" --port=8080 --v=1 &
┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl http://localhost:8080/api/v1/pods
Forbidden
┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl http://localhost:8080/api/v1/configmaps > $(mktemp kube.XXXXXX)% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100 25687    0 25687    0     0   644k      0 --:--:-- --:--:-- --:--:--  660k
┌──[root@vms81.liruilongs.github.io]-[~]
└─$head  -5 kube.zYxKiH
{"kind": "ConfigMapList","apiVersion": "v1","metadata": {"resourceVersion": "81890"
┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl http://localhost:8080/api/v1/secrets | head -5% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0{"kind": "SecretList","apiVersion": "v1","metadata": {"resourceVersion": "82039"
100 65536    0 65536    0     0  1977k      0 --:--:-- --:--:-- --:--:-- 2064k
curl: (23) Failed writing body (0 != 16378)
┌──[root@vms81.liruilongs.github.io]-[~]
└─$

kubectl proxy具有很多特性,最实用的一个特性是提供简单有效的安全机制,比如采用白名单来限制非法客户端访问时,只要增加下面这个参数即可:

--accept-hosts="^localhost$, ^127\\.0\\.0\\.1$,^\\[::1\\]$"
不使用 kubectl 代理

通过将身份认证令牌直接传给 API 服务器,可以避免使用 kubectl 代理,像这样: 使用 grep/cut 方式:

# 查看所有的集群,因为你的 .kubeconfig 文件中可能包含多个上下文
┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'
Cluster name    Server
kubernetes      https://192.168.26.81:6443# 从上述命令输出中选择你要与之交互的集群的名称
┌──[root@vms81.liruilongs.github.io]-[~]
└─$export CLUSTER_NAME=kubernetes
# 指向引用该集群名称的 API 服务器
┌──[root@vms81.liruilongs.github.io]-[~]
└─$APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")
┌──[root@vms81.liruilongs.github.io]-[~]
└─$echo $APISERVER
https://192.168.26.81:6443# 获得令牌
┌──[root@vms81.liruilongs.github.io]-[~]
└─$TOKEN=$(kubectl  get secret  default-token-xg77h -o jsonpath='{.data.token}' -n kube-system | base64 -d)# 使用令牌玩转 API
┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
{"kind": "APIVersions","versions": ["v1"],"serverAddressByClientCIDRs": [{"clientCIDR": "0.0.0.0/0","serverAddress": "192.168.26.81:6443"}]
}

编程方式访问 API

python

要使用 Python 客户端,运行下列命令: pip install kubernete

PS E:\docker> pip install kubernetes
Collecting kubernetesUsing cached kubernetes-21.7.0-py2.py3-none-any.whl (1.8 MB)............

将 ~/.kube 的config文件的内容复制到本地目录,保存为文件kubeconfig.yaml

┌──[root@vms81.liruilongs.github.io]-[~]
└─$cp .kube/config    kubeconfig.yaml
python
在这里插入图片描述
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   k8s_api.py
@Time    :   2021/12/16 23:05:02
@Author  :   Li Ruilong
@Version :   1.0
@Contact :   1224965096@qq.com
@Desc    :   K8s Demo
'''# here put the import lib
from kubernetes import client, configconfig.kube_config.load_kube_config(config_file="kubeconfig.yaml")v1=client.CoreV1Api()
print("Listing pods with their IPs:")
ret = v1.list_pod_for_all_namespaces(watch=False)
for i in ret.items:print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

输出所有的pod和对应的node IP

PS D:\code\blogger\blogger\资源> python .\k8s_api.py
Listing pods with their IPs:
10.244.88.67    kube-system     calico-kube-controllers-78d6f96c7b-85rv9
192.168.26.81   kube-system     calico-node-6nfqv
192.168.26.83   kube-system     calico-node-fv458
192.168.26.82   kube-system     calico-node-h5lsq
.................
Java
# 克隆 Java 库
git clone --recursive https://github.com/kubernetes-client/java
java的客户端
在这里插入图片描述
package io.kubernetes.client.examples;import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import java.io.FileReader;
import java.io.IOException;/*** A simple example of how to use the Java API from an application outside a kubernetes cluster** <p>Easiest way to run this: mvn exec:java* -Dexec.mainClass="io.kubernetes.client.examples.KubeConfigFileClientExample"** <p>From inside $REPO_DIR/examples*/
public class KubeConfigFileClientExample {public static void main(String[] args) throws IOException, ApiException {// file path to your KubeConfigString kubeConfigPath = "D:\\code\\k8s\\java\\examples\\examples-release-10\\src\\main\\java\\io\\kubernetes\\client\\examples\\config";// loading the out-of-cluster config, a kubeconfig from file-systemApiClient client =ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();// set the global default api-client to the in-cluster one from aboveConfiguration.setDefaultApiClient(client);// the CoreV1Api loads default api-client from global configuration.CoreV1Api api = new CoreV1Api();// invokes the CoreV1Api clientV1PodList list =api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null);for (V1Pod item : list.getItems()) {System.out.println(item.getMetadata().getName());}}
}

输出所有pod

D:\Java\jdk1.8.0_251\bin\java.exe 。。。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Bad level value for property: .level
Bad level value for property: java.util.logging.ConsoleHandler.level
calico-kube-controllers-78d6f96c7b-85rv9
calico-node-6nfqv
calico-node-fv458
calico-node-h5lsq
coredns-7f6cbbb7b8-ncd2s
coredns-7f6cbbb7b8-pjnct
etcd-vms81.liruilongs.github.io
。。。。。。。。。

独特的Kubernetes Proxy API接口

Kubernetes Proxy API接口,作用是代理REST请求,即Kubernetes API Server把收到的REST请求转发到某个Node上的kubelet·守护进程的REST端口上,由该kubelet进程负责响应。

┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl  proxy  8080 &
[1] 76543
┌──[root@vms81.liruilongs.github.io]-[~]
└─$Starting to serve on 127.0.0.1:8001
┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl  get nodes
NAME                         STATUS     ROLES                  AGE   VERSION
vms81.liruilongs.github.io   Ready      control-plane,master   4d    v1.22.2
vms82.liruilongs.github.io   Ready      <none>                 4d    v1.22.2
vms83.liruilongs.github.io   NotReady   <none>                 4d    v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl http://localhost:8001/api/
{"kind": "APIVersions","versions": ["v1"],"serverAddressByClientCIDRs": [{"clientCIDR": "0.0.0.0/0","serverAddress": "192.168.26.81:6443"}]
}┌──[root@vms81.liruilongs.github.io]-[~]
└─$
┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl http://localhost:8001/api/v1/namespaces/default/pods
{"kind": "PodList","apiVersion": "v1","metadata": {"resourceVersion": "92086"},"items": []
}
┌──[root@vms81.liruilongs.github.io]-[~]
└─$curl http://localhost:8080/api/v1/nodes/vms82.liruilongs.github.io/

需要说明的是:这里获取的Pod的信息数据来自Node而非etcd数据库,所以两者可能在·某些时间点会有偏差。此外,如果kubelet进程在启动时包含-enable-debugging-handlers=true参数,那么Kubernetes Proxy API还会增加其他的接口信息

集群功能模块之间的通信

Kubernetes API Server 作为集群的核心,负责集群各功能模块之间的通信。集群内的各个功能模块通过API Server将信息存入etcd,当需要获取和操作这些数据时,则通过API Server提供的REST接口(用GET, LIST或WATCH方法)来实现,从而实现各模块之间的信息交互。

交互场景:

kubelet进程与API Server的交互 每个Node节点上的kubelet每隔一个时间周期,就会调用一次API Server的REST接口报告自身状态, API Server接收到这些信息后,将节点状态信息更新到etcd中。 , kubelet也通过API Server的Watch接口监听Pod信息,如果监听到新的Pod副本被调度绑定到本节点,则执行Pod对应的容器的创建和启动逻辑;如果监听到Pod对象被删除,则删除本节点上的相应的Pod容器;如果监听到修改Pod信息,则kubelet监听到变化后,会相应地修改本节点的Pod容器。

kube-controller-manager进程与API Server的交互。 kube-controller-manager中的Node Controller模块通过API Sever提供的Watch接口,实时监控Node的信息,并做相应处理

kube-schedulerAPI Server的交互当Scheduler通过API Server的Watch接口监听到新建Pod副本的信息后,它会检索所有符合该Pod要求的Node列表,开始执行Pod调度逻辑,调度成功后将Pod绑定到目标节点上。

为了缓解集群各模块对API Server的访问压力,各功能模块都采用缓存机制来缓存数据。各功能模块定时从API Server获取指定的资源对象信息(通过LISTWATCH方法),然后将这些信息保存到本地缓存,功能模块在某些情况下不直接访问API Server,而是通过访问缓存数据来间接访问API Server.

这篇关于关于 Kubernetes中kube-apiserver的一些笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/304447

相关文章

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

什么是Kubernetes PodSecurityPolicy?

@TOC 💖The Begin💖点点关注,收藏不迷路💖 1、什么是PodSecurityPolicy? PodSecurityPolicy(PSP)是Kubernetes中的一个安全特性,用于在Pod创建前进行安全策略检查,限制Pod的资源使用、运行权限等,提升集群安全性。 2、为什么需要它? 默认情况下,Kubernetes允许用户自由创建Pod,可能带来安全风险。

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit