一、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

一、Node篇

kubectl get nodes 查看所有node信息
kubectl get nodes -owide 查看所有node的详细信息
kubectl get node -o yaml 查看所有node的yaml文件
kubectl get node master01 -o yaml 查看master01的yaml文件
kubectl get node --show-labels 查看所有node的label信息

kubectl describe node node01 |grep -i taint -A3 查看node01的污点配置
kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule 给node01配置污点

二、deployment篇

2.1 创建deployment,命名为nginx

kubectl create deployment nginx --image=nginx:1.15.2

2.2 查看deployment,包括IP

kubectl get deploy -owide
kubectl scale deploy {deployment的名称} -n xiyu --replicas=4  缩扩容副本数
kubectl describe -f pod-diff-nodes.yaml  通过查看文件创建deployment的具体信息备注:
NAME: Deployment名称
READY:Pod的状态,已经Ready的个数
UP-TO-DATE:已经达到期望状态的被更新的副本数
AVAILABLE:已经可以用的副本数
AGE:显示应用程序运行的时间
CONTAINERS:容器名称
IMAGES:容器的镜像
SELECTOR:管理的Pod的标签
2.3 将deployment配置导出yaml格式文件
kubectl create deploy nginx --try-run=client --image=nginx:1.15.2 >nginx_deployment.yaml
2.4 deployment更新,升级pod镜像
kubectl set image deploy nginx nginx=nginx:1.15.3 –record
2.5 deployment回滚
kubectl rollout history deploy nginx

2.6 deployment的暂停和恢复

kubectl rollout pause deployment nginx
kubectl set image deploy nginx nginx=nginx:1.15.3 --record
kubectl set resources deploy nginx -c nginx --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi  //添加内存cpu配置
kubectl get deploy nginx -oyaml
kubectl rollout resume deploy nginx

三、statefulset篇

用statefulset部署pod,会按照顺序创建,如pod名字为nginx,副本数为3,那么pod名称会自动生成nginx-0,nginx-1,nginx-2,并且容器的hostname也为nginx-0,nginx-1,nginx-2
1)创建statefulset前必须要创建service
2)statefulset 按照顺序启动,前一个正常,才会继续下一个,删除的话为倒序
3)用yaml文件创建,一个service和pod

3.1 扩容和缩容

kubectl get po -owide
kubectl label node01 node02 ds=ture  //给node打个标签

四、deamonset篇

kubectl get po -owide
kubectl label node01 node02 ds=ture  //给node打个标签

备注:yaml文件中spec块中 nodeSelector: ds: true 这样创建的deamonset就会自动选择node

kubectl rollout history ds nginx 查看回滚记录

如果想要一个node中自动部署deamonset,可以直接给node 设置一个标签

kubectl label node03 ds=ture  //给node打个标签
kubectl get pod -owide

五、label篇

kubectl get pod -A --show-labels                查看所有namespace下的所有标签
kubectl get pod -A -l app=busybox               查看所有namespace下的指定的标签
kubectl get pod -n kube-public -l app=busybox   查看指定namespace中的标签
kubectl label pod busybox app=busybox -n kube-public      配置pod的标签为app=busybox
kubectl label pod busybox app- -n kube-public   删除app=busybox的标签,用app-减号 kubectl get pod -n -A -l 'k8s-app in (metrices-server,kubernetes-dashboard)' 过滤多个标签
kubectl get pod -A -l version!=v1 过滤不等于version=v1的标签kubectl get node --show-labels  查看所有node节点标签
kubectl label nodes <node-name> <label-key>=<label-value>   给node添加标签
kubectl label nodes <node-name> <node-name ><label-key>=<label-value>   给多个node添加标签
kubectl label nodes <node-name> <label-key>-   删除标签
kubectl label nodes <node-name> <label-key>=<label-value> --overwrite  修改标签

六、volumes篇

6.1 常用命令

kubectl get pv
kubectl get pvc

6.2 emptyDir

删除pod,emptyDir会随之删除,只是做容器间共享数据用,无法持久化数据

apiVersion: v1
kind: Pod
metadata:name:test-pod
spec:containers:- image: k8s.gcr.io/test/webservername: test-containervolumeMounts:- mountpath: /cachename: cache-volumevolumes:- name: cache-volumeemptyDir:{}

6.3 hostPath

共享pod宿主机的文件或者文件夹,pod迁移后无法正常使用,因此很少被使用

apiVersion: v1
kind: Pod
metadata:name:test-pod2
spec:containers:- image: k8s.gcr.io/test/webservername: test-container2volumeMounts:- mountpath: /cache2name: cache-volume2volumes:- name: cache-volume2hostPath:path: /datatype: Directory

6.4 NFS

需要安装nfs-unils,一般生产环境下NFS共享并无法实现高可用保障,如果是公有云环境下,建议使用阿里云NAS存储,协议与NFS兼容
NFS服务端:yum install nfs* rpcbind -y
NFS客户端:yum install nfs-utils -y
NFS服务端创建共享目录 mkdir /data/k8s/ -p
NFS服务端配置 vim /etc/exports 添加一下内容
/data/k8s. *(rw,sync,no_subtree_check,no_root_squash)
NFS服务端配置加载 exportfs -r
NFS服务端服务重启 systemctl restart nfs rpcbind
NFS服务端口号查看 netstat -anlp |grep nfs
客户端挂载:mount -fs nfs 10.1.1.1:/data/k8s /mnt/
10.1.1.1是nfs服务端的IP

https://blog.csdn.net/m0_46327721/article/details/108006037
先配置好nfs共享服务后,再配置pod

apiVersion: v1
kind: Pod
metadata:name:test-pod3
spec:containers:- image: k8s.gcr.io/test/webservername: test-container3volumeMounts:- mountpath: /mntname: nfs-volumevolumes:- name: nfs-volumenfs:server:192.168.1.100path: /data/nfs/test-dp

6.5 k8s持久化存储 PV & PVC

有些问题使用volume是无法解决的,比如
1)数据卷不再被挂载了,数据如何处理?
2)只读挂载?
3)只能一个pod挂载
4)限制某个pod使用10G空间

PersistentVolume:简称PV,由k8s管理员设置的存储,可以配置ceph, NFS, GlusterFS等常用存储配置,相对于volume,它提供了更多功能,比如生命周期管理,大小限制,PV分为静态和动态,PV是没有命名空间限制

PersistentVolumeClaim:简称PVC,是对存储PV的请求,配置需要什么类型的PV,PV无法直接使用,需要配置成PVC才可以,PVC是有命名空间限制

6.6 PV的访问策略和回收策略

1)ReadWriteOnce:可以被单个节点以读写模式挂载,命令行中可缩写为RWO
2)ReadOnlyMany:可以被多个节点以只读模式挂载,命令行中可缩写为ROX
3)ReadWriteMany:可以被多个节点以读写模式挂载,命令行中可缩写为RWX
1)Retain:保留,允许手动回收,当删除pvc时,pv仍保留,可以手动回收
2)Recycle:回收,如果Volume插件支持,Recycle策略对卷支持rm -rf清理PV,为创建新的pvc做准备,但该策略将来被废弃,目前只有NFS HostPath支持
3)Delete:删除,如果Volume插件支持,删除pvc会同时删除pv,动态卷默认delete模式,目前支持delete的存储后端包括AWS EBS ,GCE PD ,Azure Disk 等

可以通过persistentVolumeReclaimPolicy:Recyle 字段配置

6.7 PV的yaml案例

apiVersion: v1
kind: PersistentVolume
metadata:name: pv001
spec:capacity:storage: 10GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RecyclestorageClassName: slowmountOptions:- hard- nfsvers=4.1nfs:path: /tmpserver:172.17.0.2

备注: volumeMode:卷的模式,目前支持Filesystem(文件系统)和block(块),其中block需要后端存储支持,默认为文件系统 accessModes:该PV的访问模式 storageClassName:PV的类,一个特定类型的PV只能绑定到特定类别的PVC,用来绑定PVC使用的名字 mountOptions:非必须,新版本中已废弃 nfs:NFS服务配置,包括两个选项,path:nfs上的共享目录,server:nfs的IP地址

  • 文件存储:一些数据被多个节点使用,实现方式:NFS NAS FTP等(生产环境中不建议使用NFS,建议使用有高可用的功能的NAS Ceph等)
  • 块存储:一些数据只能被一个节点使用,或者将一块裸盘整个挂载使用,比如数据库 redis等,实现方式:Ceph, GlusterFS 公有云等
  • 对象存储:由程序代码直接实现的一种存储方式,云原生应用无状态常用的实现方式,实现方式:一般是复核S3协议的云存储,比如AWS的S3存储,Minio等

6.8 创建NAS或者NFS类型的PV

1、先创建NFS服务端和客户端(已完成,请忽略)
2、创建yaml

apiVersion: v1
kind: PersistentVolume
metadata:name: pv001
spec:capacity:storage: 10GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RecyclestorageClassName: slowmountOptions:- hard- nfsvers=4.1nfs:path: /tmpserver:172.17.0.2

pv的几种status

Available:可用,还未被PVC绑定资源
Bound:已绑定,被PVC绑定
Released:已释放,pvc被删除,但资源还未被重新使用
Faild:失败,自动回收失败(Recycle策略中存在的一种)

6.9 创建hostPath类型的PV

2、创建yaml

apiVersion: v1
kind: PersistentVolume
metadata:name: pv002labels:type:local
spec:capacity:storage: 10GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RecyclestorageClassName: hostpathhostPath:path:"/mnt/data"

备注:path是指宿主机上的目录路径,与nas和nfs的唯一不同的地方就是后端存储的地方

  hostPath:path:"/mnt/data"

6.10 创建PVC,绑定到PV

单独创建PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-test  //随便写
spec:storageClassName: slow   //与PV一致accessModes:- ReadWriteOnceresources:requests:storage:3Gi

注意:slow为pv的storageClassName的名称,accessModes要跟pv的模式一致,容量要小于pv的大小

  • 常用命令
    kubectl create -f pvc-nfs.yaml
    kubectl get -f pvc-nfs.yaml
    kubect get pv pv-nfs

6.11 创建POD中绑定PVC

创建yaml为pvc-nfs-pod.yaml

apiVersion: v1
kind: Pod
metadata:name: pvc-pod
spec:volumes:- name:pvc-storage    #volumes的名称persistentVolumeClaim:claimName:nfs-pvc-claim  #pvc的名称containers:- name: pvc-containerimage: nginxports:- containerPort: 80name:"http-server"volumeMounts:- mountPath:"/usr/share/nginx/html"name: pvc-storage
  • 常用命令
    kubectl create -f pvc-nfs-pod.yaml
    kubectl get pod
    kubectl get pvc
    进入pod中执行
    df -Th

  • 测试
    1)写入数据,查看宿主机和pod中是否同步
    2)删除pod,查看数据是否还在

6.12 创建deployment绑定PVC

创建文件pvc-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nginxname:nginxnamespace: default
spec:replicas: 2revisionHistoryLimit: 10selector:matchLabels:app: nginxstrategy:rollingUpdate:maxSurge: 1maxUnavailable: 0type: RollingUpdatetemplate:metadata:creationTimestamp: nulllabels:app: nginxspec:volumes:- name:pvc-storage    #volumes的名称persistentVolumeClaim:claimName:nfs-pvc-claim  #pvc的名称containers:- name:nginximage: nginximagePullPolicy: IfNotPresentvolumeMounts:- mountPath:"/usr/share/nginx/htmlname: task-pv-storage
  • 常用命令
    kubectl get po
    kubectl exec -it nginx-xxxxx-xx – bash 进入pod内

6.13 pvc创建和报错分析

  • PVC一直pending
    1)PVC的空间大小大于PV的大小
    2)PVC的storageClassName没有与PV一致
    3)PVC的accessModes与PV不一致

  • 挂载PVC的pod一直处于pending
    1)PVC没有创建成功
    2)PVC和pod不在同一个Namespace

七、Job篇

7.1 Job

  • 常用命令
    kubectl create -f job.yaml
    kubectl delete -f job.yaml
    kubectl get pod
    kubectl get job
    kubectl logs -f echo-xxxx 查看执行日志

创建job.yaml

apiVersion: batch/v1
kind: Job
metadata:labels:job-name: echoname: echonamespace: default
spec:backoffLimit: 4completions: 1parallelism: 1template:spec:containers:- command:- echo- Hello,jobimage: registry.cn-beijing.aliyuncs.com/dotbalo/busyboximagePullPolicy: Alwaysname: echo
  • 备注:
    backoofLimit: 如果任务失败,多少次不再执行
    completions: 多少个pod执行成功,认为任务是成功的
    parallelism: 并行执行任务的数量(如果大于未完成的数,会多次创建)
    ttlSecondsAfterFinishe:job结束后自动清理,0表示结束后立即删除,不设置则不会清除

7.2 CronJob

CronJob用于以时间为基准周期性地执行任务,这些自动化任务和运行在Linux或UNIX系统上的CronJob一样。CronJob对于创建定期和重复任务非常有用,例如执行备份任务、周期性调度程序接口、发送电子邮件等。

对于Kubernetes 1.8以前的版本,需要添加–runtime-config=batch/v2alpha1=true参数至APIServer中,然后重启APIServer和Controller Manager用于启用API,对于1.8以后的版本无须修改任何参数,可以直接使用,本节的示例基于1.8以上的版本。

  • 创建CronJob有两种方式,一种是直接使用kubectl创建,一种是使用yaml文件创建。
  • 使用kubectl创建CronJob的命令如下:
kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"

对应的yaml文件如下:

apiVersion: batch/v1beta1  #1.21版本以上  改为batch/v1
kind: CronJob
metadata:name: hello
spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: helloimage: busyboxargs:- /bin/sh- -c- date; echo Hello from the Kubernetes clusterrestartPolicy: OnFailure
  • 创建一个每分钟执行一次、打印当前时间和Hello from the Kubernetes cluster的计划任务。
    查看创建的CronJob:
kubectl get cj
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          5s
  • 等待1分钟可以查看执行的任务(Jobs):
$ kubectl get jobs
NAME               COMPLETIONS   DURATION   AGE
hello-1558779360   1/1           23s        32s
  • CronJob每次调用任务的时候会创建一个Pod执行命令,执行完任务后,Pod状态就会变成Completed,如下所示:
$ kubectl get po
NAME                          READY   STATUS      RESTARTS   AGE
hello-1558779360-jcp4r        0/1     Completed   0          37s
  • 可以通过logs查看Pod的执行日志:
$ kubectl logs -f hello-1558779360-jcp4r
Sat May 25 10:16:23 UTC 2019
Hello from the Kubernetes cluster
  • 如果要删除CronJob,直接使用delete即可:
kubectl delete cronjob hello
  • 定义一个CronJob的yaml文件如下:
apiVersion: batch/v1beta1
kind: CronJob
metadata:labels:run: helloname: hellonamespace: default
spec:concurrencyPolicy: AllowfailedJobsHistoryLimit: 1jobTemplate:metadata:spec:template:metadata:labels:run: hellospec:containers:- args:- /bin/sh- -c- date; echo Hello from the Kubernetes clusterimage: registry.cn-beijing.aliyuncs.com/dotbalo/busyboximagePullPolicy: Alwaysname: helloresources: {}restartPolicy: OnFailuresecurityContext: {}schedule: '*/1 * * * *'successfulJobsHistoryLimit: 3suspend: false
  • 参数说明:
  • apiVersion: batch/v1beta1 #1.21+ batch/v1
    schedule:调度周期,和Linux一致,分别是分时日月周。
    restartPolicy:重启策略,和Pod一致。
    concurrencyPolicy:并发调度策略。可选参数如下:
    – Allow:允许同时运行多个任务。
    – Forbid:不允许并发运行,如果之前的任务尚未完成,新的任务不会被创建。
    – Replace:如果之前的任务尚未完成,新的任务会替换的之前的任务。
    suspend:如果设置为true,则暂停后续的任务,默认为false。
    successfulJobsHistoryLimit:保留多少已完成的任务,按需配置。
    failedJobsHistoryLimit:保留多少失败的任务。

相对于Linux上的计划任务,Kubernetes的CronJob更具有可配置性,并且对于执行计划任务的环境只需启动相对应的镜像即可。比如,如果需要Go或者PHP环境执行任务,就只需要更改任务的镜像为Go或者PHP即可,而对于Linux上的计划任务,则需要安装相对应的执行环境。此外,Kubernetes的CronJob是创建Pod来执行,更加清晰明了,查看日志也比较方便。可见,Kubernetes的CronJob更加方便和简单。

7.3 初始化容器

7.3.1 初始化容器介绍
  • 初始化容器和poststart区别,PostStart:依赖主应用的环境,而且并不一定先于Command运行,InitContainer:不依赖主应用的环境,可以有更高的权限和更多的工具,一定会在主应用启动之前完成

  • 另外,初始化容器和普通容器区别,Init 容器与普通的容器非常像,除了如下几点:
    它们总是运行到完成;上一个运行完成才会运行下一个;
    如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止,但是Pod 对应的 restartPolicy 值为 Never,Kubernetes 不会重新启动 Pod。
    Init 容器不支持 lifecycle、livenessProbe、readinessProbe 和 startupProbe

7.3.2 创建初始化容器

创建init.yaml文件,用来测试初始化容器的整个工作过程,使用deployment部署pod,定义三个pod副本,定义两个初始化容器init-touch和echo,并且为了演示效果,将echo加入for循环和sleep100秒,

kubectl create -f init.yaml
kubectl get pod -n kube-public
kubectl describe pod test-init-xxxxx -c echo -n kube-public 查看指定容器目前执行的命令
kubectl logs -f init.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: test-initname: test-initnamespace: kube-public
spec:replicas: 3selector:matchLabels:app: test-inittemplate:metadata:labels:app: test-initspec:volumes:- name: dataemptyDir: {}initContainers:- command:- sh- -c- touch /mnt/test-init.txtimage: nginximagePullPolicy: IfNotPresentname: init-touchvolumeMounts:- name: datamountPath: /mnt- command:- sh- -c- for i in `seq 1 100`; do echo $i; sleep 1; doneimage: nginximagePullPolicy: IfNotPresentname: echocontainers:- image: nginximagePullPolicy: IfNotPresentname: test-initvolumeMounts:- name: datamountPath: /mnt

7.4 临时容器

什么是临时容器?
临时容器:一种特殊的容器,该容器在现有 Pod 中临时运行,以便完成用户发起的操作,例如故障排查。 你会使用临时容器来检查服务,而不是用它来构建应用程序。
临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启, 因此不适用于构建应用程序。 临时容器使用与常规容器相同的 ContainerSpec 节来描述,但许多字段是不兼容和不允许的。

Pod 是 Kubernetes 应用程序的基本构建块。 由于 Pod 是一次性且可替换的,因此一旦 Pod 创建,就无法将容器加入到 Pod 中。 取而代之的是,通常使用 Deployment 以受控的方式来删除并替换 Pod。

有时有必要检查现有 Pod 的状态。例如,对于难以复现的故障进行排查。 在这些场景中,可以在现有 Pod 中运行临时容器来检查其状态并运行任意命令。

临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。
Pod 资源分配是不可变的,因此 resources 配置是不允许的。
有关允许字段的完整列表,请参见 EphemeralContainer 参考文档。
临时容器是使用 API 中的一种特殊的 ephemeralcontainers 处理器进行创建的, 而不是直接添加到 pod.spec 段,因此无法使用 kubectl edit 来添加一个临时容器。

与常规容器一样,将临时容器添加到 Pod 后,将不能更改或删除临时容器。

临时容器的用途
当由于容器崩溃或容器镜像不包含调试工具而导致 kubectl exec 无用时, 临时容器对于交互式故障排查很有用。

尤其是,Distroless 镜像 允许用户部署最小的容器镜像,从而减少攻击面并减少故障和漏洞的暴露。 由于 distroless 镜像不包含 Shell 或任何的调试工具,因此很难单独使用 kubectl exec 命令进行故障排查。

使用临时容器时,启用 进程名字空间共享很有帮助,可以查看其他容器中的进程。

八、污点和容忍篇(Taint和Toleration)

设计理念:Taint在一类服务器上打上污点,让不能容忍这个污点的Pod不能部署在打了污点的服务器上。Toleration是让Pod容忍节点上配置的污点,可以让一些需要特殊配置的Pod能够调用到具有污点和特殊配置的节点上。
官方文档:https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/

污点:作用在节点上(相当于锁)
容忍:作用在pod上(相当于钥匙)

注意:若是想要pod落到指定的某一个node中,需要在pod的yaml中配置nodeSelector,并且pod必须与nodes的label一致,然后还需要pod配置可以容忍node的污点。 如果单纯的只配置了容忍,未配置label,那么pod的容忍未必会起到作用。

8.1 taint污点

创建一个污点(一个节点可以有多个污点):
kubectl taint nodes NODE_NAME TAINT_KEY=TAINT_VALUE:EFFECT

 kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedulekubectl taint nodes k8s-node01 ssd=true:NoExecute(此时会驱逐没有容忍该污点的Pod)kubectl taint nodes k8s-node01 ssd=true:NoSchedulekubectl label node k8s-node01 ssd=true

NoSchedule:禁止调度到该节点,已经在该节点上的Pod不受影响
NoExecute:禁止调度到该节点,如果不符合这个污点,会立马被驱逐(或在一段时间后,配置tolerationSeconds: 6000)
PreferNoSchedule:尽量避免将Pod调度到指定的节点上,如果没有更合适的节点,可以部署到该节点

说明,配置6000秒后驱使pod

tolerations:
- key: "taintKey"operator: "Exists"effect: "NoExecute"   tolerationSeconds: 6000

8.2 Toleration容忍

创建一个pod的 toleration.yaml,Toleration是配置在pod中的,与taint不一样,taint是定义在node中的

apiVersion: v1
kind: Pod
metadata:name: nginxlabels:env: test
spec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentnodeSelector:ssd: "true"tolerations:- key: "ssd"operator: "Exists"

另外,toleration有四种模式

  • 第一种:完全匹配
tolerations:
- key: "taintKey"operator: "Equal"value: "taintValue"effect: "NoSchedule"
  • 第二种:不完全匹配(这种模式下,只配置key,不配置value)
tolerations:
- key: "taintKey"operator: "Exists"effect: "NoSchedule"
  • 第三种:大范围匹配(这种模式下,不推荐key为内置Taint)
tolerations:
- key: "taintKey"operator: "Exists"
  • 第四种:匹配所有(不推荐)
tolerations:
- operator: "Exists"

8.3 常用命令

1)创建一个污点(一个节点可以有多个污点):
#kubectl taint nodes NODE_NAME TAINT_KEY=TAINT_VALUE:EFFECT
比如:
kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule
2)查看一个节点的污点:
kubectl get node k8s-node01 -o go-template --template {{.spec.taints}}
kubectl describe node k8s-node01 | grep Taints -A 10
3)删除污点(和label类似):
基于Key删除: kubectl taint nodes k8s-node01 ssd-
基于Key+Effect删除: kubectl taint nodes k8s-node01 ssd:PreferNoSchedule-
4)修改污点(Key和Effect相同):
kubectl taint nodes k8s-node01 ssd=true:PreferNoSchedule --overwrite

8.4 内置污点

内置污点为pod创建成功后,自动生成的tolerations,是为了在机器宕机或者网络不可达后,节点自动采取迁移或者其他动作来规避故障
使用以下命令可以查看:

kubectl get pod nginx -o yaml

node.kubernetes.io/not-ready:节点未准备好,相当于节点状态Ready的值为False。
node.kubernetes.io/unreachable:Node Controller访问不到节点,相当于节点状态Ready的值为Unknown。node.kubernetes.io/out-of-disk:节点磁盘耗尽。
node.kubernetes.io/memory-pressure:节点存在内存压力。
node.kubernetes.io/disk-pressure:节点存在磁盘压力。
node.kubernetes.io/network-unavailable:节点网络不可达。
node.kubernetes.io/unschedulable:节点不可调度。
node.cloudprovider.kubernetes.io/uninitialized:如果Kubelet启动时指定了一个外部的cloudprovider,它将给当前节点添加一个Taint将其标记为不可用。在cloud-controller-manager的一个controller初始化这个节点后,Kubelet将删除这个Taint。

九、亲和力篇(Affinity)

9.1 使用背景

部署pod时,优先选择对应的标签,如果不存在,则部署到其他节点
部署pod时,部署到标签一和标签二的节点上,但需要优先部署到标签一的节点上
同一个pod多个副本,尽量或者必须部署到同一个节点上
相互有关联的pod,必须部署到同一个节点上,降低网络延迟
同一个项目的应用,尽量部署到不同的节点上,保证业务的高可用性

9.2 亲和力分类

  • NodeAffinity:节点亲和力 / 反亲和力
    1)分为硬亲和力-required(必须满足)和软亲和力-preferred(尽量满足)
    2)作用:

  • PodAffinity:Pod亲和力
    1)分为硬亲和力-required(必须满足)和软亲和力-preferred(尽量满足)
    2)作用:

  • PodAntiAffinity:Pod反亲和力
    1)分为硬亲和力-required(必须满足)和软亲和力-preferred(尽量满足)
    2)作用:为了规避所有的pod副本都部署到同一个节点,尽可能按照不同node均衡打散,或者按照机房和可用区打散

9.3 节点亲和力配置

创建nodeAffinity.yaml文件

apiVersion: v1
kind: Pod
metadata:name: with-node-affinity
spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: ipaddressoperator: Invalues:- 172-16-27-35preferredDuringSchedulingIgnoredDuringExecution:- weight: 1preference:matchExpressions:- key: another-node-label-keyoperator: Invalues:- another-node-label-valuecontainers:- name: with-node-affinityimage: nginx

注意:

nodeSelectorTerms 下的配置其一满足就可以
matchExpressions下的配置项都要符合才可以
requiredDuringSchedulingIgnoredDuringExecution:硬亲和力配置
nodeSelectorTerms:节点选择器配置,可以配置多个matchExpressions(满足其一),每个matchExpressions下可以配置多个key、value类型的选择器(都需要满足),其中values可以配置多个(满足其一)
preferredDuringSchedulingIgnoredDuringExecution:软亲和力配置
weight: 软亲和力的权重,权重越高优先级越大,范围1-100
preference:软亲和力配置项,和weight同级,可以配置多个,matchExpressions和硬亲和力一致
operator:标签匹配的方式 In:相当于key = value的形式 NotIn:相当于key != value的形式
Exists:节点存在label的key为指定的值即可,不能配置values字段
DoesNotExist:节点不存在label的key为指定的值即可,不能配置values字段
Gt:大于value指定的值
Lt:小于value指定的值

说明:可同时配置硬亲和力和软亲和力

9.4 Pod亲和力和反亲和力配置

创建pod-affinity.yaml

apiVersion: v1
kind: Pod
metadata:name: with-pod-affinity
spec:affinity:podAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: securityoperator: Invalues:- S1topologyKey: failure-domain.beta.kubernetes.io/zonepodAntiAffinity:preferredDuringSchedulingIgnoredDuringExecution:- weight: 100podAffinityTerm:labelSelector:matchExpressions:- key: securityoperator: Invalues:- S2namespaces:- defaulttopologyKey: failure-domain.beta.kubernetes.io/zonecontainers:- name: with-pod-affinityimage: nginx

注意:

labelSelector:Pod选择器配置,可以配置多个,匹配的是pod的标签,非node的标签
matchExpressions:和节点亲和力配置一致,pod中只能配置一个
operator:配置和节点亲和力一致,但是没有Gt和Lt
topologyKey:匹配的拓扑域的key,也就是节点上label的key,key和value相同的为同一个域,可以用于标注不同的机房和地区
Namespaces: 和哪个命名空间的Pod进行匹配,为空为当前命名空间

说明:可同时配置node亲和pod亲和力以及pod反亲和力

9.5 案例实践

  • 案例一
    同一个业务的pod副本,部署到不同的node中
    创建一个deployment,vim pod-diff-nodes.yaml
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: must-be-diff-nodesname: must-be-diff-nodesnamespace: kube-public
spec:replicas: 3selector:matchLabels:app: must-be-diff-nodestemplate:metadata:labels:app: must-be-diff-nodesspec:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- must-be-diff-nodestopologyKey: kubernetes.io/hostnamecontainers:- image: nginximagePullPolicy: IfNotPresentname: must-be-diff-nodes
  • 案例二
    将pod调度到符合标签ssd=true的node节点上,并且不调度到gpu=true的node节点上,如果两者都不满足,则调度到type=physical节点上。preferredDuringSchedulingIgnoredDuringExecution代表尽可能,不强制
    1、首先,对master和node节点打上对应的标签
#kubectl label node master01 master02 master03 ssd=true
#kubectl label node master01 master02 master03 gpu=true
#kubectl label node node01 ssd=true
#kubectl label node node02 type=physical
#kubectl get nodes --show-labels |grep ssd  //检查配置

2、创建pod-affinity-ssd.yaml

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: prefer-ssdname: prefer-ssdnamespace: kube-public
spec:replicas: 3selector:matchLabels:app: prefer-ssdtemplate:metadata:creationTimestamp: nulllabels:app: prefer-ssdspec:affinity:nodeAffinity:preferredDuringSchedulingIgnoredDuringExecution:- preference:matchExpressions:- key: ssdoperator: Invalues:- "true"- key: gpuoperator: NotInvalues:- "true"weight: 100- preference:matchExpressions:- key: typeoperator: Invalues:- physicalweight: 10containers:- env:- name: TZvalue: Asia/Shanghai- name: LANGvalue: C.UTF-8image: nginximagePullPolicy: IfNotPresentname: prefer-ssd说明:node中有一个label满足条件,便可以调度上去

3、将node01的ssd=true标签删除,重新创建pod,观察pod会被调度到哪个节点中(正常应该会是node02)

9.6 拓扑域(TopologyKey)

什么时拓扑域
pod亲和性调度需要各个相关的pod对象运行于"同一位置", 而反亲和性调度则要求他们不能运行于"同一位置",

这里指定“同一位置” 是通过 topologyKey 来定义的,topologyKey 对应的值是 node 上的一个标签名称,比如各别节点zone=A标签,各别节点有zone=B标签,pod affinity topologyKey定义为zone,那么调度pod的时候就会围绕着A拓扑,B拓扑来调度,而相同拓扑下的node就为“同一位置”。

可以理解成,它主要针对宿主机,相当于对宿主机进行区域的划分。用label进行判断,不同的key和不同的value是属于不同的拓扑域

实验目的,将5个节点分为三个拓扑域,分别是beijing、shanghai、hangzhou
master01、master02 为region=beijing
master03、node01 为region=shanghai
node02 为region=hangzhou
然后创建3个副本的pod,观察是否分别位于三个region上

1、首先为节点打标签

#kubectl label node master01 master02 region=beijing
#kubectl label node master03 node01 region=shanghai
#kubectl label node node03 region=hangzhou

2、创建pod ,vim diff-zone.yaml

apiVersion: apps/v1
kind: Deployment
metadata:labels:app: must-be-diff-zonename: must-be-diff-zonenamespace: kube-public
spec:replicas: 3selector:matchLabels:app: must-be-diff-zonetemplate:metadata:labels:app: must-be-diff-zonespec:affinity:podAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:- labelSelector:matchExpressions:- key: appoperator: Invalues:- must-be-diff-zonetopologyKey: regioncontainers:- image: nginximagePullPolicy: IfNotPresentname: must-be-diff-zone

3、上面yaml中,是通过region来定义区分不同的拓扑域
注意:如果副本数超过域的数量,就会一直pending,解决该问题需要按照条件调整域的逻辑定义

十、资源配额

十一、RBAC

https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/

11.1 使用 RBAC 鉴权

基于角色(Role)的访问控制(RBAC)是一种基于组织中用户的角色来调节控制对 计算机或网络资源的访问的方法。

RBAC 鉴权机制使用 rbac.authorization.k8s.io API 组 来驱动鉴权决定,允许你通过 Kubernetes API 动态配置策略。

要启用 RBAC,在启动 API 服务器 时将 --authorization-mode 参数设置为一个逗号分隔的列表并确保其中包含 RBAC。

kube-apiserver --authorization-mode=Example,RBAC --<其他选项> --<其他选项>

11.2 API 对象

RBAC API 声明了四种 Kubernetes 对象:

Role
ClusterRole
RoleBinding
ClusterRoleBinding。

11.3 Role 和 ClusterRole

RBAC 的 Role 或 ClusterRole 中包含一组代表相关权限的规则。 这些权限是纯粹累加的(不存在拒绝某操作的规则)。

Role 总是用来在某个名字空间内设置访问权限;在你创建Role时,你必须指定该Role所属的名字空间。

与之相对,ClusterRole则是一个集群作用域的资源。这两种资源的名字不同(Role 和 ClusterRole)是因为 Kubernetes 对象要么是名字空间作用域的,要么是集群作用域的, 不可两者兼具。

ClusterRole的用法

  • 定义对某名字空间域对象的访问权限,并将在各个名字空间内完成授权;
  • 为名字空间作用域的对象设置访问权限,并跨所有名字空间执行授权;
  • 为集群作用域的资源定义访问权限。
    如果你希望在名字空间内定义角色,应该使用 Role; 如果你希望定义集群范围的角色,应该使用 ClusterRole

Role 示例
下面是一个位于 “default” 名字空间的 Role 的示例,可用来授予对 pods 的读访问权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: pod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组resources: ["pods"]verbs: ["get", "watch", "list"]

ClusterRole 示例
ClusterRole 可以和 Role 相同完成授权。 因为 ClusterRole 属于集群范围,所以它也可以为以下资源授予访问权限:

  • 集群范围资源(比如 节点(Node))
  • 非资源端点(比如 /healthz)
  • 跨名字空间访问的名字空间作用域的资源(如 Pods)
    比如,你可以使用 ClusterRole 来允许某特定用户执行 kubectl get pods --all-namespaces
    下面是一个 ClusterRole 的示例,可用来为任一特定名字空间中的 Secret 授予读访问权限, 或者跨名字空间的访问权限(取决于该角色是如何绑定的):
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:# "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制name: secret-reader
rules:
- apiGroups: [""]# 在 HTTP 层面,用来访问 Secret 对象的资源的名称为 "secrets"resources: ["secrets"]verbs: ["get", "watch", "list"]

11.4 RoleBinding 和 ClusterRoleBinding

角色绑定(Role Binding)是将角色中定义的权限赋予一个或者一组用户。 它包含若干 主体(用户、组或服务账户)的列表和对这些主体所获得的角色的引用。 RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。

一个 RoleBinding 可以引用同一的名字空间中的任何 Role。 或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。 如果你希望将某 ClusterRole 绑定到集群中所有名字空间,你要使用 ClusterRoleBinding。

RoleBinding 或 ClusterRoleBinding 对象的名称必须是合法的 路径区段名称。

RoleBinding 示例
下面的例子中的 RoleBinding 将 “pod-reader” Role 授予在 “default” 名字空间中的用户 “jane”。 这样,用户 “jane” 就具有了读取 “default” 名字空间中 pods 的权限。

apiVersion: rbac.authorization.k8s.io/v1
#此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pods
kind: RoleBinding
metadata:name: read-podsnamespace: default
subjects:
#你可以指定不止一个“subject(主体)”
- kind: Username: jane # "name" 是区分大小写的apiGroup: rbac.authorization.k8s.io
roleRef:# "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系kind: Role # 此字段必须是 Role 或 ClusterRolename: pod-reader     # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配apiGroup: rbac.authorization.k8s.io

RoleBinding 也可以引用 ClusterRole,以将对应 ClusterRole 中定义的访问权限授予 RoleBinding 所在名字空间的资源。这种引用使得你可以跨整个集群定义一组通用的角色, 之后在多个名字空间中复用。

例如,尽管下面的 RoleBinding 引用的是一个 ClusterRole,“dave”(这里的主体, 区分大小写)只能访问 “development” 名字空间中的 Secrets 对象,因为 RoleBinding 所在的名字空间(由其 metadata 决定)是 “development”。

apiVersion: rbac.authorization.k8s.io/v1
#此角色绑定使得用户 "dave" 能够读取 "development" 名字空间中的 Secrets
#你需要一个名为 "secret-reader" 的 ClusterRole
kind: RoleBinding
metadata:name: read-secrets# RoleBinding 的名字空间决定了访问权限的授予范围。# 这里隐含授权仅在 "development" 名字空间内的访问权限。namespace: development
subjects:
- kind: Username: dave # 'name' 是区分大小写的apiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io

ClusterRoleBinding 示例
要跨整个集群完成访问权限的授予,你可以使用一个 ClusterRoleBinding。 下面的 ClusterRoleBinding 允许 “manager” 组内的所有用户访问任何名字空间中的 Secrets。

apiVersion: rbac.authorization.k8s.io/v1
#此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 secrets
kind: ClusterRoleBinding
metadata:name: read-secrets-global
subjects:
- kind: Groupname: manager # 'name' 是区分大小写的apiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io

创建了绑定之后,你不能再修改绑定对象所引用的 Role 或 ClusterRole。 试图改变绑定对象的 roleRef 将导致合法性检查错误。 如果你想要改变现有绑定对象中 roleRef 字段的内容,必须删除重新创建绑定对象。

这种限制有两个主要原因:
针对不同角色的绑定是完全不一样的绑定。要求通过删除/重建绑定来更改 roleRef, 这样可以确保要赋予绑定的所有主体会被授予新的角色(而不是在允许或者不小心修改 了 roleRef 的情况下导致所有现有主体未经验证即被授予新角色对应的权限)。
将 roleRef 设置为不可以改变,这使得可以为用户授予对现有绑定对象的 update 权限, 这样可以让他们管理主体列表,同时不能更改被授予这些主体的角色。

11.5 对资源的引用

在 Kubernetes API 中,大多数资源都是使用对象名称的字符串表示来呈现与访问的。 例如,对于 Pod 应使用 “pods”。 RBAC 使用对应 API 端点的 URL 中呈现的名字来引用资源。 有一些 Kubernetes API 涉及 子资源(subresource),例如 Pod 的日志。 对 Pod 日志的请求看起来像这样:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在这里,pods 对应名字空间作用域的 Pod 资源,而 log 是 pods 的子资源。 在 RBAC 角色表达子资源时,使用斜线(/)来分隔资源和子资源。 要允许某主体读取 pods 同时访问这些 Pod 的 log 子资源,你可以这么写:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: pod-and-pod-logs-reader
rules:
- apiGroups: [""]resources: ["pods", "pods/log"]verbs: ["get", "list"]

对于某些请求,也可以通过 resourceNames 列表按名称引用资源。 在指定时,可以将请求限定为资源的单个实例。 下面的例子中限制可以 “get” 和 “update” 一个名为 my-configmap 的 ConfigMap:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: defaultname: configmap-updater
rules:
- apiGroups: [""]# 在 HTTP 层面,用来访问 ConfigMap 的资源的名称为 "configmaps"resources: ["configmaps"]   resourceNames: ["my-configmap"]   #要指定名称,不指定的话对所有的cm都又权限verbs: ["update", "get"]

说明:
你不能使用资源名字来限制 create 或者 deletecollection 请求。 对于 create 请求而言,这是因为在鉴权时可能还不知道新对象的名字。 如果你使用 resourceName 来限制 list 或者 watch 请求, 客户端必须在它们的 list 或者 watch 请求里包含一个与指定的 resourceName 匹配的 metadata.name 字段选择器。 例如,kubectl get configmaps --field-selector=metadata.name=my-configmap

11.6 Role案例

以下示例均为从 Role 或 ClusterRole 对象中截取出来,我们仅展示其 rules 部分。

允许读取在核心 API 组下的 “Pods”:

rules:
- apiGroups: [""]# 在 HTTP 层面,用来访问 Pod 的资源的名称为 "pods"resources: ["pods"]verbs: ["get", "list", "watch"]

允许读/写在 “extensions” 和 “apps” API 组中的 Deployment(在 HTTP 层面,对应 URL 中资源部分为 “deployments”):

rules:
- apiGroups: ["extensions", "apps"]resources: ["deployments"]verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取核心 API 组中的 “pods” 和读/写 “batch” 或 “extensions” API 组中的 “jobs”:

rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]resources: ["jobs"]verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

允许读取名称为 “my-config” 的 ConfigMap(需要通过 RoleBinding 绑定以 限制为某名字空间中特定的 ConfigMap):

rules:
- apiGroups: [""]resources: ["configmaps"]resourceNames: ["my-config"]verbs: ["get"]

允许读取在核心组中的 “nodes” 资源(因为 Node 是集群作用域的,所以需要 ClusterRole 绑定到 ClusterRoleBinding 才生效):

rules:
- apiGroups: [""]resources: ["nodes"]verbs: ["get", "list", "watch"]

允许针对非资源端点 /healthz 和其子路径上发起 GET 和 POST 请求 (必须在 ClusterRole 绑定 ClusterRoleBinding 才生效):

rules:- nonResourceURLs: ["/healthz", "/healthz/*"] # nonResourceURL 中的 '*' 是一个全局通配符verbs: ["get", "post"]

11.7 RoleBinding 示例

下面示例是 RoleBinding 中的片段,仅展示其 subjects 的部分。

对于名称为 alice@example.com 的用户:

subjects:
- kind: Username: "alice@example.com"apiGroup: rbac.authorization.k8s.io

对于名称为 frontend-admins 的用户组:

subjects:
- kind: Groupname: "frontend-admins"apiGroup: rbac.authorization.k8s.io

对于 kube-system 名字空间中的默认服务账户:

subjects:
- kind: ServiceAccountname: defaultnamespace: kube-system

对于任何名称空间中的 “qa” 组中所有的服务账户:

subjects:
- kind: Groupname: system:serviceaccounts:qaapiGroup: rbac.authorization.k8s.io

对于 “development” 名称空间中 “dev” 组中的所有服务帐户:

subjects:
- kind: Groupname: system:serviceaccounts:devapiGroup: rbac.authorization.k8s.ionamespace: development

对于在任何名字空间中的服务账户:

subjects:
- kind: Groupname: system:serviceaccountsapiGroup: rbac.authorization.k8s.io

对于所有已经过认证的用户:

subjects:
- kind: Groupname: system:authenticatedapiGroup: rbac.authorization.k8s.io

对于所有未通过认证的用户:

subjects:
- kind: Groupname: system:unauthenticatedapiGroup: rbac.authorization.k8s.io

对于所有用户:

subjects:
- kind: Groupname: system:authenticatedapiGroup: rbac.authorization.k8s.io
- kind: Groupname: system:unauthenticatedapiGroup: rbac.authorization.k8s.io

二十、账号相关

kubectl get sa //serviceaccount
创建角色-绑定角色-授权-创建账号-测试
https://blog.csdn.net/cr7258/article/details/114274628

1、使用的命令

  • kubectl 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 查看部署的资源
kubect get nodes  查看所有的节点
kubectl get pod -n kube-system 查看是否runing状态
kubectl get pods -o wide
kubectl create deployment nginx --image=nginx     创建一个pod
kubectl  get pod 查看是否runing状态
kubectl expose deployment nginx --port=80 --type=NodePort 暴露端口
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort 暴露端口
kubectl expose deployment web --port=80 --type=NodePort --traget-port=80 --name=web1 -o yaml  > web1.yamlkubectl 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 logs ```bash
kubectl get deploy 查看部署的资源
-- 生成yaml文件
kubectl create demployment web --image=nginx  -o yaml --dry-run > my1.yaml
kubectl get deploy  nginx -o=yaml --export > my2.yaml-- 标签属于pod属性,污点taint属于node节点属性kubectl label node node1 env_role=prod 添加标签
kubectl label node node1 env_role- 删除标签kubectl taint node [node] key=value:污点三个值  添加污点
kubectl taint node k8snode1 key:NoSchedule-   删除污点-- pod升级
kubectl set image deployment web  nginx=nginx:1.15
-- 查看升级状态
kubectl rollout status deployment web
-- 查看历史版本
kubectl rollout history deployment web
-- 回滚
kubectl rollout undo deployment web-- 回滚指定版本
kubectl rollout undo deployment web --to-revision=2
-- 弹性伸缩扩容
kubectl scale deployment web --replicas=5--删除
kubectl delete statefullset --all  删除controller
kubectl delete svc nginx 删除service
kubectl delete pod --all
kubectl delete node --all
kubectl delete -f job.yaml
kubectl delete -f cronJob.yaml -- 进入具体的pod
kubectl exec -it aaa  bash 一次任务
kubectl create -f job.yaml
查看
kubectl get pods
kubectl get jobs 可以查看echo -n 'admin'| base64kubectl get ns 获取命名空间
kubectl create ns roletest  创建一个命名空间kubectl run  nginx --image=nginx -n roletest 运行一个pod,
kubect get pods -n roletestkubectl get role -n roletest  查看创建的角色kubectl get role.rolebinding -n roletest 查看角色绑定
生成证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes lucy-csr.json | cfssljson -bare lucyhelm repo list
helm repo add stable http://mirror.azure.cn/kubernetes/charts/
helm repo remove stable
helm repo updatehelm search repo weave
helm install ui stable/weave-scope
helm list
helm status uikubectl edit  svc ui-weave-scopekubectl create deployment nginxchart --image=nginx -o yaml --dry-run


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 <Master 节点的 IP 和端口 >

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 <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://xxx.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: Srtingmemory: 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=devcontainers:- name: neginximage: 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_roleoperator: Invalues:- dev- testpreferredDuringSchedulingIgnoreDuringExecution:- weight: 1preference:matchExpression:- key: groupoperator: Invalues:- otherprodcontainers:- name: webdemoimage: 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: nginxlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx---apiVersion: apps/v1
kind: StatefulSet
metadata:name: nginx-statefulsetnamespace: default
spec:serviceName: nginxreplicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestports:- 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: piimage: perlcommand: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]restartPolicy: NeverbackoffLimit: 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: helloimage: busyboxargs:- /bin/sh- -c- date; echo Hello from the Kubernetes clusterrestartPolicy: 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: nginximage: nginxenv:- name: SECRET_USERNAMEvalueFrom:secretKeyRef:name: mysecretkey: username- name: SECRET_PASSWORDvalueFrom:secretKeyRef:name: mysecretkey: password


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

secret-vol.yaml

apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: nginximage: nginxvolumeMounts:- name: foomountPath: "/etc/foo"readOnly: truevolumes:- name: foosecret: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: busyboximage: busyboxcommand: [ "/bin/sh","-c","cat /etc/config/redis.properties" ]volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: redis-configrestartPolicy: Never


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

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

vi mycm.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: myconfignamespace: default
data:special.level: infospecial.type: hello

创建pod:(config-var.yaml)

apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: busyboximage: busyboxcommand: [ "/bin/sh", "-c", "echo $(LEVEL) $(TYPE)" ]env:- name: LEVELvalueFrom:configMapKeyRef:name: myconfigkey: special.level- name: TYPEvalueFrom:configMapKeyRef:name: myconfigkey: special.typerestartPolicy: 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: roletestname: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API groupresources: ["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-podsnamespace: roletest
subjects:
- kind: Username: lucy # Name is case sensitiveapiGroup: rbac.authorization.k8s.io
roleRef:kind: Role #this must be Role or ClusterRolename: pod-reader # this must match the name of the Role or ClusterRole you wish to bind toapiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-rolebinding.yaml
kubect get role.rolebinding -n roletest

6、使用证书识别证书

rabc-user.sh

cat > lucy-csr.json <<EOF
{"CN": "lucy","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}]
}
EOFcfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes lucy-csr.json | cfssljson -bare lucykubectl config set-cluster kubernetes \--certificate-authority=ca.pem \--embed-certs=true \--server=https://192.168.163.133:6443 \--kubeconfig=lucy-kubeconfigkubectl config set-credentials lucy \--client-key=lucy-key.pem \--client-certificate=lucy.pem \--embed-certs=true \--kubeconfig=lucy-kubeconfigkubectl config set-context default \--cluster=kubernetes \--user=lucy \--kubeconfig=lucy-kubeconfigkubectl config use-context default --kubeconfig=lucy-kubeconfig

证书复制进来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-kubeconfigkubectl config set-context default \--cluster=kubernetes \--user=mary \--kubeconfig=mary-kubeconfigkubectl 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=nginxkubectl expose deployment web --port=80 --target-port=80 --type=NodePort
  • 部署ingress Controller
    ingress-controller.yaml
apiVersion: v1
kind: Namespace
metadata:name: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---kind: ConfigMap
apiVersion: v1
metadata:name: nginx-configurationnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
kind: ConfigMap
apiVersion: v1
metadata:name: tcp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
kind: ConfigMap
apiVersion: v1
metadata:name: udp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
apiVersion: v1
kind: ServiceAccount
metadata:name: nginx-ingress-serviceaccountnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:name: nginx-ingress-clusterrolelabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
rules:- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ""resources:- nodesverbs:- get- apiGroups:- ""resources:- servicesverbs:- get- list- watch- apiGroups:- ""resources:- eventsverbs:- create- patch- apiGroups:- "extensions"- "networking.k8s.io"resources:- ingressesverbs:- get- list- watch- apiGroups:- "extensions"- "networking.k8s.io"resources:- ingresses/statusverbs:- update---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:name: nginx-ingress-rolenamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
rules:- apiGroups:- ""resources:- configmaps- pods- secrets- namespacesverbs:- get- apiGroups:- ""resources:- configmapsresourceNames:# Defaults to "<election-id>-<ingress-class>"# Here: "<ingress-controller-leader>-<nginx>"# 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:- configmapsverbs:- create- apiGroups:- ""resources:- endpointsverbs:- get---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:name: nginx-ingress-role-nisa-bindingnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: nginx-ingress-role
subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:name: nginx-ingress-clusterrole-nisa-bindinglabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: nginx-ingress-clusterrole
subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx---apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-ingress-controllernamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxannotations:prometheus.io/port: "10254"prometheus.io/scrape: "true"spec:hostNetwork: true# wait up to five minutes for the drain of connectionsterminationGracePeriodSeconds: 300serviceAccountName: nginx-ingress-serviceaccountnodeSelector:kubernetes.io/os: linuxcontainers:- name: nginx-ingress-controllerimage: lizhenliang/nginx-ingress-controller:0.30.0args:- /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.iosecurityContext:allowPrivilegeEscalation: truecapabilities:drop:- ALLadd:- NET_BIND_SERVICE# www-data -> 101runAsUser: 101env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceports:- name: httpcontainerPort: 80protocol: TCP- name: httpscontainerPort: 443protocol: TCPlivenessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 10readinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 10lifecycle:preStop:exec:command:- /wait-shutdown---apiVersion: v1
kind: LimitRange
metadata:name: ingress-nginxnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx
spec:limits:- min:memory: 90Micpu: 100mtype: 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.comhttp:paths:- path: /backend:serviceName: webservicePort: 80

ingress01.yaml

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

ingress02.yaml


---
# https
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:name: tls-example-ingress
spec:tls:- hosts:- sslexample.ctnrs.comsecretName: secret-tlsrules:- host: sslexample.ctnrs.comhttp:paths:- path: /backend:serviceName: webservicePort: 80
  1. 在window系统hosts文件中添加域名访问规则
    hosts地址:C:\Windows\System32\drivers\etc

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.yamlkubectl exec -it nginx-dept1-xxx bash
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-dep1
spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxvolumeMounts:- name: wwwrootmountPath: /usr/share/nginx/htmlports:- containerPort: 80volumes:- name: wwwrootnfs:server: 192.168.63.133path: /data/nfs


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

2、PV和PVC


pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:name: my-pv
spec:capacity:storage: 5GiaccessModes:- ReadWriteManynfs:path: /k8s/nfsserver: 192.168.63.163

pvc.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-dep1
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxvolumeMounts:- name: wwwrootmountPath: /usr/share/nginx/htmlports:- containerPort: 80volumes:- name: wwwrootpersistentVolumeClaim:claimName: my-pvc---apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-pvc
spec:accessModes:- ReadWriteManyresources: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-exporternamespace: kube-systemlabels:k8s-app: node-exporter
spec:selector:matchLabels:k8s-app: node-exportertemplate:metadata:labels:k8s-app: node-exporterspec:containers:- image: prom/node-exportername: node-exporterports:- containerPort: 9100protocol: TCPname: http
---
apiVersion: v1
kind: Service
metadata:labels:k8s-app: node-exportername: node-exporternamespace: kube-system
spec:ports:- name: httpport: 9100nodePort: 31672protocol: TCPtype: NodePortselector: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- podsverbs: ["get", "list", "watch"]
- apiGroups:- extensionsresources:- ingressesverbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]verbs: ["get"]
---
apiVersion: v1
kind: ServiceAccount
metadata:name: prometheusnamespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: prometheus
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: prometheus
subjects:
- kind: ServiceAccountname: prometheusnamespace: kube-system

2、configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:name: prometheus-confignamespace: kube-system
data:prometheus.yml: |global:scrape_interval:     15sevaluation_interval: 15sscrape_configs:- job_name: 'kubernetes-apiservers'kubernetes_sd_configs:- role: endpointsscheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]action: keepregex: default;kubernetes;https- job_name: 'kubernetes-nodes'kubernetes_sd_configs:- role: nodescheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- action: labelmapregex: __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: nodescheme: httpstls_config:ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crtbearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/tokenrelabel_configs:- action: labelmapregex: __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: endpointsrelabel_configs:- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape]action: keepregex: true- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme]action: replacetarget_label: __scheme__regex: (https?)- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path]action: replacetarget_label: __metrics_path__regex: (.+)- source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port]action: replacetarget_label: __address__regex: ([^:]+)(?::\d+)?;(\d+)replacement: $1:$2- action: labelmapregex: __meta_kubernetes_service_label_(.+)- source_labels: [__meta_kubernetes_namespace]action: replacetarget_label: kubernetes_namespace- source_labels: [__meta_kubernetes_service_name]action: replacetarget_label: kubernetes_name- job_name: 'kubernetes-services'kubernetes_sd_configs:- role: servicemetrics_path: /probeparams:module: [http_2xx]relabel_configs:- source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe]action: keepregex: 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: labelmapregex: __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: ingressrelabel_configs:- source_labels: [__meta_kubernetes_ingress_annotation_prometheus_io_probe]action: keepregex: 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: labelmapregex: __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: podrelabel_configs:- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]action: keepregex: true- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]action: replacetarget_label: __metrics_path__regex: (.+)- source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]action: replaceregex: ([^:]+)(?::\d+)?;(\d+)replacement: $1:$2target_label: __address__- action: labelmapregex: __meta_kubernetes_pod_label_(.+)- source_labels: [__meta_kubernetes_namespace]action: replacetarget_label: kubernetes_namespace- source_labels: [__meta_kubernetes_pod_name]action: replacetarget_label: kubernetes_pod_name

3、prometheus.deploy.yml

---
apiVersion: apps/v1
kind: Deployment
metadata:labels:name: prometheus-deploymentname: prometheusnamespace: kube-system
spec:replicas: 1selector:matchLabels:app: prometheustemplate:metadata:labels:app: prometheusspec:containers:- image: prom/prometheus:v2.0.0name: prometheuscommand:- "/bin/prometheus"args:- "--config.file=/etc/prometheus/prometheus.yml"- "--storage.tsdb.path=/prometheus"- "--storage.tsdb.retention=24h"ports:- containerPort: 9090protocol: TCPvolumeMounts:- mountPath: "/prometheus"name: data- mountPath: "/etc/prometheus"name: config-volumeresources:requests:cpu: 100mmemory: 100Milimits:cpu: 500mmemory: 2500MiserviceAccountName: prometheus    volumes:- name: dataemptyDir: {}- name: config-volumeconfigMap:name: prometheus-config   

4、prometheus.svc.yml

---
kind: Service
apiVersion: v1
metadata:labels:app: prometheusname: prometheusnamespace: kube-system
spec:type: NodePortports:- port: 9090targetPort: 9090nodePort: 30003selector:app: prometheus

3、grafana

1、grafana-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:name: grafana-corenamespace: kube-systemlabels:app: grafanacomponent: core
spec:selector:matchLabels:app: grafanacomponent: corereplicas: 1template:metadata:labels:app: grafanacomponent: corespec:containers:- image: grafana/grafana:4.2.0name: grafana-coreimagePullPolicy: IfNotPresent# env:resources:# keep request = limit to keep this container in guaranteed classlimits:cpu: 100mmemory: 100Mirequests:cpu: 100mmemory: 100Mienv:# The following env variables set up basic auth twith the default admin user and admin password.- name: GF_AUTH_BASIC_ENABLEDvalue: "true"- name: GF_AUTH_ANONYMOUS_ENABLEDvalue: "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: /loginport: 3000# initialDelaySeconds: 30# timeoutSeconds: 1volumeMounts:- name: grafana-persistent-storagemountPath: /varvolumes:- name: grafana-persistent-storageemptyDir: {}

2、grafana-svc.yaml

apiVersion: v1
kind: Service
metadata:name: grafananamespace: kube-systemlabels:app: grafanacomponent: core
spec:type: NodePortports:- port: 3000selector:app: grafanacomponent: core

3、grafana-ing.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:name: grafananamespace: kube-system
spec:rules:- host: k8s.grafanahttp:paths:- path: /backend:serviceName: grafanaservicePort: 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 <Master节点的IP和端口 >

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 <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-ltdlyum install -y keepalived

3.2配置master节点

master1节点配置

cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalivedglobal_defs {router_id k8s
}vrrp_script check_haproxy {script "killall -0 haproxy"interval 3weight -2fall 10rise 2
}vrrp_instance VI_1 {state MASTER interface ens33 virtual_router_id 51priority 250advert_int 1authentication {auth_type PASSauth_pass ceb1b3ec013d66163d6ab}virtual_ipaddress {192.168.44.158}track_script {check_haproxy}}
EOF

master2节点配置

cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalivedglobal_defs {router_id k8s
}vrrp_script check_haproxy {script "killall -0 haproxy"interval 3weight -2fall 10rise 2
}vrrp_instance VI_1 {state BACKUP interface ens33 virtual_router_id 51priority 200advert_int 1authentication {auth_type PASSauth_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 local2chroot      /var/lib/haproxypidfile     /var/run/haproxy.pidmaxconn     4000user        haproxygroup       haproxydaemon # turn on stats unix socketstats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaultsmode                    httplog                     globaloption                  httplogoption                  dontlognulloption http-server-closeoption forwardfor       except 127.0.0.0/8option                  redispatchretries                 3timeout http-request    10stimeout queue           1mtimeout connect         10stimeout client          1mtimeout server          1mtimeout http-keep-alive 10stimeout check           10smaxconn                 3000
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#---------------------------------------------------------------------
frontend kubernetes-apiservermode                 tcpbind                 *:16443option               tcplogdefault_backend      kubernetes-apiserver
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiservermode        tcpbalance     roundrobinserver      master01.k8s.io   192.168.44.155:6443 checkserver      master02.k8s.io   192.168.44.156:6443 check
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen statsbind                 *:1080stats auth           admin:awesomePasswordstats refresh        5sstats realm          HAProxy\ Statisticsstats 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://xxx.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.yamlapiServer:certSANs:- master1- master2- master.k8s.io- 192.168.44.158- 192.168.44.155- 192.168.44.156- 127.0.0.1extraArgs:authorization-mode: Node,RBACtimeoutForControlPlane: 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/16serviceSubnet: 10.1.0.0/16
scheduler: {}

6.2 在master1节点执行

$ kubeadm init --config kubeadm-config.yaml

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

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 cskubectl 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 nodekubectl 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 nodekubectl 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

六、在集群环境部署项目

k8s:概念以及搭建高可用集群相关推荐

  1. k8s高可用集群_搭建高可用集群(初始化和部署keepalived)---K8S_Google工作笔记0055

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们来部署keepalived,搭建高可用集群. 然后我们这里需要master,155, ma ...

  2. k8s高可用集群_搭建高可用集群(实现方式介绍)---K8S_Google工作笔记0054

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 然后我们来说搭建高可用集群,为什么要搭建高可用集群. 因为,首先我们说master节点是用来管理其 ...

  3. 用Keepalived搭建高可用集群

    一.集群介绍 1.根据功能划分为两大类:高可用和负载均衡 2.高可用:一台工作,另一台冗余,当一台服务器故障宕机时,另一台服务器提供服务.开源软件有heartbeat,keepalived. 3.负载 ...

  4. 【Nginx那些事】nginx配置实例(四)搭建高可用集群

    [Nginx那些事]nginx配置实例(四)搭建高可用集群 nginx 实现高可用 安装keepalived keepalived配置 主Nginx服务器配置 从nginx服务器配置 脚本文件权限设置 ...

  5. Kafka基于Zookeeper搭建高可用集群实战

    Kafka基于Zookeeper搭建高可用集群实战 1 前言 1.1 高可用的由来 为何需要Replication? 在Kafka在0.8以前的版本中,是没有Replication的,一旦某一个Bro ...

  6. 12. 搭建高可用集群

    文章目录 12.1 Keepalived+Nginx 高可用集群(主从模式) 12.1.1 集群架构图 12.1.2 具体搭建步骤 12.1.2.1 搭建高可用集群基础环境 12.1.2.2 完成高可 ...

  7. 在 Kubernetes 中, 搭建高可用集群

    永久地址:在 Kubernetes 中, 搭建高可用集群(保存网址不迷路

  8. 16、Kubernetes搭建高可用集群

    文章目录 前言 一.高可用集群 1.1 高可用集群技术细节 二.部署高可用集群 2.1 准备环境 2.2 所有master节点部署keepalived 2.2.1 安装相关包和keepalived 2 ...

  9. RocketMQ的组织架构和基本概念,Dledger高可用集群架构原理

    文章目录 1. MQ产品介绍 2. rocketMQ组织架构 ①:NameServer ②:Broker ③:生产者(Producer) ④:消费者(Consumer) ⑤:主题(Topic) ⑥:消 ...

最新文章

  1. 【转】不分主副卡!全网通5.0时代到来
  2. 使用tab键分割的文章能快速转换成表格。( )_无需按空格键,就能将Word文字对齐,3种方法了解一下...
  3. SQL Server 为什么事务日志自动增长会降低你的性能
  4. 补补算术基础:编程中的进制问题
  5. 中国磁性材料行业竞争趋势及供需前景分析报告2021年版
  6. 云路由 vyatta 体验(一)基本设置
  7. 批处理 操作mysql_用批处理对MySQL进行数据操作
  8. HTML5与CSS3权威指南笔记案例1
  9. linux-----强大的find
  10. 三个线程打印ABC10次,ABCABCABC....
  11. 设计模式-观察者模式 发布/订阅模式
  12. android内容提供器读取图片,android实现拍照或从相册选取图片
  13. 牛客网–华为机试在线训练8:合并表记录
  14. 编写测试用例方法之等价类划分法
  15. AI人工智能的5种绝佳编程语言
  16. 【英语:基础进阶_原著扩展阅读】J6.原著阅读实战训练
  17. 调焦后焦实现不同距离成像_照片要清晰、对焦必须深入理解!对焦模式、对焦区域模式等对焦知识...
  18. 矩阵范数,向量范数,奇异值有什么用?
  19. ATOM基础教程一linter-php配置(12)
  20. 层次结构图和层次图的联系_了解层次结构的限制

热门文章

  1. 模型训练评估——交叉验证法的介绍
  2. 深信服EDS与Intel合作,让性能与低价不必“二选一”
  3. matlab非同秩矩阵相乘_MATLAB自学笔记(八):矩阵元素运算与矩阵运算
  4. 去中心化区块链应用(DAPP)windows开发环境配置
  5. Proto3使用指南
  6. Camera Tunning调试相关
  7. 曲面屏那么好看,为什么实际购买的人并不多?这4点原因很真实
  8. Cypress-this element is detached from the DOM报错
  9. 世界第一位半机械人出现
  10. eclipse 注释配置