# Kubernetes基础入门

#### 什么是K8S？ <a href="#toc201604305" id="toc201604305"></a>

* &#x20;Kubernetes 是做什么的？
* &#x20;什么是 Docker？
* &#x20;什么是容器编排？

Kubernetes 一词来自希腊语，意思是“飞行员”或“舵手”。这个名字很贴切，Kubernetes 可以帮助你在波涛汹涌的容器海洋中航行。

&#x20;

* &#x20;Kubernetes 是 Google 基于 Borg 开源的容器编排调度引擎，作为 CNCF最重要的组件之一，它的目标不仅仅是一个编排系统，而是提供一个规范，可以让你来描述集群的架构，定义服务的最终状态，Kubernetes 可以帮你将系统自动得达到和维持在这个状态。
* &#x20;用户可以通过编写一个 YAML 或者 json 格式的配置文件，也可以通过工具代码生成或直接请求 Kubernetes API 创建应用，该配置文件中包含了用户想要应用程序保持的状态，不论整个 Kubernetes 集群中的个别主机发生什么问题，都不会影响应用程序的状态，你还可以通过改变该配置文件或请求 Kubernetes API 来改变应用程序的状态。

**K8s组件**

<figure><img src="/files/a01M9CWJEJAfP6EoJnKn" alt=""><figcaption></figcaption></figure>

核心组件

* &#x20;API Server：资源操作唯一入口，提供认证、授权、访问控制、API注册等机制
* &#x20;etcd：保存集群状态信息
* &#x20;Controller Manager：维护集群状态，故障检测、自动扩展、滚动更新
* &#x20;Scheduler：资源调度，按照调度策略将Pod调度相应机器上
* &#x20;kubelet：维护容器生命周期，Volume、网络的管理
* &#x20;Container runtime：镜像管理以及Podcast容器运行
* &#x20;kube-proxy：为Service提供cluster内部服务发现、负载均衡

&#x20;

其它组件

* &#x20;kube-dns：为集群提供DNS服务
* &#x20;Ingress Controller：提供外网入口
* &#x20;Heapster：资源监控
* &#x20;Dashboard：GUI操作界面
* &#x20;Federation：跨可用区的集群
* &#x20;Fluentd-elasticsearch：集群日志采集、存储与查询

**K8s设计理念**

**API设计原则**

声明式API：指的是只需提交一个定义好的API对象来声明，"YAML文件就是一种声明"，声明式与命令式的区别在于前者是能处理多个操作，后者是请求只能一个一个实现。

高内聚、低耦合：使得模块的“可重用性”、“移植性”大大增强

* &#x20;内聚：每个模块尽可能独立完成自己的功能，不依赖于模块外部的代码。
* &#x20;耦合：模块与模块之间接口的复杂程度，模块之间联系越复杂耦合度越高，牵一发而动全身。
* &#x20;所有API应该是声明式的
* &#x20;API对象是彼此互补而且可组合的
  * &#x20;高内聚，松耦合
* &#x20;高层API以操作意图为基础设计
  * &#x20;高层设计一定是从业务出发，而不是过早的从技术实现出发，以系统调度管理容器的操作意图为基础设计。
* &#x20;低层API根据高层API的控制需要设计
  * &#x20;减少冗余、提高重用性的目的
* &#x20;尽量避免简单封装，不要有在外部API无法显式知道的内部隐藏的机制
  * &#x20;内部隐藏的机制也是非常不利于系统维护的设计方式
* &#x20;API操作复杂度与对象数量成正比
  * &#x20;保证整个系统随着系统规模的扩大，性能不会迅速变慢到无法使用
* &#x20;API对象状态不能依赖于网络连接状态
  * &#x20;在分布式环境下要保证API对象状态能应对网络的不稳定，API对象的状态就不能依赖于网络连接状态。
* &#x20;尽量避免让操作机制依赖于全局状态，因为在分布式
* &#x20;系统中要保证全局状态的同步是非常困难的。

**架构设计原则**

* &#x20;只有apiserver可以直接访问etcd存储，其他服务必须通过Kubernetes API来访问集群状态
* &#x20;单节点故障不应该影响集群的状态
* &#x20;在没有新请求的情况下，所有组件在故障恢复后继续执行上次最后收到的请求
* &#x20;所有组件都应该在内存中保持所需要的状态，apiserver将状态写入etcd存储，而其他组件则通过apiserver更新并监听所有的变化

#### Kubernetes架构 <a href="#toc1781842816" id="toc1781842816"></a>

&#x20;

<figure><img src="/files/0DlaSQke2mIPAdlqDPJF" alt=""><figcaption></figcaption></figure>

**Master组件**

* &#x20;Master节点是Kubernetes集群的控制节点
  * &#x20;API Server：资源操作唯一入口，提供认证、授权、访问控制、API注册等机制
  * &#x20;Controller Manager：维护集群状态，故障检测、自动扩展、滚动更新
  * &#x20;Scheduler：资源调度，按照调度策略将Pod调度相应机器上
* &#x20;etcd：用于保存集群所有的网络配置和对象的状态信息

**API-Server**

资源操作唯一入口，实现了认证、授权、准入控制等安全校验功能，同时也负责集群状态的存储操作（通过 etcd）

&#x20;

<figure><img src="/files/AHT4K6yRBvWSyrlJocrj" alt=""><figcaption></figcaption></figure>

只有API Server才能操作etcd

API层

* &#x20;Kube Core API Server 核心接口服务器
  * &#x20;负责对请求的一些通用处理，认证、鉴权等，以及处理各个内建资源的 REST 服务。
* &#x20;API Extensions Server 可扩展接口服务器
  * &#x20;主要处理 CustomResourceDefinition（CRD）和 CustomResource（CR）的 REST 请求
* &#x20;Aggregator Server 聚合服务器
  * &#x20;暴露的功能类似于一个七层[负载均衡](https://cloud.tencent.com/product/clb?from=10680)，将来自用户的请求拦截转发给其他服务器，并且负责整个 APIServer 的 Discovery 功能。

&#x20;

访问控制层

* &#x20;访问控制层对用户进行身份鉴权，然后根据配置的各种访问许可逻辑判断是否允许访问

注册表层

* &#x20;Kubernetes 把所有资源都保存在注册表（Registry）中，针对注册表中的各种资源对象，都定义了相应的资源对象类型，以及如何创建资源，转换不同版本的资源，编码解码资源。

访问控制

* &#x20;API Server会对每个请求都要经过合法性检验、用户身份鉴别、操作权限验证以及操作是否符合全局规范的约束才会被接受。
* &#x20;所有检查均正常完成且对象配置信息合法性检验无误之后才能访问或存入数据到后端存储系统etcd中

&#x20;

<figure><img src="/files/7hRr5uVTf3tlPpdveODa" alt=""><figcaption></figcaption></figure>

这里有两个访问方式，第一种管理员访问，第二种是通过Pod访问

* &#x20;User Account
  * &#x20;一般由外部的用户管理系统，K8s本身并不维护这类帐户信息，它不会存储到API Server上，仅用于检测用户是否有权限执行所请求的操作。
* &#x20;Service Account 简称SA
  * &#x20;其使用主体是应用程序，专用于为Pod资源中的服务进程提供访问K8s API时的身份标识
  * &#x20;Service Account通常由API Server创建，并通过准入控制器将其流入Pod对象
  * &#x20;通常附带着API Server认证凭据-Secret

Authentication

开启TLS时所有请求都需要认证，认证成功后会传入授权模块进一步授权验证，Kubernetes不直接管理用户，也不能创建user对象，也不存储用户。

Kubernetes 支持以下认证插件：

· X509 证书

· 静态 Token 文件

· 引导 Token

· 静态密码文件

· Service Account

· OpenID

· Webhook

· 认证代理

· OpenStack Keystone 密码

<https://kubernetes.feisky.xyz/extension/auth/authentication>

&#x20;

Authorization

主要用于对集群资源的访问控制，如授权成功后，将请求发送到准入控制模块做进一步的请求验证。

Kubernetes 授权仅处理以下的请求属性：

· user, group, extra

· API、请求方法（如 get、post、update、patch 和 delete）和请求路径（如 /api）

· 请求资源和子资源

· Namespace

· API Group

&#x20;

目前，Kubernetes 支持以下授权插件：

· ABAC

· RBAC

· Webhook

· Node

&#x20;

Admission Control

用来对请求做进一步的验证或添加默认参数，准入控制还处理请求的内容，并且仅对创建、更新、删除、删除等有效，对读操作无效。

**Scheduler**

负责分配调度 Pod 到集群内的节点上

<https://kubernetes.feisky.xyz/concepts/components/scheduler>

Controller Manager

Controller Manager 由 kube-controller-manager 和 cloud-controller-manager 组成，是 Kubernetes 的大脑通过 apiserver 监控整个集群的状态，负责集群内的Node、Pod副本、服务端点（Endpoint）、命名空间（Namespace）、服务账号（ServiceAccount）、资源定额（ResourceQuota） 的管理，当某个Node意外宕机时，Controller Manager会及时发现并执行自动化修复流程，并确保集群处于预期的工作状态。

Controller manager metrics 默认监听在 kube-controller-manager 的 10252 端口，提供 Prometheus 格式的性能度量数据

**etcd**

保存了整个集群的状态，就是一个数据库；

etcd — 架构原理：<https://blog.51cto.com/u_15301988/3085390>

**Node组件**

* &#x20;Node节点是物理机或虚拟机，组成了K8s的资源池，Node上的工作由Master分配
  * &#x20;kubele：负责Pod的创建、启动、监控、重启、销毁等工作，同时与Master节点协作，实现集群管理的基本功能。
* &#x20;Pod是运行应用的载体，由多个容器组成、是K8s的最小高度单元
  * &#x20;Kube-proxy：它监听API Server中server和endpoint的变化情况，并通过iptables等来为服务配置负载均衡
  * &#x20;Container Runtime：负责真正管理镜像和容器的

**Kubelet**

* 每个Node节点上都运行一个 Kubelet 服务进程，默认监听 10250 端口，接收并执行 Master 发来的指令，管理 Pod 及 Pod 中的容器。
* 每个 Kubelet 进程会在 API Server 上注册所在Node节点的信息，定期向 Master 节点汇报该节点的资源使用情况，并通过 cAdvisor 监控节点和容器的资源。

&#x20;

<figure><img src="/files/PXrICgyXZKVfbfoq8mQl" alt=""><figcaption></figcaption></figure>

&#x20;

**Kube-proxy**

它监听 API server 中 service 和 endpoint 的变化情况，并通过 iptables 等来为服务配置负载均衡（仅支持 TCP 和 UDP）

&#x20;

<figure><img src="/files/BZdpY8pNb5cN5vkRT3Bw" alt=""><figcaption></figcaption></figure>

工作原理

<https://kubernetes.feisky.xyz/concepts/components/kube-proxy>

**Container Runtime**

容器运行时（Container Runtime）是 Kubernetes 最重要的组件之一，负责真正管理镜像和容器的生命周期。

kubelet通过容器运行时接口（RCI）与容器运行时交互以管理镜像和容器

&#x20;

<figure><img src="/files/r0MSZME5SZcWljhd1FhD" alt=""><figcaption></figcaption></figure>

&#x20;

**其它组件**

**kube-dns**

通过 kube-dns 或 CoreDNS 作为集群的必备扩展来提供命名服务。

* &#x20;kube-dns：DNS 服务的核心组件，主要由 KubeDNS 和 SkyDNS 组成
  * &#x20;KubeDNS 负责监听 Service 和 Endpoint 的变化情况，并将相关的信息更新到 SkyDNS 中
  * &#x20;SkyDNS 负责 DNS 解析，监听在 10053 端口 (tcp/udp)，同时也监听在 10055 端口提供 metrics
  * &#x20;kube-dns 还监听了 8081 端口，以供健康检查使用
* &#x20;dnsmasq-nanny：负责启动 dnsmasq，并在配置发生变化时重启 dnsmasq
  * &#x20;dnsmasq 的 upstream 为 SkyDNS，即集群内部的 DNS 解析由 SkyDNS 负责
* &#x20;sidecar：负责健康检查和提供 DNS metrics（监听在 10054 端口）

&#x20;

工作原理

<https://kubernetes.feisky.xyz/concepts/components/kube-dns>

**Pod**

Pod 是 Kubernetes 调度的基本单位，Pod 的设计理念是每个 Pod 都有一个唯一的 IP。

它共享着PID、IPC、Network 和 UTS namespace，Pod内的多个容器共享网络和文件系统。

一个Pod的所有容器都运行在同一个节点上，不会跨越多个工作节点。

同一Pod内的容器间通信、各Pod彼此间通信、Pod与Service间的通信以及集群外部的流量与Service间的通信。

* &#x20;所有Pod间均可不经NAT机制而直接通信；
* &#x20;所有节点均可不经NAT机制直接与所有容器通信；
* &#x20;所有Pod对象都位于同一平面网络中，而且可以使用Pod自身的地址直接通信。

**YAML创建Pod**

```bash
---
apiVersion: v1
kind: Pod
metadata:
  name: kube100-site
  labels:
    app: web
spec:
  containers:
    - name: front-end
      image: nginx
      ports:
        - containerPort: 80
    - name: flaskapp-demo
      image: jcdemo/flaskapp
      ports:
        - containerPort: 5000
```

* &#x20;apiVersion，这里它的值是 v1，这个版本号需要根据我们安装的 kubernetes 版本和资源类型进行变化
* &#x20;kind，这里资源类型可以是 Deployment、Job、Ingress、Service 等
* &#x20;metadata：包含了定义的 Pod 的一些 meta 信息，比如名称、namespace、标签等信息
* &#x20;spec：包括一些 containers，storage，volumes，或者其他 Kubernetes 需要知道的参数，以及诸如是否在容器失败时重新启动容器的属性。

&#x20;

#### kubeasz安装k8s <a href="#toc772751097" id="toc772751097"></a>

<https://github.com/easzlab/kubeasz>

| 名称              | IP              |
| --------------- | --------------- |
| Ansible/Master1 | 192.168.238.129 |
| Master2         | 192.168.238.130 |
| Node1           | 192.168.238.131 |
| Node2           | 192.168.238.132 |

每台机器基本设置

{% code overflow="wrap" %}

```bash
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
systemctl stop firewalld
systemctl disable firewalld
timedatectl set-timezone Asia/Shanghai
Ansible/Master1
yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py
python get-pip.py
python -m pip install --upgrade "pip < 21.0"
pip install ansible -i https://mirrors.aliyun.com/pypi/simple/
 
ssh-keygen
ssh-copy-id Master1
ssh-copy-id Master2
ssh-copy-id Node1
ssh-copy-id Node2
```

{% endcode %}

&#x20;

```bash
git clone https://github.com/easzlab/kubeasz.git
./ezdown -D #拉取镜像等文件
vim /etc/kubeasz/clusters/k8s-01/hosts #ansible配置文件
./ezctl setup k8s-01 all #分1-7个步骤，可以单步骤安装也可以all
```

#### kubernetes常用命令 <a href="#toc1794073870" id="toc1794073870"></a>

```bash
#获取token
kubectl -n kube-system describe secret admin-user
 
#获取集群API服务的地址
kubectl cluster-info
kubectl cluster-info dump
 
#获取节点信息
kubectl get nodes
 
#节点详细信息
kubectl describe nodes ${NODENAME}
 
#kubectl config file
cat ~/.kube/config
 
#获取nodes节点
kubectl get nodes
 
#查看pods
kubectl get pods
 
#查看Pod运行的主机
kubectl get pods -o wide
 
#查看更详细主机信息
kubectl describe pods nginx-deployment-66b6c48dd5-9vzfv
 
#执行容器中命令
kubectl exec nginx-deployment-66b6c48dd5-9wmvj -- ls -l
 
#进入容器中
kubectl exec -it nginx-deployment-66b6c48dd5-9wmvj bash
 
#查看Deployment
kubectl get deployment
 
#将已有的资源导出yaml文件
kubectl get pods nginx-deployment-66b6c48dd5-9wmvj -o yaml
 
#通过yaml创建资源
kubectl create -f nginx.yaml
 
#查看资源对象
kubectl get namespaces
```

&#x20;

&#x20;

<figure><img src="/files/7AwttOZBS0TcuzqlmBVi" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/AhVYOdT62fBivuylVVUK" alt=""><figcaption></figcaption></figure>

#### kubernetes学习方法 <a href="#toc181645563" id="toc181645563"></a>

* &#x20;K8s学习过程和疑惑

&#x20;

<figure><img src="/files/bIagChQ5yQNIaidPFDz7" alt=""><figcaption></figcaption></figure>

{% embed url="<https://github.com/caicloud/kube-ladder>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lzcloudsecurity.gitbook.io/yun-an-quan-gong-fang-ru-men/di-liu-zhang-yun-yuan-sheng-gong-fang/kubernetes-ji-chu-ru-men.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
