Kubernetes(一)之概念 & 架构解析 & 证书创建 & 分发

参考链接:https://www.cnblogs.com/linuxk/p/9272567.html

一.Kubernetes的重要概念

1.1 Cluster

Cluster 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用。

1.2 Master

Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。Master 运行 Linux 操作系统,可以是物理机或者虚拟机。为了实现高可用,可以运行多个 Master。

1.3 Node

Node 的职责是运行容器应用。Node 由 Master 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。Node 运行在 Linux 操作系统,可以是物理机或者是虚拟机。

1.4 Pod

Pod 是 Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。

1.5 Kubernetes 引入 Pod 主要基于下面两个目的:

  • 可管理性。
    有些容器天生就是需要紧密联系,一起工作。Pod 提供了比容器更高层次的抽象,将它们封装到一个部署单元中。Kubernetes 以 Pod 为最小单位进行调度、扩展、共享资源、管理生命周期。

  • 通信和资源共享。
    Pod 中的所有容器使用同一个网络 namespace,即相同的 IP 地址和 Port 空间。它们可以直接用 localhost 通信。同样的,这些容器可以共享存储,当 Kubernetes 挂载 volume 到 Pod,本质上是将 volume 挂载到 Pod 中的每一个容器。

1.6 Pods 有两种使用方式:

  • 运行单一容器。
    one-container-per-Pod 是 Kubernetes 最常见的模型,这种情况下,只是将单个容器简单封装成 Pod。即便是只有一个容器,Kubernetes 管理的也是 Pod 而不是直接管理容器。

  • 运行多个容器。
    但问题在于:哪些容器应该放到一个 Pod 中?
    答案是:这些容器联系必须 非常紧密,而且需要 直接共享资源。

举个例子。

下面这个 Pod 包含两个容器:一个 File Puller,一个是 Web Server。

File Puller 会定期从外部的 Content Manager 中拉取最新的文件,将其存放在共享的 volume 中。Web Server 从 volume 读取文件,响应 Consumer 的请求。
这两个容器是紧密协作的,它们一起为 Consumer 提供最新的数据;同时它们也通过 volume 共享数据。所以放到一个 Pod 是合适的。

再来看一个反例:是否需要将 Tomcat 和 MySQL 放到一个 Pod 中?
Tomcat 从 MySQL 读取数据,它们之间需要协作,但还不至于需要放到一个 Pod 中一起部署,一起启动,一起停止。同时它们是之间通过 JDBC 交换数据,并不是直接共享存储,所以放到各自的 Pod 中更合适。

1.7 Controller

Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。为了满足不同的业务场景,Kubernetes 提供了多种 Controller,包括 Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job 等,我们逐一讨论。

  • 1.Deployment 是最常用的 Controller,比如前面在线教程中就是通过创建 Deployment 来部署应用的。Deployment 可以管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。

  • 2.ReplicaSet 实现了 Pod 的多副本管理。使用 Deployment 时会自动创建 ReplicaSet,也就是说 Deployment 是通过 ReplicaSet 来管理 Pod 的多个副本,我们通常不需要直接使用 ReplicaSet。

  • 3.DaemonSet 用于每个 Node 最多只运行一个 Pod 副本的场景。正如其名称所揭示的,DaemonSet 通常用于运行 daemon。

  • 4.StatefuleSet 能够保证 Pod 的每个副本在整个生命周期中名称是不变的。而其他 Controller 不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。

  • 5.Job 用于运行结束就删除的应用。而其他 Controller 中的 Pod 通常是长期持续运行。

1.8 Service

Deployment 可以部署多个副本,每个 Pod 都有自己的 IP,外界如何访问这些副本呢?

通过 Pod 的 IP 吗?
要知道 Pod 很可能会被频繁地销毁和重启,它们的 IP 会发生变化,用 IP 来访问不太现实。

答案是 Service。
Kubernetes Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP 和端口,Service 为 Pod 提供了负载均衡。

Kubernetes 运行容器(Pod)与访问容器(Pod)这两项任务分别由 Controller 和 Service 执行。

1.9 Namespace

如果有多个用户或项目组使用同一个 Kubernetes Cluster,如何将他们创建的 Controller、Pod 等资源分开呢?

答案就是 Namespace。
Namespace 可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的。

Kubernetes 默认创建了两个 Namespace。

[root@linux-node1 ~]# kubectl get namespace
NAME          STATUS    AGE
default       Active    1d
kube-system   Active    1d

default -- 创建资源时如果不指定,将被放到这个 Namespace 中。
kube-system -- Kubernetes 自己创建的系统资源将放到这个 Namespace 中。

二.Kubernetes架构和集群规划

2.1 Kubernetes架构

2.2 Kubernetes架构拆解图

2.3 K8S Master节点

从上图可以看到,Master是K8S集群的核心部分,主要运行着以下的服务:kube-apiserver、kube-scheduler、kube-controller-manager、etcd和Pod网络(如:flannel)

  • API Server:K8S对外的唯一接口,提供HTTP/HTTPS RESTful API,即kubernetes API。所有的请求都需要经过这个接口进行通信。主要处理REST操作以及更新ETCD中的对象。是所有资源增删改查的唯一入口。

  • Scheduler:资源调度,负责决定将Pod放到哪个Node上运行。Scheduler在调度时会对集群的结构进行分析,当前各个节点的负载,以及应用对高可用、性能等方面的需求。

  • Controller Manager:负责管理集群各种资源,保证资源处于预期的状态。Controller Manager由多种controller组成,包括replication controller、endpoints controller、namespace controller、serviceaccounts controller等

  • ETCD:负责保存k8s 集群的配置信息和各种资源的状态信息,当数据发生变化时,etcd会快速地通知k8s相关组件。

  • Pod网络:Pod要能够相互间通信,K8S集群必须部署Pod网络,flannel是其中一种的可选方案。

2.4 K8S Node节点

Node是Pod运行的地方,Kubernetes支持Docker、rkt等容器Runtime。Node上运行的K8S组件包括kubelet、kube-proxy和Pod网络。

  • Kubelet:kubelet是node的agent,当Scheduler确定在某个Node上运行Pod后,会将Pod的具体配置信息(image、volume等)发送给该节点的kubelet,kubelet会根据这些信息创建和运行容器,并向master报告运行状态。

  • Kube-proxy:service在逻辑上代表了后端的多个Pod,外借通过service访问Pod。service接收到请求就需要kube-proxy完成转发到Pod的。每个Node都会运行kube-proxy服务,负责将访问的service的TCP/UDP数据流转发到后端的容器,如果有多个副本,kube-proxy会实现负载均衡,有2种方式:LVS或者Iptables

  • Docker Engine:负责节点的容器的管理工作

三.Kubernetes中pod创建流程

  Pod是Kubernetes中最基本的部署调度单元,可以包含container,逻辑上表示某种应用的一个实例。例如一个web站点应用由前端、后端及数据库构建而成,这三个组件将运行在各自的容器中,那么我们可以创建包含三个container的pod。

3.1 具体的创建步骤包括:

  • 1.客户端提交创建请求,可以通过API Server的Restful API,也可以使用kubectl命令行工具。支持的数据类型包括JSON和YAML。

  • 2.API Server处理用户请求,存储Pod数据到etcd。

  • 3.调度器通过API Server查看未绑定的Pod。尝试为Pod分配主机。

  • 4.过滤主机 (调度预选):调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量,那么可用资源比Pod需要的资源量少的主机会被过滤掉。

  • 5.主机打分(调度优选):对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把容一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等。

  • 6.选择主机:选择打分最高的主机,进行binding操作,结果存储到etcd中。

  • 7.kubelet根据调度结果执行Pod创建操作: 绑定成功后,scheduler会调用APIServer的API在etcd中创建一个boundpod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步boundpod信息,一旦发现应该在该工作节点上运行的boundpod对象没有更新,则调用Docker API创建并启动pod内的容器。

3.2 实验环境准备:

主机名 IP地址 描述
linux-node1.example.com ens33:192.168.172.30 K8S Master节点/ETCD节点
linux-node2.example.com ens33:192.168.172.40 K8S Node节点/ETCD节点
linux-node3.example.com ens33:192.168.172.50 K8S Node节点/ETCD节点

3.3 系统环境初始化

  • 1.安装Docker

第一步:使用国内Docker源

[root@linux-node1.example.com ~]# cd /etc/yum.repos.d/
[root@linux-node1.example.com /etc/yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

[root@linux-node2.example.com ~]# cd /etc/yum.repos.d/
[root@linux-node2.example.com /etc/yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

[root@linux-node3.example.com ~]# cd /etc/yum.repos.d/
[root@linux-node3.example.com /etc/yum.repos.d]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

第二步:Docker安装:

[root@linux-node1.example.com /etc/yum.repos.d]# yum install docker-ce -y
[root@linux-node2.example.com /etc/yum.repos.d]# yum install docker-ce -y
[root@linux-node3.example.com /etc/yum.repos.d]# yum install docker-ce -y

第三步:启动后台进程:

[root@linux-node1.example.com /etc/yum.repos.d]#  systemctl start docker
[root@linux-node2.example.com /etc/yum.repos.d]#  systemctl start docker
[root@linux-node3.example.com /etc/yum.repos.d]#  systemctl start docker
  • 2.准备部署目录
[root@linux-node1.example.com /etc/yum.repos.d]#  mkdir -p /opt/kubernetes/{cfg,bin,ssl,log}
[root@linux-node2.example.com /etc/yum.repos.d]#  mkdir -p /opt/kubernetes/{cfg,bin,ssl,log}
[root@linux-node3.example.com /etc/yum.repos.d]#  mkdir -p /opt/kubernetes/{cfg,bin,ssl,log}
  • 3.准备软件包

百度网盘下载地址:
https://pan.baidu.com/s/1zs8sCouDeCQJ9lghH1BPiw

  • 4.解压软件包
[root@linux-node1 src]# tar zxf kubernetes.tar.gz 
[root@linux-node1 src]# tar zxf kubernetes-server-linux-amd64.tar.gz 
[root@linux-node1 src]# tar zxf kubernetes-client-linux-amd64.tar.gz
[root@linux-node1 src]# tar zxf kubernetes-node-linux-amd64.tar.gz

[root@linux-node1 src]# cd kubernetes   #解压的server、client、node都会解压到kubernetes目录下
[root@linux-node1 kubernetes]# ll
total 29536
drwxr-xr-x  2 root root        6 Apr 12 23:16 addons
drwxr-xr-x  3 root root       31 Apr 12 23:16 client
drwxr-xr-x 13 root root     4096 Apr 12 23:24 cluster
drwxr-xr-x  7 root root      131 Apr 12 23:25 docs
drwxr-xr-x 34 root root     4096 Apr 12 23:25 examples
drwxr-xr-x  3 root root       17 Apr 12 23:24 hack
-rw-r--r--  1 root root 24710771 Apr 12 23:16 kubernetes-src.tar.gz
-rw-r--r--  1 root root  5516760 Apr 12 23:16 LICENSES
drwxr-xr-x  3 root root       17 Apr 12 23:16 node
-rw-r--r--  1 root root     3329 Apr 12 23:25 README.md
drwxr-xr-x  3 root root       66 Apr 12 23:16 server
drwxr-xr-x  3 root root       22 Apr 12 23:24 third_party
-rw-r--r--  1 root root        8 Apr 12 23:25 version
  • 5.各个节点增加kubernetes的环境变量:
[root@linux-node1.example.com ~]# vim .bash_profile 
PATH=$PATH:$HOME/bin:/opt/kubernetes/bin
[root@linux-node1.example.com ~]# source .bash_profile

[root@linux-node2.example.com ~]# vim .bash_profile 
PATH=$PATH:$HOME/bin:/opt/kubernetes/bin
[root@linux-node2.example.com ~]# source .bash_profile

[root@linux-node3.example.com ~]# vim .bash_profile 
PATH=$PATH:$HOME/bin:/opt/kubernetes/bin
[root@linux-node3.example.com ~]# source .bash_profile
  • 6.CA证书创建和分发
      从k8s的1.8版本开始,K8S系统各组件需要使用TLS证书对通信进行加密。每一个K8S集群都需要独立的CA证书体系。CA证书有以下三种:easyrsa、openssl、cfssl。这里使用cfssl证书,也是目前使用最多的,相对来说配置简单一些,通过json的格式,把证书相关的东西配置进去即可。这里使用cfssl的版本为1.2版本。

第一步:安装 CFSSL:

[root@linux-node1 ~]# cd /usr/local/src
[root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@linux-node1 src]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
[root@linux-node1 src]# chmod +x cfssl*  #增加执行权限
[root@linux-node1 src]# mv cfssl-certinfo_linux-amd64 /opt/kubernetes/bin/cfssl-certinfo
[root@linux-node1 src]# mv cfssljson_linux-amd64  /opt/kubernetes/bin/cfssljson
[root@linux-node1 src]# mv cfssl_linux-amd64  /opt/kubernetes/bin/cfssl

复制cfssl命令文件到k8s-node1和k8s-node2节点。如果实际中多个节点,就都需要同步复制。

[root@linux-node1 ~]# ssh-copy-id linux-node1
[root@linux-node1 ~]# ssh-copy-id linux-node2
[root@linux-node1 ~]# ssh-copy-id linux-node3
[root@linux-node1 ~]# scp /opt/kubernetes/bin/cfssl* 192.168.56.120:/opt/kubernetes/bin
cfssl                                              100%   10MB  18.1MB/s   00:00    
cfssl-certinfo                                     100% 6441KB  21.3MB/s   00:00    
cfssljson                                          100% 2224KB  13.3MB/s   00:00    
[root@linux-node1 ~]# scp /opt/kubernetes/bin/cfssl* 192.168.56.130:/opt/kubernetes/bin
cfssl                                              100%   10MB  22.5MB/s   00:00    
cfssl-certinfo                                     100% 6441KB  40.7MB/s   00:00    
cfssljson                                          100% 2224KB  43.1MB/s   00:00   

第二步:创建用来生成 CA 文件的 JSON 配置文件:

[root@linux-node1 src]# mkdir ssl && cd ssl    #创建临时证书存放目录
[root@linux-node1 ssl]# pwd
/usr/local/src/ssl

[root@linux-node1 ssl]# vim ca-config.json
{
  "signing": {
    "default": {
      "expiry": "8760h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "8760h"
      }
    }
  }
}

第三步:创建用来生成 CA 证书签名请求(CSR)的 JSON 配置文件:

[root@linux-node1 ssl]# vim ca-csr.json
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}

第四步:生成CA证书(ca.pem)和密钥(ca-key.pem):

[root@linux-node1 ssl]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca  #生成证书和密钥
2018/05/30 14:11:02 [INFO] generating a new CA key and certificate from CSR
2018/05/30 14:11:02 [INFO] generate received request
2018/05/30 14:11:02 [INFO] received CSR
2018/05/30 14:11:02 [INFO] generating key: rsa-2048
2018/05/30 14:11:02 [INFO] encoded CSR
2018/05/30 14:11:02 [INFO] signed certificate with serial number 167714418220584190953978332616641264281080483250
[root@linux-node1 ssl]# ll
total 20
-rw-r--r-- 1 root root  290 May 30 14:09 ca-config.json
-rw-r--r-- 1 root root 1001 May 30 14:11 ca.csr
-rw-r--r-- 1 root root  208 May 30 14:10 ca-csr.json
-rw------- 1 root root 1675 May 30 14:11 ca-key.pem
-rw-r--r-- 1 root root 1359 May 30 14:11 ca.pem

第五步:分发证书:

[root@linux-node1 ssl]# cp ca.csr ca.pem ca-key.pem ca-config.json /opt/kubernetes/ssl

SCP证书到k8s-node1和k8s-node2节点,以后增加节点也是需要将这些证书进行分发
[root@linux-node1 ssl]# scp ca.csr ca.pem ca-key.pem ca-config.json 192.168.56.120:/opt/kubernetes/ssl 
ca.csr                                                   100% 1001   350.2KB/s   00:00    
ca.pem                                                   100% 1359   891.4KB/s   00:00    
ca-key.pem                                               100% 1675     1.0MB/s   00:00    
ca-config.json                                           100%  290   180.7KB/s   00:00    
[root@linux-node1 ssl]# scp ca.csr ca.pem ca-key.pem ca-config.json 192.168.56.130:/opt/kubernetes/ssl 
ca.csr                                                   100% 1001   350.2KB/s   00:00    
ca.pem                                                   100% 1359   891.4KB/s   00:00    
ca-key.pem                                               100% 1675     1.0MB/s   00:00    
ca-config.json                                           100%  290   180.7KB/s   00:00    
原文地址:https://www.cnblogs.com/even160941/p/14832834.html