K8S入门基本概念

2023-11-24 16:30 雾与狼 539

1 k8s 简介

Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、 扩缩和管理平台。

官网:https://kubernetes.io/zh-cn/

临时 kubenets 环境: https://kubesphere.cloud/

1.1 能做什么

  • 服务发现和负载均衡
  • 存储编排
  • 自动部署和回滚
  • 自动完成装箱计算
  • 自我修复
  • 密钥与配置管理

1.2 kubenetes 架构

1.3 组件

1.3.1 控制面板:
  • kube-apiserver: 资源操作的唯一入口, 接收用户输入的命令,提供认证,授权, APU注册和发现等机制。
  • etcd: 是一个键值存储仓库,存储中各种资源 用于配置共享和服务发现。
  • kube-scheduler: 负载资源调度, 按照预定的调度策略将Pod调度到相应的工作节点上。
  • kube-controller-manager: 负责维护集群状态,比如服务的部署安排, 故障检测,自动扩展,滚动更新等。
1.3.2 Node
  • kubelet: 负责维护Pod的生命周期,即通过控制docker来创建,更新,销毁容器等
  • kube-proxy: 负责提供集群内部的服务发现和负载均衡
  • Container Runtime:负责运行容器的软件
  • supervisord: 是一个轻量级的进程监控系统,可以用来保证 kubelet 和 docker 运行

1.4 kubernetes API

Kubernetes 控制面板的核心是 API 服务器。 API 服务器负责提供 HTTP API,以供用户、集群中的不同部分和集群外部组件相互通信。Kubernetes API 使你可以查询和操纵 Kubernetes API 中对象(例如:Pod、Namespace、ConfigMap 和 Event)的状态。可以有三种方式访问 kubenetes API:

  • Restful API
  • 命令行接口 CLI(kubectl)
  • 客户端

1.5 kubernetes 对象管理

主要是通过 Kubenetes API 对 kuberntes 对象进行管理

1.5.1 kubernetes 对象

被 kubernetes 持久化的实体, 比如 Pod, Deployment, Service 等

1.5.2 kubernetes 对象描述

通常使用 .yaml 文件来描述有一个 kubernetes 对象, 但是必须包含以下字段

  • apiVersion
  • metadata 的 name
  • spec
1.5.3 管理对象的方式
  • 指令式命令
  kubectl run nginx --image=nginx --namespace=test [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool]
  • 指令式对象配置
apiVersion: v1
metadata:
  name: nginx
  namespace: test
  labels:
    app: nginx
    version: 1.7.6
spec:
  containers:
image: nginx
  
kubectl create -f -
  • 声明式对象配置


1.5.4 常用的对象属性
  • metadata 的 name: 同类资源对象的名称唯一,名称只能包含小写字母、数字,以及 '-' 和 '.'
  • 命名空间: 资源隔离的一种机制, 同一名字空间内的资源名称要唯一
  • label"release" : "stable", "release" : "canary""environment" : "dev", "environment" : "qa", "environment" : "production""tier" : "frontend", "tier" : "backend", "tier" : "cache""partition" : "customerA", "partition" : "customerB""track" : "daily", "track" : "weekly"

(1) cm 进程通过字段对象 RC 上定义的 Label Selector 来筛选要监控的 pod 副本数量, 从而实现 pod 的数量始终符合预期.

(2) kube-proxy进程通过 Service 的 Label Selector 来选择对应的 Pod, 自动建立每个 Service 到对应的 Pod 的转发路由信息, 从而实现 Service 智能负载均衡

  • annotation: 主要存放非标识的元数据

2 kubenetes 资源对象

2.1 Pod

是 K8s 里最基本的概念, 也是最小的操作单位.

资源文件定义, 以 nginx 为例:

apiVersion: v1
 kind: Pod
metadata:
  name: nginx-pod
  namespace: demo
  labels:
    app: nginx
    environment: dev
    version: 1.16.0-alpine
  annottations:
    creator: hhh
spec:
  containers:
image: nginx:1.16.0-alpine
name: nginx-1.16
ports:

需要注意的是:

在设置资源的时候,通常是以千分之一的 CPU 配额为最小单位, 用 m 表示. 比如 一个容器的 CPU 的配额定义是100m~200m, 相当于占用 0.1~0.2个CPU. 数值是绝对值,不是相对值. 单核 和 多核 CPU 100m 一样的.

创建 pod, 使用 create 或者 apply
kubectl create -f nginx-pod.yaml

2.2 Replication Controller(已经被废弃)

定义一个期望的场景, 声明期望的 Pod 的数量,并在任意时刻都符合这个期望值

资源文件定义, 以 nginx 为例, 副本数量为 2:

apiVersion: v1
Kind: ReplicationController
metadata:
  name: nginx-rc
  namespace: demo
  labels:
    controller: rc
  spec:
    replicas: 2
    selector:
      app: nginx
      version: 1.16.0-alpine
    template:
      metadata:
        labels:
          app: nginx
          version: 1.16.0-alpine
      spec:
        containers:
        - image: nginx:1.16.0-alpine
          name: nginx-1.16
          ports:
          - containerPort: 80

2.2 Replication Set

和 Replication Controller 功能几乎相同, 在Label Selector前者只支持等式, 在  Replication Set 中可以支持表达式.同时功能上支持Pod的 数量变更和版本变更

.....
spec:
selector:
  matchLabels:
    app: nginx
  matchExpressions:
{key: version, operator: In, values: [1.16.0-alpine, 1.17.0-alpine]}
......

数量变更

kubectl scale --replicas=3 rs/nginx-rs -n demo

版本变更

kubectl set image nginx=nginx:1.17.0-alpine rs/nginx-rs -n demo

2.3 Deployment

Deployment 为了更好的解决服务编排问题, 而且它非直接管理 Pod, 而是通过管理 ReplicaSet

除了支持 ReplicaSet 所有功能, 还支持以下主要功能:

  • 支持Pod的发布的暂停和继续
  • 支持版本的升级和回退

资源清单

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: demo
  labels:
    controller: deploy
spec:
  replicas: 2
revisionHistoryLimit: 3, # default 10
pause: false, # default false
progressDeadlineSeconds: 50, # default 600
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 30%, # 最大额外存在的副本数
maxUnavailable: 30% # 最大不可用的副本数量
  selector:
    matchLabels:
      app: nginx
      version: 1.16.0-alpine
  template:
    metadata:
      labels:
        app: nginx
        version: 1.16.0-alpine
    spec:
      containers:
      - image: nginx:1.16.0-alpine
        name: nginx
        ports:
        - containerPort: 80
        

deploy的扩缩容:

通过 scale 来实现扩缩容
kubectl scale deploy/nginx-deploy --replias=5 -n demo:

镜像的更新,一般支持两种策略

  • 重建更新(recreate)
  • 滚动更新(rollongUpdate)
kubectl set image nginx=nginx:1.16.0-alpine deploy/nginx-deploy -n demo

版本回退: kubectl rollout

常见的选项有:

  • status
  • history
  • pause
  • resume
  • restart
  • undo
在创建deployment 时, 启用recode 标记
kubectl create -f nginx-deploy.yaml -n demo --record
##查看部署版本历史
kubectl rollout history depploy/nginx-deploy -n  demo
#版本回退
kubectl rollout undo deploy/nginx-deploy --to-reversion=1 -n demo

金丝雀发布

2.4 Service

service 类似于 所谓的 "微服务", service 定义了服务的同意访问入口, 而 RS 保证了服务能力和服务质量始终保持预期.  客户端通过 Service 访问 Pod, 具体则是由 kube-proxy来实现, 通过它来把具体的请求发送给 Pod.

服务清单

apiVersion: apps/v1
kind: Service
metadata:
  name: nginx-service
  namespace: demo
spec:
  selector:
    app: nginx
    version: nginx:1.16.0-alpine
  type: ClusterIP
  ports:
nodePort: 31080
port: 80
targetPort: 80

service type 分为 四种:

  • ClusterIP
  • NodePort
  • LoadBalance
  • ExternalName(将集群的外部服务引入到集群内部)

2.5 Volume

Volume 是 Pod 中能够被多个容器访问的目录, 目前主要有以下几种类型:

  • emptyDir
  • hostPath
  • nfs
  • pv/pvc
...
spec:
  volumes:
name: tmp-volume
emptydir: {}
containers:
image: nginx
name: nginx
ports:
...
spec:
  volumes:
name: tmp-volume
hostPath:
    path: /data
    type: DirectoryOrCreate
containers:
image: nginx
name: nginx
ports:
type: DirectoryOrCreate, Directory, FileOrCreate, File, Socket, CharDevice, BlockDevice
      
      

2.6 Secret

对敏感数据的存储, 值是Base64加密的字符串,  它只会存储在节点的内存里, 不会落盘, 以下场景可以使用:

  • 作为挂载到一个或多个容器上的卷 中的文件。
  • 作为容器的环境变量。
  • 由 kubelet 在为 Pod 拉取镜像时使用。


apiVersion:  v1
apiVersion: v1
data:
  mysql_password: YWRtaW4= #admin
  mysql_url: YWRtaW4=
  db_name: MWYyZDFlMmU2N2Rm #1f2d1e2e67df
kind: Secret
metadata:
  name: mysql-secret
  namespace: demo
  type: Opaque

键值方式使用

apiVersion: v1
kind: Pod
metadata:
  name: user-service-pod
  namespace: demo
  labels:
    app: user-service
    version: 1.0.0
    envirionment: dev
spec:
  containers:
name: user-serivce
image: user-service:1.0.0
env:

或 将所有环境变量都加载进来

apiVersion: v1
kind: Pod
metadata:
  name: user-service-pod
  namespace: demo
  labels:
    app: user-service
    version: 1.0.0
    envirionment: dev
spec:
  containers:
name: user-serivce
image: user-service:1.0.0
envFrom:

也可以创建透明的数据的 secret

apiVersion: v1
kind: Secret
metadata:
  name: public-data-secret
  namespace: demo
stringData:
  baidu_url: www.baidu.com
type: Opaque

2.7 ConfigMap

configMap 的数据是透明的, 不被加密的. 在以下场景中可以用 configmap 来存储信息,

  1. 在容器命令和参数内
  2. 容器的环境变量
  3. 在只读卷里面添加一个文件,让应用来读取
  4. 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

最简单的键值对方式:


apVersion: v1
kind: ConfigMap
metadata:
  name: cm-appvars
data:
  baidu_url: www.baidu.com

使用:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  namespace: demo
spec:
  selector:
    app: nginx
    version: 1.16.0-alpine
  templates:
    metadata:
      labels:
        app: nginx
        version: 1.16.0-alpine
    sepc:
      containers:
      - name: nginx-pod
        image: nginx:1.16.0-alpine
        env:
        - name: BAIDU_URL
          valueFrom:
            configMapKeyRef:
              name: cm-appvars
              key: baidu_url
        ports:
        - containerPort: 80
   

以配置文件方式:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-user-upsteam-cm
  namespace: demo
data:
  user-upstram.conf: |
    upstream user-service {
      server 192.168.1.10 weight=1;
      server 192.168.1.11 weight=2;
    }
 

使用:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: demo
  labels:
    app: nginx
    verison: 1.16.0-alpine
spec:
  containers:
name: nginx
image: nginx:1.16.0-alpine
ports:
name: user-upstream-cm
configMap:
  name: nginx-user-upsteam-cm
  items:
 

当使用卷方式来存储数据时, 使用的 ConfigMap 被更新时,所投射的键最终也会被更新

     使用 kubectl 来创建 configMap

#创建键值对configMap
kubectl create cm demo-cm -n demo --from-literal=baidu_url=www.baidu.com --form-literal=....
#创建文件
kubecttl create cm demo-cm -n demo --from-file=user-upstram.conf
#从文件目录中创建
#目录 config , 将会将这个目录的所有文件都会生成在 configMap 中
kubecttl create cm demo-cm -n demo --from-file=conf
//user-service-upstream.conf
kubectl create cm user-service-upstream-cm --file-from=user-service-upstream.conf -o yaml --dry-run=client > user-service-upstream-cm.yaml

实用技巧:

如果 pod 出现问题,可以用 describle 来查看信息,
它会记录 Pod 创建的时候各种事件信息,基本 80% 能看到原因
kubectl describle pod/{pod_name} -n {namespace}
查看 Pod 容器日志, 也是标准的日志输出
kubectl logs -f --tail 100 pod/{pod_name} {container_name} -n {namespace}
进入 Pod 容器内部
kubectl exec -it pod/{pod_name} -n {namespace} -- sh
做端口映射来做本地联调
kubectl port-forward pod/{pod_name} -n {namespace} {local_port}:{container_port}