大数据——云原生|拥抱K8s——前置篇


文章目录

  • 拥抱K8S
  • 介绍+搭建
    • 简介
    • 主要特性
    • K8S组件
      • master组件---管理
      • node组件---具体工作者
    • 核心概念
    • 下载部署
    • 二进制安装
  • 资源管理
    • 资源管理方式
      • 命令式对象管理
      • 命令式对象配置
      • 声明式对象配置
  • 逻辑概念
    • namespace
    • pod
    • Label
    • Deployment
    • Service
  • Pod详述

拥抱K8S 介绍+搭建 传送门
  • 传统式部署:直接将应用程序部署在物理机上,很难合理性分配资源
  • 虚拟化部署:每个虚拟机都是一个独立的环境,解决了应用程序之间的影,一定程度上解决了资源,但增加了操作系统的部署
  • 容器化部署:类似虚拟化,但是共享了操作系统,而且可以跨云服务商、跨linux操作系统
    • 某个容器出故障宕机,另外一个容器立刻启动补上
    • 并发访问变大,如何做到横向扩展容器数量
【大数据——云原生|拥抱K8s——前置篇】最后的问题实则都是关于容器编排的问题
简介
容器化部署、管理、扩展,想想带环境安装,虽说docker也可以实现容器化的部署,但是还是需要一个完全功能的集群部署功能,而且k8s利于应用的扩展
主要特性 自动装箱:应用自动部署
自愈能力:当有容器失败的时候会对容器进行重启,有问题时,会重新部署和调度,未通过检查,会关闭该容器
水平扩展:根据简单命令和ui页面以及cpu使用情况,方便扩容和裁剪
服务发现:k8s自带发现服务功能和负载均衡
滚动更新:可根据应用变化,对容器运行应用进行批次或一次性更新,检测没有问题再更新
版本回退:历史版本记录,可以即时回退
密码配置管理:热部署,不需要重启
存储编排:支持存储本地、网络存储、公有云存储
批处理:支持一次性任务、定时任务
K8S组件
master(主控节点)和node(工作节点)
大数据——云原生|拥抱K8s——前置篇
文章图片

master组件—管理
api server:集群的统一控制访问入口,以restful方式,交给etcd进行存储
scheduler:节点调度,选择节点应用部署
controller-manager:处理集群中常规的后台任务,一个资源对应一个控制器
形象理解三者关系,统一入口rest请求,scheduler选择某个节点,controller去在该节点上部署服务
etcd:存储状态类的数据,比如master、node的节点信息。有点类型元数据库,也可以替换成mysql或者其他数据库
node组件—具体工作者
kubelet:node里面的管理者,各种状态信息,节点用来管理容器
kube-proxy:提供网络代理,外部访问容器应用程序,负载均衡,类似nginx
docker:负责节点上容器的各种操作
核心概念 Pod:最小的部署单元,一组容器的集合,共享网络,生命周期短暂的
controller
  • 确保预期pod的副本的数量
  • 无状态的应用部署(一个节点挂了的容器自动在另外节点启动),有状态应用部署(需要特定条件,不考虑依赖性)
  • 确保所有的node运行同一个pod(比如多个节点运行同一个服务)
  • 可以创建一致性任务和定时任务
形象理解无状态,就是比如一个容器宕了,直接可以将运行该容器内的服务拿到其他容器运行,这就是无状态的
service:定义一组pod访问规则,不同服务请求不同的pod
下载部署 确保docker已安装完成
# 时间同步 yum install ntpdate -y ntpdate time.windows.com# 关闭防火墙 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# 永久# 三台节点/etc/hosts需要配置# 将桥接的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源,方便安装 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# 安装1.18.0版本 yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0# 开机自启 systemctl enable kubelet# 主节点启动 参数介绍:当前节点ip 国内镜像 k8s版本 可连接的ip网段 kubeadm init \ --apiserver-advertise-address=172.16.6.10 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.18.0 \ --service-cidr=10.96.0.0/12 \ --pod-network-cidr=10.244.0.0/16mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config# 使用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# 从节点加入主节点集群 kubeadm join 172.16.6.10:6443 --token jvdyus.xkae0oh1j7qkvluu \ --discovery-token-ca-cert-hash sha256:b738b0598deb74177613994c9299f28a3899144e0d7e61da859b26d0768db148# 如果产生报错[ERROR FileContent--proc-sys-net-ipv4-ip_forward]: /proc/sys/net/ipv4/ip_forw sysctl -w net.ipv4.ip_forward=1# 再次查看节点信息,没有准备好,需要进行下一步 [root@lv118 sysctl.d]# kubectl get nodes NAMESTATUSROLESAGEVERSION lv118.dct-znv.comNotReadymaster10mv1.18.0 lv121.dct-znv.comNotReady77sv1.18.0 lv123.dct-znv.comNotReady14sv1.18.0# 部署CNI网络插件 wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml kubectl apply -f kube-flannel.yml# 等待全部都是ready kubectl get pods -n kube-system# 再次查看节点信息 [root@lv118 sysctl.d]# kubectl get nodes NAMESTATUSROLESAGEVERSION lv118.dct-znv.comReadymaster18mv1.18.0 lv121.dct-znv.comReady9m21sv1.18.0 lv123.dct-znv.comReady8m18sv1.18.0# 测试k8s集群 kubectl create deployment nginx --image=nginx kubectl expose deployment nginx --port=80 --type=NodePortkubectl get pod,svc # 任意一个节点访问80端口对外暴露端口,这里的是32574

大数据——云原生|拥抱K8s——前置篇
文章图片

二进制安装 资源管理 yaml书写介绍:https://www.bilibili.com/video/BV1Qv41167ck?p=13&share_source=copy_web
yaml转json的网站,可以通过它验证yaml是否书写正确https://www.json2yaml.com/convert-yaml-to-json
资源管理方式 kubectl是一个命令行工具
  • 命令式对象管理:直接用命令去操作kubernetes资源(命令行直接写参数)
kubectl run nginx-pod --image=nginx:1.17.1 --port=80

  • 命令式对象配置:通过命令配置和配置文件去操作kubernetes资源(通过配置文件)
kubectl create/patch -f nginx-pod.yaml

  • 声明式对象配置:通过apply命令和配置文件去操作kubernetes资源(只有一个apply关键字,只用于创建和更新资源,也就是该命令没有的时候创建,有了就表示更新)
kubectl apply -f nginx-pod.yaml

综上,第一个比较简单,一般用于测试,不能追踪;第二个适用于开发环境,可以直接定位追踪到文件配置,但项目较大的时候,文件过多;第三个适用于开发环境,支持目录的操作(yaml文件放在一个目录内,对目录进行操作,整体创建/更新)
命令式对象管理
kubectl [command] [type] [name] [flags]# 查看所有的pod kubectl get pod# 差看某一个pod kubectl get pod [pod_name]# 查看某个pod所处节点 kubectl get pod [pod_name] -o wide# 查看某个pod,以yaml格式展示结果 kubectl get pod [pod_name] -o yaml# 查看资源 kubectl api-resources

资源分类 资源名称 缩写 资源作用
集群级别资源 nodes no 集群组成部分
namespaces ns 隔离Pod
pod资源 pods po 装载容器
pod资源控制器 replicationcontrollers rc 控制pod资源
replicasets rs 控制pod资源
deployments deploy 控制pod资源
daemonsets ds 控制pod资源
jobs 控制pod资源
cronjobs cj 控制pod资源
horizontalpodautoscalers hpa 控制pod资源
statefulsets sts 控制pod资源
服务发现资源 services svc 统一pod对外接口
ingress ing 统一pod对外接口
存储资源 volumeattachments 存储
persistentvolumes pv 存储
persistentvolumeclaims pvc 存储
配置资源 configmaps cm 配置
secrets 配置
# 测试使用# 创建一个dev的命名空间,ns是namespaces缩写,上表有提及 kubectl create ns dev# 查看全部namespaces kubectl get ns# 在dev下创建一个pod kubectl run pod --image=nginx -n dev# 查看所创建的pod kubectl get pods -n dev# 查看创建该pod的详细信息 kubectl describe pods pod -n dev# 删除该创建的pod kubectl delete pods pod -n dev# 删除空间dev kubectl delete ns dev

命令式对象配置
# 创建nginxpod.yaml文件,写入如下内容 apiVersion: v1 kind: Namespace metadata: name: dev---apiVersion: v1 kind: Pod metadata: name: nginxpod namespace: dev spec: containers: - name: nginx-containers image: nginx:latest# 创建资源 kubectl create -f nginxpod.yaml# 删除资源 kubectl delete -f nginxpod.yaml

声明式对象配置
# 利用前文提及yaml文件进行创建 kubectl apply -f nginxpod.yaml# 查看资源 kubectl get pods -n dev# 再次执行,会进行更新操作,因为已存在,如果没有变化会显示unchanged,有变动会显示configured kubectl apply -f nginxpod.yaml

以上操作都是在主节点进行,如果需要从节点执行,需要拷贝主节点用户目录下的.kube文件到从节点用户目录下
逻辑概念 namespace 实现多套环境的资源隔离和多租户的资源隔离
  • namespace用于将pod划分为逻辑上的分组,以便于实现不同组之间的资源隔离
  • namespace也可对不同的租户进行管理,限制不同租户所占用的资源,例如cpu核数、内存使用
# 查看namespace,k8s启动时会有几个默认的namespace kubectl get nsdefault#所有未指定Namespace的对象都会被分配在default命名空间 kube-node-lease#集群节点之间的心跳维护,v1.13开始引入 kube-public#此命名空间下的资源可以被所有人访问(包括未认证用户) kube-system#所有由Kubernetes系统创建的资源都处于这个命名空间# 查看某一ns详情 kubectl get ns defaultName:default Labels: Annotations: Status:Active# Active 命名空间正在使用中Terminating 正在删除命名空间 No resource quota.# ResourceQuota 针对namespace做的资源限制 No LimitRange resource. # LimitRange针对namespace中的每个组件做的资源限制# 查、创、删 命令行 [root@lv118 disk3]# kubectl create ns dev namespace/dev created [root@lv118 disk3]# kubectl get ns dev NAMESTATUSAGE devActive10s [root@lv118 disk3]# kubectl delete ns dev namespace "dev" deleted# 查、创、删 yaml文件 [root@lv118 disk3]# cat ns-dev.yaml apiVersion: v1 kind: Namespace metadata: name: dev[root@lv118 disk3]# kubectl create -f ns-dev.yaml namespace/dev created [root@lv118 disk3]# kubectl get ns dev NAMESTATUSAGE devActive12s [root@lv118 disk3]# kubectl delete -f ns-dev.yaml namespace "dev" deleted

pod pod是k8s最小单元,应用程序跑在容器内,容器存在pod内,所以一个pod可以有多个容器
# 创建并运行指定镜像的pod kubectl run nginx --image=nginx --port=80 --namespace dev# 查看pod相关信息 kubectl get pods -n dev -o wide# 查看pod详细信息 kubectl describe pod nginx -n dev# 删除pod kubectl delete pod nginx -n dev # 旧版本删完还存在,是因为后台是存在一个控制器,删除立马重启,这里需要删除控制器,就可删除干净(新版本忽略) kubectl delete deploy nginx -n dev# yaml文件形式创建 cat pod-nginx.yamlapiVersion: v1 kind: Pod metadata: name: nginx namespace: dev spec: containers: - image: nginx:latest name: pod ports: - name: nginx-port containerPort: 80 protocol: TCP [root@lv118 disk3]# kubectl create -f pod-nginx.yaml pod/nginx created [root@lv118 disk3]# kubectl get pods -n dev NAMEREADYSTATUSRESTARTSAGE nginx1/1Running09s [root@lv118 disk3]# kubectl delete -f pod-nginx.yaml pod "nginx" deleted

Label label的作用在于给资源添加标识,和用于区分选择,和namespace不同的是这是可以互相通信的,由于在功能上不同,所以用以标签区别
  • 基于等式的标签选择器,选择所有包含Label中key="name"且value="https://www.it610.com/article/slave"的对象
  • 基于集合的标签选择器 name in (master,slave):选择所有label中key="name"且value="https://www.it610.com/article/master"或"slave"的对象
# 查看pod打标签 [root@lv118 disk3]# kubectl get pod -n dev --show-labels NAMEREADYSTATUSRESTARTSAGELABELS nginx1/1Running03m14s# 打标签 [root@lv118 disk3]# kubectl label pod nginx -n dev version=1.0 pod/nginx labeled# 再次查看 [root@lv118 disk3]# kubectl get pod -n dev --show-labels NAMEREADYSTATUSRESTARTSAGELABELS nginx1/1Running03m56sversion=1.0# 修改标签 [root@lv118 disk3]# kubectl label pod nginx -n dev version=2.0 --overwrite pod/nginx labeled# 再次查看 [root@lv118 disk3]# kubectl get pod -n dev --show-labels NAMEREADYSTATUSRESTARTSAGELABELS nginx1/1Running05m22sversion=2.0# 再添加一个pod,记得修改yaml文件内pod名字 # 将新pod增加版本,结果最后如下 [root@lv118 disk3]# kubectl get pod -n dev --show-labels NAMEREADYSTATUSRESTARTSAGELABELS nginx1/1Running07m36sversion=2.0 nginx11/1Running060sversion=1.0# 查询指定范围标签的pod [root@lv118 disk3]# kubectl get pods -l version!=1.0-n dev --show-labels NAMEREADYSTATUSRESTARTSAGELABELS nginx1/1Running013mversion=2.0# 删除某个标签 [root@lv118 disk3]# kubectl label pod nginx -n dev version-# pod-nginx.yaml文件配置 apiVersion: v1 kind: Pod metadata: name: nginx namespace: dev labels: version: "3.0" env: "test" spec: containers: - image: nginx:latest name: pod ports: - name: nginx-port containerPort: 80 protocol: TCP # 更新 kubectl apply -f pod-nginx.yaml #再次查看 [root@lv118 disk3]# kubectl get pods -n dev --show-labels NAMEREADYSTATUSRESTARTSAGELABELS nginx1/1Running022menv=test,version=3.0

Deployment pod虽然作为k8s中最小控制单元,但k8s却很少去直接控制,一般都是通过pod控制器来完成,pod控制器用于pod的管理,当pod故障时,会尝试重启/重建pod
# 创建Deployment kubectl create deployment nginx --image=nginx -n dev# 删除Deployment kubectl delete deploy nginx -n dev# deploy-nginx.yaml文件配置 apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: dev spec: replicas: 3 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: nginx:latest name: nginx ports: - containerPort: 80 protocol: TCP # 运行文件 kubectl create -f deploy-nginx.yaml # 查看 kubectl get deployment,pods -n dev

Service 利用pod控制器可以很轻松让挂掉的pod重新启动,但是如果我们访问的是之前旧的podip端口,这样一重启岂不是ip都变了嘛
service可以看作是一组同类pod对外访问的接口,接助service,应用可以很方便的实现服务发现和负载均衡,同类指的是标签,serviceip是不变的
# 1、集群内部访问 # 创建service kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev# 查看service [root@lv118 disk3]# kubectl get svc svc-nginx1 -n dev -o wide NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGESELECTOR svc-nginx1ClusterIP10.96.19.19780/TCP4mrun=nginx# 访问service的ip和端口 [root@lv118 disk3]# curl 10.96.19.197:80# 2、外部访问 [root@lv118 disk3]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev [root@lv118 disk3]# kubectl get svc -n dev NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE svc-nginx1ClusterIP10.96.19.19780/TCP6m39s svc-nginx2NodePort10.110.163.15680:30419/TCP13s # 本机浏览器访问,注意端口来自上文的svc端口 master服务器地址:30419# 删除service [root@lv118 disk3]# kubectl delete svc svc-nginx2 -n dev service "svc-nginx2" deleted [root@lv118 disk3]# kubectl delete svc svc-nginx1 -n dev service "svc-nginx1" deleted# svc-nginx.yaml文件 apiVersion: v1 kind: Service metadata: name: svc-nginx namespace: dev spec: clusterIP: 10.109.179.231 #固定svc的内网ip ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx type: ClusterIP # 执行文件 kubectl create -f svc-nginx.yaml # 查看 kubectl get svc -n dev

Pod详述 pod配置项
apiVersion: v1#必选,版本号,例如v1 kind: Pod#必选,资源类型,例如 Pod metadata:#必选,元数据 name: string#必选,Pod名称 namespace: string#Pod所属的命名空间,默认为"default" labels:#自定义标签列表 - name: string spec:#必选,Pod中容器的详细定义 containers:#必选,Pod中容器列表 - name: string#必选,容器名称 image: string#必选,容器的镜像名称 imagePullPolicy: [ Always|Never|IfNotPresent ]#获取镜像的策略 command: [string]#容器的启动命令列表,如不指定,使用打包时使用的启动命令 args: [string]#容器的启动命令参数列表 workingDir: string#容器的工作目录 volumeMounts:#挂载到容器内部的存储卷配置 - name: string#引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名 mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符 readOnly: boolean #是否为只读模式 ports: #需要暴露的端口库号列表 - name: string#端口的名称 containerPort: int#容器需要监听的端口号 hostPort: int#容器所在主机需要监听的端口号,默认与Container相同 protocol: string#端口协议,支持TCP和UDP,默认TCP env:#容器运行前需设置的环境变量列表 - name: string#环境变量名称 value: string #环境变量的值 resources: #资源限制和请求的设置 limits:#资源限制的设置 cpu: string#Cpu的限制,单位为core数,将用于docker run --cpu-shares参数 memory: string#内存限制,单位可以为Mib/Gib,将用于docker run --memory参数 requests: #资源请求的设置 cpu: string#Cpu请求,容器启动的初始可用数量 memory: string #内存请求,容器启动的初始可用数量 lifecycle: #生命周期钩子 postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启 preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止 livenessProbe:#对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器 exec:#对Pod容器内检查方式设置为exec方式 command: [string]#exec方式需要制定的命令或脚本 httpGet:#对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port path: string port: number host: string scheme: string HttpHeaders: - name: string value: string tcpSocket:#对Pod内个容器健康检查方式设置为tcpSocket方式 port: number initialDelaySeconds: 0#容器启动完成后首次探测的时间,单位为秒 timeoutSeconds: 0#对容器健康检查探测等待响应的超时时间,单位秒,默认1秒 periodSeconds: 0#对容器监控检查的定期探测时间设置,单位秒,默认10秒一次 successThreshold: 0 failureThreshold: 0 securityContext: privileged: false restartPolicy: [Always | Never | OnFailure]#Pod的重启策略 nodeName: > #设置NodeName表示将该Pod调度到指定到名称的node节点上 nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上 imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定 - name: string hostNetwork: false#是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络 volumes:#在该pod上定义共享存储卷列表 - name: string#共享存储卷名称 (volumes类型有很多种) emptyDir: {}#类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值 hostPath: string#类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录 path: string#Pod所在宿主机的目录,将被用于同期中mount的目录 secret:#类型为secret的存储卷,挂载集群与定义的secret对象到容器内部 scretname: string items: - key: string path: string configMap:#类型为configMap的存储卷,挂载预定义的configMap对象到容器内部 name: string items: - key: string path: string

    推荐阅读