kubernetese架构介绍

kubernetes的名字来之希腊语,意思是舵手 或 领航员。

中间8个字母ubernete替换称8的缩写

k8s的创造者,是重人皆知的行业巨头——-Google

k8s并不是一项全新的发明,它是Google10多年大规模容器管理技术Borg的开源版本

2014年6月k8s由Google公司正式公布出来并宣布开源

k8s的用途

  • 就在docker容器技术被炒得热火朝天之时,大家发现,如果想要docker应用于具体的业务实现,是存在困难的——编排,管理和调度等各个方面,都不容易。于是,人们迫切需要一套管理系统,对docker及容器进行更高级更灵活的管理,就在这个时候,k8s出现了

  • k8s是容器集群管理系统,是一个开源平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能

k8s适用场景

  • 有大量跨主机容器需要管理
  • 快速部署应用
  • 快速扩展应用
  • 无缝对接新的引用功能
  • 节省资源,优化硬件资源的使用

k8s架构

核心角色

  • master(管理节点)
  • node(计算节点)
  • image(镜像节点)

1.jpg

k8s master 是做什么的

master管理节点

  • master提供集群的控制
  • 对集群进行全局决策
  • 检测和响应集群事件
  • master由apiserver,scheduler,etcd和controllermanager服务组成

master节点服务

  • API server

    是整个系统的对外接口,供客户端和其他组件调用

    后端元数据存储与etcd中(键值数据库)

  • Scheduler

    负责对集群内部的资源进行调度,相当于”调度室”

  • Controller manager

    负责管理控制器,相当于“大总督”

  • etcd

etcd的定义:

etcd是CoreOS团队于2013年6月发起的开源项目,他的目标是构建一个高可用的分布式键值(key-value)数据库,基于Go语言实现。在分布式系统中,各种服务的配置信息的管理和分享,服务的发现是一个很基本同时也是很重要的问题。CoreOS项目就希望基于etcd来解决这一问题。

kubernetes在运行过程中产生的元数据全部存储在etcd中

  • etcd键值管理

    在键的组织上etcd采用了层次化的空间结构(类似于文件系统中的目录的概念),用户指定的键可以为单独的名字

    如何创建key键值,此时实际上放在根目录/key下面

    也可以为指定目录结构,如/dir1/dir2/key,则将创建相应的目录结构

    etcd有kubernetes集群自动管理,用户无需手动干预

    etcdctl是etcd的客户端管理程序

服务端口

协议 端口范围 软件 用途
TCP 6443 kube-apiserver 所有组件接口服务
TCP 2379~2380 etcd kube-api,etcd服务
TCP 10250 kubelet kubelet服务
TCP 10251 kube-scheduler kube-scheduler服务
TCP 10252 kube-controller-manager kube-controller-manager服务

node节点服务

  • docker
  • kubelet
  • kube-proxy

2.png

安装部署工具

集群规划

主机名 ip地址 角色 最低配置
master 192.168.1.21 管理节点 2核2G
node 192.168.1.31 计算节点 2核2G
registry 192.168.1.100 私有仓库 2核2G

准备虚拟机环境

  • 关闭防火墙
  • 关闭selinux
  • 关闭swap
1
2
3
4
5
6
7
8
9
10
11
12
systemctl disable --now firewalld

setenforce 0
vi /etc/sysconfig/selinux
SELinux=disabled

swapoff -a
vim /etc/fstab
# 删除swap行

free -m
swap 0 0

安装部署工具

安装部署方式

  • 官网:https://kubernetes.io/
  • 源码&二进制(容器化部署)
  • 下载源码或编译好的二进制,手工添加参数启动服务
  • kubernetes采用证书认证方式,需要创建大量证书
  • 官方把服务做成“镜像”,下载镜像,启动镜像即可
  • 官方工具kubeadm采用的方式(推荐)
  • 安装kubeadm,kubelet,kubectl和docker-ce

    kubeadm:用来初始化集群的指令

    kubelet:在集群中的每个节点上启动pod和容器等

    kubectl:用来集群通信的命令行工具

    docker:容器管理工具

配置YUM仓库

docker安装包在目录kubernetes/docker

k8s安装包在目录kubernetes/v1.17.6/k8s-install

依赖包kubernetes/extras

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
yum install -y httpd createrepo

mkdir -p /var/www/html/localrepo

systemctl enable --now httpd

cp -a k8s-install /var/www/html/localrepo

cp -a docker /var/www/html/localrepo

cp -a extras /var/www/html/localrepo

cd /var/www/html/localrepo

createrepo .

安装工具包

  • master
  • 配置http的yum源
1
2
3
4
5
6
[yum]
baseurl=http://192.168.1.100/localrepo

yum install kubeadm kubelet kubectl docker-ce -y

systemctl enable --now kubelet docker

docker配置

为docker配置私有仓库,和cgroup控制器

kubelet使用的是cgroup控制器是systemd,而docker使用的是cgroupfs,必须设置成统一的(查询命令:docker info)

配置文件/etc/docker/daemon.json

1
2
3
4
5
6
7
8
9
# 新文件
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://hub-mirror.c.163.com"],
"insecure-registries":["192.168.1.100:5000","registry:5000"]
}

systemctl restart docker

内核环境参数

  • 修改host解析
  • 开启路由转发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vim /etc/hosts
192.168.1.21 master
192.168.1.31 node
192.168.1.100 registry

# 新建
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

modprobe br_netfilter #加载模块

sysctl --system #启动模块

kubeadm介绍

kubeadm命令

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

Tab键设置

kubectl、kubeadm支持自动补全功能,可以节省大量输入

自动补全脚本由kubectl、kubeadm产生,仅需要在你的shell配置文件中调用即可

配置完成以后需要退出,重新登陆后生效

1
2
3
4
5
kubectl completion bash >/etc/bash_completion.d/kubectl

kubeadm completion bash >/etc/bash_completion.d/kubeadm

exit

私有仓库

初始化镜像仓库

kubernetes/v1.17.6/registry/myos下的myos.tar.gz压缩了4个基础镜像

里面还有一个脚本,适当修改执行,解压上传镜像

1
2
3
4
5
6
7
vim /etc/yum.repo.d/local.repo

baseurl=http://192.168.1.100/localrepo

yum -y install docker-distribution

systemtl enable --now docker-destribution

需要配置daemon.json

1
2
3
4
5
sh kubernetes/v1.17.6/registry/myos/init-img.sh

curl http://192.168.1.100:5000/v2/myos/tags/list

{"name":"myos":"tags":["nginx","php-fpm","v1804","httpd"]}

镜像管理

kubernetes v1.17.6推荐的部署方式是使用镜像

kubernetes的master各个服务是运行在容器内的

镜像有多个,获取镜像的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 列出master所需镜像
kubeadm config images list
k8s.grc.io/kube-apiserver:v1.17.6
k8s.grc.io/kube-controller-manager:v1.17.6
k8s.grc.io/kube-scheduler:v1.17.6
k8s.grc.io/kube-proxy:v1.17.6
k8s.grc.io/pause:3.1
k8s.grc.io/etcd:3.4.3-0
k8s.grc.io/coredns:1.6.5

# 导入镜像
for i in $(ls kubernetes/v1.17.6/base-images)
do
docker load -i $i
done

# 改标签上传
docker tag k8s.grc.io/pause:3.1 192.168.1.100:5000/pause:3.1

docker push 192.168.1.100:5000/pause:3.1

# 查看
curl http://192.168.1.100:5000/v2/_catalog

安装master节点

kube-proxy代理

  • kube-proxy是什么

    kube-proxy是实现kubernetes service的通信与负载均衡机制的重要组件,是kubernetes的核心组件

  • kube-proxy代理模式

    kubernetes v1.0, 用户空间代理模式2

    kubernetes v1.1, iptables模式代理

    kubernetes v1.8, ipvs代理模式,如果不满足条件退回至iptables的代理模式

IPVS代理模式

  • 如何启用IPVS代理模式

  • 条件1:内核必须支持ip_vs,ip_vs_rr,ip_vs_wrr,ip_vs_sh,nf_conntrack_ipv4

  • 条件2:必须有ipvsadm和ipset软件包

  • 条件3:配置文件中开启IPVS参数

  • mode: ipvs

  • yum install -y ipvsadm ipset

应答文件

master必须能访问所有计算节点

配置/etc/hosts

  • 检测环境(排错)# 模拟安装

    kubeadm init –dry-run

  • 创建配置文件(应答文件)

    kubeadm config print init-defaults >kubeadm-init.yaml

1
2
3
4
5
6
7
8
9
10
11
12
06:	ttl: 24h0m0s						# token生命值
12: advertiseAddress: 192.168.1.21 # apiserver的IP地址
32:imageRepository: 192.168.1.100:5000 # 镜像仓库地址
34: kubernetesVersion: v1.17.6 # 当前安装的k8s版本
36: dnsDomain: cluster.local # 默认域名地址
37: podSubnet: 10.244.0.0/16 # 容器地址cidr,添加
38: serverSubnet: 10.254.0.0/16 # 服务地址cidr

--- # 启用ipvs模式
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

安装master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
kubeadm init --config=kubeadm-init.yaml


# 以下命令会输出
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config


# 查看状态
kubectl get componentstatuses
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-0 Healthy {"health":"true"}

# 查看版本
kubectl version
Client Version: version.Info{Major:"1",Minor:"17",GitVersion:"v1.17.6",......}

安装node节点

kubernetes node是计算节点

运行容器的实际节点

维护运行Pod,并提出具体应用的运行环境

node由kubelet,kube-proxy和docker组成

计算节点被设计为水平扩展,该组件在多个节点上运行

node节点服务

  • docker

    容器管理

  • kubelet

    主要负责监视指派到它的Pod,包括创建,修改,删除等

  • kube-proxy

    主要负责为Pod对象提供代理

    实现service的通信与负载均衡

Pod

Pod是什么

  • pod是kubernetes调度的基本单元
  • 一个Pod包含一个或多个容器
  • 这些容器使用相同的网络命名空间和端口号
  • Pod是一个服务的多线程的聚合单位
  • Pod作为一个独立的部署单位,支持横向扩展和复制

Pod的作用

  • 由若干容器组成的一个容器组
  • 每个组内容器共享一个存储卷(volume)
  • 每个Pod被分配到节点上运行直至运行结束或删除
  • 同个Pod下的容器使用相同的网络命名空间,IP地址,和端口区间相互之间能通过localhost来发现和通信

node安装

  • 初始化

    firewalld、swap、selinux、yum

1
2
3
4
5
6
7
8
9
10
11
12
systemctl disable --now firewalld

setenforce 0

swapoff -a

[yum]
baseurl=http://192.168.1.100/localrepo

yum install -y kubeadm kubelet docker-ce kubectl

systemctl enable --now kubelet docker
  • 安装IPVS模式软件包
1
yum install ipvsadm ipset -y
  • 配置docker私有仓库镜像和cgroup驱动(daemon.json)
1
2
3
scp master:/etc/docker/daemon.json  /etc/docker/daemon.json

systemctl restart docker
  • 配置内核参数(k8s.conf)
1
2
3
4
5
scp  master:/etc/sysctl.d/k8s.conf /etc/sysctl.d/k8s.conf

modprobe br_netfilter

sysctl --system
  • 配置host解析
1
scp  master:/etc/hosts /etc/hosts

安装命令(加入集群),当master节点安装完成后(kubeadm init –config=kubeadm-init.yaml)

最后一行会输出

kubeadm join 192.168.1.12:6442 –tocken <token> –discovery-tocken-ca-cert-hash sha256: <token ca hash>

Token

  • 如何获取token证书的hash

    –discovery-tocken-ca-cert-hash sha256: <token ca hash>

  • CA证书路径master:/etc/kubernetes/pki/ca.crt

  • 通过openssl指令获取(master)

1
2
3
4
5
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | \
openssl rsa -pubin -outform der | openssl dgst -sha256 -hex

writing RSA key
(stdin)= f46ddwi84jrf0984tjn3obla34u458iw45u9nfd923n5921j

token管理

  • 列出所有token

    kubeadm token list

  • 删除指定token

    kubeadm token delete <token名>

  • 创建token

    kubeadm token create –ttl=0 –print-join-command

    ttl=0:永久有效

    print:打印命令

node加入集群

1
2
3
4
5
6
kubeadm join 192.168.1.12:6442 --tocken <token名> \
--discovery-tocken-ca-cert-hash sha256: <token ca hash>


# 加入失败,执行重置命令,检查配置无误后,再次加入
kubeadm reset

安装Flannel插件

flannel网络

flannel 是什么

flannel实质上是一种“覆盖网络(overlay network)”, 也就是将TCP数据包装在另一种网络包里面的进行路由转发和通信,目前已经支持UDP, VxLAN, AWS VPC和GCE路由等数据转发方式

  • 使用flannel目标

    不同主机内的容器实现互联互通

转发原理

3.png

flannel镜像

安装flannel

  • 导入镜像到私有仓库
1
2
3
4
5
docker load -i flannel.tar.gz

docker tag quay.io/coreos/flannel:v0.12.0-amd64 192.168.1.100:5000/flannel:v0.12.0-amd64

docker push 192.168.1.100:5000/flannel:v0.12.0-amd64
  • 修改kube-flannel.yaml
1
2
3
4
5
6
7
128: "Network":"10.244.0.0/16" # 修改为PodSubnet地址

172: image: 192.168.1.100:5000/flanner:v0.12.0-amd64

186: image: 192.168.1.100:5000/flanner:v0.12.0-amd64

227~结尾: 全部删除
  • 安装并验证
1
2
3
4
5
6
7
8
# 只需在master安装,其他节点就会自动完成适配
kubectl apply -f kube-flannel.yml

# 等待十几秒,node状态就会变成Ready
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 26h v1.17.6
node Ready <none> 152m v1.17.6

kubectl命令

语法格式

  • kubectl [command] [TYPE] [NAME] [flags]

    command: 子命令,如create,get,describe,delete

    type:资源类型,可表示为单数,复数或缩写形式

    name:资源名称,如果省略,则显示所有资源信息

    flags:指定可选标志,或附加的参数

kubectl get

  • kubectl get 查询资源

    get node 查询节点

    get deployment 查询资源

    get pod 查询pod容器

    get pod -o wide 查询pod详细信息

命名空间

系统默认含有的命名空间

  • default默认的命名空间,不声明命名空间的POD都在

  • kube-node-lease为高可用提供心跳监视的命名空间

  • kube-public公共数据,所有用户都可以读取它

  • kube-system系统服务对象所使用的命名空间

  • 查看命名空间

    kubectl get namespace

  • 查看命名空间中的资源

    kubectl get pod -n 命名空间

查看资源类型模板

  • kubectl explain DaemonSet –recursive 可查看模板
  • kubectl api-resources 可以查看资源的kind
  • kubectl edit DaemonSet kube-proxy 可修改调度

排错常用命令

kubectl get

  • 查看资源基础信息

    kubectl get 资源类型

kubectl describe

  • 查看资源详细信息

    kubectl describe 资源类型 资源名称

kubectl logs

  • 查看容器运行日志

    kubectl logs 资源名称

Pod与控制器

创建容器

  • kubectl run

  • 语法格式

    kubectl run 资源名称(自定义) -i -t –image=私有仓库镜像名称:标签

资源控制器

  • Deployment资源控制器
  • Deployments为RS提供滚动更新
  • ReplicaSet 资源控制器(RS)
  • ReplicaSet 创建POD
  • ReplicaSet 可以扩容和缩容
  • POD 最小的管理单位
  • POD 负责启动和运行容器

4.png

POD概述

  • POD是kubernetes中最小的管理元素
  • Pod可以理解为linux命名空间的联合
  • 同一个Pod共享进程(PID)
  • 同一个Pod共享网络ip及权限(NETWORK)
  • 同一个Pod共享IPC通信信号(IPC)
  • 同一个Pod共享主机名称(UTS)

pod创建过程

5.png

pod生命周期

  • Pod对象自从其创建开始至其中止退出的时间范围称为其生命周期。在这段时间中,Pod会处于多种不同状态,并执行一些操作;
  • 其中,创建主容器(main container)为必须的操作,其他可选的操作还包括运行初始化容器(init container),容器启动后钩子(post start hook),容器存活性探测(liveness probe),就绪性探测(readiness probe)以及容器终止前钩子(pre stop hook)等。
  • 这些操作是否执行取决于Pod的定义

pod启动过程

6.png

pod phase

  • pod的status 字段是一个podstatus的对象,pod对象总是应该处于其生命进程中以下介个相位(phase)之一。

  • Pending容器创建过程中,但它尚未被调度完成

  • Running所有容器都已经被kubelet创建完成

  • Succeeded所有容器都已经成功终止并不会被重启

  • Falied Pod中所有容器中至少有一个容器退出是非0状态

  • Unknown无法正常获取到Pod对象的状态信息

7.png

pod特点

  • pod的生命周期是短暂的,用后即焚的实体

  • 注意:重启POD中容器跟重启POD不是一回事,POD只提供容器的运行环境并保持容器的运行状态,重启容器不会造成POD重启。

    pod不会自愈,如果pod运行的node故障,或者是调度器本身故障,这个pod就会被删除

    控制器(Deployment/RC/RS)可以创建和管理多个Pod,提供副本管理,滚动升级和集群级别的的自愈能力

进程容器

  • kubectl exec
  • 启动新命令,进入一个正在运行的容器
  • kubectl exec -it 容器id – 执行命令(/bin/bash)

删除容器

  • 删除资源
  • kubectl delete 资源类型 资源名称

yaml资源文件

资源对象文件

什么是资源文件对象文件

  • kubernetes通过RC/RS管理POD,在RC中定义了如何启动POD,如何运行,启动几副本等功能
  • 如果我们创建的文件,在其中使用yaml的语法格式描述了上面的信息,这个文件就是我们的资源对象文件

资源对象文件有什么用

  • 可以创建,删除,管理资源对象
  • 很多高级的复杂的功能靠简单的命令方式无法实现,这些都需要使用资源对象文件

POD资源文件样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
apiVersion: v1
kind: Pod
metadata:
name: pod-example
labels:
app: myweb
spec:
containers:
- name: apache
image: 192.168.1.100:5000/myos:httpd
ports:
- porotocol: TCP
containerPort: 80

Deployment资源文件

1
2
3
4
5
6
7
8
9
10
11
12
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-example
spec:
selector:
matchLabels:
app: myapp
replicas: 1
template:
... ... # 以下为POD的定义

标签和选择器

为了建立控制器和pod间的关联,kubernetes先给每个pod打上一个标签(label),然后在给相应的的位置定义标签选择器(Label Selector),引用这些标签

1
2
3
4
5
6
7
8
... ...
metadata:
labels: # 声明标签
app: nginx
... ...
selector: # 声明标签选择器
app: nginx
... ...

使用资源文件管理对象

  • cteate|apply创建/声明更新 资源对象 #创建只能执行一次,声明更新可重复执行
  • delete删除资源对象
  • kubectl (apply|creat|delete)-f 资源文件

查看资源对象文件

  • 查看对象文件一般由用户根据需求编写
  • 我们也可以查询一个资源对象文件
  • 格式包含json、yaml
  • kubectl get 资源对象 资源名称 -o 格式

deployment控制器

deployment案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache-example
spec:
selector:
matchLabels:
app: myapp-apache
replicas: 1
template:
metadata:
labels:
app: myapp-apache
spec:
containers:
- name: apache
image: 192.168.1.100:5000/myos:httpd
ports:
- protocol: TCP
containerPort: 80

nodeName标签

  • 容器创建是随机的,如何选择固定的宿主机
  • 使用nodaName标签根据节点名称选择宿主机

注意:如果添加了选择标签,但无法使用该主机,POD将一直处于Pending状态

1
2
spec:		# POD.SPEC标签
nodeName: node # 直接指定node主机名称

nodeSelector标签

  • 如何选择一类宿主机
  • 需要提前为目标主机打上特定的标签(可以是多台)
  • 在资源文件中根据标签选择宿主机(更加灵活)
1
2
3
spec:		# POD.SPEC标签
nodeSelector:
disktype: ssd # node标签(key:value自定义)

node设置标签

nodeSelector是节点选择约束的最简单推荐形式

我们可以给节点打上标签,根据标签来选择需要的节点

  • 查看标签

    kubectl get node –show-labels

  • 设置标签

    kubectl label nodes <node-name> <label-key>=<lable-value>

  • 删除标签

    kubectl label nodes <node-name> <lable-key>-

集群扩容

replicas决定了集群pod的数量

创建一个单字节的web容器

  • kubectl apply -f web-exampie.yaml

在集群运行过程中我们可以动态调整集群pod的数量

修改服务配置,及时生效

  • kubectl edit deployments.apps web-example

  • scale命令

    kubectl scale deployments.apps web-example –replicas=3

    需要清理之前设置的标签

亲和与反亲和

  • 高级调度策略–亲和与反亲和(扩展知识)
  • 亲和可以理解为偏爱喜好,同样反亲和可以理解为不喜欢
  • 在kubernetes中亲和在pod.spec.affinity中设置
  • 从亲和的对象又可以分为(节点亲和)和(容器亲和)
  • 从亲和的策略又可以分为(硬亲和)和(软亲和)
  • 手册地址:https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/

DaemonSet控制器

DaemonSet控制器介绍

  • DaemonSet每个机器都要启动运行的Pod,确保全部或一些Node上运行Pod副本
  • 当有node加入集群时,也会为它新增pod副本,当node从集群移除时,这些pod也会被回收
  • 删除DeamonSet时将删除所有它创建的pod副本
  • 典型应用:ceph节点,监控节点,filebeat日志收集等
  • 系统服务kube-proxy和flannel就是这种类型

DaemonSet案例

daemonset与deployment非常相似,区别是不需要设置replicas,因为daemonset是每节点都启动的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-example
namespace: default
spec:
selector:
matchLabels:
app: myweb
template:
metadata:
labels:
app: myapp-apache
spec:
containers:
- name: apache
image: 192.168.1.100:5000/myos:httpd
ports:
- protocol: TCP
containerPort: 80

pod部署策略

我们会发现一个有趣的现象

daemonset会调度到除了master以外的所有的节点

master节点除了一些系统服务以外不会有其它pod

为什么其他pod不会在master上部署?

污点与容忍

污点

污点标签

  • NoSchedule不会被调度
  • PreferNoSchedule尽量不调度
  • NoExecute驱逐节点

查看污点标签

  • kubectl describe node 节点名
  • kubectl describe node master

设置标签污点

  • kubectl taint node node-0001 key=value:NoSchedule

删除污点标签

  • kubectl taint node node-0001 key=value:NoSchedule-

查看污点标签

  • kubectl describe nodes | grep -P “^Taints”

容忍

  • 容忍污点(扩展知识)

某些时候我们需要无视污点标签进行操作,这种方式对称为污点的容忍

污点容忍文档:https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/

1
2
3
4
5
6
7
... ...			# POD.SPEC添加容忍策略
tolerations: # 声明容忍规则
- key: "node-role.kubernetes.io/master" # 键key
operator: "Equal" # Equal完全匹配,Exists键存在即可
value: "" # 值value
effect: "NoChedule" # 容忍策略
... ...

Job控制器

job控制器介绍

  • Job控制器可以理解为定时任务

  • Job单任务控制器,负责执行一次任务,保证任务在一个或多个pod上执行成功

  • 高级的CronJob重复多次任务控制器

    基于时间管理的Job,是在特定时间内自动创建Job

    典型用法:周期性计划任务

单次任务

  • yaml案例
1
2
3
4
5
6
7
8
9
10
11
12
13
---
apiVersion: batch/v1
kind: Job
metadata:
name: job-example
spec:
template:
spec:
containers:
- name: echo-hello
image: 192.168.1.100:5000/myos:v1804
command: ["echo","hello"]
restartPolicy: OnFailure # 重启策略,只支持[OnFailure,Never]
  • kubectl logs job-example # 查询返回结果

计划任务

  • cronjob任务的本质是多次创建job
  • 在job中会保留最后三次的状态,其他会被清除
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-example
spec:
schedule: "*/1 * * * *" # 定义周期时间[分,时,日,月,周]
jobTemplate:
spec:
template:
spec:
containers:
- name: echo-hello
image: 192.168.1.100:5000/myos:v1804
command: ["echo","hello"]
restartPolicy: OnFailure

服务与负载均衡

使用之前的yaml创建一个2副本的pod,

当我们delete一个pod后,发现它会自动重建,

并随机分配到集群中的任意节点上,每次重建IP都会发生变化。

service服务

会变化的pod(指重建后IP会变化)给我们访问带来了非常多的不便

  • service就是解决这一问题的方法
  • service会创建一个cluster ip,这个地址对应资源地址,不管pod如何变化,service总能找到对应的pod,且cluster ip保持不变,如果由pod对应多个容器,service会在多个容器间实现负载均衡
  • service通过IPTABLES/LVS规则将访问的请求最终映射到pod容器内部服务上

servicie服务资源文件

1
2
3
4
5
6
7
8
9
10
11
12
13
---
apiVersion: v1
kind: Service
metadata:
name: apache-service
spec:
ports:
- protocol: TCP
port: 80 # 开放在前端的访问端口
targetPort: 80 # 目标主机端口
selector:
app: myapache
type: ClusterIP

服务端口

  • port: service暴露在cluster ip上的端口,是提供给集群内部客户访问service的入口,供集群内部服务访问使用

  • targetPort:是pod上容器服务监听的端口,从port或nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort进入容器,从而达到访问pod容器内服务的目的

服务自动发现

创建/查询服务

  • 创建服务:kubectl apply -f 资源文件
  • 查询服务可以使用:kubectl get service
  • curl http://10.103.57.47 #访问

服务自动发现

  • cluster ip是集群分配的服务的IP,供集群访问,在集群内部也可以通过服务的名称访问,服务的名称是通过coredns解析的,每个服务在创建的过程中都会完成自动注册
  • 服务名称:<服务名称>.<名称空间>.svc.cluster.local
  • 在master应答文件中定义了serviceSubnet: 10.254.0.0/16
  • ping my-service.default.svc.cluster.local查看cluster ip

service服务验证

  • 访问服务(Cluster IP)
  • 集群内可以直接访问服务,但集群外无法访问服务
1
2
3
4
5
6
7
# 集群外无法直接访问
curl -m 2 http://10.254.146.37/

# 进入集群
kubectl run test -it --image=192.168.1.100:5000/myos:v1804

curl -m 2 http://10.254.146.37/

多资源文件

多个资源文件可以写到同一个yaml文件中,使用---分割

1
2
3
4
5
6
7
8
9
10
11
12
13
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: apache
... ...

---
apiVersion: v1
kind: Service
metadata:
name: http-service
... ...

服务原理解析

代理模式种类

  • kubernetes v1.0服务支持userspace代理模式
  • kubernetes v1.1服务支持iptables代理模式
  • kubernetes v1.8服务支持ipvs代理模式

在kubenetes v1.2中,kube-proxy的iptables模式成为默认设置,现在默认使用ipvs,如果不满足要求退回至iptables的代理模式

userspace模式

8.png

iptables模式

9.png

ipvs模式

10.png

服务类型

Service允许指定一个Type类型的,默认是ClusterIP

  • ClusterIP:通过集群内布的IP暴露服务,服务只能在集群内部可以访问,也就是默认的ServiceType。

  • NodePort:通过每个node上的ip和静态端口(NodePort)暴露服务。NodePort服务会路由到ClusterIP服务。

  • LoadBalancer:使用云提供商的负载均衡器,外部的负载均衡器可以路由到NodePort服务和ClusterIP服务。

对外发布服务

我们之前构建的服务已经可以在集群内部运转起来了,但集群外还无法访问集群内部的服务

有时候,服务可能来自第三方或其他团队,我们无法把所有服务都放入集群内部,这时候我们就需要集群内部和集群外部的服务能够实现互访

  • LoadBalancer:使用外部的云服务(需要支持,externallPs)

  • nodePort:基于端口对外提供服务(四层)

  • Ingress:使用ingress控制器(七层)

nodePort服务

  • 资源文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
apiVersion: v1
kind: Service
metadata:
name: apache-service2
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30001
selector:
app: myapache
type: NodePort

访问nodePort

  • nodePort开放的端口所有node均可访问
1
2
3
4
5
6
kubectl get service web-service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGS SELECTOP
web-service NodePort 10.254.232.91 <none> 80:30001/TCP 11s run=apache
# 80是targetPort,30001是NodePort

curl http://node:30001/

Headless服务

  • 要是不需要或者不想要负载均衡,以及单独的service IP。遇到这种情况,我们可以创建Headless服务

  • Headless服务会把ip通过多个A记录的形式解析到具体的容器ip上面,多用于状态的服务

1
2
3
4
5
6
dig -t all hl-service.default.svc.cluster.local
... ...
;;ANSWER SECTION:
hl-service.default.svc.cluster.local. 30 IN A 10.244.1.41
hl-service.default.svc.cluster.local. 30 IN A 10.244.6.34
... ...

Headless服务资源文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
---
apiVersion: v1
kind: Service
metadata:
name: apache-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: myapache
type: ClusterIP
clusterIP: None

Ingress控制器

Ingress介绍

Ingress本质上也是一种负载均衡

  • Ingress公开从集群外部到集群内service路由
  • 可以将Igress配置为提供服务外部可访问的URL、负载均衡流量
  • Ingress控制器通常由负载均衡器来实现
  • 必须具有ingress控制器才能满足ingress要求,仅创建资源无效
  • 与nodeport不同nodeport是在所有节点都可访问,而ingress在哪个节点发布,那个节点才能访问

Ingress架构

11.png

Ingress安装配置

1
2
3
4
5
6
7
8
# 修改mandatory.yaml
image:192.168.1.100:5000/nginx-ingress-controller:0.30.0

kubectl create -f ingress/mandatory.yaml

kubectl -n ingress-nginx get pod
NAME READY STATUS RESTARTS AGE
nginx-ingress-xxx 1/1 Runing 0 50m

向外发布服务

通过ingress向外发布集群内服务

1
2
3
4
5
6
7
8
9
10
11
---
apiVersion: extensions/v1bate1
kind: Ingress
metadata:
name: my-app
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
backend:
serviceName: apache-service
servicePort: 80

验证服务

  • 查询验证
1
2
3
4
kubectl get ingress

NAME HOSTS ADDRESS PORTS AGE
my-app * 192.168.1.31 80 16s

多域名发布

  • ingress本质是nginx/haproxy实现的负载均衡
  • ingress可以设置七层规则,例如根据域名选择服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-app
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: apache.tedu.local
http:
paths:
- path: /
backend:
serviceName: web-apache
serviPort: 80
- host: nginx.tude.local
http:
paths:
- path: /
backend:
serviceName: web-nginx
servicePort: 80

ConfigMap映射

ConfigMap是Pod中映射(文件/目录)的一种方式,允许你将配置文件与镜像文件分离,使容器化的应用程序具有可移植性。

在日常工作中经常需要修改各种配置文件的参数,数据库的地址,用户名密码等,这些操作在容器内非常麻烦,POD在重启或迁移的时候又会恢复到初始的状态,使用ConfigMap就可以解决这样的问题。

集群架构

12.png

ConfigMap应用案例

  • nginx需要修改配置文件才能支持php
  • 解决方案:configmap
  • nginx如何访问php服务
  • 解决方案:同一个pod中共享网络命名空间
1
2
3
kubectl cp nginx-pod:/usr/local/nginx/conf/nginx.conf nginx.conf

vim nginx.conf # 配置动静分离

定义ConfigMap

  • configMap可以映射单一文件,也可以映射一个目录
  • 创建cinfigmap
  • kubectl create configmap 名称(自定义) –from-file=文件路径
1
2
3
4
5
6
kubectl create configmap nginx-conf --from-file=nginx.conf

kubectl get configmap nginx-conf

NAME DATA AGE
nginx-conf 1 10s

加载configmap的配置

  • 资源文件
  • 在配置容器的地方引用刚刚加载的configmap配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
... ...
spec: # pod.spec
volumes:
- name: nginx-php
configMap:
name: nginx-conf
containers:
- name: php-fpm
image: 192.168.1.100:5000/myos:php-fpm
- name: nginx
image: 192.168.1.100:5000/myos:nginx
ports:
- protocol: TCP
containerPort: 80
volumeMounts:
- name: nginx-php
subPath: nginx.conf # 单一文件路径(没有该选项就是目录)
mountPath: /usr/local/nginx/conf/nginx.conf

执行资源文件访问测试

1
2
3
4
5
6
7
kubectl apply -f web.yaml

kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP
myweb-xx 2/2 Running 0 30s 10.244.1.44

curl http://10.244.1.44/info.php

存储卷

容器磁盘上的文件的生命周期是短暂的,这就使得容器在运行一些重要应用时会出现一些问题。首先,当容器崩溃时,kubelet会重启它,但是容器中的文件将丢失——容器以最干净的状态(镜像最初状态)重新启动。其次,在pod中同时运行多个容器时,这些容器通常需要共享文件。kubernetes中Volume抽象就很好的解决了这些问题。

存储卷类型

所有 类型
awsElasticBlockStore downwardAPI glusterfs projected
azureDisk empthDir hostPath quobyte
azureFile fc iscsi rbd
cephfs flexVolume nfs scalelO
cinder flocker persistentVolumeClaim secret
configMap gcePersistenDisk photonPersistenDisk storageos
sci gitRepo portworxVolume vsphereVolume

卷类型案例

empthDir

最基础的volume类型,用于存储临时数据的简单空目录。如果pod设置了emptyDir类型volume,pod被分配到node上的时候,会创建emptyDir,只要pod运行在node上emptyDir都会存在(容器挂掉不会导致emptyDir丢失数据),但是如果pod从node上被删除(pod被删除或者发生迁移),emptyDir也会被删除,并且永久丢失。

emptyDir可以实现同一个pod中的数据共享

emptyDir常用来存放缓存数据

1
2
3
4
5
6
7
8
9
... ...
volumes:
- name: empth-data
empthDir: {}
... ...
volumeMounts:
- name: empth-data
mountPath: /var/cache
... ...

hostPath

映射node文件系统中的文件或者目录到pod里。在使用hostPath类型的存储卷时,也可以设置type字段,支持的类型有文件,目录,file,Socket,CharDevice和BlockDevice。

注意事项:配置相同的pod,可能在不同的node上表现不同,因为不同节点上映射的文件不同。

hostPath里面的数据不会随着pod的结束而消失

hostPath常用来分布式节点的存储目录,或日志存放目录。

1
2
3
4
5
6
7
8
9
10
11
... ...
volumes:
- name: my-data
hostPath:
path: /var/webroot
type: DirectoryOrCreate
... ...
volumeMounts:
- name: my-data
mountPath: /var/www/html
... ...

持久卷

在生产环境中通常需要多个pod或多个APP共享数据,而这些应用又在不同机器的不同pod里,网络文件系统通常用来解决这一问题

kubernetes中通过简单的配置就可以挂载到NFS(网络文件系统)到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持并发写操作

当然cephfs、glusterfs等都能很好的解决这个问题,我们以NFS为例

pv/pvc

  • persistentVolume(持久卷,简称PV)
  • PV是资源的提供者,根据集群的基础设施变化而变化,有k8s集群管理员配置
  • persistent VolumeClaim(持久卷声明,简称PVC)
  • 而PVC是资源的使用者,根据业务服务需求变化来配置
  • PV/PVC的引入是k8s集群具备了存储的逻辑抽象能力

配置NFS服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 节点192.168.1.100
yum install -y nfs-utils

mkdir -m 777 /var/webroot

vim /etc/exports
/var/webroot *(rw)

systemctl start nfs

# 其他节点调用
yum install -y nfs-utils

showmount -e 192.168.1.100
Export list for 192.168.1.100
/var/webroot *

配置PV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
volumeMode: Filesystem
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany #ReadWriteMany/ReadWriteOnce/ReadOnlyMany
persistentVolumeReclaimPolicy: Retain # Retain/Delete
nfs:
path: /var/webroot
server: 192.168.1.100

配置PVC

1
2
3
4
5
6
7
8
9
10
11
12
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-nfs
spec:
volumeMode: Filesystem
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi

应用配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
... ...
spec:
volumes:
- name: site-data
persistentVolumeClaim:
claimName: pvc-nfs
containers:
- name: nginx-app
image: myos:nginx
ports:
- protocol: TCP
containerPort: 80
volumeMounts:
- name: site-data
mountPath: /var/webroot

资源利用率监控

metrics

  • metrics是一个监控系统资源使用的插件,可以将空node节点上的cpu,内存使用率,或pod对资源的占用率,通过对资源占用的了解,可以更加合理的部署容器应用

  • metrics从kubernetes 1.8开始,资源使用情况的监控可以通过Metrics API的形式获取,具体的组件为Metrics Server,用来替换之前的heapster,heapster从1.11开始逐渐被放弃

查看资源占用情况

1
2
kubectl top node
Error from server (NotFound): the server could not find the requested resource (get services http:heapster)
  • metric-server是扩展的apiserver,依赖于kube-aggregator,因此需要apiserver中开启相关参数,开启聚合API

    –enable-aggregator-routing=true

  • 修改api-server启动参数

1
2
3
4
5
vim /etc/kubernetes/manifests/kube-apiserver.yaml

# spec.container.command中添加

- --enable-aggregator-routing=true
  • 验证配置
1
2
3
systemctl restart kubelet

kubectl -n kube-system get pod kube-apiserver-master -o yaml | grep enable-aggregator-routing

kubelet证书

metrics使用kubelet证书,为kubelet签发证书

  • 在/var/lib/kubelet/config.yaml配置文件中添加

  • serverTLSBootstrap: true

  • 重启服务,等待几分钟后就看到了

  • 包括master在内的所有节点都需要做

查看证书

1
2
3
4
kubectl	get	certificatesigningrequests
NAME AGE REQUESTOR CONDITION
csr-nvd65 8m system:node:master Pending
csr-t5fvc 5m2s system:node:node Pending

签发证书

  • 看到pending的状态后我们就可以签发证书了
  • 证书只能在master上签发
  • kubelet certificate approve证书名称
1
2
3
4
5
6
7
8
kubectl certificate approve csr-nvd65

kubectl certificate approve csr-t5fvc

kubectl get certificatesigningrequests
NAME AGE REQUESTOR CONDITION
csr-nvd65 8m system:node:master Approved,Issued
csr-t5fvc 5m2s system:node:node Approved,Issued

安装metrics-server

  • 官网https://github.com/kubernetes-sigs/metrics-server

  • 下载镜像和资源文件,导入私有仓库

  • 镜像导入私有仓库

  • 安装metrics-server

    rabc.yaml授权控制器

    pdb.yaml中断控制器

    deployment.yaml主进程metrics

    service.yaml后端是metrics主进程的服务

    apiservice.yaml注册集群API

  • 编辑deployment.yaml

    image:替换称私有仓库

  • 依次安装资源对象

1
2
3
4
5
kubectl apply -f rbac.yaml
kubectl apply -f pdb.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f apiservice.yaml

查询资源

  • 查询内存、cpu使用情况
1
2
3
4
5
kubectl top node

NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 73m 3% 1196Mi 68%
node 20m 1% 729Mi 41%

Dashboard管理

Dashboard是基于网页的kubernetes用户界面。你可以使用Dashboard将容器应用部署到kubernetes集群中,也可以对容器应用排错,还能管理集群资源。你可以使用Dashboard获取运行在集群中的应用的概览信息,也可以创建或修改kubernetes资源(如Deployment,Job,DaemonSet等等)

Dashboard同时展示了kubernetes集群中的资源状态信息和所有报错信息

dashboard镜像

dashboard安装

  • 在docker中导入镜像,并上传到私有仓库
  • dashboard.tar.gz镜像
  • metrics-scraper.tar.gz收集metrics监控信息插件
  • metrics-scraper插件

kubernetes Dashboard从v2.0.0-beta1版本开始,集成了一个metrics-scraper的组件,可以通过kubernetes的metrics API收集一些资源的监控信息,并在web页面显示

  • 配置资源文件
1
2
3
image: 192.168.1.100:5000/dashboard:v2.0.0

image: 192.168.1.100:5000/metrics-scraper:v1.0.4

发布到nodeport

1
2
3
4
5
6
7
8
9
10
11
12
13
vim recommended.yaml

... ...
spec:
ports:
- port: 443
targetPort: 8443
nodePort: 30090
selector:
k8s-app: kubernetes-dashboard
type: NodePort

kubectl apply -f recommended,yaml

13.png

认证登录

  • admin-token.yaml

    创建用户管理admin-user

    绑定为集群管理角色

1
2
3
4
5
6
7
8
vim admin-token.yaml

---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-adshboard
  • admin-token资源文件
1
2
3
4
5
6
7
8
9
10
11
12
13
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
  • 查询token登录
1
2
3
4
5
6
7
8
kubectl -n kubernetes-dashboard get secrets

NAME TYPE
admin-user-token-xx kubernetes.io/service-account-token

kubectl -n kubernetes-dashboard describe secrets admin-user-token-xx

token:eyJhbGciOiJSUzl1NilslmtpZCI6ljJyTE9nZWpWLWFhTXV6cnJla3U4aXNngxVTZV2M5Y0FYOWRancifQevJpc3MiOiJrdWJicm5idGVzL3NIcnZpY2VhY2NvdW501iwia3VizXJuZXRIcy5pby9zZXJ2aWNIYWNjb3VudC9

Prometheus安装

prometheus是SoundCloud公司开发的一个监控系统和时间序列数据库,许多公司接受和采用prometheus,之后他们便将它独立成开源项目,并且用公司运作,该项目有非常活跃的社区和开发人员,2016年prometheus加入了云计算基金会,成为kubernetes之后的第二个托管项目。

下载最常见的k8s容器管理系统中,通常搭配prometheus进行监控,可以把它看成google BorgMon监控的开源版本。

prometheus的主要特点

  • 自定义多维数据模型
  • 非常高效的存储 平均一个采样数据占 -3.5bytes左右
  • 在多维度上灵活且强大的查询语言(PromQ)
  • 不依赖分布式存储,支持单主节点工作通过基于HTTP的pull方式采集时序数据通过push getway进行时序数据推送(pushing)可以通过服务发现或者静态配置去获取要采集的目标服务器多种可视化图标及仪表盘

部署架构

14.png

prometheus组成

  • Prometheus Server:对监控数据的获取,存储以及查询
  • Exporters:采集node节点的数据提供给Prom Server
  • metrics-state:获取各种资源的最新状态(pod,deploy)
  • adapter:获取APIServer的资源指标提供给Prom Server
  • Alert Manager:Prometheus体系中的告警处理中心
  • Grafana:支持多种图形化的Dashboard的展示
  • operator:以扩展kubernetes api的形式,帮助用户创建配置和管理复杂的有状态应用程序

安装Prometheus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 安装operator
vim setup/prometheus-operator-deployment.yaml
27: - --config-reloader-image=192.168.1.100:5000/configmap-reload:v0.3.0
28: - --prometheus-config-reloader=192.168.1.100:5000/prometheus-config-reloader:v0.35.1
29: image: 192.168.1.100:5000/promethues-operator:v0.35.1

kubectl apply -f setup/

# 安装prometheus server
vim prom-server/prometheus-prometheus.yaml
14: baseImage: 192.168.1.100:5000/prometheus
34: version: v2.11.0

kubectl apply -f prome-server/

# 安装prom-adapter
vim prom-adapter/prometheus-adapter-deployment.yaml
28: image: 192.168.1.100:5000/k8s-prometheus-adapter-amd64:v0.5.0

kubectl apply -f prom-adapter

# 安装metrics-state
vim metrics-state/kube-state-metrice-deployment.yaml
24: image: 192.168.1.100:5000/kube-rbac-proxy:v0.4.1
41: image: 192.168.1.100:5000/kube-rbac-proxy:v0.4.1
58: image: 192.168.1.100:5000/kube-state-metrics:v1.9.2

kubectl apply -f metrics-state/

# 安装node-exporter
vim node-exporter/node-exporter-daemonset.yaml
27: image: 192.168.1.100:5000/node-exporter:v1.0.0
57: image: 192.168.1.100:5000/kube-rbac-proxy:v0.4.1

kubectl apply -f node-exporter/

# 安装alertmanager
vim alertmanager/alertmanager-alertmanager.yaml
09: baseImage: 192.168.1.100:5000/alertmanager
18: version: v0.18.0

kubectl apply -f alertmanager/

# 安装grafana
vim grafana/grafana-deployment.yaml
19: - image: 192.168.1.100:5000/grafana:6.4.3

kubectl apply -f grafana/

发布Grafana服务

  • grafana默认的服务使用ClusterIP
  • 使用nodePort发布服务
1
2
3
4
5
6
7
8
9
10
11
12
13
vim grafana-service.yaml

... ...
spec:
type: NodePort
ports:
- name: http
port: 3000
nodePort: 30002
targetPort: http
... ...

kubectl apply -f grafana-service.yaml

浏览器访问

  • 192.168.1.21L:30002

15.png

  • 登录的默认用户(admin/admin)
  • 第一次登录需要修改密码
  • 选择数据源

16.png

1
2
3
kubectl -n monitoring get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
prometheus-k8s NodePort 10.254.44.72 <none> 9090:30001/TCP

17.png

  • 添加数据源

    名字随意

    URL填写Prometheus内部的DNS名称(prometheus.k8s:9090)

    默认端口9090

18.png

  • 导入模板

    正确配置后点击保存和测试后添加仪表盘

    输入模板ID

19.png

20.png

21.png

22.png

HPA控制器

Horizontal Pod Autoscaling,简称HPA,是kubernetes中实现POD水平自动伸缩的功能,HPA可以基于CPU利用率或其他应用程序提供的度量指标自动缩放POD的数量

pod水平自动伸缩性由kubernetes API资源和控制器实现。资源决定了控制器的行为。控制器会周期性的获取平均利用率,并与目标值相比较后来调整副本数量

限制:不适用于无法缩放的对象,比如DaemonSets

资源文件案例

  • 首先创建一个单pod的apache集群
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb
spec:
selector:
matchLabels:
app: apache
replicas: 1
template:
metadata:
labels:
app: apache
spec:
containers:
- name: apache
image: 192.168.1.100:5000/myos:httpd
ports:
- protocol: TCP
containerPort: 80
resources:
requests:
cpu: 200m
restartPolicy: Always

---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: apache
type: ClusterIP

HPA资源对象定义

1
2
3
4
5
6
7
8
9
10
11
12
13
---
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: myweb
spec:
minReplicas: 1
maxReplicas: 3
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myweb
targetCPUUtilizationPercentage: 50

验证HPA集群

  • 创建以后会有一个unknown不会立即生效,需要等待几分钟才能获取到CPU的信息,这是正常现象
1
2
3
4
5
6
7
8
9
10
kubectl get hpa

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
myweb Deploy/myweb <unkonwn>/50% 1 3 0 10s

# 等待几分钟
kubectl get hpa

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
myweb Deploy/myweb 3%/50% 1 3 0 10s

压力测试

持续访问Apache,增加CPU负载,在几分钟后会发现副本数量增加了

停止访问,让CPU空闲,副本不会立即释放,大约180~300秒后才开始释放副本,当副本达到最小保留数量以后停止释放pod

curl ‘http://192.168.1.21/info.php?id=200000'

  • ab压力测试
1
2
3
4
5
6
7
8
9
yum -y install httpd-tools

ab -c 10 -n 100 http://a.ilanni.com/index.php

-c 10表示并发用户数为10

-n 100表示请求总数为100

# http://a.ilanni.com/index.php表示请求的目标URL