栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

k8s:概念以及搭建高可用集群

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

k8s:概念以及搭建高可用集群

一、k8s概念和架构 1、k8s概述
  • k8s是谷歌在2014年开源的容器化集群管理系统
  • 使用k8s进行容器化应用部署
  • 使用k8s利于应用扩展
  • k8s目标实施让容器化应用程序更加简洁高效
2、特性

(1)自动装箱
(2)自我修复(自愈能力)
(3)水平扩展
(3)服务发现
(4)滚动更新
(5)版本回退
(6)密钥和配置管理
(7)存储编排
(8)批处理

3、k8s 集群架构节点角色功能 1、Master Node

k8s 集群控制节点,对集群进行调度管理,接受集群外用户去集群操作请求; Master Node 由
API Server:集群统一入口,以restfull方式交给etcd存储
Scheduler:节点调度,选择node节点应用部署
ClusterState Store(ETCD 数据库): 存储系统,用于保存集群数据
Controller MangerServer :处理集群中常规后台任务,一个资源对应一个控制器

2、Worker Node

集群工作节点,运行用户业务应用容器; Worker Node 包含
kubelet:master派到node节点的代表,管理本机容器如生命周期,容器的创建,容器的各种操作。
kube proxy :提供网络代理,可以实现负载均衡等
和 ContainerRuntime;

4、概念 1、pod
  • 部署的最小单元
  • 一组容器的集合
  • 共享网络
  • 生命周期是短暂的
2、controller
  • 确保pod中预期的副本数量
  • 无状态应用部署
  • 有状态应用部署
  • 确保所有的node都运行同一个pod
  • 一次性任务和定时任务
ReplicaSet:确保预期的Pod副本数量

Deployment:无状态应用(例如:web、nignx、apache、tomcat)

StatefulSet:有状态应用部署(例如:mysql)

有状态:该应用独一无二,无法重新创建进行完美替代,例如mysql、Oracle数据库
DaemonSet:确保所有的Node运行同一个Pod(把所有的Node设置为同一个命名空间)

Job:一次性任务(类似linux:at)

Cronjob:定时任务(类似linux:crontab)
3、service
  • 定义一组pod访问规则

二、从零搭建k8s集群

1、基于客户端工具kubeadm 1、使用的命令
  • kubect get nodes 查看所有的节点
  • kubectl get pod -n kube-system 查看是否runing状态
  • kubectl create deployment nginx --image=nginx 创建一个pod
  • kubectl get pod 查看是否runing状态
  • kubectl expose deployment nginx --port=80 --type=NodePort 暴露端口
  • kubectl get pod,svc 查看pod
  • kubectl get cs 检查状态
  • kubectl apply -f a.yaml 部署yaml文件
  • kubectl get csr 查看申请
  • kubectl logs --tail=200 --all-containers=true -f -n sip -lapp=contractmg
  • kubectl get pods -o wide 可以看到pod的ip等完整信息
kubectl get deploy 查看部署的资源


2、kubeadm部署

1、前置知识点

目前生产部署 Kubernetes 集群主要有两种方式:

  • (1)kubeadm Kubeadm 是一个 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部 署 Kubernetes 集群。 官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
  • (2)二进制包 从 github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。 Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可 控,推荐使用二进制包部署 Kubernetes 集群,虽然手动部署麻烦点,期间可以学习很 多工作原理,也利于后期维护。
2、kubeadm 部署方式介绍

kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具,这个工具能通 过两条指令完成一个 kubernetes 集群的部署: 第一、创建一个 Master 节点 kubeadm init 第二, 将 Node 节点加入到当前集群中 $ kubeadm join

3、安装要求

在开始之前,部署 Kubernetes 集群机器需要满足以下几个条件:

  • 一台或多台机器,操作系统 CentOS7.x-86_x64
  • 硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 30GB 或更多
  • 集群中所有机器之间网络互通 - 可以访问外网,需要拉取镜像
  • 禁止 swap 分区
4、最终目标
  • (1) 在所有节点上安装 Docker 和 kubeadm
  • (2)部署 Kubernetes Master
  • (3)部署容器网络插件
  • (4)部署 Kubernetes Node,将节点加入 Kubernetes 集群中
  • (5)部署 Dashboard Web 页面,可视化查看 Kubernetes 资源
5、准备环境


角色 IP
k8smaster 192.168.163.133
k8snode1 192.168.163.134
k8snode2 192.168.163.135

6、系统初始化 6.1 关闭防火墙:
$ systemctl stop firewalld 
$ systemctl disable firewalld
6.2 关闭 selinux:
$ sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久 
$ setenforce 0 # 临时
6.3 关闭 swap:
$ swapoff -a # 临时 
$ vim /etc/fstab # 永久
6.4 主机名:
$ hostnamectl set-hostname 
  • hostnamectl set-hostname k8smaster
  • hostnamectl set-hostname k8snode1
  • hostnamectl set-hostname k8snode2
6.5 在 master 添加 hosts:
$ cat >> /etc/hosts << EOF 
192.168.163.133 k8smaster 
192.168.163.134 k8snode1 
192.168.163.135 k8snode2 
EOF
6.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 # 生效
6.7 时间同步
$ yum install ntpdate -y 
$ ntpdate time.windows.com
7、所有节点安装 Docker/kubeadm/kubelet

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

(1)安装 Docker
$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
 
$ yum -y install docker-ce-18.06.1.ce-3.el7 

$ systemctl enable docker && systemctl start docker

$ docker --version
(2)添加阿里云 YUM 软件源

设置仓库地址

# cat > /etc/docker/daemon.json << EOF 
{ "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] }
EOF

添加 yum 源

$ cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] 
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 
enabled=1 
gpgcheck=0 
repo_gpgcheck=0 
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg 
EOF
(3)安装 kubeadm,kubelet 和 kubectl

由于版本更新频繁,这里指定版本号部署:

$ yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
$ systemctl enable kubelet
8、部署 Kubernetes Master (1)在 192.168.163.133(Master)执行

提供了一种在拉去镜像时指定镜像仓库的方法

kubeadm init --apiserver-advertise-address=192.168.163.133 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.22.3 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16

由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址。

(2)使用 kubectl 工具:

如果kubeadm reset后需要删除这个目录重新弄

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 nodes
9、安装 Pod 网络插件(CNI)
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/documentation/kube-flannel.yml

确保能够访问到 quay.io 这个 registery。如果 Pod 镜像下载失败,可以改这个镜像地址

10、加入 Kubernetes Node

在 192.168.163.134/135(Node)执行
向集群添加新节点,执行在 kubeadm init 输出的 kubeadm join 命令:

$ kubeadm join 192.168.31.61:6443 --token esce21.q6hetwm8si29qxwn  
--discovery-token-ca-cert-hash sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5
11、测试 kubernetes 集群

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

$ kubectl create deployment nginx --image=nginx 
$ kubectl expose deployment nginx --port=80 --type=NodePort 
$ kubectl get pod,svc

访问地址:http://NodeIP:Port。比如这里访问的http://192.168.163.134:30521

2、基于二进制包安装k8s 三、k8s核心概念 1、kubernetes 集群命令行工具 kubectl 1、kubectl 概述

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

2、kubectl 命令的语法

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




4、kubectl 子命令使用分类 (1)基础命令

(2)部署和集群管理命令

(3)故障和调试命令

(4)其他命令

2、kubernetes 集群 YAML 文件详解 1、YAML 文件概述

k8s 集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,也 就是可以把需要对资源对象操作编辑到 YAML 格式文件中,我们把这种文件叫做资源清单文 件,通过 kubectl 命令直接使用资源清单文件就可以实现对大量的资源对象进行编排部署 了。

2、YAML 文件书写格式

(1)YAML 介绍 YAML :仍是一种标记语言。为了强调这种语言以数据做为中心,而不是以标记语言为重点。 YAML 是一个可读性高,用来表达数据序列的格式。
(2)YAML 基本语法

  • 使用空格做为缩进
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • 低版本缩进时不允许使用 Tab 键,只允许使用空格
  • 使用#标识注释,从这个字符一直到行尾,都会被解释器忽略

(3)YAML 支持的数据结构

  • 对象
    键值对的集合,又称为映射(mapping) / 哈希(hashes) / 字典(dictionary)
  • 数组
    一组按次序排列的值,又称为序列(sequence) / 列表 (list)
  • 纯量(scalars)
    单个的、不可再分的值







3、资源清单描述方法

  • (1)在 k8s 中,一般使用 YAML 格式的文件来创建符合我们预期期望的 pod,这样的 YAML 文件称为资源清单。
  • (2)常用字段
    必须存在的属性

spec 主要对象




额外的参数

4、创建yaml方式 1、kubectl create

适合还没有部署的资源
将创建的过程写入my1.yaml
如果写错deployment就会报unknown flags --image 有坑

kubectl create demployment web --image=nginx  -o yaml --dry-run > my1.yaml
2、kubectl get

适合已经部署过的资源,从已经有的导出成yaml编排清单

kubectl get deploy  nginx -o=yaml --export > my2.yaml
3 、pod

1、Pod 概述

Pod 是 k8s 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最 小资源对象模型,也是在 k8s 上运行容器化应用的资源对象,其他的资源对象都是用来支 撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,k8s 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成 Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为”根容器“的 Pause 容器。Pause 容器对应的镜 像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器

  • (1) 最小的部署单元
  • (2)包含多个容器(一组容器的集合)
  • (3)一个pod容器共享网络命名空间
  • (4)pod是短暂的
2、存在的意义
  • (1)创建容器使用docker,一个docker对应一个容器,一个容器一个进程,是单进程设计,一个容器运行一个应用
  • (2)pod是多线程设计,运行多个应用程序,一个pod有多个容器,是容器的集合体
  • (3)pod是为了亲密性应用,两个应用之间交互, 网络之间调用,两个容器需要频繁调用
3、pod实现机制

  • (1)共享网络
    通过pause容器,把其他业务容器加入到pause容器里面,让所有的业务容器在一个名称空间中,可以实现网络共享
  • (2)共享存储
    引入数据卷概念volumn,使用数据卷进行持久化存储

4、Pod 特性 (1)资源共享
一个 Pod 里的多个容器可以***共享存储和网络***,可以看作一个逻辑的主机。共享的如 namespace,cgroups 或者其他的隔离资源。
 多个容器共享同一 network namespace,由此在一个 Pod 里的多个容器共享 Pod 的 IP 和 端口 namespace,所以一个 Pod 内的多个容器之间可以通过 localhost 来进行通信,所需要 注意的是不同容器要注意不要有端口冲突即可。不同的 Pod 有不同的 IP,不同 Pod 内的多 个容器之前通信,不可以使用 IPC(如果没有特殊指定的话)通信,通常情况下使用 Pod 的 IP 进行通信。 
 一个 Pod 里的多个容器可以**共享存储卷**,这个存储卷会被定义为 Pod 的一部分,并且可 以挂载到该 Pod 里的所有容器的文件系统上。
(2)生命周期短暂

Pod 属于生命周期比较短暂的组件,比如,当 Pod 所在节点发生故障,那么该节点上的 Pod 会被调度到其他节点,但需要注意的是,被重新调度的 Pod 是一个全新的 Pod,跟之前的 Pod 没有半毛钱关系。

(3)平坦的网络

K8s 集群中的所有 Pod 都在同一个共享网络地址空间中,也就是说每个 Pod 都可以通过其 他 Pod 的 IP 地址来实现访问

5、pod镜像拉取策略


imagesPullPolicy: [ Always| Never| IfNotPresent]
获取镜像的策略,默认值为 IfNotPresent 在宿主机不存在时拉取

6、pod资源限制

resources: 
	limits: //资源限制,容器的最大可用资源数量 
		cpu: Srting
		memory: string 
	requeste: //资源限制,容器启动的初始可用资源数量
		cpu: string 
		memory: string

7、pod重启策略

restartPolicy: [ Always| Never| OnFailure]
//重启策略,默认值为 Always

8、pod容器检查

1、 存活检查 livenessProbe

如果检查失败,将杀死容器,根据pod的restartPolicy来操作

2、就绪检查 readinessProbe

如果检查失败,kubernetes会把pod从service endpoints剔除

3、probe支持三种检查方法 1、httpGet

发送http请求,返回200-400范围状态码为成功

2、exec

执行shell命令返回状态码0位成功

3、tcpSocket

发起tcp Socket建立连接

9、pod调度策略 1、创建pod的流程

2、影响调度的属性
  • pod的资源限制
  • 节点选择器标签
spec:
	ndoeSelector:
		env_role=dev
	containers:
		- name: neginx
		 image: nginx:1.15
		
对节点创建标签,master上面设置
kubectl label node node1 env_role=prod

删除节点标签:后面的-表示将该标签删除
kubectl label node node1 env_role-
  • 节点亲和性
spec:
	affinity:
		nodeAffinity:
			requiredDruingSchedulingIgnoredDuringExecution:
				nodeSelectorTerms:
					- matchexpression:
						- key: env_role
						  operator: In
						  values:
						  	- dev
						  	- test
			preferredDuringSchedulingIgnoreDuringExecution:
				- weight: 1
				  preference:
				  	matchexpression:
				  		- key: group
				  		  operator: In
				  		  values:
				  		  	- otherprod
	containers:
		- name: webdemo
		  image: nginx

节点亲和性nodeAffinity和之前的nodeSelector基本一样,根据节点上标签约束来决定pod调度到哪个节点上,
硬亲和性:约束条件必须满足
软亲和性:尝试满足,不保证
支持的常用操作符:

In   NotIn  Exists   Gt   Lt   DoesNotExists

  • 污点和污点容忍性
    污点是节点属性,不是pod属性,不做普通的分配调度,
    使用场景比如专用节点,配置特点硬件节点,基于Taint驱逐
    污点的三个值:
    NoSchedule:一定不会被调度
    PreferSchedule : 尽量不被调度
    NoExecute:不会被调度,并且还会驱逐Nde已有的pod
(1)为节点添加污点
	kubectl taint node [node] key=value:污点三个值
(2)删除污点
例如:	kubectl taint node k8snode1 key:NoSchedule-  


污点容忍:就是配置内容

spec:
	tolerations:
		- kye: "key"
		  operator: "Equal"
		  value: "value"
		  effect: "NoSchedule"

4 、Conttroller


1、什么是controller

在集群上管理和运行容器的对象

2、Pod和Controller的关系

Pod是通过Controller实现应用的运维,比如弹性伸缩,滚动升级等

3、Pod和Controller是通过label建立关系的 4、deployment应用场景
  • 部署无状态应用
  • 管理pod和ReplicaSet
  • 部署,滚动升级等功能
  • 应用场景:web服务,微服务
5、使用deployment部署引用(yaml)

1、导出yaml文件
kubectl create deployment web --image=nginx --dry-run -o yaml > web.yaml
2、使用yaml部署应用
kubectl apply -f web.yaml
3、对外发布(暴露对外端口号)
kubectl expose deployment web --port=80 --type=NodePort --traget-port=80 --name=web1 -o yaml  > web1.yaml
4、查看应用运行状态
kubectl get pod,svc
6、deployment升级回滚和弹性伸缩 1、升级应用deployment 类型的controller nginx版本为1.15

kubectl set image deployment web  nginx=nginx:1.15   

2、查看升级的状态
kubectl rollout status deployment web

3、查看升级的历史版本
kubectl rollout history deployment web

4、回滚版本 1、回滚到上一个版本
kubectl rollout undo deployment web
2、回滚到指定版本
kubectl rollout undo deployment web --to-revision=2

5、弹性伸缩
kubectl scale deployment web --replicas=5
5、Service

1、存在的意义
  • 1、防止pod失联(服务发现)
  • 2、定义一组pod的访问规则(负载均衡)
    *
2、pod和service的关系

根据label和selector标签建立关联的

3、service常见的三中类型
  • ClusterIP 默认,集群内部使用
  • NodePort 对外访问应用使用
  • LoadBalancer 对外访问应用使用,公有云

    node内网部署应用,外网一般不能访问到,
    方法:
    1 找到一台可以进行外网访问机器,安装nginx,反向代理,手动把可以访问的节点添加上

2 loadBalancer公有云,把负载均衡,控制器

4、无状态,有状态部署

(1) 无状态:
认为pod都是一样的 ,使用kubectl get pods -o wide 查看pod的ip地址,ip是不一样的,每个pod内统一用一个ip
没有顺序要求
不用考虑哪个node运行
随意伸缩和扩展
(2)有状态
上面因素都需要考虑
让每个pod独立 ,保持pod启动顺序和唯一性
(唯一性网络标识符,持久存储
有序,比如mysql主从)

5、部署有状态应用 1、无头service 就是ClusterIp为None


2、SatefullSet部署有状态应用

3、查看pod有三个副本,没有名次不一样

deployment和satefullSet区别:有身份(唯一标识),根据主机名+按照一定规则生成域名

域名规则:
主机名称.service名称.名称空间.svc.cluster.local

4、查看创建无头的service

5、sts.yaml文件内容
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

---

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

6、部署守护进程,确保所有node在一个pod运行,DamonSet

在每个node上运行一个pod,新加入的node也同时运行在一个pod里面
例子:

为每个mode节点安装数据采集工具

7、一次任务job 1、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

2、部署
kubectl apply -f job.yaml

3、删除:job

8、定时任务 1、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


2、部署
kubectl apply -f cronjob.yaml

3、查看
kubectl get pods -o wide

4、查看日志
kubectl logs 容器名称

5、删除
kubectl delete -f cronjob.yaml

6、secret

加密: echo -n ‘admin’ | base64
解密:echo -n ‘fewfewf’ | base64 -d

作用:加密数据存储在etcd里面,让pod容器以挂载volmn方式进行访问
场景:凭证

1、创建secret数据secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

2、以变量形式挂载到pod中

secret-var.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod
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


3、以volumn形式挂载pod容器中

secret-vol.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

部署应用:记得删除之前的变量的形式,因为都叫mypod名称的,会报错部署的时候

kubectl apply -f kubectl-vol.yaml


检查是否挂载上

7、ConfigMap

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

1、创建配置文件

redis.properties

redis.host=127.0.0.1
redis.port=6379
redis.password=123456

2、创建configMap
kubectl create configmap redis-config --from-file=redis.properties


3、以volumn形式挂载到pod中config-vo.yaml

创建pod,挂载volumn

apiVersion: v1
kind: Pod
metadata:
  name: mypod
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



4、以变量的形式挂载到pod容器中

(1)创建yaml,声明变量信息configMap创建
(2)以变量挂载pod

vi mycm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfig
  namespace: default
data:
  special.level: info
  special.type: hello

创建pod:(config-var.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: mypod
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并将变量挂载到pod上

kubectl apply -f config-var.yaml


8、RABC k8s安全机制


1、概述

访问k8s集群时候,需要经过三个步骤完成具体操作:认证,授权,准入控制
进行访问的时候,过程中都需要经过apiserver,apiserver作为统一协调,比如门卫
访问过程中需要证书,token,或者用户名密码,如果访问pod,需要serviceAccount

2、第一步 传输安全
传输安全:对外不暴露8080端口,只能内部访问,对外使用端口6443
  • 认证:客户端身份常用方式
  • https证书认证,基于CA证书
  • http token 认证通过token识别用户
  • http基本认证,用户名+密码
3、第二步 鉴权(授权)

基于RBAC进行鉴权操作
基于角色访问控制

4、准入控制

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

5、RBAC:基于角色的访问控制

角色:
role:特定命名空间访问权限
clusterRole:所有命名空间访问权限
角色绑定
roleBinding:角色绑定到主体
ClusterRoleBinding:集群角色绑定到主体
主体:
user:用户
group:用户组
serviceAccount:服务账号

1、创建命名空间
kubectl create ns roletest
2、查看命名空间
kubectl get ns
3、在新创建的命名空间创建pod
-- 运行pod
kubectl run  nginx --image=nginx -n roletest
-- 查看创建的pod
kubect get pods -n roletest
4、创建角色

rbac-role.yaml

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: roletest
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

部署yaml文件创建角色:

kubectl apply -f rbac-role.yaml

查看创建的角色

kubectl get role -n roletest
5、创建角色绑定

rbac-rolebinding.yaml

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: roletest
subjects:
- kind: User
  name: lucy # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

kubectl apply -f rbac-rolebinding.yaml
kubect get role.rolebinding -n roletest
6、使用证书识别证书

rabc-user.sh

cat > lucy-csr.json < 

证书复制进来ca开头的 cp /root/TLS/k8s/ca* ./

这个证书没有用,所以自己生成一个ca证书
ca-config.json

cat>ca-config.json<< EOF
{
	"signing": {
		"default": {
			"expiry": "87600h"
		},
		"profiles": {
			"kubernetes": {
				"expiry": "87600h",
				"usages": ["signing", "key encipherment", "server auth", "client auth"]
			}
		}
	}
}
EOF

ca-csr.json

cat > ca-csr.json<< EOF
{
	"CN": "etcd CA",
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [{
		"C": "CN",
		"L": "Beijing",
		"ST": "Beijing"
	}]
}
EOF
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

生成ca.csr,ca.pem ,ca-key.pem 三个文件

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes lucy-csr.json | cfssljson -bare lucy

即是rbac-user.sh里面的前两个命令拿出来执行了

kubectl config set-cluster kubernetes 
  --certificate-authority=ca.pem 
  --embed-certs=true 
  --server=https://192.168.31.63:6443 
  --kubeconfig=mary-kubeconfig
kubectl config set-credentials mary 
  --client-key=mary-key.pem 
  --client-certificate=mary.pem 
  --embed-certs=true 
  --kubeconfig=mary-kubeconfig

kubectl config set-context default 
  --cluster=kubernetes 
  --user=mary 
  --kubeconfig=mary-kubeconfig

kubectl config use-context default --kubeconfig=mary-kubeconfig

kubectl  get pods  -n roletest

9、ingress



查看pod详细部署在哪个节点上然后修改window的hosts域名映射

1、把端口号对外暴露,通过ip+端口号进行访问

使用service里面的NodePort实现

2、NodePort缺陷

在每个节点都会起到端口,在访问的时候通过任意节点,通过节点ip+端口号实现访问

  • 意味着每个端口只能使用一次,一个端口对应一个应用
  • 实际访问中跳转到不同端口服务中都是用域名,根据不同的域名
3、Ingress和pod的关系

pod和ingress通过service关联的,ingress作为统一的入口,由service关联一组pod

4、ingress工作流程


ongoing

5、使用ingress

第一步 部署ingress Controller
第二步 创建ingress规则
我们这里选择官方维护nginx控制器,实现部署

6、使用ingress对外暴露应用
  1. 创建nginx应用,对外暴露端口使用NodePort
kubect create deployment web --image=nginx

kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
  • 部署ingress Controller
    ingress-controller.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "-"
      # Here: "-"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      hostNetwork: true
      # wait up to five minutes for the drain of connections
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        kubernetes.io/os: linux
      containers:
        - name: nginx-ingress-controller
          image: lizhenliang/nginx-ingress-controller:0.30.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 101
            runAsUser: 101
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown

---

apiVersion: v1
kind: LimitRange
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  limits:
  - min:
      memory: 90Mi
      cpu: 100m
    type: Container

kubectl apply -f ingress-controller.yaml
  1. 查询ingress状态
kubectl get pods -n ingress-nginx
  1. 创建ingress规则
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.ingredemo.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web
          servicePort: 80

ingress01.yaml

---
# http
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.ctnrs.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web
          servicePort: 80


ingress02.yaml

---
# https
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
    - sslexample.ctnrs.com
    secretName: secret-tls
  rules:
    - host: sslexample.ctnrs.com
      http:
        paths:
        - path: /
          backend:
            serviceName: web
            servicePort: 80
  1. 在window系统hosts文件中添加域名访问规则
    hosts地址:C:WindowsSystem32driversetc
10、Helm 1、helm的引入

之前方式部署应用的基本过程

  1. 编写yaml文件(deployment,service,ingress)
  2. 如果使用之前方式部署单一应用,少数服务的应用,比较合适
  3. 比如微服务项目,可能有几十个服务,每个服务都有yaml文件。需要维护大量的yaml,版本管理特别不合适。
2、使用helm可以解决哪些问题
  1. 使用heml可以把这些yaml作为一个整体管理
  2. 实现yaml高效复用
  3. 使用helm应用级别的版本管理
3、helm介绍

helm是一个Kubernetes包管理工具,就想linux包管理器,如yum、apt,可以很方便将之前打包好的yaml文件部署到kubernetes上

4 、Helm的三个重要概念
  • Helm 是一个命令行客户端工具
  • Chart 把yaml打包,是yaml的集合
  • Release 基于Chart部署实体,应用级别的版本管理
5、helm在2019年发布V3版本,和之前版本相比有变化
  • V3版本删除Tiller架构变化
  • release可以在不同命名空间重用
  • 将Chart推送到docker仓库中

6、helm安装(V3版本以后)

下载helm安装压缩文件,上传到linux,解压helm压缩文件,把解压后helm目录复制到/usr/bin目录下

1、配置helm仓库 1、添加仓库
helm repo add 仓库名称  仓库地址
比如
helm repo add stable http://mirror.azure.cn/kubernetes/charts/

2、查看仓库地址
helm repo list

3、删除仓库
kubectl repo remove  aliyun

4、更新仓库地址
helm repo update

7、使用helm快速部署应用 1、搜索weave应用
helm search repo weave

2、安装weave应用
helm install ui stable/weave-scope

3、查看安装列表
helm list

4、查看安装状态
helm status ui

8、如何自己创建chart 1、使用命令创建chart


2、在templates文件夹创建两个yaml文件

nginxchart.yaml

kubectl create deployment nginxchart --image=nginx -o yaml --dry-run >nginxchartweb.yaml

nginxchartsvc.yaml

kubectl expose deployment nginxchart --port=80 --target-port=80 --name=nginxhcart --type=NodePort -o yaml --dry-run >nginxchartsvc.yaml

进入templates目录,并删除生成的文件

3、安装mychart
helm install nginxchart mychart/

4、应用升级
helm upgrade ngingxchart mychart/

9、实现yaml高效复用

通过传递参数,动态渲染模板,yaml内容动态传入参数生成

1、values.yaml定义变量

在chart有values.yaml文件,定义yaml文件局变量



deployment.yaml文件替换变量

service.yaml 替换变量

2、在templates的yaml文件使用values.yaml定义的变量

3、可以检查变量替换是否成功 --dry-run

10、持久化存储nfs 1、nfs网络存储 pod重启数据化存在

第一步找一台服务器nfs服务器
安装nfs

yum install -y nfs-utils

设置挂载路径

vi /etc/exports

添加/data/nfs *(rw,no_root_squash)
挂载路径需要创建出来 /data/nfs

第二步:在k8s集群node节点安装nfs: yum install -y nfs-utils
第三步:在nfs服务器启动nfs服务

system start nfs
查看
ps -ef | grep nfs

第四步:在k8s集群部署应用使用nfs持久网络存储

kubectl apply -f nfs-nginx.yaml

kubectl exec -it nginx-dept1-xxx bash 
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.63.133
            path: /data/nfs


暴露端口后使用ip访问首页

2、PV和PVC


pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /k8s/nfs
    server: 192.168.63.163

pvc.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dep1
spec:
  replicas: 3
  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
        persistentVolumeClaim:
          claimName: my-pvc

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
四、搭建集群监控平台系统 1、监控指标

集群监控:资源资源利用率,节点数,运行pods
pod监控:容器指标,应用指标

2、监控平台搭建方案 prometheus+Grafana接入即可

prometheus:开源的,监控报警,数据库,以http协议周期性抓取被监控组件状态,不需要复杂的集成过程,使用http接口即可
grafana:开源的数据分析和可视化工具,支持多种数据源

1、node-exporter.yaml 守护进程
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: kube-system
  labels:
    k8s-app: node-exporter
spec:
  selector:
    matchLabels:
     k8s-app: node-exporter
  template:
    metadata:
      labels:
        k8s-app: node-exporter
    spec:
      containers:
      - image: prom/node-exporter
        name: node-exporter
        ports:
        - containerPort: 9100
          protocol: TCP
          name: http
---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: node-exporter
  name: node-exporter
  namespace: kube-system
spec:
  ports:
  - name: http
    port: 9100
    nodePort: 31672
    protocol: TCP
  type: NodePort
  selector:
    k8s-app: node-exporter

2、prometheus 1、rbac-setup.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - nodes/proxy
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups:
  - extensions
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: kube-system

2、configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: kube-system
data:
  prometheus.yml: |
    global:
      scrape_interval:     15s
      evaluation_interval: 15s
    scrape_configs:

    - job_name: 'kubernetes-apiservers'
      kubernetes_sd_configs:
      - role: endpoints
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: default;kubernetes;https

    - job_name: 'kubernetes-nodes'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics

    - job_name: 'kubernetes-cadvisor'
      kubernetes_sd_configs:
      - role: node
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)
      - target_label: __address__
        replacement: kubernetes.default.svc:443
      - source_labels: [__meta_kubernetes_node_name]
        regex: (.+)
        target_label: __metrics_path__
        replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor

    - job_name: 'kubernetes-service-endpoints'
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]
        action: replace
        target_label: __scheme__
        regex: (https?)
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: ([^:]+)(?::d+)?;(d+)
        replacement: $1:$2
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        action: replace
        target_label: kubernetes_name

    - job_name: 'kubernetes-services'
      kubernetes_sd_configs:
      - role: service
      metrics_path: /probe
      params:
        module: [http_2xx]
      relabel_configs:
      - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]
        action: keep
        regex: true
      - source_labels: [__address__]
        target_label: __param_target
      - target_label: __address__
        replacement: blackbox-exporter.example.com:9115
      - source_labels: [__param_target]
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_service_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_service_name]
        target_label: kubernetes_name

    - job_name: 'kubernetes-ingresses'
      kubernetes_sd_configs:
      - role: ingress
      relabel_configs:
      - source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_ingress_scheme,__address__,__meta_kubernetes_ingress_path]
        regex: (.+);(.+);(.+)
        replacement: ${1}://${2}${3}
        target_label: __param_target
      - target_label: __address__
        replacement: blackbox-exporter.example.com:9115
      - source_labels: [__param_target]
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_ingress_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_ingress_name]
        target_label: kubernetes_name

    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::d+)?;(d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: kubernetes_pod_name

3、prometheus.deploy.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    name: prometheus-deployment
  name: prometheus
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - image: prom/prometheus:v2.0.0
        name: prometheus
        command:
        - "/bin/prometheus"
        args:
        - "--config.file=/etc/prometheus/prometheus.yml"
        - "--storage.tsdb.path=/prometheus"
        - "--storage.tsdb.retention=24h"
        ports:
        - containerPort: 9090
          protocol: TCP
        volumeMounts:
        - mountPath: "/prometheus"
          name: data
        - mountPath: "/etc/prometheus"
          name: config-volume
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 500m
            memory: 2500Mi
      serviceAccountName: prometheus    
      volumes:
      - name: data
        emptyDir: {}
      - name: config-volume
        configMap:
          name: prometheus-config   

4、prometheus.svc.yml
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: prometheus
  name: prometheus
  namespace: kube-system
spec:
  type: NodePort
  ports:
  - port: 9090
    targetPort: 9090
    nodePort: 30003
  selector:
    app: prometheus

3、grafana 1、grafana-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana-core
  namespace: kube-system
  labels:
    app: grafana
    component: core
spec:
  selector:
    matchLabels:
     app: grafana
     component: core
  replicas: 1
  template:
    metadata:
      labels:
        app: grafana
        component: core
    spec:
      containers:
      - image: grafana/grafana:4.2.0
        name: grafana-core
        imagePullPolicy: IfNotPresent
        # env:
        resources:
          # keep request = limit to keep this container in guaranteed class
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 100m
            memory: 100Mi
        env:
          # The following env variables set up basic auth twith the default admin user and admin password.
          - name: GF_AUTH_BASIC_ENABLED
            value: "true"
          - name: GF_AUTH_ANONYMOUS_ENABLED
            value: "false"
          # - name: GF_AUTH_ANONYMOUS_ORG_ROLE
          #   value: Admin
          # does not really work, because of template variables in exported dashboards:
          # - name: GF_DASHBOARDS_JSON_ENABLED
          #   value: "true"
        readinessProbe:
          httpGet:
            path: /login
            port: 3000
          # initialDelaySeconds: 30
          # timeoutSeconds: 1
        volumeMounts:
        - name: grafana-persistent-storage
          mountPath: /var
      volumes:
      - name: grafana-persistent-storage
        emptyDir: {}

2、grafana-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: kube-system
  labels:
    app: grafana
    component: core
spec:
  type: NodePort
  ports:
    - port: 3000
  selector:
    app: grafana
    component: core

3、grafana-ing.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
   name: grafana
   namespace: kube-system
spec:
   rules:
   - host: k8s.grafana
     http:
       paths:
       - path: /
         backend:
          serviceName: grafana
          servicePort: 3000

3、部署prometheus

先部署守护进程
kubectl create -f xxx.yaml
kubectl apply -f xxx.yaml

kubectl appply -f node-exporter.yaml
kubectl appply -f rbac-setup.yaml
kubectl appply -f configmap.yaml
kubectl appply -f prometheus.deploy.yml
kubectl appply -f prometheus.svc.yml
4、部署grafana
kubectl apply -f grafana-deploy.yaml
kubectl apply -f grafana-svc.yaml
kubectl apply -f grafana-ing.yaml
5、打开grafana配置数据源导入显示模板315

用户名密码都是admin

五、从零搭建高可用k8s集群


1、搭建高可用步骤
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。

这个工具能通过两条指令完成一个kubernetes集群的部署:

创建一个 Master 节点

$ kubeadm init

将一个 Node 节点加入到当前集群中

$ kubeadm join

## 1. 安装要求

在开始之前,部署Kubernetes集群机器需要满足以下几个条件:

- 一台或多台机器,操作系统 CentOS7.x-86_x64
- 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
- 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
- 禁止swap分区

## 2. 准备环境

| 角色          | IP             |
| ------------- | -------------- |
| master1       | 192.168.44.155 |
| master2       | 192.168.44.156 |
| node1         | 192.168.44.157 |
| VIP(虚拟ip) | 192.168.44.158 |

关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

关闭selinux

sed -i ‘s/enforcing/disabled/’ /etc/selinux/config # 永久
setenforce 0 # 临时

关闭swap

swapoff -a # 临时
sed -ri ‘s/.swap./#&/’ /etc/fstab # 永久

根据规划设置主机名

hostnamectl set-hostname

在master添加hosts

cat >> /etc/hosts << EOF
192.168.44.158 master.k8s.io k8s-vip
192.168.44.155 master01.k8s.io master1
192.168.44.156 master02.k8s.io master2
192.168.44.157 node01.k8s.io node1
EOF

将桥接的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 # 生效

时间同步

yum install ntpdate -y
ntpdate time.windows.com



## 3. 所有master节点部署keepalived

### 3.1 安装相关包和keepalived

yum install -y conntrack-tools libseccomp libtool-ltdl

yum install -y keepalived

### 3.2配置master节点

master1节点配置

cat > /etc/keepalived/keepalived.conf < ! Configuration File for keepalived

global_defs {
router_id k8s
}

vrrp_script check_haproxy {
script “killall -0 haproxy”
interval 3
weight -2
fall 10
rise 2
}

vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 250
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab
}
virtual_ipaddress {
192.168.44.158
}
track_script {
check_haproxy
}

}
EOF

master2节点配置

cat > /etc/keepalived/keepalived.conf < ! Configuration File for keepalived

global_defs {
router_id k8s
}

vrrp_script check_haproxy {
script “killall -0 haproxy”
interval 3
weight -2
fall 10
rise 2
}

vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 200
advert_int 1
authentication {
auth_type PASS
auth_pass ceb1b3ec013d66163d6ab
}
virtual_ipaddress {
192.168.44.158
}
track_script {
check_haproxy
}

}
EOF

### 3.3 启动和检查

在两台master节点都执行

启动keepalived

$ systemctl start keepalived.service
设置开机启动
$ systemctl enable keepalived.service

查看启动状态

$ systemctl status keepalived.service

启动后查看master1的网卡信息

ip a s ens33



## 4. 部署haproxy

### 4.1 安装

yum install -y haproxy

### 4.2 配置

两台master节点的配置均相同,配置中声明了后端代理的两个master节点服务器,指定了haproxy运行的端口为16443等,因此16443端口为集群的入口

cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------

Global settings

#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
# 1) configure syslog to accept network log events. This is done
# by adding the ‘-r’ option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2

chroot      /var/lib/haproxy
pidfile     /var/run/haproxy.pid
maxconn     4000
user        haproxy
group       haproxy
daemon 
   
# turn on stats unix socket
stats socket /var/lib/haproxy/stats

#---------------------------------------------------------------------

common defaults that all the ‘listen’ and ‘backend’ sections will use if not designated in their block

#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------

kubernetes apiserver frontend which proxys to the backends

#---------------------------------------------------------------------
frontend kubernetes-apiserver
mode tcp
bind *:16443
option tcplog
default_backend kubernetes-apiserver
#---------------------------------------------------------------------

round robin balancing between the various backends

#---------------------------------------------------------------------
backend kubernetes-apiserver
mode tcp
balance roundrobin
server master01.k8s.io 192.168.44.155:6443 check
server master02.k8s.io 192.168.44.156:6443 check
#---------------------------------------------------------------------

collection haproxy statistics message

#---------------------------------------------------------------------
listen stats
bind *:1080
stats auth admin:awesomePassword
stats refresh 5s
stats realm HAProxy Statistics
stats uri /admin?stats
EOF

### 4.3 启动和检查

两台master都启动

设置开机启动

$ systemctl enable haproxy

开启haproxy

$ systemctl start haproxy

查看启动状态

$ systemctl status haproxy

检查端口

netstat -lntup|grep haproxy



## 5. 所有节点安装Docker/kubeadm/kubelet

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

### 5.1 安装Docker

$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum -y install docker-ce-18.06.1.ce-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version
Docker version 18.06.1-ce, build e68fc7a

 

$ cat > /etc/docker/daemon.json << EOF
{
“registry-mirrors”: [“https://b9pmyelo.mirror.aliyuncs.com”]
}
EOF

### 5.2 添加阿里云YUM软件源

$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

### 5.3 安装kubeadm,kubelet和kubectl

由于版本更新频繁,这里指定版本号部署:

$ yum install -y kubelet-1.16.3 kubeadm-1.16.3 kubectl-1.16.3
$ systemctl enable kubelet



## 6. 部署Kubernetes Master

### 6.1 创建kubeadm配置文件

在具有vip的master上操作,这里为master1

$ mkdir /usr/local/kubernetes/manifests -p

$ cd /usr/local/kubernetes/manifests/

$ vi kubeadm-config.yaml

apiServer:
certSANs:
- master1
- master2
- master.k8s.io
- 192.168.44.158
- 192.168.44.155
- 192.168.44.156
- 127.0.0.1
extraArgs:
authorization-mode: Node,RBAC
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: “master.k8s.io:16443”
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.16.3
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.1.0.0/16
scheduler: {}



### 6.2 在master1节点执行

$ kubeadm init --config kubeadm-config.yaml



按照提示配置环境变量,使用kubectl工具:

```bash
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 nodes
$ kubectl get pods -n kube-system

按照提示保存以下内容,一会要使用:

kubeadm join master.k8s.io:16443 --token jv5z7n.3y1zi95p952y9p65 
    --discovery-token-ca-cert-hash sha256:403bca185c2f3a4791685013499e7ce58f9848e2213e27194b75a2e3293d8812 
    --control-plane 

查看集群状态

kubectl get cs

kubectl get pods -n kube-system
7.安装集群网络

从官方地址获取到flannel的yaml,在master1上执行

mkdir flannel
cd flannel
wget -c https://raw.githubusercontent.com/coreos/flannel/master/documentation/kube-flannel.yml

安装flannel网络

kubectl apply -f kube-flannel.yml 

检查

kubectl get pods -n kube-system
8、master2节点加入集群 8.1 复制密钥及相关文件

从master1复制密钥及相关文件到master2

# ssh root@192.168.44.156 mkdir -p /etc/kubernetes/pki/etcd

# scp /etc/kubernetes/admin.conf root@192.168.44.156:/etc/kubernetes
   
# scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@192.168.44.156:/etc/kubernetes/pki
   
# scp /etc/kubernetes/pki/etcd/ca.* root@192.168.44.156:/etc/kubernetes/pki/etcd
8.2 master2加入集群

执行在master1上init后输出的join命令,需要带上参数--control-plane表示把master控制节点加入集群

kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b     --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba --control-plane

检查状态

kubectl get node

kubectl get pods --all-namespaces
5. 加入Kubernetes Node

在node1上执行

向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:

kubeadm join master.k8s.io:16443 --token ckf7bs.30576l0okocepg8b     --discovery-token-ca-cert-hash sha256:19afac8b11182f61073e254fb57b9f19ab4d798b70501036fc69ebef46094aba

集群网络重新安装,因为添加了新的node节点

检查状态

kubectl get node

kubectl get pods --all-namespaces
7. 测试kubernetes集群

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

$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc

访问地址:http://NodeIP:Port

``

六、在集群环境部署项目

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/642334.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号