Linux云计算 |【第五阶段】CLOUD-DAY6

主要内容:

了解Kubernetes的架构、搭建Kubernetes集群

一、Kubernetes 概述

Kubernetes 这个名字来自希腊语,意思是"舵手"或"领航员";K8S 是 Kubernetes 的缩写,其中"8"代表字母"ubernete"中的8个字母。Kubernetes 是由谷歌(Google)公司制作的,是谷歌10多年大规模容器管理技术 Borg 的开源版本。于2014年6月由谷歌公司正式发布并宣布开源。

功能与特点:

  1. **容器集群管理系统:**Kubernetes 是一个开源的平台,用于管理容器集群
  2. **自动化部署:**Kubernetes 可以实现容器集群的自动化部署
  3. **自动扩缩容:**Kubernetes 支持根据需求自动扩展或缩减容器集群的规模
  4. **维护功能:**Kubernetes 提供维护功能,确保容器集群的稳定运行

1. 自动化部署

  • 描述:Kubernetes 可以自动部署应用程序和服务到容器集群中,减少手动操作的复杂性和错误
  • 优势:提高部署效率,减少人为错误,确保一致性和可重复性

2. 自动扩缩容

  • 描述:Kubernetes 可以根据应用程序的负载情况自动扩展或缩减容器集群的规模
  • 优势:优化资源利用率,降低成本,确保应用程序在高负载下仍能稳定运行

3. 维护功能

  • 描述:Kubernetes 提供维护功能,包括自动修复、滚动更新、回滚等,确保容器集群的稳定运行
  • 优势:减少停机时间,提高系统的可靠性和可用性

1、Kubernetes (K8S) 集群解析

Kubernetes (K8S) 集群是一个由多个节点组成的系统,用于管理和运行容器化应用程序。Kubernetes 集群的核心组件包括控制平面(Control Plane)工作节点(Worker Nodes)

核心角色:

    • Master(管理节点、控制平面)
    • Node(计算节点、工作节点)
    • image(镜像仓库)

1)控制平面(Control Plane)

控制平面是 Kubernetes 集群的大脑,负责管理和控制整个集群的状态,对集群进行全局决策,检测和响应集群事件;主要由 API Server、Scheduler、Etcd和Controller manager 组件组成。

① API Server

  • 功能:提供 Kubernetes API,是集群的入口点,负责处理所有 API 请求
  • 特点:支持 RESTful API,用于与集群进行交互
  • 备注:整个系统的对外接口,提供客户端和其它组件调用,后端运行的所有元数据都会存储于etcd中(键值数据库)

② etcd

  • 功能:分布式键值存储,用于存储集群的所有配置数据和状态信息
  • 特点:高可用性和一致性,确保集群状态的可靠存储
  • 备注:由kubernetes集群自动管理,用户无需手动干预,etcdctl是etcd的客户端管理程序

③ Scheduler

  • 功能:负责将 Pod(Kubernetes 的最小调度单元)调度到合适的节点上运行
  • 特点:根据资源需求、节点状态和策略进行智能调度
  • 备注:负责对集群内部的资源进行调度,负责分配容器运行地址

④ Controller Manager

  • 功能:运行各种控制器进程,负责维护集群的状态,如副本控制器、节点控制器等
  • 特点:确保集群的实际状态与期望状态一致

⑤ Cloud Controller Manager

  • 功能:与云服务提供商的 API 交互,管理云资源,如负载均衡器、存储卷等
  • 特点:特定于云环境的控制器,提供云资源的集成管理

Master相关组件接口:

2)工作节点(Worker Nodes)

工作节点是 Kubernetes 集群中实际运行容器化应用程序的节点,负责维护运行Pod,并提供具体应用的运行环境;每个工作节点包含以下核心组件:

① Kubelet:

  • 功能:负责管理节点上的容器,与控制平面通信,确保容器按照 Pod 规范运行
  • 特点:节点上的代理,负责执行控制平面的指令
  • 备注:用来启动、监视pod及调用Docker去对容器进行操作,包括增删改等操作

② Kube-proxy:

  • 功能:负责维护节点上的网络规则,实现服务发现和负载均衡
  • 特点:确保 Pod 之间的网络通信和服务的可达性
  • 备注:为Pod对象提供代理,并实现kubernetes Service的通信与负载均衡机制

③ 容器运行时(Container Runtime):

  • 功能:负责运行容器,如 Docker、containerd、CRI-O 等
  • 特点:支持多种容器运行时,提供容器生命周期管理

2、kube-proxy 代理模式解析

kube-proxy 是 Kubernetes 集群中负责网络代理和负载均衡的关键组件。它确保集群内部和外部的网络流量能够正确地路由到相应的 Pod。kube-proxy 支持多种代理模式,每种模式都有其特定的实现方式和适用场景。以下是对 kube-proxy 代理模式的详细解析:

1)用户空间代理模式(User Space Proxy Mode)

版本:Kubernetes v1.0

实现方式:kube-proxy 在用户空间运行,通过切换不同的用户空间来实现对应用的访问。

特点:

  • 简单:实现简单,易于理解和调试。
  • 性能较低:由于在用户空间和内核空间之间频繁切换,性能较低。
  • 适用场景:早期版本中使用,适用于小型集群或测试环境。

2)iptables 模式代理(iptables Proxy Mode)

版本:Kubernetes v1.1

实现方式:kube-proxy 使用 iptables 规则来实现网络流量的转发和映射。

特点:

  • 性能较高:直接在内核空间操作,性能优于用户空间代理模式。
  • 复杂性:iptables 规则复杂,管理和维护难度较大。
  • 适用场景:适用于大多数生产环境,特别是需要高性能和稳定性的场景。

3)IPVS 代理模式(IPVS Proxy Mode)

版本:Kubernetes v1.8

实现方式:kube-proxy 使用 IPVS(IP Virtual Server)来实现负载均衡。IPVS 是 Linux 内核的一部分,提供高性能的负载均衡功能。

特点:

  • 高性能:IPVS 在内核空间实现负载均衡,性能非常高。
  • 可扩展性:支持多种负载均衡算法(如轮询、加权轮询、最小连接等)。
  • 复杂性:需要满足一定的内核和软件包要求。
  • 适用场景:适用于大规模集群,特别是需要高性能负载均衡的场景。

启用 IPVS 模式的条件

内核支持,内核必须支持以下模块:

  • ip_vs:IPVS 核心模块。
  • ip_vs_rr:轮询调度算法。
  • ip_vs_wrr:加权轮询调度算法。
  • ip_vs_sh:源地址哈希调度算法。
  • nf_conntrack_ipv4:连接跟踪模块。

软件包支持,必须安装以下软件包:

  • ipvsadm:IPVS 管理工具。
  • ipset:用于管理 IP 集合的工具。

配置文件中开启 IPVS 参数,在 kube-proxy 的配置文件中开启 IPVS 参数,例如:

复制代码
mode: ipvs

3、Pod 的详细解析

在 Kubernetes 中,Pod 是调度的基本单元,也是最小的部署和管理单元。Pod 的设计理念是将一组紧密关联的容器打包在一起,共享相同的网络命名空间和存储卷。以下是对 Pod 的详细解析:

1)Pod 的基本概念

调度的基本单元

Pod 是 Kubernetes 调度的基本单元,Kubernetes 通过调度 Pod 来管理容器的运行;

容器组

一个 Pod 可以包含一个或多个容器,这些容器共享相同的网络命名空间和存储卷;

网络命名空间

Pod 中的所有容器共享相同的 IP 地址和端口号,容器之间可以通过 localhost 进行通信;

存储卷

Pod 中的容器可以共享存储卷,实现数据的共享和持久化;

2)Pod 的特点

  • 独立部署单元:Pod 是一个独立的部署单元,支持横向扩展和复制。通过复制 Pod,可以实现应用的高可用性和负载均衡。
  • 多进程聚合:Pod 可以看作是一个服务的多个进程的聚合单位。例如,一个 Pod 可以包含一个主应用容器和一个辅助容器(如日志收集器)。
  • 生命周期管理:Pod 的生命周期由 Kubernetes 管理,支持自动重启、扩缩容等。
  • 资源隔离:Pod 中的容器在同一节点上运行,但资源隔离由容器运行时管理。

3)Pod 的管理

在 Kubernetes 中,用户无法单独管理某一个容器。管理容器的时候是以 Pod 为单位,必须先创建 Pod,才能够去创建容器。每个容器都在 Pod 中,没有不在 Pod 的容器。Pod 是容器运行的最小环境。

4)Pod 的创建和使用

① 创建 Pod:

通过定义 YAML 或 JSON 格式的 Pod 配置文件,可以创建 Pod。配置文件中指定 Pod 的名称、容器镜像、端口、存储卷等信息。

② 管理 Pod:

Kubernetes 提供了丰富的命令和 API 来管理 Pod,如 kubectl create、kubectl get、kubectl delete 等。

③ Pod 的扩展:

通过复制 Pod,可以实现应用的横向扩展。Kubernetes 的副本控制器(ReplicaSet 或 Deployment)负责管理 Pod 的副本数量。

二、kubernetes 集群安装部署

1)安装部署方式:

  1. **源码部署:**下载源码或编译好的二进制,手工添加参数启动服务,Kubernetes采用证书认证方式,需要创建大量证书;
  2. **容器部署:**官方把服务做成"镜像",下载镜像、启动即可;

官方特意根据容器部署方式,制作kubeadm工具,为用户提高下载良好体验度(推荐)

官网地址:Kubernetes

2)部署环境要求:

  • ① 内核版本:>= 3.10
  • ② 最低配置:2CPU、2G内存
  • ③ 节点之中不可以有重复的主机名、MAC地址或product_uuid
  • ④ 卸载防火墙、禁用Swap交换分区、禁用SELinux;

安装部署示例:

环境准备:实验集群规划,需购买5台云主机

|-----------|---------------|-----------|--------|
| 主机名 | IP地址 | 最低配置 | 集群角色 |
| master | 192.168.1.21 | 2CPU,4G内存 | 管理节点 |
| node-0001 | 192.168.1.31 | 2CPU,4G内存 | 计算节点 |
| node-0002 | 192.168.1.32 | 2CPU,4G内存 | 计算节点 |
| node-0003 | 192.168.1.33 | 2CPU,4G内存 | 计算节点 |
| registry | 192.168.1.100 | 1CPU,1G内存 | 私有镜像仓库 |

步骤1:私有镜像仓库初始化(registry操作192.168.1.100)

① 安装仓库软件并启动服务

bash 复制代码
[root@registry ~]# yum makecache
[root@registry ~]# yum install -y docker-distribution    //安装私有镜像仓库软件
[root@registry ~]# systemctl enable --now docker-distribution  //开启镜像仓库服务

② 使用脚本初始化仓库(init-img.sh

拷贝云盘kubernetes/v1.17.6/registry/myos目录的部署脚本和镜像压缩包到仓库服务器

bash 复制代码
[root@ecs-proxy ~]# scp /root/kubernetes/v1.17.6/registry/myos/* 192.168.1.100:/root/
[root@registry ~]# mkdir myos    //创建存放目录
[root@registry ~]# cp init-img.sh myos.tar.gz myos/
[root@registry ~]# ls myos
init-img.sh  myos.tar.gz
[root@registry ~]# cd myos
[root@registry myos]# chmod 755 init-img.sh   //赋予脚本执行权限
[root@registry myos]# ./init-img.sh    //执行脚本(导入4个镜像)
[root@registry myos]# curl http://192.168.1.100:5000/v2/myos/tags/list   //查看镜像仓库的myos镜像的标签
{"name":"myos","tags":["php-fpm","httpd","nginx","v1804"]}

**补充:**其中镜像标签是v1804即原来的latest,因latest在k8s中有特殊含义;在k8s集群中,latest标签是不会被缓存,如果想缓存可以使用其他标签;

步骤2:配置YUM仓库(proxy跳板机操作)

在跳板机上拷贝kubernetes/v1.17.6/k8s-install/到Yum仓库,提供安装工具软件包

bash 复制代码
[root@ecs-proxy ~]# cp -a kubernetes/v1.17.6/k8s-install/ /var/ftp/localrepo/
[root@ecs-proxy ~]# cd /var/ftp/localrepo/
[root@ecs-proxy localrepo]# createrepo --update .
[root@ecs-proxy localrepo]# ls k8s-install/

补充:官网下载软件包地址https://packages.cloud.google.com/

步骤3:Master管理节点安装工具部署(master操作192.168.1.21)

① 安装基础软件包(kubeadm、kubectl、kubelet、docker-ce)

    • Kubeadm:用来初始化集群的命令行工具;
    • kubectl:用来与集群通信的命令行工具(K8S集群管理工具);
    • kubelet:在集群中的每个节点上用来启动pod和容器等,用来管理容器和应用的;
    • docker-ce:容器的管理工具
bash 复制代码
[root@master ~]# yum makecache
[root@master ~]# yum install -y kubeadm kubelet kubectl docker-ce

② Tab键自动补全设置

Kubectl、kubeadm工具支持自动补全功能,可节省大量输入,需在Shell配置文件中调用

bash 复制代码
[root@master ~]# kubectl completion bash > /etc/bash_completion.d/kubectl
[root@master ~]# kubeadm completion bash > /etc/bash_completion.d/kubeadm
[root@master ~]# exit   //配置完成后,重新登录后生效

③ 修改内核参数(开启netfilter对bridge设备的监控)

bash 复制代码
[root@master ~]# vim /etc/sysctl.d/k8s.conf    //编写配置文件
net.bridge.bridge-nf-call-ip6tables = 1    //开启网桥监控
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1     //路由转发
[root@master ~]# modprobe br_netfilter   //载入内核模块
[root@master ~]# sysctl --system

步骤4:Master管理节点服务镜像部署(master操作192.168.1.21)

① 编写配置文件/etc/docker/daemon.json,指定私有镜像仓库

注意:为docker指定私有镜像仓库和Cgroup驱动控制器;因kubelet使用的Cgroup控制器是Systemd,而docker使用的是Cgroupfs,所以必须设置统一(查询命令:docker info)

bash 复制代码
[root@master ~]# mkdir -p /etc/docker
[root@master ~]# vim /etc/docker/daemon.json   //指定registry的镜像仓库地址IP端口
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "registry-mirrors": ["https://hub-mirror.c.163.com"],
    "insecure-registries":["192.168.1.100:5000", "registry:5000"]
}
[root@master ~]# systemctl enable --now docker kubelet   //启动Docker、kubelet服务
[root@master ~]# docker info | grep Cgroup
Cgroup Driver: systemd      //必须使用systemd驱动

② 镜像导入私有仓库

补充:K8S v1.17.6推荐的部署方式是使用镜像部署,master节点各个服务是运行在容器内的;

拷贝云盘kubernetes/v1.17.6/base-images中的7个镜像拷贝到master(apiserver、coredns、controller-manager、kube-proxy、scheduler、etcd、pause)

bash 复制代码
[root@ecs-proxy ~]# scp -r /root/kubernetes/v1.17.6/base-images/ 192.168.1.21:/root
[root@master ~]# cd base-images/
[root@master base-images]# ls
coredns.tar.gz  etcd.tar.gz  kube-apiserver.tar.gz  kube-controller-manager.tar.gz kube-proxy.tar.gz  kube-scheduler.tar.gz  pause.tar.gz

③ 导入镜像到本地仓库

bash 复制代码
[root@master base-images]# for i in *.tar.gz
> do
> docker load -i ${i}
> done
[root@master base-images]# docker images

④ 上传到私有镜像仓库

bash 复制代码
[root@master base-images]# docker images | awk '$2!="TAG"{print $1,$2}'|while read _f _v;do
>     docker tag ${_f}:${_v} 192.168.1.100:5000/${_f##*/}:${_v};
>     docker push 192.168.1.100:5000/${_f##*/}:${_v};
>     docker rmi ${_f}:${_v};
> done

查看验证

bash 复制代码
[root@master base-images]# curl http://192.168.1.100:5000/v2/_catalog   //查看私有镜像仓库的镜像
{"repositories":["coredns","etcd","kube-apiserver","kube-controller-manager","kube-proxy","kube-scheduler","myos","pause"]}

步骤5:Master管理节点初始化安装(master操作192.168.1.21)

① 安装IPVS代理软件包

bash 复制代码
[root@master ~]# yum install -y ipvsadm ipset

② 配置主机名

bash 复制代码
[root@master ~]# vim /etc/hosts
192.168.1.21   master
192.168.1.31   node-0001
192.168.1.32   node-0002
192.168.1.33   node-0003
192.168.1.100  registry

③ 使用kubeadm工具初始化应答文件安装master(kubeadm-init.yaml)

拷贝云盘的kubernetes/v1.17.6/config/kubeadm-init.yaml应答文件到Master

    • 格式:kubeadm init --config=应答文件.yaml //初始化安装
bash 复制代码
[root@ecs-proxy ~]# scp /root/kubernetes/v1.17.6/config/kubeadm-init.yaml 192.168.1.21:/root
[root@master ~]# mkdir init ; cd init
[root@master init]# cp /root/kubeadm-init.yaml ./
[root@master init]# kubeadm init --config=kubeadm-init.yaml | tee master-init.log   //初始化安装
[root@master init]# tree /root/init/
init/
├── kubeadm-init.yaml
└── master-init.log
0 directories, 2 files

④ 通过tee的输出提示,根据提示执行命令

bash 复制代码
[root@master init]# mkdir -p $HOME/.kube
[root@master init]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@master init]# sudo chown $(id -u):$(id -g) $HOME/.kube/config

⑨ 验证安装结果(安装完成即集群已组建,需等Node节点加入)

bash 复制代码
[root@master ~]# kubectl version   //查看版本
bash 复制代码
[root@master ~]# kubectl get componentstatuses    //查看Master组件的状态

补充:Kubeadm常用命令

|-----------|-------------|
| 命令 | 说明 |
| - config | 配置管理命令 |
| - help | 查看帮助 |
| - init | 初始命令 |
| - join | node加入集群的命令 |
| - reset | 还原状态命令 |
| - token | token凭证管理命令 |
| - version | 查看版本 |

补充:通过tee命令记录日志(输出到终点且记录到日志)

补充:Node节点需要加入集群,必须有Master节点提供的Token令牌;

获取Token,需要从Master的安装日志里查找安装指令示例:

  • token:相当于证明文件

  • token-ca-cert-hash: 验证文件的真伪

补充:Token管理

管理token使用kubeadm token指令:

    • 格式:kubeadm token list //列出token
    • 格式:kubeadm token delete //删除token
    • 格式:kubeadm token create 参数 //创建token

可选参数:

--ttl 设置token生命周期,0为无限;

--print-join-command 直接打印安装命令;


步骤6:在Master上创建生成token(master操作192.168.1.21)

bash 复制代码
[root@master ~]# kubeadm token create --ttl=0 --print-join-command
bash 复制代码
[root@master ~]# kubeadm token list
  • 方法1:获取token证书的hash,--discovery-token-ca-cert-hash sha256:
  • 方法2:获取token证书的hash,CA证书路径/etc/kubernetes/pki.ca.crt,通过Openssl指令获取;
bash 复制代码
[root@master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der | openssl dgst -sha256 -hex

token证书:2f5px8.l2tgvrpppe4i3ha2

token_hash:23ddaaad95ac7377bbc858975ac068529a0bda07d60cd32e5726611c576751b4

token_hash加密算法:sha256

步骤7:Node计算节点安装并加入集群(proxy跳板机操作)

  • ① 卸载防火墙
  • ② 禁用SELinux和SWAP
  • ③ 配置YUM仓库,安装kubeadm、kubelet、docker-ce
  • ④ 安装IPVS模式软件包:ipvsadm、ipset
  • ⑤ 配置Docker私有镜像仓库和Cgroup驱动(daemon.json)
  • ⑥ 配置内核参数(/etc/sysctl.d/k8s.conf)
  • ⑦ 配置/etc/host(Master能访问Node的主机名)

拷贝云盘上 kubernetes/v1.17.6/node-install 的Ansible安装Playbook剧本到跳板机

bash 复制代码
[root@ecs-proxy ~]# cp -a /root/kubernetes/v1.17.6/node-install/ /root/
[root@ecs-proxy ~]# cd node-install/
[root@ecs-proxy node-install]# ls
ansible.cfg  files  hostlist.yaml  node_install.yaml
//注释:Ansible配置文件、主机清单文件、安装Node节点Playbook
[root@ecs-proxy node-install]# tree files/
files/
├── daemon.json   //指定私有仓库配置文件
├── hosts         //主机名解析文件
└── k8s.conf     //内核参数配置文件
0 directories, 3 files

① 修改主机名解析文件,删除多余主机,呈现以下效果

bash 复制代码
[root@ecs-proxy node-install]# vim files/hosts
::1             localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1       localhost localhost.localdomain localhost4 localhost4.localdomain4
192.168.1.21    master
192.168.1.31    node-0001
192.168.1.32    node-0002
192.168.1.33    node-0003
192.168.1.100   registry

② 修改node_instal.yaml文件,将从Master获取得token证书、验证hash替换;

bash 复制代码
[root@ecs-proxy node-install]# vim node_install.yaml
...
  vars:
    master: '192.168.1.21:6443'         //masterIP:apiserver接口
    token: '2f5px8.l2tgvrpppe4i3ha2'    //获取的token
    token_hash: 'sha256:23ddaaad95ac7377bbc858975ac068529a0bda07d60cd32e5726611c576751b4'    //token的hash算法和hash值
...

③ 执行Playbook前,测试主机文件

bash 复制代码
[root@ecs-proxy node-install]# ansible nodes --list-hosts
  hosts (3):
    192.168.1.31
    192.168.1.33
    192.168.1.32

执行Playbook前,测试主机Ping测试

bash 复制代码
[root@ecs-proxy node-install]# ansible-playbook node_install.yaml    //执行Playbook
...
192.168.1.31               : ok=12   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.32               : ok=12   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
192.168.1.33               : ok=12   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

④ 在Master节点验证安装

bash 复制代码
[root@master ~]# kubectl get nodes    //查看节点信息
NAME        STATUS     ROLES    AGE     VERSION
master      NotReady   master   4h11m   v1.17.6
node-0001   NotReady   <none>   6m55s   v1.17.6
node-0002   NotReady   <none>   6m54s   v1.17.6
node-0003   NotReady   <none>   6m41s   v1.17.6

补充:Master和Node容器已启动,但服务状态不可用NoteReady未就绪,是因为容器的网络不通,需要更新完网络插件以后,状态将变成Ready;
Flannel实质上是一种"覆盖网络(overlay network)",也就是将TCP数据包装在另一种网络包里进行路由转发和通信,目前已支持UPD、VXLAN、AWS VPC和GCE路由等数据转发方式;使用Flannel目标:不同主机内的容器实现互联互通;

软件地址:GitHub - flannel-io/flannel: flannel is a network fabric for containers, designed for Kubernetes

步骤8:网络flannel插件安装配置(实现不同主机之间的容器互联互通)(master操作)

拷贝云盘 kubernetes/v1.17.6/flannel 目录下的镜像压缩包和Playbook文件到 master 上

bash 复制代码
[root@ecs-proxy ~]# scp -r /root/kubernetes/v1.17.6/flannel/ 192.168.1.21:/root/
[root@ecs-proxy ~]# ssh 192.168.1.21
[root@master ~]# cd flannel/
[root@master flannel]# ls
flannel.tar.gz  kube-flannel.yml

① 导入镜像到本地仓库

bash 复制代码
[root@master flannel]# docker load -i flannel.tar.gz
[root@master flannel]# docker images

② 上传镜像到私有镜像仓库

bash 复制代码
[root@master flannel]# docker tag quay.io/coreos/flannel:v0.12.0-amd64 192.168.1.100:5000/flannel:v0.12.0-amd64
[root@master flannel]# docker push 192.168.1.100:5000/flannel:v0.12.0-amd64
bash 复制代码
[root@master flannel]# curl http://192.168.1.100:5000/v2/flannel/tags/list
{"name":"flannel","tags":["v0.12.0-amd64"]}

③ 修改资源文件kube-flannel.yml并flannel安装

只需在Master安装,其它节点会自动完成适配

bash 复制代码
[root@master flannel]# vim kube-flannel.yml
128       "Network": "10.244.0.0/16",     // flannel创建Pod的网络地址,16位表示限制容器个数
172         image: 192.168.1.100:5000/flannel:v0.12.0-amd64   //定义启动容器所使用的的镜像(指定私有仓库地址)
186         image: 192.168.1.100:5000/flannel:v0.12.0-amd64
227  ---开始到结尾的配置为嵌入式配置,删除无效配置
...
[root@master flannel]# kubectl apply -f kube-flannel.yml   //安装,-f指定文件
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds-amd64 created

③ 验证结果(等待30秒程序启动)

bash 复制代码
[root@master flannel]# kubectl get nodes
NAME        STATUS   ROLES    AGE    VERSION
master      Ready    master   5h6m   v1.17.6
node-0001   Ready    <none>   62m    v1.17.6
node-0002   Ready    <none>   62m    v1.17.6
node-0003   Ready    <none>   62m    v1.17.6

补充:如果kube-flannel.yml配置文件修改错误,可以使用kubectl delete -f kube-flannel.yml删除,在重新安装;


扩展:初始化仓库所使用的init-img.sh脚本

主要内容:

  • ① 安装Dokcer工具、启动Docker服务;
  • ② 配置指定私有镜像仓库文件;
  • ③ 导入镜像压缩包,通过Dockerfile制作镜像;
  • ④ 同步4个镜像到私有镜像仓库;
bash 复制代码
[root@registry myos]# cat init-img.sh
#!/bin/bash
yum install -y docker-ce    //安装Docker管理工具
mkdir -p /etc/docker
cat >/etc/docker/daemon.json <<'EOF'    //指定私有镜像仓库
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "registry-mirrors": ["https://hub-mirror.c.163.com"],
    "insecure-registries":["192.168.1.100:5000", "registry:5000"]
}
EOF
systemctl enable --now docker.service    //启动Docker服务
systemctl restart docker.service
docker load -i myos.tar.gz     //导入镜像压缩包(v1804 httpd php-fpm nginx)
# init apache images     //Dockerfile ------> Apache
cat >Dockerfile<<'EOF'
FROM myos:latest
ENV  LANG=C
WORKDIR /var/www/html/
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
EOF
docker build -t 192.168.1.100:5000/myos:httpd .   //创建镜像
 
# init php-fpm images     //Dockerfile ------> php-fpm
cat >Dockerfile<<'EOF'
FROM myos:latest
EXPOSE 9000
WORKDIR /usr/local/nginx/html
CMD ["/usr/sbin/php-fpm", "--nodaemonize"]
EOF
docker build -t 192.168.1.100:5000/myos:php-fpm .   //创建镜像
 
# init nginx images     //Dockerfile ------> Nginx
cat >Dockerfile<<'EOF'
FROM myos:latest
EXPOSE 80
WORKDIR /usr/local/nginx/html
CMD  ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
EOF
docker build -t 192.168.1.100:5000/myos:nginx .   //创建镜像
 
# upload images
rm -f Dockerfile
docker tag myos:latest 192.168.1.100:5000/myos:v1804   //给myos镜像创建标签
for i in v1804 httpd php-fpm nginx;do
    docker push 192.168.1.100:5000/myos:${i}   //同步到私有镜像仓库
done

扩展:安装Master节点的kubeadm-init.yaml应答文件

bash 复制代码
[root@master init]# cat /root/kubeadm-init.yaml
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef    //token令牌
  ttl: 24h0m0s     //token的生命周期
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.1.21   //apiserver的IP地址(Master节点地址)
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: 192.168.1.100:5000    //镜像仓库地址
kind: ClusterConfiguration
kubernetesVersion: v1.17.6    //仓库镜像标签TAG(表示当前安装的K8S版本)
networking:
  dnsDomain: cluster.local    //默认服务域名地址
  podSubnet: 10.244.0.0/16    //POD的地址(fannel)
  serviceSubnet: 10.254.0.0/16   //K8S服务的地址
scheduler: {}
---   //---代表对kubeproxy新的定义
apiVersion: kubeproxy.config.k8s.io/v1alpha1    //kubeproxy版本
kind: KubeProxyConfiguration     //资源对象
mode: ipvs      //开启IPVS模式参数

扩展:创建应答配置文件模板

    • 命令:kubeadm config print init-defaults > kubeadm-init.yaml

扩展:安装Node节点的node_install.yaml

主要内容:

  • ① 卸载防火墙
  • ② 禁用SELinux和SWAP
  • ③ 配置YUM仓库,安装kubeadm、kubelet、docker-ce
  • ④ 安装IPVS模式软件包:ipvsadm、ipset
  • ⑤ 配置Docker私有镜像仓库和Cgroup驱动(daemon.json)
  • ⑥ 配置内核参数(/etc/sysctl.d/k8s.conf)
  • ⑦ 配置/etc/host(Master能访问Node的主机名)
bash 复制代码
[root@ecs-proxy ~]# cat node-install/node_install.yaml
---
- name: kubernetes node install
  hosts:    //主机清单(nodes分组)
  - nodes
  vars:     //定义变量
    master: '192.168.1.21:6443'    //指定Master主机的Apiserver接口
    token: '2f5px8.l2tgvrpppe4i3ha2'
    token_hash: 'sha256:23ddaaad95ac7377bbc858975ac068529a0bda07d60cd32e5726611c576751b4'
  tasks:    //执行命令
  - name: disable swap    //关闭SWAP空间
    lineinfile:
      path: /etc/fstab
      regexp: 'swap'
      state: absent
    notify: disable swap
  - name: Ensure SELinux is set to disabled mode    //关闭SELinux
    lineinfile:
      path: /etc/selinux/config
      regexp: '^SELINUX='
      line: SELINUX=disabled
    notify: disable selinux
  - name: remove the firewalld    //卸载防火墙
    yum:
      name:
      - firewalld
      - firewalld-filesystem
      state: absent
  - name: install k8s node tools    //安装Node节点所需工具
    yum:
      name:
      - kubeadm
      - kubelet
      - docker-ce
      - ipvsadm
      - ipset
      state: present
      update_cache: yes
  - name: Create a directory if it does not exist    //创建/etc/docker目录存放daemon.json
    file:
      path: /etc/docker
      state: directory
      mode: '0755'
  - name: Copy file with /etc/hosts   //拷贝host文件
    copy:
      src: files/hosts
      dest: /etc/hosts
      owner: root
      group: root
      mode: '0644'
  - name: Copy file with /etc/docker/daemon.json    //创建daemon.json文件,配置私有镜像仓库和cgroup驱动
    copy:
      src: files/daemon.json
      dest: /etc/docker/daemon.json
      owner: root
      group: root
      mode: '0644'
  - name: Copy file with /etc/sysctl.d/k8s.conf    //配置内核参数文件
    copy:
      src: files/k8s.conf
      dest: /etc/sysctl.d/k8s.conf
      owner: root
      group: root
      mode: '0644'
    notify: enable sysctl args    //触发handles载入内核模块sysctl --system
  - name: enable k8s node service     //启动docker、kubelet服务
    service:
      name: "{{ item }}"
      state: started
      enabled: yes
    with_items:
    - docker
    - kubelet
  - name: check node state      //检查节点状态
    stat:
      path: /etc/kubernetes/kubelet.conf    //查看文件是否存在
    register: result
  - name: node join       //将node节点加入集群
    shell: kubeadm join '{{ master }}' --token '{{ token }}' --discovery-token-ca-cert-hash '{{ token_hash }}'
    when: result.stat.exists == False     //判断文件不存在则执行Node加入集群
  handlers:
  - name: disable swap
    shell: swapoff -a
  - name: disable selinux
    shell: setenforce 0
  - name: enable sysctl args
shell: sysctl --system

扩展:网络配置插件kube-flannel.yml资源文件

bash 复制代码
[root@master ~]# cat flannel/kube-flannel.yml
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp.flannel.unprivileged
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
    seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
    apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
    apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
spec:
  privileged: false
  volumes:
    - configMap
    - secret
    - emptyDir
    - hostPath
  allowedHostPaths:
    - pathPrefix: "/etc/cni/net.d"
    - pathPrefix: "/etc/kube-flannel"
    - pathPrefix: "/run/flannel"
  readOnlyRootFilesystem: false
  # Users and groups
  runAsUser:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  # Privilege Escalation
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  # Capabilities
  allowedCapabilities: ['NET_ADMIN']
  defaultAddCapabilities: []
  requiredDropCapabilities: []
  # Host namespaces
  hostPID: false
  hostIPC: false
  hostNetwork: true
  hostPorts:
  - min: 0
    max: 65535
  # SELinux
  seLinux:
    # SELinux is unused in CaaSP
    rule: 'RunAsAny'
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
rules:
  - apiGroups: ['extensions']
    resources: ['podsecuritypolicies']
    verbs: ['use']
    resourceNames: ['psp.flannel.unprivileged']
  - apiGroups:
      - ""
    resources:
      - pods
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes/status
    verbs:
      - patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-system
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-system
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: kubernetes.io/os
                    operator: In
                    values:
                      - linux
                  - key: kubernetes.io/arch
                    operator: In
                    values:
                      - amd64
      hostNetwork: true
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni
        image: 192.168.1.100:5000/flannel:v0.12.0-amd64
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: 192.168.1.100:5000/flannel:v0.12.0-amd64
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
          limits:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
        - name: run
          hostPath:
            path: /run/flannel
        - name: cni
          hostPath:
            path: /etc/cni/net.d
        - name: flannel-cfg
          configMap:
            name: kube-flannel-cfg

小结:

本篇章节为**【第五阶段】CLOUD-DAY6 的**学习笔记,这篇笔记可以初步了解到 Kubernetes的架构、搭建Kubernetes集群。


Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。

相关推荐
A小辣椒9 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒13 小时前
TShark:基础知识
linux
AlfredZhao15 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334661 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式