K8S - 架构、常用K8S命令、yaml资源清单部署、Ingress、故障排查、存储卷

K8S

  • K8S官网文档:https://kubernetes.io/zh/docs/home/
  • 学习东西还是要从官方文档入手;
  • 用于管理、扩展、自动部署容器; 其实就是 对多个跨机器的Docker集群;

K8S特性

  • 服务发现和负载均衡
    Kubernetes 可以使用 DNS 名称或自己的 IP 地址来暴露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
  • 自动部署和回滚
    创建新容器, 删除现有容器并将它们的所有资源用于新容器。
  • 自我修复
    Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。

Docker编排常用命令

K8S 的核心功能:自动化运维管理多个容器化程序;

核心架构角色:

  • kube-apiserver

    负责公开了 Kubernetes API,负责处理接受请求的工作;

  • etcd

    分布式数据库;一致且高可用的键值存储,用作 Kubernetes 所有集群数据的后台数据库。需要保证高可用、避免单点故障;

  • kube-scheduler

    • 分布式调度器;用来调度在指定节点上创建pod;
    • 调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、工作负载;简单可以理解为选择空闲的机器创建pod;
  • kube-controller-manager

    • 节点控制器(Node Controller):负责在节点出现故障时进行通知和响应
    • 任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
    • 还有其他控制器、暂时不涉及;
  • kubelet

    • Worker Node 的监视器,以及与 Master Node 的通讯器
    • kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。
    • 会向Master node汇报自身node服务运行的状态;并接受来自 Master Node 的指示采取调整措施
    • kubelet 只管理由 Kubernetes 创建的容器。
  • kube-proxy

    • kube-proxy 是集群中每个节点(node)上所运行的网络代理, 负责 Node 在 K8S 的网络通讯
  • Container Runtime

    • Worker Node 的运行环境 ,负责运行容器的软件。例如Docker Engine引擎;

简单命令执行流程

当我们执行创建Ngnix的容器时、执行以下K8S命令

kubectl create deployment nginx --image=nginx

命令的执行流程如下:

  1. API Server收到命令请求;
  2. API Server将命令交给Controller Manager 、CM生成应用部署记录;
  3. CM调用 API Server 将 应用部署记录 存入 etcd数据库;
  4. Scheduler调度器 定时调用 API Server 查询 etcd,获取到应用部署记录 与 worker node运行情况、 根据调度算法 决定 要在哪台node上部署应用;
  5. Scheduler 调用 API Server将调度结果记录放入etcd数据;
  6. 每个worker node的Kubelet 定时与 Master Node API Server 保持心跳与通信、获取到etcd中的调度结果记录, 每个节点判断是否要在本机上部署、 是则创建Pod、并随时汇报Pod运行情况;
  7. 每一个机器上的kube-proxy能知道集群的所有网络,只要node访问别人或者别人访问node,node上的kube-proxy网络代理自动计算进行流量转发

kubectl命令使用

语法:

kubectl command TYPE NAME flags

  • command :操作类型、例如 create、get、describe、delete
  • TYPE: 资源类型、 资源类型不区分大小写;
  • NAME: 指定资源的名称。名称区分大小写。 如果省略名称,则显示所有资源的详细信息。例如:kubectl get pod

你需要帮助,在终端窗口中运行 kubectl help

创建一个Tomcat应用程序

kubectl create deployment my-tomcat --image=tomcat:7.0.75-alpine

查询部署信息

kubectl get deployment

获取pod信息

kubectl get pod -o wide

根据name查询pod信息

kubectl get pod my-tomcat -o wide

查看容器日志

kubectl logs my-tomcat-685b8fd9c9-rw42d(pod名称)

使用 exec 可以在Pod的容器中执行命令,这里使用 env 命令查看环境变量

kubectl exec my-tomcat-685b8fd9c9-rw42d -- env

kubectl exec my-tomcat-685b8fd9c9-rw42d -- ls / # 查看容器的根目录下面内容

进入Pod容器内部并执行bash命令,如果想退出容器可以使用exit命令

kubectl exec -it my-tomcat-685b8fd9c9-rw42d -- sh

访问一下这个tomcat pod

集群内访问(在集群里任一worker节点都可以访问)

curl 10.244.36.69:8080

集群外部访问

K8S中、将服务暴露到外网访问、需要使用service;

kubectl expose deployment my-tomcat --name=tomcat --port=8080 --type=NodePort

查看service

kubectl get svc -o wide

svc 是 service简写

K8S的service服务端口号为8080, 宿主机映射的随机端口为32224, 因此可通过 集群工作节点IP : 随机端口 访问

service服务有个特点,如果端口暴露类型为NodePort,那么可以通过集群内所有worker主机加暴露的端口进行访问

删除Pod:

  1. 查看 pod运行情况、 -w代表一直等待、可查看变化;类似tail -f 命令

#查看pod信息,-w意思是一直等待观察pod信息的变动

kubectl get pod -w

  1. 开另外一个命令窗口执行删除命令、 并观察1中的内容变化;

kubectl delete pod my-tomcat-685b8fd9c9-rw42d

  1. 重启了一个Pod;

这意味着、每次执行del都会重新创建运行Pod, 相当于是Pod重启命令、 也是 K8S的核心特性、服务自愈;

  1. 查看下deployment和service的状态

kubectl get pod,svc

  1. 查看服务运行情况, 还是可以访问成功;

服务扩缩容

  1. 执行scale扩容

kubectl scale --replicas=5 deployment my-tomcat

  1. 查看pod
  1. 执行scale缩容

kubectl scale --replicas=3 deployment my-tomcat

滚动升级与回滚

对my-tomcat这个deployment进行滚动升级和回滚,将tomcat版本由tomcat:7.0.75-alpine升级到tomcat:8.0.41-jre8-alpine,再回滚到tomcat:7.0.75-alpine

  1. 滚动升级:
    使用set image设置镜像

kubectl set image deployement my-tomcat tomcat= tomcat:8.0.41-jre8-alpine

  1. 执行 kubectl get pod -w 观察pod的变动情况,可以看到有的pod在销毁,有的pod在创建
  1. 查看pod信息
  2. 查看某个pod的详细信息

kubectl describe pod my-tomcat-547db86547-4btmd

镜像已经升级了;

  1. 访问下tomcat

  2. 版本回滚

  3. 查看历史版本

kubectl rollout history deploy my-tomcat

  1. 回滚到上一个版本

kubectl rollout undo deployment my-tomcat #--to-revision 参数可以指定回退的版本

  1. 再次访问tomcat,发现版本已经回退

标签的使用

通过给资源添加Label,可以方便地管理资源(如Deployment、Pod、Service等)。

  1. 查看Deployment中所包含的Label

kubectl subscribe deployment my-tomcat

  1. 通过Label查询Pod

kubectl get pod -l app=my-tomcat

  1. 通过Label查询Service

kubectl get service -l app=my-tomcat

  1. 给Pod添加Label

kubectl label pod my-tomcat-685b8fd9c9-lrwst version = v1

  1. 查看Pod的详细信息,可以查看Label信息:

kubectl describe pods my-tomcat-685b8fd9c9-lrwst

  1. 通过Label查询Pod

kubectl get pod -l version=v1

  1. 通过Label删除服务

kubectl delete service -l version=v1

命令总结:

kubectl create deployment #创建一个deployment来管理创建的容器

kubectl get #显示一个或多个资源,可以使用标签过滤,默认查看当前名称空间的资源

kubectl expose #将一个资源暴露为一个新的kubernetes的service资源,资源包括pod (po), service (svc), replicationcontroller (rc),deployment(deploy), replicaset (rs)

kubectl describe #显示特定资源或资源组的详细信息

kubectl scale #可以对Deployment, ReplicaSet, Replication Controller, 或者StatefulSet设置新的值,可以指定一个或多个先决条件

kubectl set #更改现有的应用程序资源

kubectl rollout #资源回滚管理

kubectl delete #删除资源

K8S 核心概念

Deployment

负责创建和更新应用程序的实力、 应用程序可以理解为Pod;

创建Deployment后,Master Node将应用程序实例调度到各个工作节点上运行;

如果工作节点上的应用程序关闭停止、则Master Node会将应用程序实例调度到其他的工作节点上、也是服务自愈;

Pod

相当于逻辑主机、 托管应用程序实例; 内部包含一个或者多个程序容器(Docker层);

可以理解为 在Docker容器层之上、再封装了一层的容器;

Service

为Pod提供外部访问暴露、负载均衡、服务发现;即Pod的网络代理;

若Pod没有设置Service、则只能在集群内部访问、集群外部无法访问;

在ServiceSpec标记type的方式暴露,type类型如下:

  1. ClusterIP(默认):在集群的内部IP上公开Service。这种类型使得Service只能从集群内访问。
  2. NodePort:使用NAT在集群中每个选定Node的相同端口上公开Service。使用 : 从集群外部访问Service。是ClusterIP的超集。
  3. LoadBalancer:在当前云中创建一个外部负载均衡器(如果支持的话),并为Service分配一个固定的外部IP。是NodePort的超集。
  4. ExternalName:通过返回带有该名称的CNAME记录,使用任意名称(由spec中的externalName指定)公开Service。不使用代理

k8s中的资源

  • 工作负载型资源(workload): Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet等等

  • 服务发现及负载均衡型资源(ServiceDiscovery LoadBalance): Service,Ingress等等

  • 配置与存储型资源: Volume(存储卷),CSI(容器存储接口,可以扩展各种各样的第三方存储卷)

  • 特殊类型的存储卷:ConfigMap(当配置中心来使用的资源类型),Secret(保存敏感数据),DownwardAPI(把外部环境中的信息输出给容器)

  • 集群级资源:Namespace,Node,Role,ClusterRole,RoleBinding(角色绑定),ClusterRoleBinding(集群角色绑定)

  • 元数据型资源:HPA(Pod水平扩展),PodTemplate(Pod模板,用于让控制器创建Pod时使用的模板),LimitRange(用来定义硬件资源限制的)

就业务开发来看、涉及频率高的是Pod、Deployment、 Ingress、Service, Volume、其他比较少涉及实用;

资源清单

在k8s中,我们一般都会使用yaml格式的文件来创建符合我们预期期望的资源,这样的yaml文件我们一般称为资源清单

资源清单yaml的格式

yaml 复制代码
apiVersion: group/apiversion  # 如果没有给定group名称,那么默认为croe,可以使用kubectl api-versions 获取当前k8s版本上所有的apiVersion版本信息(每个版本可能不同)
kind:       #资源类别
metadata:  #资源元数据
   name
   namespace  #k8s自身的namespace
   lables
   annotations   #主要目的是方便用户阅读查找
spec:期望的状态(disired state)
status:当前状态,本字段由kubernetes自身维护,用户不能去定义
#配置清单主要有五个一级字段,其中status字段用户不能定义,由k8s自身维护

使用资源清单yaml来创建k8s的资源对象

用创建deployment的命令加上参数 --dry-run -o yaml 输出部署的资源清单yaml

kubectl create deployment my-tomcat --image=tomcat:7.0.75-alpine --dry-run -o yaml

使用yaml部署tomcat

yml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: my-tomcat-yaml
  name: my-tomcat-yaml  #修改deployment的名称
spec:
  replicas: 2  #修改pod副本为两个
  selector:
    matchLabels:
      app: my-tomcat-yaml
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-tomcat-yaml
    spec:
      containers:
      - image: tomcat:7.0.75-alpine #容器的镜像(核心)
        name: tomcat
        resources: {}
status: {}

使用apply命令

kubectl apply -f deployment-demo.yaml

用yaml创建service资源的对象

同样使用dry-run yaml获取yaml

kubectl expose deployment my-tomcat --name=tomcat --port=8080 --type=NodePort --dry-run -o yaml

创建service的yaml文件

yml 复制代码
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: my-tomcat-yaml
  name: tomcat-service-yaml  #修改service名称
spec:
  ports:
  - port: 80  # service的虚拟ip对应的端口,在集群内网机器可以访问用service的虚拟ip加该端口号访问服务
    nodePort: 30001  # service在宿主机上映射的外网访问端口,端口范围必须在30000-32767之间
    protocol: TCP
    targetPort: 8080  # pod暴露的端口,一般与pod内部容器暴露的端口一致
  selector:
    app: my-tomcat-yaml #应用名称
  type: NodePort
status:
  loadBalancer: {}

执行apply命令创建service资源

kubectl apply -f service-demo.yaml

查看已存在资源的yaml

业务开发中、服务已经在运行了,我们需要查看yaml、就无需使用创建方式来查看了;

可以根据已运行的资源查看其yaml内容;

  1. 查看资源
  2. 将资源的配置以yaml的格式输出出来
    使用 -o yaml输入;

kubectl get pod nginx-deploy-7db697dfbd-2qh7v -o yaml

Ingress

Ingress类型Nginx, 可以基于域名访问、实现访问的负载均衡;

  1. 使用K8S安装Ingress
  2. 创建Ingress访问配置yaml文件
yml 复制代码
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
  - host: tomcat.com  #转发域名
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat-service-yaml
          servicePort: 80  #service的端口
  1. 执行apply应用;

kubectl apply -f ingress-tomcat.yaml

  1. 查看生效的ingress规则

kubectl get ing #ingress 缩写 ing

  1. C:\Windows\System32\drivers\etc,在host里增加如下host

192.168.65.203 (服务器IP) tomcat.com

或者

192.168.65.210 (服务器IP) tomcat.com

  1. 访问
    客户机浏览器访问http://tomcat.com/ ,能正常访问tomcat。

存储卷使用

通过存储卷,我们可以把外部数据挂载到容器中去,供容器中的应用访问,这样就算容器崩溃了,数据也不会丢失;

docker的挂载:

docker run -p 80:80 --name nginx

-v /mydata/nginx/html:/usr/share/nginx/html

-v /mydata/nginx/logs:/var/log/nginx

-v /mydata/nginx/conf:/etc/nginx

-d nginx:1.10

K8S也可以挂载文件,添加配置文件nginx-volume-deployment.yaml用于创建Deployment:

yml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-volume-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.10
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: html-volume
            - mountPath: /var/log/nginx
              name: logs-volume
            - mountPath: /etc/nginx
              name: conf-volume
      volumes:
        - name: html-volume
          hostPath:
            path: /home/docker/mydata/nginx/html
            type: Directory
        - name: logs-volume
          hostPath:
            path: /home/docker/mydata/nginx/logs
            type: Directory
        - name: conf-volume
          hostPath:
            path: /home/docker/mydata/nginx/conf
            type: Directory

kubectl 进行故障排除

若是服务部署失败、则可通过subscribe查看问题

kubectl describe {RESOURCE} {NAME}

拉到最后看到Events部分,会显示出 K8S 在部署这个服务过程的关键日志。

若是服务部署成功、业务运行出现异常、则通过logs查看问题;

kubectl logs ${POD_NAME}

进入容器内部;

kubectl exec -it options {POD_NAME} -c {CONTAINER_NAME} args

kubectl exec -ti $POD_NAME -- bash

总结

  • Service 是 K8S 服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了"微服务"。
  • 一方面外部用户不需要感知因为 Pod 上服务的意外崩溃、K8S 重新拉起 Pod 而造成的 IP 变更,外部用户也不需要感知因升级、变更服务带来的 Pod 替换而造成的 IP 变化,另一方面,Service 还可以做流量负载均衡。
相关推荐
菜地里的小菜鸟1 天前
kubectl debug
k8s·kubectldebug
腾飞开源4 天前
01_K8s干货笔记之认识K8s
运维·笔记·云原生·容器·kubernetes·k8s·容器化部署
小匠石钧知6 天前
02_在多个RockyLinux10虚拟机上安装k8s集群
云原生·容器·kubernetes·k8s
ShirleyWang01212 天前
让headlamp控制台能访问
linux·服务器·python·k8s·k3s
spider_xcxc12 天前
K8s 部署学习笔记
docker·容器·kubernetes·云计算·k8s
ShirleyWang01212 天前
Day02 K3s NGF(Nginx Gateway Fabric)单 Worker 环境网关更新与故障处置 SOP
linux·服务器·python·k8s·k3s
ShirleyWang01212 天前
DAY01 K3s 私有化部署排障复盘与 SOP
linux·服务器·k8s·k3s·企业部署
XUHUOJUN16 天前
AKS 不是安装在 Windows Server 上,而是运行在 Windows Server 之上的 Azure 平台能力
windows·架构·k8s·azure local·azure stack
Geek-Chow16 天前
Connecting kubectl to a Private EKS Cluster Over an Internal Domain
kubernetes·k8s·aws
spider_xcxc18 天前
Docker Compose 容器通信详解:同一个 Compose 文件才能互通吗?
docker·容器·k8s·容器化·容器网络