Kubernetes、k8s从入门到实战

本文章用到k8s安装包及工具文件链接:https://pan.baidu.com/s/1gYU9xxwxI9cXfJ1IJGQjwg?pwd=ye11 提取码:ye11

云计算 + 服务

我们对于云计算的概念,维基百科有以下定义:Cloud computing is a new form of Internet-based computing that provides shared computer processing resources and data to computers and other devices on demand.

云计算就是一种按照需求通过Internet获取计算资源的形态。这些计算资源被包装成为服务,提供给用户。而提供这些服务的主体,我们称之为云服务供应商(Cloud Service Provider)。

按照NIST (National Institute of Standards and Technology,国家标准和技术研究院)的定义,云服务最主要的有三类,就是题主提问的IaaSPaaSSaaS

IaaS (基础设施即服务)

Infrastructure as a Service :

1.既基础设施即服务,指把IT基础设施作为一种服务通过网络对外提供,并根据用户对资源的实际使用量或占用量进行计费的一种服务模式;

2.在这种服务模型中,普通用户不用自己构建一个数据中心等硬件设施,而是通过租用的方式,利用Internet从IaaS服务提供上获取计算机基础设施服务,包括服务器,存储和网络等服务;

特点:租赁、自助服务、动态缩放、服务等级、许可、计量

PaaS (平台即服务)

Platform as a Service :

1.把服务器平台作为一种服务提供的商业模式,通过网络进行程序提供的服务称之为Saas,云计算时代响应的服务器平台或者开发环境作为服务进行提供就成了PaaS;

2.所谓PaaS实际上是指将软件研发的平台作为一种服务,以SaaS的模式交给用户;

特点:平台即服务、平台及服务、平台级服务

SaaS (软件即服务)

Software as a Service :

1.通过网络提供软件服务,SaaS平台供应商将应用软件同意部署在自己的服务器上,客户可以根据工作实际需求,通过互联网向厂商定购所需的应用软件服务,按定购的服务多少和时间长短向厂商支付费用;

特点:免费、付费、多重租赁、可扩展

总结

IaaS(Infrastructure as a service – 基础设施即服务):用户可以在云服务提供商提供的基础设施上部署和运行任何软件,包括操作系统和应用软件。用户没有权限管理和访问底层的基础设施,如服务器、交换机、硬盘等,但是有权管理操作系统、存储内容,可以安装管理应用程序,甚至是有权管理网络组件。简单的说用户使用IaaS,有权管理操作系统之上的一切功能。我们常见的IaaS服务有虚拟机、虚拟网络、以及存储。

PaaS(Platform as a service – 平台即服务):PaaS给用户提供的能力是使用由云服务提供商支持的编程语言、库、服务以及开发工具来创建、开发应用程序并部署在相关的基础设施上。用户无需管理底层的基础设施,包括网络、服务器,操作系统或者存储。他们只能控制部署在基础设施中操作系统上的应用程序,配置应用程序所托管的环境的可配置参数。常见的PaaS服务有数据库服务、web应用以及容器服务。成熟的PaaS服务会简化开发人员,提供完备的PC端和移动端软件开发套件(SDK),拥有丰富的开发环境(Inteli、Eclipse、VS等),完全可托管的数据库服务,可配置式的应用程序构建,支持多语言的开发,面向应用市场。

SaaS(Software as a Service – 软件即服务):SaaS给用户提供的能力是使用在云基础架构上运行的云服务提供商的应用程序。可以通过轻量的客户端接口(诸如web浏览器(例如,基于web的电子邮件))或程序接口从各种客户端设备访问应用程序。 用户无需管理或控制底层云基础架构,包括网络,服务器,操作系统,存储甚至单独的应用程序功能,可能的例外是有限的用户特定应用程序配置设置。类似的服务有:各类的网盘(Dropbox、百度网盘等),JIRA,GitLab等服务。而这些应用的提供者不仅仅是云服务提供商,还有众多的第三方提供商(ISV: independent software provider)。

案例

这里借用汽车的例子对IaaSPaaSSaaS的解释进一步阐述三者的区别。假设你需要出去外出使用交通工具,我们有四种的方案:

On-premise方案: 自己开车,需要维护汽车,是其安全工作。同时需要为车上保险,提供燃料。(服务器 + 操作系统/数据库 + 应用软件)

IaaS: 从租车公司租一辆车,汽车的维修、安检都由租车公司承担。你只需要提供燃料(需要提供操作系统+应用软件)

PaaS: 除了基础设施(汽车),还为你提供司机。类似出租车。只需要提供目的地,汽车的行驶和运行都有司机决定。(只需要提供应用软件)。

SaaS:类似于做轨道交通, 一切都是由别人控制。只有较少的定制化功能。

—————————————————————————————————————————————

有状态服务及无状态服务

简介

Kubernetes、k8s从入门到实战_第1张图片
Kubernetes、k8s从入门到实战_第2张图片

Kubernetes、k8s从入门到实战_第3张图片

有状态和无状态服务应用

Kubernetes、k8s从入门到实战_第4张图片

白话:用大白话讲就是,有状态服务之间存在依赖关系、数据存储等各种问题,不能被轻易代替。无状态服务就是不存在依赖关系、数据存储等问题,可以随意替换新的。

—————————————————————————————————————————————

Kubernetes

Kubernetes、k8s从入门到实战_第5张图片

1. 简介

​ k8s是做什么的? 容器化集群管理系统
​ 官网:http://docs.kubernetes.org.cn/

1.1 优点

  1. 轻量级:消耗资源小
  2. 开源
  3. 弹性伸缩
  4. 负载均衡
  5. 高可用集群副本数最好是大于等于3奇数以上集群(方便选主节点)

1.2. K8s 组件

Kubernetes、k8s从入门到实战_第6张图片

API Server所有服务访问统一入口;

ControllerManager维持副本期望数目;

Scheduler负责介绍任务,选择合适的节点进行分配任务;

ETCD键值对 数据库,存储K8S集群所有重要信息(持久化);

Kubelet直接跟容器引擎交互实现容器的生命周期管理,管理本机容器;

Kube-proxy负责写入规则至 IPTABLES、IPVS,实现服务映射访问;

1.3. K8s 插件

CoreDNS可以为集群中的SVC创建一个域名IP的对应关系解析;

Dashboardk8s集群提供一个B/S 结构访问体系;

Ingress Controller官方只能实现四层代理,Ingress可以实现七层代理;

Federation提供一个可以跨集群中心多K8s统一管理功能;

Prometheus提供K8s集群的监控能力;

ELKk8s集群日志统一分析平台;

—————————————————————————————————————————————

2. K8s三个核心概念

2.1 Pod

pod是什么pod是k8s中基本的构建模块,一个pod可以包含多个和单个容器,包含多个容器时,这些容器总是运行在同一个工作节点上,因为一个pod绝不会跨多个工作节点。

Kubernetes、k8s从入门到实战_第7张图片

2.1.1 控制器管理 Pod

  1. ReplicationController & ReplicaSet & Deployment

Kubernetes、k8s从入门到实战_第8张图片

Kubernetes、k8s从入门到实战_第9张图片

  1. HPA(Horizontal Pod Autoscaling) -> 水平弹性伸缩,仅适用于Deployment和ReplicaSet,在V1版本中仅支持根据Pod的CPU利用率扩缩容,在vlalpha版本中,支持根据内存和用户自定义的metric扩缩容
  • Kubernetes、k8s从入门到实战_第10张图片

Kubernetes、k8s从入门到实战_第11张图片

  1. StatefulSet 是为了解决有状态服务的问题(对应Deployments 和 ReplicaSets 是为无状态服务而设计),

    其中应用场景包括:

    Kubernetes、k8s从入门到实战_第12张图片

  2. DaemonSet

Kubernetes、k8s从入门到实战_第13张图片

  1. Job

    Kubernetes、k8s从入门到实战_第14张图片

2.1.2 Pod中的数据共享存储

使用Docker中数据卷持久化的概念,不同节点中的Pod产生的数据存在一个数据卷中。创建新的节点容器后直接读取 ;

2.2 Controller

2.2.1 Controller作用

  • 确保预期的Pod副本数量
  • 有状态应用部署
  • 无状态应用部署
  • 确保所有的node运行同一个pod
  • 一次性任务和定时任务

2.2.2 Pod和Controller关系

  • Pod是通过Controller实现应用的运维。比如伸缩、滚动升级等等

  • Pod和Controller之间通过label标签建立关系 selector【见图2.2.2.1】

    Kubernetes、k8s从入门到实战_第15张图片

    图2.2.2.1

2.3 Service

2.3.1 Service存在意义

  • 防止Pod失联(服务发现)【见图2.3.1.1】

    Kubernetes、k8s从入门到实战_第16张图片

    图2.3.1.1

  • 定义一组Pod的访问规则(均衡负载处就是Service)【见图2.3.1.2】

    Kubernetes、k8s从入门到实战_第17张图片

    图2.3.1.2

2.3.2 Pod和Service关系

  • 根据label和Selector标签建立关联的【见图2.3.2.1】

Kubernetes、k8s从入门到实战_第18张图片

图2.3.2.1

2.3.3 Service常用的三种类型

  1. ClusterIP:集群内部使用,不会暴露出端口号。不可外部访问;
  2. NodePort:对外访问应用使用,会暴露出端口号。可外部访问;
  3. LoadBalancer:对外访问应用使用,公有云的使用;

—————————————————————————————————————————————

3. 网络通讯方式

​ k8s的网络模型假定了所有Pod都在一个可以直接连通的扁平的网络空间中(pod和pod之间通信直接通过 ip + port 端口),我们需要将不同节点上的Docker容器之间互相访问先打通,然后运行Kubernetes(Pod中的容器端口不可一致)。

  • 同一个Pod内的多个容器之间:lo (localhost),原理:一个Pod中的多个容器(容器部署的命名空间属于一致的)创建时都会注册到一个统一的Pause容器(根容器),然后暴露出Pause容器IP、MAC、Port 所以Pod中的容器网络是共享的

  • 各Pod之间通讯:Overlay Network

  • Pod与Service之间通讯:各节点的Iptables规则

—————————————————————————————————————————————

4. 安装要求

4.1 搭建k8s环境平台规划

单master集群
Kubernetes、k8s从入门到实战_第19张图片

多master集群

Kubernetes、k8s从入门到实战_第20张图片

—————————————————————————————————————————————
Kubernetes、k8s从入门到实战_第21张图片

4.2 服务器硬件配置要求

  1. 一台或多台机器,操作系统CentOS7 x-86_x64

  2. 集群中所有机器网络互通

  3. 可以访问外网,用于拉取镜像

  4. 禁止swap分区(不然k8s会报错)

  5. 测试环境: master节点 :2核 4G 20G以上 , node节点: 4核 8G 40G以上

    生产环境:至少不能少于测试环境配置

5. k8s安装前环境配置

  1. 关闭防火墙

    // 临时关闭(重启系统后失效)
    # systemctl stop firewalld
    
    // 永久关闭
    # systemctl disable firewalld
    
  2. 关闭selinux

    // 临时关闭 setenforce 0
    # setenforce 0
    
    // 永久关闭 sed -i 's/enforcing/disabled/' /etc/selinux/config 
    # sed -i 's/enforcing/disabled/' /etc/selinux/config 
    
  3. 关闭swap

    // 临时关闭 swapoff -a
    # swapoff -a 
    
    // 永久关闭 sed -ri 's/.*swap.*/#&/' /etc/fstab
    # sed -ri 's/.*swap.*/#&/' /etc/fstab
    
  4. 可省略(为后面使用方便,给每个主机定义一个名称)

    // 根据规划设置主机名称 hostnamectl set-hostname [hostname]
    # hostnamectl set-hostname [hostname]
    
    // 查看主机名 hostname
    # hostname
    
  5. 将node节点添加到主节点中(只在主节点中执行、IP和hostname为集群)

    // 将node节点添加到主节点中 cat >> /etc/hosts << EOF [IP地址 hostname] [IP地址 hostname] ... EOF
    # cat >> /etc/hosts << EOF
    	192.168.47.134 master
    	192.168.47.135 node1
    	192.168.47.136 node2
    EOF
    
  6. 将桥接的IPv4流量传递到Iptables链(主节点、子节点都要执行)

    //
    # cat > /etc/sysctl.d/k8s.conf << EOF
    	net.bridge.bridge-nf-call-ip6tables = 1
    	net.bridge.bridge-nf-call-iptables = 1
    EOF
            
    // 生效
    # sysctl --system
    
  7. 时间同步(几台服务器时间同步自行度娘)

    // 时间同步插件
    # yum install ntpdate -y
    
    // 虚拟机中跟当前windows系统时间一致
    # ntpdate time.windows.com
    // 跟阿里云时间同步
    # ntpdate -u ntp2.aliyun.com
    

6. 安装 Docker

6.1 Docker 安装前准备

Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker;

  1. CentOS7安装Docker要内核是3.10_x64以上
// 查看linux内核版本
# uname -r
 3.10.0-1062.12.1.el7.x86_64
  1. 卸载旧版本Docker
// 卸载Docker Engine,CLI和Containerd软件包
# yum remove docker-ce docker-ce-cli containerd.io
// 主机上的映像,容器,卷或自定义配置文件不会自动删除。要删除所有镜像,容器和卷
# rm -rf /var/lib/docker 

6.2 Docker 二种安装方式

k8s使用二进制安装最好docker也使用二进制的安装方案,统一管理

6.2.1 官网快速安装

​ 官网安装地址: https://docs.docker.com/engine/install/centos/#install-using-the-repository

案例使用镜像仓库安装所以需要连接外网

  1. 安装前条件
// 切换到root用户,不切换root用户 执行命令前加上 # sudo
# su root
// 卸载旧版本docker 但镜像,容器,卷和网络会被保留
# sudo yum remove docker \
             docker-client \
             docker-client-latest \
             docker-common \
             docker-latest \
             docker-latest-logrotate \
             docker-logrotate \
             docker-engine

  1. 快速安装此安装根据官网步骤安装(镜像安装)
// 1.安装yum-utils软件包(提供yum-config-manager 实用程序)
# sudo yum install -y yum-utils
# sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo


// 2.安装最新版本Docker和容器(版本可根据官网安装方法指定)
# sudo yum install docker-ce docker-ce-cli containerd.io

// 查看docker版本
# docker -v 

6.2.2 二进制方式安装

// 1.添加docker包,解压放入工作目录
# rz -E zxvf docker-20.10.3.tgz  //上传docker.tgz包、自取
# tar zxvf docker-20.10.3.tgz
# mv docker/* /usr/bin

// 2.添加docker.service管理启动文件
# cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
EOF

6.3 配置镜像下载地址

// 配置的阿里云的镜像地址(阿里云管理后台有每个人的私人镜像加速地址:控制台->产品与服务->容器镜像服务->镜像加速器)  !!!开启docker生成文件后才可编辑
# vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://jxxhar25.mirror.aliyuncs.com"]
}

// 修改后重新加载配置文件,重启docker
# systemctl daemon-reload
# systemctl start docker

6.4 Docker 守护进程管理

# systemctl start docker     // 运行Docker
# systemctl stop docker      // 停止Docker
# systemctl restart docker   // 重启Docker
# systemctl disable docker   // 开机停止Docker守护进程
# systemctl enable docker    // 开机启动Docker守护进程
# systemctl status docker    // Docker守护进程状态

镜像容器存放路径containers、image

# cd /var/lib/docker/
containers  image  network  overlay2  plugins  swarm  tmp  trust  volumes

7. K8s 两种安装方式

目前部署Kubernetes集群主要有二种方式:

  1. kubeadm

    官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/

    kubeadm是一个K8s部署工具,官方推出快速部署k8s集群工具,提供 kubeadm init 和 kubeadm join ,这个工具通过二条指令完成一个kubernetes集群部署。

    第一、创建一个Master节点,kubeadm init;

    第二、将Node 节点加入到当前集群中 $ kubeadm join [ Master 节点的IP和端口 ]

  2. 二进制包方式

    从 github 下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群(遇见问题好排查,有利于后期维护)。

7.0 部署中报错日志查找

// 查看k8s日志
# journalctl -f   ||   journalctl -xe |grep {etcd}

7.1 Kubeadm方式安装 (易)

集群IP 节点名称
192.168.136.130 master
192.168.136.131 node1
192.168.136.132 node2

操作系统初始化(安装环境配置)

1. 见标题5

2. 安装docker所有节点操作,推荐快速版安装

  1. 添加阿里云中下载yum源
// 添加阿里云中下载yum源
# cat < /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
       http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

  1. 安装kubeadm、kubectl、kubelet

    ( 安装有问题卸载,重新安装:https://blog.csdn.net/weixin_41831919/article/details/108111150 )

// 查看kubeadm kubectl kubelet版本
# yum list kubeadm --showduplicates | sort -r
# yum list kubectl --showduplicates | sort -r
# yum list kubelet --showduplicates | sort -r  

// 不加版本默认下载最新版本 yum install -y kubelet kubeadm kubectl
# yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0

// 开机启动kubelet
# systemctl enable kubelet

  1. Master节点初始化操作(只在master执行)
// 192.168.136.130 Master节点IP  v1.18.0版本如果安装时候没指定版本就可去掉
// —apiserver-advertise-address 集群通告地址
// —image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。
// —kubernetes-version K8s版本,与上面安装的一致
// —service-cidr 集群内部虚拟网络,Pod统一访问入口
// —pod-network-cidr Pod网络,与下面部署的CNI网络组件yaml中保持一致
# kubeadm init \
  --apiserver-advertise-address=192.168.136.130 \
  --image-repository registry.aliyuncs.com/google_containers \
  --kubernetes-version v1.18.0 \
  --service-cidr=10.96.0.0/12 \
  --pod-network-cidr=10.244.0.0/16

执行后:

Kubernetes、k8s从入门到实战_第22张图片

// 查看已连接节点
# kubectl get nodes

// 默认token有效期为24小时,当过期之后,该token就不可用,这里需要重新创建token后到子节点执行
# kubeadm token create --print-join-command

// 查看apiserver.crt证书的签署日期和过期日期
# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep ' Not '


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Fp4UlKf-1656048400947)(images\cluster.jpg)]

  1. 部署CNI网络插件(将节点状态改为Ready)
// dockerhub外网有时会连接不上,可以百度找这个文件或手动下载然后 kubectl apply -f kube-flannel.yml
# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# kubectl get pods -n kube-system
    NAME                          READY   STATUS    RESTARTS   AGE
    kube-flannel-ds-amd64-2pc95   1/1     Running   0          72s
    ......
        
// kubectl get pods -n kube-system 全部启动后在使用kubectl get nodes 看一下节点状态

  1. 测试Kubernetes集群

    在Kubernetes集群中创建一个pod,验证是否正常运行:

// deployment 下载一个nginx进行测试
# kubectl create deployment nginx --image=nginx

// 外网访问,暴露端口
# kubectl expose deployment nginx --port=80 --type=NodePort

// 查看集群外网访问端口
# kubectl get pod,svc

Kubernetes、k8s从入门到实战_第23张图片

访问地址:http://NodeIP:Port = 192.168.136.131:32029

7.2 二进制方式安装 (难)

集群 ip 节点名 组件
192.168.136.137 master docker、etcd、kube-apiserver、kubelet、kube-controller-manager、kube-scheduler、kubectl
192.168.136.138 node1 docker、kubelet、kube-proxy、 etcd
192.168.136.139 node2 docker、kubelet、kube-proxy、 etcd

操作:

1.操作系统初始化(安装环境配置)

1. 见标题5

2. 安装docker所有节点操作,建议使用Docker二进制安装方式

2.为etcd自签证书

(master节点操作)

官网地址:http://docs.kubernetes.org.cn/698.html

// 1.下载 cfssl,执行失败多尝试几次 (master节点操作)
# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
# chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
# mv cfssl_linux-amd64 /usr/local/bin/cfssl
# mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
# mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
# chmod +x /usr/bin/cfssl*

// 2.为生成Etcd证书自签证书颁发机构(CA)创建工作目录
# cd //
# mkdir -p ~/TLS/{etcd,k8s}
# cd ~/TLS/etcd


// 3.CA过期失效配置
# cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "www": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF


// 4.自签CA
# cat > ca-csr.json << EOF
{
    "CN": "etcd CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
}
EOF

    
// 5.生成证书:读取上边两个文件生成证书(结果见下图1.5.1)
# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -


// 6.使用自签 CA 签发 Etcd HTTPS 证书 创建证书申请文件:(修改对应的master和node的IP地址)
# cat > server-csr.json << EOF
{
    "CN": "etcd",
    "hosts": [
    "192.168.136.137",
    "192.168.136.138",
    "192.168.136.139"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing"
        }
    ]
}
EOF

// 7.执行【见下图2.7.2】
# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
    
    
// 8.查看生成证书的路径
# ls  ~/TLS/etcd/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-crbCrzvK-1656048400948)(images\result1.jpg)]

图1.5.1

Kubernetes、k8s从入门到实战_第24张图片

图2.7.2

查看证书:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yxg1Lw2n-1656048400948)(images\cfssl.jpg)]

3.部署etcd集群

(master节点操作)

GitHub下载地址: https://github.com/etcd-io/etcd/releases , git下载太慢 ,文件夹自取

// 1.上传etcd-v3.4.14-linux-amd64.tar.gz包
# rz -E etcd-v3.4.14-linux-amd64.tar.gz

// 2.创建工作目录并解压包
# mkdir /opt/etcd/{bin,cfg,ssl} -p
# tar zxvf etcd-v3.4.14-linux-amd64.tar.gz
# mv etcd-v3.4.14-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/


// 配置参数说明
// ETCD_NAME:节点名称,集群中唯一
// ETCD_DATA_DIR:数据目录
// ETCD_LISTEN_PEER_URLS:集群通信监听地址
// ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
// ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址
// ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
// ETCD_INITIAL_CLUSTER:集群节点地址
// ETCD_INITIAL_CLUSTER_TOKEN:集群 Token
// ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new 是新集群,existing 表示加入 已有集群

// 3.创建etcd.conf(修改对应的master的IP地址,其中47.137本机ip,还有对应集群ip)
# cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.136.137:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.136.137:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.136.137:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.136.137:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.136.137:2380,etcd-2=https://192.168.136.138:2380,etcd-3=https://192.168.136.139:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF
    
// 4.创建etcd.service启动文件  
# cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
    
// 5.拷贝刚才生成的证书 把刚才生成的证书拷贝到配置文件中的路径:
# cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/
    
    
// 6.启动并设置开机启动,启动后会卡住因为需要和node节点一起执行该命令
# systemctl daemon-reload
  systemctl start etcd  
  systemctl enable etcd 
  systemctl status etcd

将主节点准备好的文件拷贝到node上

// 7.将主节点所有生成的文件拷贝到节点1和节点2(主节点中操作,注意修改ip地址)
# scp -r /opt/etcd/ root@192.168.136.138:/opt/
# scp /usr/lib/systemd/system/etcd.service root@192.168.136.138:/usr/lib/systemd/system/

# scp -r /opt/etcd/ root@192.168.136.139:/opt/
# scp /usr/lib/systemd/system/etcd.service root@192.168.136.139:/usr/lib/systemd/system/


// 8.然后在节点1和节点2分别修改etcd.conf配置文件中的节点名称和当前服务器IP(node1、node2中操作)【见图1.8.3】
# vim /opt/etcd/cfg/etcd.conf

Kubernetes、k8s从入门到实战_第25张图片

图1.8.3

// 9.最后启动 etcd 并设置开机启动(node1、node2中操作都要执行)
# systemctl daemon-reload
  systemctl start etcd        // master、node节点一起执行启动操作
  systemctl enable etcd
  systemctl status etcd

// 10.查看etcd集群状态(修改对应ip地址)【见图1.10.4】
# /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.136.137:2379,https://192.168.136.138:2379,https://192.168.136.139:2379" endpoint status --write-out=table

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6fCJSxYg-1656048400952)(images\etcd_status.jpg)]

图1.10.4

4.为apiserver自签证书

(master节点操作)

// 1.进入之前操作目录
# cd ~/TLS/k8s

// 2.kube-apiserver证书时效
# cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF
    
// 3.自签证书颁发机构(CA)
# cat > ca-csr.json << EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF

// 4.生成CA证书
# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
# ls *pem // 【见图5.5】
    
    
// 5.使用自签CA签发 kube-apiserver HTTPS 证书创建证书申请文件(添加可信任ip列表{后期可能加入到集群中的ip也可添加})
# cat > server-csr.json << EOF
{
    "CN": "kubernetes",
    "hosts": [
      "10.0.0.1",
      "127.0.0.1",
      "192.168.136.137",
      "192.168.136.138",
      "192.168.136.139",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF
    
    
// 6.生成server证书
# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
# ls server*pem // 【见图6.6】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFQKbW01-1656048400952)(images\apiserver_ca.jpg)]

图5.5

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-37zywckl-1656048400953)(images\apiserver_server.jpg)]

图6.6

5. 部署master组件 apiserver

(master节点操作)

// 1.新建操作目录
# mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} 

/* 2.上传、解压kubernetes-server-linux-amd64.tar.gz包、可自取
 * 下载址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG- 1.20.1.md*#v1183
 */
# rz -E kubernetes-server-linux-amd64.tar.gz    //上传操作
# tar zxvf kubernetes-server-linux-amd64.tar.gz

// 3.拷贝需要的文件到指定目录
# cd kubernetes/server/bin
# cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
# cp kubectl /usr/bin/
# chmod +x /usr/bin/


/**
 *	4.部署 kube-apiserver.config配置文件
 *	注:\\ 第一个是转义符,第二个是换行符,使用转义符是为了使用 EOF 保留换 行符。
 *	–logtostderr:启用日志
 *	—v:日志等级
 *	–log-dir:日志目录
 *	–etcd-servers:etcd 集群地址
 *	–bind-address:监听地址
 *	–secure-port:https 安全端口
 *	–advertise-address:集群通告地址
 *	–allow-privileged:启用授权
 *	–service-cluster-ip-range:Service 虚拟 IP 地址段
 *	–enable-admission-plugins:准入控制模块
 *	–authorization-mode:认证授权,启用 RBAC 授权和节点自管理
 *	–enable-bootstrap-token-auth:启用 TLS bootstrap 机制
 *	–token-auth-file:bootstrap token 文件
 *	–service-node-port-range:Service nodeport 类型默认分配端口范围
 *	–kubelet-client-xxx:apiserver 访问 kubelet 客户端证书
 *	–tls-xxx-file:apiserver https 证书
 *	–etcd-xxxfile:连接 Etcd 集群证书
 *	–audit-log-xxx:审计日志
 **/ 
# cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=https://192.168.136.137:2379,https://192.168.136.138:2379,https://192.168.136.139:2379 \\
--bind-address=192.168.136.137 \\
--secure-port=6443 \\
--advertise-address=192.168.136.137 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-32767 \\
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/opt/kubernetes/ssl/server.pem  \\
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
EOF
    
    
// 5.生成的证书拷贝到配置文件中的路径
# cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/


/* 6.配置kube-apiserver.conf中的token文件,【下图5.6.6解释】
 * 格式:token,用户名,UID,用户组 token 也可自行生成替换:
 * head -c 16 /dev/urandom | od -An -t x | tr -d ' '
 * c47ffb939f5ca36231d9e3121a252940可以由上面的命令可生成然后替换
 */
# cat > /opt/kubernetes/cfg/token.csv << EOF
c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper"
EOF
    
    
// 7.systemd 管理 apiserver启动文件
# cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
    
// 8.执行kube-apiserver刷新配置文件、启动、开机启动、查看状态
# systemctl daemon-reload
  systemctl start kube-apiserver
  systemctl enable kube-apiserver
  systemctl status kube-apiserver
    
    
// 9.授权 kubelet-bootstrap 用户允许请求证书,【下图5.6.6解释】
# kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap

图6.6解释:启用 TLS Bootstrapping 机制:TLS Bootstraping:Master apiserver启用TLS认证后,Node节点kubelet和kube-proxy要与kube-apiserver进行通信,必须使用CA签发的有效证书才可以,当Node节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展复杂度。为了简化流程,Kubernetes引入了TLS bootstraping机制来自动颁发客户端证书,kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。所以强烈建议在Node上使用这种方式,目前主要用于kubelet,kube-proxy还是由我们统一颁发一个证书。

TLS bootstraping 工作流程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-16SW0UfT-1656048400953)(images\kubelet_auth.jpg)]

图5.6.6

6.部署master组件 kube-controller-manager、kube-scheduler

主节点master操作

6.1 部署kube-controller-manager
// 以下命令在master执行
/* 1.创建 kube-controller-manager.conf 配置文件
* –master:通过本地非安全本地端口 8080 连接 apiserver。
* –leader-elect:当该组件启动多个时,自动选举(HA)
* –cluster-signing-cert-file/–cluster-signing-key-file:自动为kubelet颁发证书的 CA,与apiserver保持一致
*/ 
# cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--master=127.0.0.1:8080 \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--experimental-cluster-signing-duration=87600h0m0s"
EOF
    
    
// 2.创建kube-controller-manager.service 启动文件
# cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
    
// 3.执行kube-controller-manager启动、开机启动、查看状态
# systemctl daemon-reload
  systemctl start kube-controller-manager
  systemctl enable kube-controller-manager
  systemctl status kube-controller-manager     

6.2 部署kube-scheduler
/*
 * 4.创建kube-scheduler.conf配置文件
 * –master:通过本地非安全本地端口 8080 连接 apiserver。
 * –leader-elect:当该组件启动多个时,自动选举(HA)
 */  

# cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect \
--master=127.0.0.1:8080 \
--bind-address=127.0.0.1"
EOF
    
    
// 5.创建kube-scheduler.service启动文件
# cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
      
    
// 4.执行kube-scheduler启动、开机启动、查看状态
# systemctl daemon-reload
  systemctl start kube-scheduler
  systemctl enable kube-scheduler
  systemctl status kube-scheduler
    
    
// 5.查看集群状态(所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态)
# kubectl get cs

7.部署组件 kubelet, kube-proxy

7.1~7.3在Master节点 操作,除特别表明。master创建后直接拷贝到子节点中应用见7.4

7.1 部署kubelet
// 1.在所有node节点新建目录(node执行)
# mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} 

// 2.从master节点拷贝需要文件 进入解压的kubernetes-server-linux-amd64.tar.gz文件夹(master执行)
# 进入解压的kubernetes-server-linux-amd64.tar.gz文件夹
# cd kubernetes/server/bin
# cp kubelet kube-proxy /opt/kubernetes/bin

/**
* 2.创建kubelet.conf 配置文件(master执行)
* –hostname-override:显示名称,集群中唯一!!!!!!!!!!!多个集群别忘记改名字,改为本机hostname查询名称
* –network-plugin:启用CNI
* –kubeconfig:空路径,会自动生成,后面用于连接apiserver
* –bootstrap-kubeconfig:首次启动向apiserver申请证书
* –config:配置参数文件
* –cert-dir:kubelet证书生成目录
* –pod-infra-container-image:管理Pod网络容器的镜像 
* 可尝试替换为:--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64
**/ 
# cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=master \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=lizhenliang/pause-amd64:3.0"
EOF
    
    
// 3.创建kubelet-config.yaml 配置文件(master执行)
# cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local 
failSwapOn: false
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /opt/kubernetes/ssl/ca.pem 
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF
    
    
// 4.生成bootstrap.kubeconfig文件(master执行)
# KUBE_APISERVER="https://192.168.136.137:6443"   // apiserver IP:PORT
# TOKEN="c47ffb939f5ca36231d9e3121a252940"       // 与token.csv里保持一致
    
    
// 5.生成 kubelet bootstrap kubeconfig 配置文件(master执行)
# kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=bootstrap.kubeconfig
    
# kubectl config set-credentials "kubelet-bootstrap" \
  --token=${TOKEN} \
  --kubeconfig=bootstrap.kubeconfig
    
# kubectl config set-context default \
  --cluster=kubernetes \
  --user="kubelet-bootstrap" \
  --kubeconfig=bootstrap.kubeconfig
   
# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
# cp bootstrap.kubeconfig /opt/kubernetes/cfg
    
    
// 6.创建kubelet.service启动文件(master执行)
# cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
    
    
// 7.执行kube-scheduler启动、开机启动、查看状态
# systemctl daemon-reload
  systemctl start kubelet
  systemctl enable kubelet
  systemctl status kubelet
    
    
// 8.批准kubelet证书申请并加入集群(master节点操作)【见图8.7.7】(master执行)
// 查看kubelet证书请求
# kubectl get csr
    
NAME                                                   AGE    REQUESTOR          CONDITION
node-csr-uCEGPOIiDdlLODKts8J658HrFq9CZ--K6M4G7bjhk8A   6m3s   kubelet-bootstrap  Pending	  

// 批准申请
# kubectl certificate approve [node-csr-uCEGPOIiDdlLODKts8J658HrFq9CZ--K6M4G7bjhk8A]

// 查看节点
# kubectl get node   // 注:由于网络插件还没有部署,节点会没有准备就绪 NotReady

Kubernetes、k8s从入门到实战_第26张图片

图8.7.7

7.2 部署kube-proxy
// 1.添加kube-proxy.conf配置文件(master执行)
# cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"
EOF
       
/*
 * 2.添加kube-proxy-config.yml配置文件(master执行)
 * hostnameOverride:几个从node节点改名字 !!!!!!!!!!!!!!!改成hostname的名字
 */
# cat > /opt/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
  kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: master
clusterCIDR: 10.0.0.0/24
EOF  

// 3.生成kube-proxy.kubeconfig文件(master执行)
# cd ~/TLS/k8s

// 4. 创建证书请求文件(master执行)
# cat > kube-proxy-csr.json << EOF
{
  "CN": "system:kube-proxy",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
  ]
}
EOF
    
// 5.生成证书(master执行)
# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
# ls kube-proxy*pem
    
    
// 6.拷贝认证文件(master执行)
# cp -p kube-proxy-key.pem  kube-proxy.pem /opt/kubernetes/ssl/

// 7.生成kubeconfig文件(master执行)
# cd /opt/kubernetes/ssl/
# KUBE_APISERVER="https://192.168.136.137:6443"

# kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kube-proxy.kubeconfig

# kubectl config set-credentials kube-proxy \
  --client-certificate=./kube-proxy.pem \
  --client-key=./kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig

# kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig

# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
# cp -p kube-proxy.kubeconfig /opt/kubernetes/cfg/



// 8.systemd管理kube-proxy.service启动文件(master执行)
# cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy
After=network.target
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
    
// 9.管理kube-proxy
# systemctl daemon-reload
  systemctl start kube-proxy
  systemctl enable kube-proxy
  systemctl status kube-proxy

7.3 部署CNI网络
/* 1.先准备好CNI二进制文件,可自取(master执行)
* 下载址:https://github.com/containernetworking/plugins/releases/download/v0.9.1/cni-plugins-linux-amd64-v0.9.1.tgz
*/

// 2.新建CNI管理目录(master执行)
# mkdir /opt/cni/bin -p


// 3.解压二进制包并移动到默认工作目录(master执行)
# rz -E cni-plugins-linux-amd64-v0.9.1.tgz
# tar zxvf cni-plugins-linux-amd64-v0.9.1.tgz -C /opt/cni/bin


// 4.部署CNI网络、kube-flannel.yml可自取(master执行)
# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

# sed -i -r "s#quay.io/coreos/flannel:.*-amd64#lizhenliang/flannel:v0.12.0-amd64#g" kube-flannel.yml

// 5.授权kube-flannel.yml(master执行)
# kubectl apply -f kube-flannel.yml

// 6.部署好网络插件,Node准备就绪(master执行)
# kubectl get pods -n kube-system
# kubectl get node

// 7.授权apiserver访问kubelet(master执行)
# cat > apiserver-to-kubelet-rbac.yaml << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/proxy
      - nodes/stats
      - nodes/log
      - nodes/spec
      - nodes/metrics
      - pods/log
    verbs:
      - "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: kubernetes
EOF

// 8.授权apiserver-to-kubelet-rbac.yaml(master执行)
# kubectl apply -f apiserver-to-kubelet-rbac.yaml

7.4 新增加Node节点
// 1.拷贝已部署master好的Node相关文件到新节点(在master节点执行拷贝到node节点)执行下面4个拷贝
# scp -r /opt/kubernetes root@192.168.136.138:/opt/

# scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@192.168.136.138:/usr/lib/systemd/system

# scp -r /opt/cni/ root@192.168.136.138:/opt/

# scp /opt/kubernetes/ssl/ca.pem root@192.168.136.138:/opt/kubernetes/ssl


// 2.删除kubelet证书和kubeconfig文件(node执行)
# rm -rf /opt/kubernetes/cfg/kubelet.kubeconfig 
# rm -rf /opt/kubernetes/ssl/kubelet*

// 3.修改主机名--hostname-override=`主机的hostname`(node执行)
# vim /opt/kubernetes/cfg/kubelet.conf
修改:--hostname-override=node1
    
# vim /opt/kubernetes/cfg/kube-proxy-config.yml
修改:hostnameOverride: node1
    
    
// 4.启动并设置开机启动(node执行)
# systemctl daemon-reload
# systemctl start kubelet
# systemctl enable kubelet
# systemctl start kube-proxy
# systemctl enable kube-proxy
    
# systemctl status kubelet
# systemctl status kube-proxy
    
    
// 5.在Master上批准新Node kubelet证书申请(master执行)【见图7.4.5】
# kubectl get csr   
NAME                                                   AGE    REQUESTOR          CONDITION
node-csr-uCEGPOIiDdlLODKts8J658HrFq9CZ--K6M4G7bjhk8A   6m3s   kubelet-bootstrap  Pending	  

// 6.批准申请(master执行)
# kubectl certificate approve [node-csr-uCEGPOIiDdlLODKts8J658HrFq9CZ--K6M4G7bjhk8A]
    
// 7.查看节点状态(master执行)
# kubectl get node
    

node2节点 将7.4 新增加Node节点中拷贝ip换成192.168.137.139然后在node2中继续执行

!此操作增加第一个node1节点,新增加下一个node2节点重复执行 <7.4 新增加Node节点>菜单 操作即可

Kubernetes、k8s从入门到实战_第27张图片

图7.4.5

~~查看二进制安装后服务是否都正常

// 主节点服务
# systemctl status etcd
# systemctl status docker 
# systemctl status kube-apiserver
# systemctl status kube-controller-manager 
# systemctl status kube-scheduler
# systemctl status kubelet
# systemctl status kube-proxy
    
// 子节点服务
# systemctl status etcd
# systemctl status docker 
# systemctl status kubelet
# systemctl status kube-proxy

8. 部署k8s界面化工具

8.1 Dashboard

借鉴文章:https://blog.51cto.com/14320361/2473879?source=drh

搭建:主节点master操作

// 1.下载dashboard配置文件、或自取
# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

// 2.默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部见【下图8.1.1】
# vim recommended.yaml
//修改内容:
----
kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 30001   // 添加这里暴露端口
  type: NodePort
  selector:
    k8s-app: kubernetes-dashboard
----

Kubernetes、k8s从入门到实战_第28张图片

图8.1.1

// 3.执行应用recommended.yaml文件
# kubectl apply -f recommended.yaml
        
// 4.查看暴露端口
# kubectl get pods,svc -n kubernetes-dashboard
  
// 5.创建service account并绑定默认cluster-admin管理员集群角色(授权登录时token)
# kubectl create serviceaccount dashboard-admin -n kube-system

# kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin

// 6.获取dashboar登录token
# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

 输出token: eyxxxxxxxxxxxxxxxxxxxxxxxxx【见图8.1.2,生成的token】
     
     
访问地址:https://NodeIP:30001  【见图8.1.3,需要token才可登录进去】  goole浏览器输入:thisisunsafe

Kubernetes、k8s从入门到实战_第29张图片

													 	    	**图8.1.2**

Kubernetes、k8s从入门到实战_第30张图片

图8.1.3

  • 基于kubeconfig配置文件的方法登录dashboard
// 操作见【图8.1.4】
// 1.先得到Token的名称
# kubectl get secrets -n kube-system | grep dashboard-admin

// 2.查看上述得到的secret资源的详细信息,会得到token
# kubectl describe secrets -n kube-system  [dashboard-admin-token-5wgf5]

// 3.设置一个环境变量代表获取的token
# DASH_TOKEN=$(kubectl get secrets -n kube-system [dashboard-admin-token-5wgf5] -o jsonpath={.data.token} | base64 -d)

// 4.将k8s集群的配置信息写入kubeconfig配置文件中
# kubectl config set-cluster kubernetes --server=192.168.136.137:6443 --kubeconfig=/root/.dashboard-admin.conf

# kubectl config set-credentials dashboard-admin --token=$DASH_TOKEN --kubeconfig=/root/.dashboard-admin.conf 

# kubectl config set-context dashboard-admin@kubernetes --cluster=kubernetes --user=dashboard-admin --kubeconfig=/root/.dashboard-admin.conf

# kubectl config use-context dashboard-admin@kubernetes --kubeconfig=/root/.dashboard-admin.conf

// 5.生成配置文件位置(复制内容到windows桌面使用)
# cat /root/.dashboard-admin.conf 

Kubernetes、k8s从入门到实战_第31张图片

图8.1.4

8.2 Prometheus + Grafana

Prometheus Grafana
1. 开源的
2. 监控、报警、数据
3. 以HTTP协议周期性抓取被监控组件状态
4. 不需要复杂的集成过程,使用http接口接入即可
1. 开源的数据分析和可视化工具
2. 支持多种数据源
  1. 官方版本部署:本同级目录下:..\YAML\prometheus-grafana\2 官网版部署/>

  2. **Yaml安装方式未成功(target里的cadivor和nodes报错):**https://www.cnblogs.com/terrycy/p/10058944.html

9. 部署CoreDNS

CoreDNS用于集群内部Service名称解析

// 1.coredns.yaml包下载或自取
# 访问:https://gitee.com/luoping_test/kubernetes/blob/master/coredns.yaml

// 2.应用coredns.yaml
# kubectl apply -f coredns.yaml

Kubernetes、k8s从入门到实战_第32张图片

Kubernetes、k8s从入门到实战_第33张图片

// DNS解析测试
# kubectl run -it --rm dns-test --image=busybox:1.28.4 sh
# nslookup kubernetes

Kubernetes、k8s从入门到实战_第34张图片

10. k8s命令行工具Kubectl

kubectl是kubernetes集群的命令行工具,通过kubectl对集群进行管理,并能够在集群上进行容器化应用安装部署;

10.1 基础命令

// kubectl基本语法
# kubectl [command] [TYPE] [NAME] [flags]

command: 指定要对资源执行的操作,例如 create、get、describe、delete;
TYPE:指定资源的类型,资源类型是大小写敏感的,开发者能够以单数node、复数nodes的缩略的形式,例如:【图10.1.1】
    # kubectl get node node1
    # kubectl get nodes node1
NAME:指定资源的名称,名称也是大小写敏感的。如果省略则会显示所有的资源;
flags:指定可选参数,例如可用 -s 或 -server 参数指定Kubernetes API server的地址和端口;
获取更多信息: kubectl --help  ||  kubectl [get] --help

Kubernetes、k8s从入门到实战_第35张图片

图10.1.1

10.2 删除一个Pod的正确做法

/** 【见图10.2.1】
 *  1.直接删除Pod还是会重启(因为deployment还存在还会在创建)
 *  2.先删除 deployment | daemonSet | statefulset | job | cronjob 的控制器配置文件
 *  3.在删除对应的 Service | Ingress 的配置文件
 *  4.删除Pod (也可能会由于控制器的删除,Pod也已经删除)
 * /
 
/*  在执行的kubetcl后面加上 --namespace=default 来指定命名空间操作, 
 *  # kubectl get deployment --namespace=myself
 *  删除全部也可指定成 --all
 *  # kubectl delete pods --all 
 */

// 查看命名空间 kubectl get namespace
# kubectl get ns

// 查看暴露端口 
# kubectl get svc

// 进入容器 kubectl exec -it web-nginx-5dc49f44b4-jmb55 bash
# kubectl exec -it [pod名称] bash

// 查看容器日志 kubectl logs -f web-nginx-5dc49f44b4-jmb55
# kubectl logs [-f] [pod名称]

// 查看Deployment无状态服务
# kubectl get deployment     
// 删除Deployment无状态服务
# kubectl delete deployment  [xxx...]


// 查看Service
# kubectl get service    
// 删除Service
# kubectl delete service [xxx...]


// 查看Pod
# kubectl get pod  
// 删除pod
# kubectl delete pod [xxx... ,xxx...]


// 查看daemonset
# kubectl get daemonSet  
// 删除daemonset
# kubectl delete daemonSet  [xxx...]


// 查看statufulset有状态服务
# kubectl get statefulset 
// 删除statufulset有状态服务
# kubectl delete statefulset  [xxx...]


// 查看一次性任务
# kubectl get job     
// 删除一次性任务
# kubectl delete job [xxx...]


// 查看定时任务
# kubectl get cronjob    
// 删除定时任务
# kubectl delete cronjob [xxx...]		          

Kubernetes、k8s从入门到实战_第36张图片

Kubernetes、k8s从入门到实战_第37张图片

图10.2.1

10.3 kubectl子命令使用分类

  1. 基础命令

    命令 说明
    create 通过文件名或标准输入创建资源;
    例如:kubectl create deployment nginx --image=nginx
    expose 将一个资源公开为一个新得Service;
    例如:kubectl expose deployment nginx --port=80 --type=NodePort
    run 在集群中运行一个特定的镜像
    set 在对象上设置特定的功能
    get 显示一个或多个资源
    例如:kubectl expose deployment nginx --port=80 --type=NodePort
    explain 文档参考资源
    edit 使用默认的编辑器编辑一个资源
    delete 通过文件名、标准输入、资源名称或标签选择器来删除资源
  2. 部署命令

    命令 说明
    rollout 管理资源的发布
    rolling-update 对给定的复制控制器滚动更新
    sacle 扩容或缩容Pod数量,Deployment、ReplicaSet、RC或Job
    autoscale 创建一个自动选择扩容或缩容并设置Pod数量
  3. 集群管理命令

    命令 说明
    certificate 修改整证书资源
    cluster-info 显示集群信息
    top 显示资源(CPU、Memory、Storage)使用,需要Heapster运行
    cordon 标记节点不可调度
    uncordon 标记节点可调度
    drain 驱逐节点上的应用,准备下线维护
    taint 修改节点taint标记
  4. 故障诊断和调试命令

    命令 说明
    describe 显示特定资源或资源组的详细信息
    logs 在一个Pod中打印一个容器日志。如果Pod只有一个容器,容器名称是可选的
    attach 附加到一个运行的容器
    exec 执行命令到容器
    port-forward 转发一个或多个本地端口到一个Pod
    proxy 运行一个proxy到kubernetes API server
    cp 拷贝文件或目录到容器中
    auth 检查授权
  5. 其它命令

    命令描述 命令 说明
    高级命令 apply 通过文件名或标准输入对资源应用配置;
    例如:kubectl apply -f kube-flannel.yml
    patch 使用补丁修改、更新资源的字段
    replace 通过文件名或标准输入替换一个资源
    convert 不同的API版本质检转换配置文件
    设置命令 label 更新资源上的标签
    annotate 更新资源上的注释
    completion 用于实现kubectl工具自动补全
    其它命令 api-versions 打印受支持的API版本
    config 修改kubeconfig文件(用于访问API,比如配置认证信息)
    help 所有命令行插件
    plugin 运行一个命令行插件
    version 打印客户端和服务版本信息

11. K8s部署项目三个文件配置说明(无状态部署)

Deployment和Service文件预览【图11.1.1】

# 注意:- name: 这种配置情况属于可以配置多个使用
spec:
  containers:
    - name: nginx
      image: nginx:1.15
      ...
    - name: mysql
      image: mysql:latest
      ...

Kubernetes、k8s从入门到实战_第38张图片

图11.1.1

11.1 Deployment 部署文件配置

作用:见上2.2节 Controller

# Deployment有关配置详解
# 1.镜像拉取策略
# spec:
#   template:
#     spec:
#       containers:
#         imagePullPolicy: IfNotPresent
#  IfNotPresent 策略:默认值,镜像在宿主机上不存在时才拉取
#  Always 策略:每次创建Pod都会重新拉取一次镜像
#  Never 策略:Pod永远不会主动拉取这个镜像
# 
# 2.重启策略:
# spec:
#   template:
#     spec:
#       containers:
#         restartPolicy: Always
#  Always:当容器终止退出后,总是重启容器。默认策略
#  OnFailure:当容器异常退出(退出状态码非0)时,才重启容器
#  Never: 当容器终止退出,从不重启容器
#		
#	
# 3.通过节点选择器进行指定节点调用-影响Pod调度
# spec:
#   template:
#    spec:
#     nodeSelector:
#       env_role: dev
# // 使用命令进行节点命名kubectl label node [节点名称] env_role=[标签名称]
# $ kubectl label node node1 env_role=dev
# // 查看打标签命令 kubectl get nodes [节点名称] --show-labels
# $ kubectl get nodes node1 --show-labels
#
#
# 4.节点亲和性-影响Pod调度【见图11.1.2】
#
#
# 5.使用污点和污点容忍,实现节点是否可以被调用。
# 见文章:https://blog.csdn.net/qq_34556414/article/details/109471676
# nginx-deployment.yaml
apiVersion: apps/v1         
kind: Deployment           
metadata:                   
  name: nginx-deployment
  namespace: xinghongxiang      
  labels:
    app: nginx
spec:                    
  replicas: 2           
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nginx
  template:             
    metadata:             
      labels:
        app: nginx
    spec:
      nodeSelector:
        env_role: dev
      containers:          
        - name: nginx
          image: nginx:1.15 
          imagePullPolicy: IfNotPresent
          restartPolicy: Never
          ports:
            - containerPort: 80
          resources:   
            requests:
              memory: 512Mi
              cpu: 250m
            limits:     
              memory: 1000Mi
              cpu: 500m
      imagePullSecrets:   
        - name: default-secret

Kubernetes、k8s从入门到实战_第39张图片

图11.1.2

11.2 Service 部署文件配置

作用:见上2.3节 Service

# Service有关配置详解
# 1.内部访问还是外部访问
# spec:
#   selector:
#     type: NodePort
#  ClusterIP:集群内部使用,不会暴露出端口号。不可外部访问;
#  NodePort:对外访问应用使用,会暴露出端口号。可外部访问;
#  LoadBalancer:对外访问应用使用,直接读取公有云配置使用,比如暴露ip都是公有云中配置的;
# 可通过kubectl get svc 返回结果中的 TYPE 查看
# nginx-service.yaml
apiVersion: v1   
kind: Service
metadata:
  name: nginx-service
  namespace: xinghongxiang 
  labels:
    app: nginx-service
spec:
  type: NodePort
  selector:
    app: nginx
    type: NodePort
  ports:
  - port: 8000
    targetPort: 80
    nodePort: 31999

11.3 使用Deployment和Service部署一个Nginx服务

/* 1.`生成上面的YAML中Deployment格式配置,可修改使用`【见图11.1.3】
 * 命令解析: 
 *	web:资源名称 
 *	nginx:使用nginx镜像的模板 
 *	-o yaml:提取YAML文件
 *  --dry-run:不运行此容器(这个有时候会报错被弃用则使用 --dry-run=client)
 *  > myNginxDeployment.yaml:当前路径下生成文件名称
 */
# kubectl create deployment web --image=nginx -o yaml --dry-run >myNginxDeployment.yaml

// 2.`暴露端口,生成Service`
# kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web1 -o yaml > myNginxService.yaml

// 3.`部署`
# kubectl apply -f myNginxDeployment.yaml
# kubectl apply -f myNginxService.yaml

// 4.`查看端口访问`
# kubectl get pods,svc

// 5.`升级应用 kubectl set image deployment [应用名称] [镜像标签名]=nginx:v1.15`
# kubectl set image deployment web nginx=nginx:v1.15

// 6.`查看是否升级成功`
# kubectl rollout status deployment web

// 7.`查看历史升级`
# kubectl rollout history deployment web

// 8.`还原到上一个版本`
# kubectl rollout undo deployment web

// 9.`还原到指定版本 --to-revision=[7.查看历史升级]`
# kubectl rollout undo deployment web --to-revision=2

// 10..`扩容副本数`
# kubectl scale deployment web --replicas=10

// 11.`删除Deployment和Service`
# kubectl delete deployment web
# kubectl delete Service web

Kubernetes、k8s从入门到实战_第40张图片

														                      **图11.1.3**

11.4 Ingress 部署文件配置

作用:Ingress: 统一入口,负责统一管理外部对k8s 集群中service的请求,使用ingress前要部署Ingress Contrller;

使用Ingress的好处:

  1. 端口管理。减少不必要端口暴露,便于管理。
  2. 所有的请求,通过Ingress对应的I ip:port 进入,过滤/转发/负载均衡到相应的 service / pod。

11.4.1 部署Ingress Controller

作用:Ingress Controller: Ingress可以给service提供集群外部访问的URL、负载均衡、SSL终止、HTTP路由等。为了配置这些 Ingress规则,集群管理员需要部署一个Ingress controller,它监听Ingress和service的变化,并根据规则配置负载均衡并提供访问入口;

选型:Ingress Controller选型百度看优缺点。官网使用nginx-ingress;

# 在YAML文件中的 nginx-controller.yaml 【见图11.4.1】
# 查看ingress-controller是否运行成功 kubectl get pods -n [命名空间]
$ kubectl get pods -n ingress-nginx 

Kubernetes、k8s从入门到实战_第41张图片

图11.4.1

  1. 使用案例 - 配置详情:【见图11.2.1】

Kubernetes、k8s从入门到实战_第42张图片

图11.2.1

# Kind类型为Ingress、 metadata.name=ingress名称、 spec.rules.-host=域名地址 、 serviceName=service名
# 本地windows测试需要在hosts文件中添加下[域名 映射地址  例:test.nginx.com 192.168.136.137]
# nginx-ingress.yaml
apiVersion: networking.k8s.io/v1beta1   
kind: Ingress                           
metadata:                               
  name: nginx-ingress
  namespace: default                    
spec:
  rules:
    - host: test.nginx.com              
      http:
        paths:
          - backend:
              serviceName: nginx-service 
              servicePort: 31999

访问:test.nginx.com:31999

11.5 配置文件导出

# 指定类型文件导出
# kubectl get $resource_type $resource_name -n $ns -o yaml > ${resource_type}/${resource_name}.yaml
$ kubectl get Deployment nginx-deployment -n xinghongxiang -o yaml > nginx-deployment.yaml

# 脚本循环全部导出
链接:https://blog.csdn.net/weixin_47677347/article/details/120871612

12. 番外:控制器其它使用方式

见章节2.1.1

12.1 有状态部署 -> StatefulSet

无状态 有状态
* 认为Pod都是一样的
* 没有顺序要求
* 不用考虑在那个node运行
* 随意进行伸缩和扩容
* 无状态的因素都需考虑到
* 让每个Pod独立,保持Pod启动顺序和唯一性
* 唯一的网络标识符,持久存储
* 有序,比如mysql主从

使用StatefulSet部署有状态应用

# 有状态部署必须有无头Service,也就是Service配置文件必须`spec.clusterIp:None`
# Service名称为metadata.name: nginx
# vim sts.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
    
---
# Controller控制器,控制部署有状态应用(就是对应无状态的Deployment),将设置Kind: StatefulSet,
# 控制器名称为metadata.name: nginx-statefulset
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx-statefulset
  namespace: default
spec:
  serviceName: nginx
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

部署: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5rjM5Gx-1656048400959)(images\statefulSet_apply.jpg)]

查看控制器: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-naPqjSXj-1656048400959)(images\statefulSet_pods.jpg)]

查看Service:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-izOk96H6-1656048400960)(images\statufulSet_service.jpg)]

删除:
# kubectl delete statefulset --all
# kubectl delete svc nginx
# kubectl delete svc web

12.2 确保所有node运行在同一个Pod中 -> DaemonSet

​ 例如:在每个node节点安装数据采集工具

# Controller控制器,控制部署有状态应用(就是对应无状态的Deployment),将设置Kind: DaemonSet,
# 控制器名称为metadata.name: ds-test
# vim ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ds-test 
  labels:
    app: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      containers:
      - name: logs
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: varlog
          mountPath: /tmp/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

部署及查看: Kubernetes、k8s从入门到实战_第43张图片

进入Pod查看日志:Kubernetes、k8s从入门到实战_第44张图片

12.3 一次性任务 -> job

# 执行一次就结束:模拟计算圆周率
# backoffLimit: 4 ,失败重启多少次(默认是6)
# vim job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4 

创建及查看: Kubernetes、k8s从入门到实战_第45张图片

查看pod: Kubernetes、k8s从入门到实战_第46张图片

查看执行结果:Kubernetes、k8s从入门到实战_第47张图片

删除: # kubectl delete job pi

12.4 定时任务 -> cronjob

数据的备份可以用到

# 模拟每分钟输出一个hello
# vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

创建定时任务:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O8CBlUut-1656048400961)(images\cronjob_create.jpg)]

执行结果: Kubernetes、k8s从入门到实战_第48张图片

删除: # kubectl delete cronjob hello

13. Secret

作用:存储加密(Base64)数据到etcd,让Pod容器以挂载Volume方式进行访问;
场景:凭证的使用(帐号密码);

13.1 创建Secret加密数据

# kind: Secret 方式为加密,data.username=YWRtaW4、data.password=YWRtaW4为加密后的用户名密码
# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: YWRtaW4=

Kubernetes、k8s从入门到实战_第49张图片

13.2 挂载到Pod中

  1. 以变量方式挂载

    # 变量方式配置文件
    # metadata.name=my-secret-var-pod
    # vim secret-var.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-secret-var-pod
    spec:
      containers:
      - name: nginx
        image: nginx
        env:
          - name: SECRET_USERNAME
            valueFrom:
              secretKeyRef:
                name: mysecret
                key: username
          - name: SECRET_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysecret
                key: password
    
    

    创建变量配置文件: Kubernetes、k8s从入门到实战_第50张图片

    生成Pod查看结果: Kubernetes、k8s从入门到实战_第51张图片

  2. 以Volumn方式挂载

    # Volumn方式配置文件
    # metadata.name=mysecret-volume-pod
    # vim secret-vol.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: mysecret-volume-pod
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: foo
          mountPath: "/etc/foo"
          readOnly: true
      volumes:
      - name: foo
        secret:
          secretName: mysecret
    
    

    创建Volumn配置文件: Kubernetes、k8s从入门到实战_第52张图片

    生成Pod查看结果: Kubernetes、k8s从入门到实战_第53张图片

14. ConfigMap

作用:存储不加密数据到etcd,让Pod以变量或者Volume挂载到容器中;
场景:配置文件;

1. 创建配置文件

// 1.新建配置文件【见图14.1.2】
# vim redis.properties
redis.host=127.0.0.1
redis.port=6379
redis.password=123456

2. 创建ConfigMap

// 【见图14.1.2】
// 2.创建ConfigMap命令 kubectl create configmap [configmap名称] --from-file=[由那个文件创建] 
# kubectl create configmap redis-config --from-file=redis.properties

// 查看创建的configMap
# kubectl get configmap    或    # kubectl get cm
// 查看详情(文件内容) kubectl describe configmap [configmap名称]
# kubectl describe configmap redis-config

Kubernetes、k8s从入门到实战_第54张图片

图14.1.2

3. 将配置文件挂载到Pod中

  1. 将配置文件以volume挂载到Pod中【见图14.3.1】

    # 挂载yaml将redis.proprties挂载到Pod,启动Pod输出redis.properties内容
    # volumes.configMap.name=redis-config,这里必须配置刚刚生成的configMap名称
    # Pod名称:metadata.name=myRedisConfig
    # vim cm.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: myredisconfig
    spec:
      containers:
        - name: busybox
          image: busybox
          command: [ "/bin/sh","-c","cat /etc/config/redis.properties" ]
          volumeMounts:
          - name: config-volume
            mountPath: /etc/config
      volumes:
        - name: config-volume
          configMap:
            name: redis-config
      restartPolicy: Never
    
    

    Kubernetes、k8s从入门到实战_第55张图片

    图14.3.1

  2. 将配置文件以变量的方式挂载到Pod中(此演示方式和使用–from-file 指定文件不同)
    结合学习:此种方式和Secret加密变量挂载方式差不多;

    # kind: ConfigMap 方式生成CnnfigMap,进行设置一些数据值
    # vim myconfig.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: myconfig
      namespace: default
    data:
      special.level: info
      special.type: hello
    
    
    # kind: Pod 方式生成Pod,进行读取kind: ConfigMap中名称为metadata.name=myconfig的变量
    # vim myconfig-var.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: my-configmap-var-pod
    spec:
      containers:
        - name: busybox
          image: busybox
          command: [ "/bin/sh", "-c", "echo $(LEVEL) $(TYPE)" ]
          env:
            - name: LEVEL
              valueFrom:
                configMapKeyRef:
                  name: myconfig
                  key: special.level
            - name: TYPE
              valueFrom:
                configMapKeyRef:
                  name: myconfig
                  key: special.type
      restartPolicy: Never
    
    

    模拟创建变量文件用Pod配置进行读取:Kubernetes、k8s从入门到实战_第56张图片

    编写Pod读取ConfigMap:Kubernetes、k8s从入门到实战_第57张图片

    生成Pod,查看结果: Kubernetes、k8s从入门到实战_第58张图片

15.集群安全机制

​ 1. 访问K8s集群时,需要经过三个步骤完成具体操作【见图15.1.1】

​ 一、认证(传输安全)

* 传输安全:对外不暴露8080端口,只能内部访问,对外使用端口6443

* 认证,客户端身份认证常用方式
​ 1、https 证书认证,基于ca证书
​ 2、http token认证,通过token识别用户
​ 3、http 基本认证,用户名+密码认证

​ 二、鉴权(授权)

* 基于RBAC(基于角色访问控制)进行鉴权操作。RBAC已是鉴权标准化自行百度

​ 三、准入控制

* 就是准入控制器的列表,如果列表中有请求内容则通过,没有则拒绝

  1. 进行访问时,过程中需要经过apiserver,apiserver做统一协调,比如门卫。

    访问过程中需要证书、token、或者用户名+密码、如果访问Pod需要serviceAccount(服务的帐号)。
    Kubernetes、k8s从入门到实战_第59张图片

    图15.1.1

  2. k8s集群基于角色的权限访问—RBAC的使用

    官网API使用RBAC授权:http://docs.kubernetes.org.cn/148.html

16. Helm

1.介绍

引入原因:之前使用部署单一应用方式是少数服务的应用比较合适,比如部署微服务项目,可能有几十个服务,每个服务 都有一套yaml文件,需要维护大量yaml文件,版本管理起来也不方便。

解决问题:使用helm可以把yaml作为一个整体管理;
实现yaml高效服用(里面结构相同值可统一写一个);
使用helm应用级别的版本管理;

Helm:是一个Kubernetes的包管理工具(类似kubectl),就像Linux下的包管理起,如yum/apt等。可以很方便的将之前 打包好的yaml文件部署到Kubernetes上;

Helm的三个概念:1、helm: 一个命令行客户端工具,主要用于Kubernetes应用chart的创建、打包、发布和管理;
2、Chart: 应用描述,一系列用于描述k8s资源相关文件的集合(打包yaml、yaml集合);
3、Release: 基于Chart的部署实体,一个chart被Heml运行后将会生成对应的一个release,将在k8s 中创建出真实运行的资源对象;

Kubernetes、k8s从入门到实战_第60张图片

2.安装及配置

// 官网:https://helm.sh/
// 1.下载helm安装包,解压
# tar -zxvf  helm-v3.0.0-linux-amd64.tar.gz

// 2.将解压的helm文件复制到/usr/bin目录下
# cd linux-amd64
# cp helm /usr/bin

// 3.是否安装成功
# helm version

// 4.配置helm仓库
// 添加仓库  helm repo add [仓库名称] [仓库地址] (二个都可以加,以下操作以只加微软为例)
# (微软仓库) helm repo add stable http://mirror.azure.cn/kubernetes/charts
# (阿里仓库) helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
# (刷新仓库) helm repo update

// 5.查看配置的存储库
# helm repo list
# helm search repo stable

// 6.删除存储库
# helm repo remove aliyun

3.安装部署插件chart

  1. 安装部署的插件【见图16.3.1】

    // 1.搜索chart:helm search repo [名称]
    # helm search repo weave
    
    // 2.根据搜索内容选择安装 helm install [自定义名称] [搜索到的文件名称]
    # helm install ui stable/weave-scope
    
    // 3.查看安装状态 helm list 或 helm status [名称]
    # helm list
    
    

    Kubernetes、k8s从入门到实战_第61张图片

    图16.3.1

    k8s上暴露端口【见图16.3.2.1】

    // * weave安装成功,k8s上会自动部署weave的Pod和Service
    // 1.查看weave的Service文件
    # kubectl get pods,svc
    
    // 2.修改service文件中的最下面暴露端口类型ClusterPort改为NodePort,用于外网访问【见图16.3.2.2】
    # kubectl edit svc ui-weave-scope
    
    // 3.编辑后保存,查看暴露的端口
    # kubectl get svc
    
    

Kubernetes、k8s从入门到实战_第62张图片

图16.3.2.1

Kubernetes、k8s从入门到实战_第63张图片
图16.3.2.2

访问:http://192.168.136.137:32007

Kubernetes、k8s从入门到实战_第64张图片

4.使用chart部署一个应用

主要介绍三个命令:1、chart install
2、chart upgrade
3、chart rollback

// 1.使用命令创建chart: helm create [chart名称] 【见图16.4.1】
# helm create mychart

/**
 * 创建的chart的文件解读
 * charts:普通文件夹
 * Chart.yaml:用于chart的属性配置信息
 * templates:将部署的yaml文件放入这里,比如 Deployment、Service、Ingress(可以将生成时里面有的文件全部删除)
 * values.yaml:定义的一些全局变量,可以在templates中使用此变量
 */

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OOwyw5dQ-1656048400967)(images\helm_create_chart.jpg)]图16.4.1

# 2.部署一个nginx
# 在templates文件夹创建两个yaml文件(deployment.yaml、service.yaml)
# 进入templates目录
# deployment.yaml (2个文件通过11.3的命令生成的)
$ cat > deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
 creationTimestamp: null
 labels:
   app: chart-nginx
 name: chart-nginx
spec:
 replicas: 1
 selector:
   matchLabels:
     app: chart-nginx
 strategy: {}
 template:
   metadata:
     creationTimestamp: null
     labels:
       app: chart-nginx
   spec:
     containers:
     - image: nginx
       name: nginx
       resources: {}
status: {}
EOF
            
       
# service.yaml配置文件
$ cat > service.yaml << EOF
apiVersion: v1
kind: Service
metadata:
 labels:
   app: chart-nginx
 name: chart-nginx-service
 namespace: default
spec:
 selector:
   app: chart-nginx
 ports:
 - nodePort: 30080
   port: 80
   protocol: TCP
   targetPort: 80
 type: NodePort
EOF

# 3.进入chart的上次目录(执行前的当前目录为template下,退二层目录到chart的上级目录)
$ cd ../..

# 4.部署命令:helm install [自定义名] [生成的chart目录]、【见图16.4.4.2】
$ helm install chart-nginx mychart/

# 5.修改里面的文件更新升级:helm upgrade [自定义名] [生成的chart目录]
$ helm upgrade chart-nginx mychart/

Kubernetes、k8s从入门到实战_第65张图片
图16.4.4.2

​ 访问:http://192.168.136.137:30080

5. Yaml文件的高效复用

* template放入通用模板,然后通过values.yaml的全局配置,进行读取

# 1.在value,yaml定义变量和值。【见图16.5.1】
# 基本上deployment或service模板中(name、label、image、tag、replicas、port)会有所不同
$ values.yaml
app: chart-nginx1
label: chart-nginx1
image: nginx:1.15
imageName: nginx
nodePort: 30081
port: 80
replicas: 1

# 2.在具体的template中的yaml文件中,获取定义的变量值。【见图16.5.2】
# 通过表达式使用全局变量
# {{ .Values.变量名称}} 注意.前面有个空格
# {{ .Release.Name}} 随机生成一个不重复的名字


# 3.重新使用helm部署。【见图16.5.3】
$ helm install chart-nginx1 mychart/

Kubernetes、k8s从入门到实战_第66张图片

图16.5.1

Kubernetes、k8s从入门到实战_第67张图片

图16.5.2

Kubernetes、k8s从入门到实战_第68张图片

图16.5.3

17. 持久化存储

数据卷 emptydir,s是本地储存,pod重启,数据就不存在了,需要对数据持久化存储;

1. nfs网络存储插件

// 第一步:找一台服务器nfs服务端,安装nfs,设置挂载路径
//(如果是新机器需要k8s集群和新nfs服务机可以连通,因为是通过网络进行挂载)

// 1.安装nfs(新机器或本地机器)
# yum install -y nfs-utils

// 2.设置挂载路径  => 说明:/date/nfs挂载所有内容的读写权限 (新机器)
# vim /etc/exports
/data/nfs *(rw,no_root_squash)
    
// 3.创建挂载的目录 (新机器或本地机器)
# mkdir -p /data/nfs
    
// 4.在k8s集群node节点安装nfs(k8s节点所有node节点上)
# yum install -y nfs-utils
    
// 5.启动nfs服务 (新机器或本地机器)
# systemctl start nfs
# systemctl status nfs

2. k8s集群使用nfs持久网络

/**
 * 1.创建一个nginx中一个目录挂载到nfs路径下,然后启动
 * nfs.server: 192.168.136.140 (挂载nfs的机器IP)
 * nfs.path: /data/nfs     	   (挂载nfs的机器配置的路径)
 */
# vim nfs-nginx.yaml 【见图17.2.1】
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dep1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
        - name: wwwroot
          nfs:
            server: 192.168.136.140
            path: /data/nfs

Kubernetes、k8s从入门到实战_第69张图片

图17.2.1

// 2.启动
# kubectl apply -f nfs-nginx.yaml

/**
 * 3.测试验证,在nfs服务机器中的/data/nfs中新建一个index.html,写上一些内容hello nfs
 *   在k8s集群中进入刚刚启动的pod中查看/usr/share/nginx/html是否挂载进去了index.html
 * 【见图17.2.2】
 */


// 4.访问测试,由于演示使用的是deployment没有Service,所以手动暴露nginx-dep1的端口
# kubectl expose deployment nginx-dep1 --port=80 --target-port=80 --type=NodePort


访问:http://ip:port【见图17.2.3】

Kubernetes、k8s从入门到实战_第70张图片

										  **图17.2.2**

Kubernetes、k8s从入门到实战_第71张图片

										   		**图17.2.3**

3. 使用pv和pvc解决ip暴露的问题

pv:持久化储存配置,对外提供一个名称来关联到nfs的ip上(类似生产者)
pvc:用于调用pv,不需要知道pv的实现细节,实现持久化(类似消费者)
【见图17.3.1】

# kind方式为持久卷、spec.capacity.storage=5Gi是对外提供的连接名称、accessModes=所有读写权限、
# nfs.server=nfs服务机ip、nfs.path=nfs服务机配置的挂载目录、accessModes=匹配模式(读写)、storage=容量5Gi
# vim pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
  labels:
    pv: my-pvbound
spec:
  capacity:
    storage: 5Gi
  accessModes: ["ReadWriteMany"]
  nfs:
    path: /data/nfs
    server: 192.168.136.140

# 1.kind:Deployment中通过spec.template.spec.volumes.persistentVolumeClaim.claimName=my-pvc和   kind:PersistentVolumeClaim的spec.metadata.name=my-pvc进行关联;
# 2.kind:PersistentVolumeClaim的spec.resources.selector.matchLabels.pv=my-pvbound和kind: PersistentVolume的metadata.labels.pv=my-pvbound进行匹配到
# vim pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-persistent
spec:
replicas: 1
selector:
 matchLabels:
   app: nginx
template:
 metadata:
   labels:
     app: nginx
 spec:
   containers:
   - name: nginx
     image: nginx:1.15
     volumeMounts:
     - name: wwwroot
       mountPath: /usr/share/nginx/html
     ports:
     - containerPort: 80
   volumes:
   - name: wwwroot
     persistentVolumeClaim:
       claimName: my-pvc

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes: ["ReadWriteMany"]
resources:
 requests:
   storage: 5Gi
selector:
 matchLabels:
   pv: my-pvbound

// 一些PVC常用命令
// 查看、删除持久化配置
# kubectl get PersistentVolume     或     kubectl get PersistentVolume --show-labels 
# kubectl get PersistentVolume delete [PersistentVolume名称]

// 查看、删除绑定持久化配置
# kubectl get PersistentVolumeClaim
# kubectl get PersistentVolumeClaim delete [PersistentVolumeClaim名称]

Kubernetes、k8s从入门到实战_第72张图片

图17.3.1

更加pvc详细说明见:https://blog.csdn.net/qq_33591903/article/details/103783627

18. 搭建高可用HA K8S集群(多master节点)

说明:单master节点,如果这一个master节点宕机,会导致其余的node也不可用。因为都是通过master进行转发的;

Kubernetes、k8s从入门到实战_第73张图片

原理:k8sHA集群我觉得更应该叫做主从结构k8s集群,它由三台master组成,有三个keepalived提供一个vip(虚拟IP<跟当前机器ip属同一网段>) 来作为apiserver的ip入口,keepalived设置权重,使得vip落在权重大的master节点上,node节点通过访问这个vip从而访问到这一台master,另外两台master则通过etcd集群,来完成数据同步。

缺点:这样的集群是通过keepalived来实现高可用的,也就是说在权重较大的节点没有故障之前,keepalived所指向的流量永远都是经过主master,只有当主master出现故障或者宕机的情况下,才有可能转移到另外两台从master节点上。这样会导致主master节点压力过大,而另外两台从master可能永远不会被调用,导致资源浪费等等情况。

部署文档本同级目录下: ...\YAML\使用kubeadm搭建高可用k8s集群

19. 部署一个Java应用程序

部署流程:项目 -> 编写Dockerfile文件 -> 打成镜像 -> 推送镜像到镜像仓库 -> 准备k8s部署文件 -> 查看服务状态

Kubernetes、k8s从入门到实战_第74张图片

# ---- 1.maven 打包
$ mvn clear package

# ---- 2.Dockerfile编写 ###########  Docekrfile文件放在项目src同级目录

# 基础镜像为openjdk:8u242-jdk
FROM openjdk:8u242-jdk

# 签名
MAINTAINER author "[email protected]"

# 同步日期
RUN rm -f /etc/localtime && ln -sv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone

# 添加jar和配置文件
ADD ./logback-spring.xml /opt/projectname/logback-spring.xml
ADD ./application.yml /opt/projectname/application.yml
ADD ./projectname.jar /opt/projectname/projectname.jar

# 映射日志目录
VOLUME ["/home/logs/projectname","/home/logs/projectname"]

# 暴露端口
EXPOSE 18000

# 默认工作目录
WORKDIR /opt/projectname

# 启动命令
ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Xss256k", "-jar", "projectname.jar"]

# ---- 3.打成镜像包
$ docker build -f Dockerfile -t projectname:v1.0.0 .

# ---- 4.将镜像存放到阿里云或华为云镜像仓库
$ 云仓库有推送镜像命令

# ---- 5.编写K8S所需的Deployment、Service、Ingress
$ 编写Deployment、Service、Ingress配置文件见 --> 【标题11】

# 在k8上创建pod控制器及暴露端口、使用ingress域名访问
$ kubectl apply -f Deployment.yaml 
$ kubectl apply -f Service.yaml
$ kubectl apply -f Ingress.yaml

END

!!! 只使用镜像快速测试一个项目部署

# ---->  只使用镜像快速测试一个项目部署成功  <----
# 创建控制器 kubectl create deployment [deployment名称] --image=[镜像地址:镜像版本]
$ kubectl create deployment javademo --image=registry.cn.beijing.aliyuncs.com/alidemowz/java-project:v1.0.0

# 扩容 kubectl scale deployment [deployment名称]  --replicas=[整数]
$ kubectl scale deployment javademo  --replicas=2

# 暴露端口 kubectl expose deployment [deployment名称] --port=[对外访问端口] --target-port=[容器端口]  --type=[暴露方式]
$ kubectl expose deployment javademo --port=8111 --target-port=8111 --type=NodePort

# 查看
$ kubectl get all 

# 访问
http://IP:对外访问端口/接口

你可能感兴趣的:(kubernetes,云计算,容器,linux,负载均衡)