Kubernetes 概念

GA666666 2022-12-08 AM 15℃ 1条

第一章 Kubernetes 对象(Kubernetes Objects)

1.1 什么是 Kubernetes 的对象?

  • 官网
  • Kubernetes 里面操作的资源实体,就是 Kubernetes 的对象,可以使用 yaml 来声明,然后让 Kubernetes 根据 yaml 的声明创建出这个对象。
  • 操作 Kubernetes 对象,无论是创建、修改还是删除,都需要使用 Kubernetes 的 API 。如:当使用 kubectl 命令行的时候,CLI 会执行必要的 Kubernetes API 调用。
  • Kubernetes 对象指的是 Kubernetes 系统的持久化实体,所有的这些 Kubernetes 对象,就代表了当前集群中的实际情况。常规的应用中,我们将应用程序产生的数据存放在数据库中;同理,Kubernetes 将其数据以 Kubernetes 对象的形式通过 api-server 存储在 etcd 中。具体来说,这些数据(Kubernetes 对象)描述了:

    • 集群中运行了那些容器化应用程序,以及在哪个节点上运行。
    • 集群中应用程序可用的资源,如:网络、存储等。
    • 应用程序相关的策略定义,如:重启策略、升级策略和容错策略等。
    • 其他 Kubernetes 管理应用程序时所需要的信息。
  • 每一个 Kubernetes 对象都包含了两个重要字段:

    • spec:需要由我们来提供,描述了我们对该对象所期望的 目标状态
    • status:只能由 Kubernetes 系统来修改,描述了该对象在 Kubernetes 系统中的实际状态。
  • Kubernetes 通过对应的控制器(如:Deployment 等),不断的使得实际状态趋向于我们期望的目标状态。
  • 示例:查看 Deployment 时在系统底层运行的 yaml
kubectl create deployment my-nginx --image=nginx -o yaml
kubectl get deployment my-nginx -o yaml

1.gif

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2022-03-11T06:39:04Z"
  generation: 1
  labels:
    app: my-nginx
  name: my-nginx
  namespace: default
  resourceVersion: "21848"
  uid: 0919fb61-2543-49be-a6cc-9f4d41add783
spec: # 期望的状态
  progressDeadlineSeconds: 600
  replicas: 1 # 副本数量
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: my-nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: my-nginx
    spec:
      containers:
      - image: nginx  # 使用这个镜像创建容器
        imagePullPolicy: Always
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status: # 当前状态
  conditions:
  - lastTransitionTime: "2022-03-11T06:39:04Z"
    lastUpdateTime: "2022-03-11T06:39:04Z"
    message: Deployment does not have minimum availability.
    reason: MinimumReplicasUnavailable
    status: "False"
    type: Available
  - lastTransitionTime: "2022-03-11T06:39:04Z"
    lastUpdateTime: "2022-03-11T06:39:04Z"
    message: ReplicaSet "my-nginx-6b74b79f57" is progressing.
    reason: ReplicaSetUpdated
    status: "True"
    type: Progressing
  observedGeneration: 1
  replicas: 1
  unavailableReplicas: 1  # 当前集群不可用
  updatedReplicas: 1
  • 【问】:Kubernetes 是如何保证最终一致的?
  • 【答】:

    • etcd 保存的创建资源期望的状态以及最终这个资源的状态,这两种状态需要最终一致,即:spec 和 status 要最终一致。
    • 当输入 kubectl create deployment my-nginx --image=nginx 命令的时候,api-server 保存到 etcd ,controller-manager 会解析数据,知道集群中需要 my-nginx ,保存到 etcd 中。
    • kubelet 在底层不停的死循环使得 spec 状态和 status 最终一致,如果 spec.replicas != status.replicas ,就启动 Pod。
 while(true){   
     if(status.replicas != spec.replicas){     
         kubelet.startPod();   
     }
 }

1.2 描述 Kubernetes 对象

  • 当我们在 Kubernetes 集群中创建一个对象的时候,我们必须提供:

    • 该对象的 spec 字段,通过该字段描述我们期望的目标状态
    • 该对象的一些基本信息,如:名字等。
  • 可以使用 kubectl 命令行创建对象,也可以使用 yaml 格式的文件进行创建。
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  nginx-deployment
  namespace: default
  labels:
    app:  nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app:  nginx
    spec:
      containers:
      - name:  nginx
        image:  nginx
        ports:
        - containerPort:  80
  • 使用 kubectl apply 命令进行部署:
kubectl apply -f deployment.yaml
  • 使用 kubectl delete 命令进行部署:
kubectl delete -f deployment.yaml

1.3 Kubernetes 对象的 yaml 格式

2.png

  • 在上述的 yaml 文件中,如下的字段是必须填写的:

    • apiVersion:用来创建对象时所需要的 Kubernetes API 的版本,可以通过 kubectl api-resources 查询。
    • kind:创建对象的类型,可以通过 kubectl api-resources 查询。
    • metadata:用来唯一确定该对象的元数据,包括 name 、namespace 等,如果 namespace 为空,则默认值为 default 。
    • spec:翻译为 规格 ,表示我们对该对象的期望状态。
status 不需要编写,那是 Kubernetes 实际运行过程中将变化的记录保存在此字段中。
  • 不同类型的 Kubernetes ,其 spec 对象的格式不同(含有不同的内嵌字段),通过 API 手册可以查看 Kubernetes 对象的字段和描述。
  • 当然,我们以后也可以通过此地址来参照。

1.4 实际中如何创建 Kubernetes 对象的 yaml

  • ① 如果 Kubernetes 集群中已经存在了要创建的对象,那么可以使用 kubectl get 直接输出 yaml ,然后去除 status 即可:
kubectl get pod xxx -o yaml > demo.yaml

3.gif

  • ② 如果 Kubernetes 集群中不存在了要创建的对象,那么可以使用类似 kubectl run xxx --dry-run=client 输出 yaml :
# --dry-run=client 表示客户端干跑
kubectl run nginx-pod --image=nginx --dry-run=client -o yaml > demo.yaml

4.gif

1.5 对象名称

1.5.1 概述

  • Kubernetes REST API 中,所有的对象都是通过 nameUID 唯一性的确定。
  • 可以通过 namespace + name 唯一性的确定一个 RESTful 对象,如:
/api/v1/namespaces/{namespace}/pods/{name}

1.5.2 Name

  • 在同一名称空间下,同一个类型的对象,可以通过 name 来确定唯一性。如果删除该对象之后,可以再重新创建一个同名对象。
  • 根据命名规则,Kubernetes 对象的名称应该是:

    • 最长不超过 253 个字符。
    • 必须由小写字母、数字、减号 - 、小数点 . 组成。
    • 某些资源类型有更具体的要求。
  • 示例:下面的配置文件定义了一个 name 为 nginx-demo 的 Pod,该 Pod 包含一个 name 为 nginx 的 容器
apiVersion: v1 
kind: Pod 
metadata: 
  name: nginx-demo ##pod的名字 
spec: containers:
  - name: nginx ##容器的名字 
  image: nginx:1.7.9 
  ports:
    - containerPort: 80

1.5.3 UID

  • UID 是由 Kubernetes 系统生成的,唯一标识某个 Kubernetes 对象的字符串。
  • Kubernetes集群中,每创建一个对象,都有一个唯一的 UID 。用于区分多次创建的同名对象(如前面所述,按照名字删除对象后,重新再创建同名对象时,两次创建的对象 name 相同,但是 UID 不同。)

5.gif

1.6 名称空间(命名空间)

1.6.1 概述

  • 在 Kubernetes 中名称空间是用来对象资源进行隔离的。
  • 默认情况下,Kubernetes 会初始化四个名称空间:
kubectl get ns|namespace

6.png

  • default:所有没有指定 namespace 的对象都会被分配到此名称空间中。
  • kube-node-lease:Kubernetes 集群节点之间的心跳维护,V 1.13 开始引入。
  • kube-system:Kubernetes 系统创建的对象放在此名称空间中。
  • kube-public:此名称空间是 Kubernetes 集群安装时自动创建的,并且所有的用户都可以访问(包括未认证的用户),主要是为集群预留的,如:在某些情况中,某些 Kubernetes 对象应用应该能被所有集群用户访问到。

1.6.2 名称空间在实际开发中如何划分?

  • ① 基于环境隔离,如:dev(开发)、test(测试)、prod(生产)等。
  • ② 基于产品线隔离,如:前端、后端、中间件、大数据、Android、iOS、小程序等。
  • ③ 基于团队隔离,如:企业发展事业部、技术工程事业部、云平台事业部等。

1.6.3 名称空间的特点

  • 名称空间资源隔离、网络不隔离,如:配置文件不可以跨名称空间访问,但是网络访问可以跨名称空间访问。
  • 默认情况下,安装 Kubernetes 集群的时候,会初始化一个 default 名称空间,用来承载那些没有指定名称空间的 Pod 、Service 、Deployment 等对象。

1.6.4 名称空间的命名规则

  • ① 不能带小数点(.)。
  • ② 不能带下划线(_)。
  • ③ 使用数字、小写字母或减号(-)组成的字符串。

1.6.5 名称空间的操作

  • 示例:创建和删除名称空间(yaml )
vim k8s-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name:  demo # 名称空间的名字
spec: {}  
status: {}
# 创建名称空间
kubectl apply -f k8s-namespace.yaml
kubectl delete -f k8s-namespace.yaml

7.gif

  • 示例:创建和删除名称空间(命令行 )
# 创建名称空间
kubectl create ns demo
kubectl delete ns demo

8.gif

  • 示例:创建 Pod 的同时,指定自定义的名称空间(yaml)
vim k8s-pod.yaml
apiVersion: v1
kind: Namespace
metadata:
  name:  demo # 名称空间的名字
spec: {} # 默认为空,其实可以不写
status: {} # 默认为空,其实可以不写

# 以上是 namespace 
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: demo # 指定自定义的名称空间,如果不写,默认为 default
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    resources: # 后面会讲
      limits:
        cpu: 200m
        memory: 500Mi
      requests:
        cpu: 100m
        memory: 200Mi
    ports:
    - containerPort:  80
      name:  http
    volumeMounts:
    - name: localtime
      mountPath: /etc/localtime
  volumes:
    - name: localtime
      hostPath:
        path: /usr/share/zoneinfo/Asia/Shanghai
  restartPolicy: Always 

  # 以上的 Pod
kubectl apply -f k8s-pod.yaml

9.gif

1.6.6 重点(后面讲)

  • 当我们创建一个 Service 的时候,Kubernetes 会创建一个相应的 DNS 条目
  • 该条目的形式是<service-name>.<namespace-name>.svc.cluster.local,这意味着如果容器中只使用<服务名称>,它将被解析到本地名称空间的服务器。这对于跨多个名字空间(如开发、测试和生产) 使用相同的配置非常有用。如果你希望跨名字空间访问,则需要使用完全限定域名(FQDN)。

1.6.7 注意事项

  • 大多数的 Kubernetes 资源(如:Pod、Service、副本控制器等)都位于某些名称空间中,但是名称空间本身并不在名称空间中,而且底层资源(如:node 和持久化卷)不属于任何命名空间。
  • 查看在名称空间中的资源:
kubectl api-resources --namespaced=true
  • 查看不在名称空间中的资源:
kubectl api-resources --namespaced=false

1.7 标签和选择器

1.7.1 概述

  • 标签(Label)是附件在 Kubernetes 对象上的一组键值对,其意图是按照对用户有意义的方式来标识 Kubernetes 镀锡,同时,又不对 Kubernetes 的核心逻辑产生影响。标签可以用来组织和选择一组 Kubernetes 对象。我们可以在创建 Kubernetes 对象的时候为其添加标签,也可以在创建以后为其添加标签。每个 Kubernetes 对象可以有多个标签,同一个对象的标签的 key 必须是唯一的,如:
metadata: 
  labels:   
    key1: value1   
    key2: value2
  • 使用标签(Label)可以高效的查询和监听 Kubernetes 镀锡,在 Kubernetes 界面工具(如:Kubernetes DashBoard)和 kubectl 中,标签使用的非常普遍。而那些非标识性的信息应该记录在 注解(Annotation) 中。

1.7.2 为什么要使用标签?

  • 使用标签,用户可以按照自己期望的形式组织 Kubernetes 对象之间的结构,而无需对 Kubernetes 有任何修改。
  • 应用程序的部署或者批处理程序的部署通常是多维度的(如:多个高可用分区、多个程序版本、多个微服务分层)。管理这些对象的时候,很多时候要针对某一个维护的条件做整体操作,如:将某个版本的程序整体删除。这种情况下,如果用户能够事先规划好标签的使用,再通过标签进行选择,就非常的便捷。
  • 标签的例子有:

    • release: stablerelease: canary
    • environment: devenvironment: qaenvironment: production
    • tier: frontendtier: backendtier: cache
    • partition: customerApartition: customerB
    • track: dailytrack: weekly
  • 上面只是一些使用比较普遍的标签,我们也可以根据自己的情况建立合适的标签。

1.7.3 标签的语法

  • 标签是一组键值对(key/value),标签的 key 有两个部分:可选的前缀和标签名,通过 / 分隔。
  • 标签前缀:

    • 标签前缀部分是可选的。
    • 如果指定,必须是一个 DNS 的子域名,如:k8s.eip.work 。
    • 不能多余 253 个字符。
    • 使用 / 和标签名分隔。
  • 标签名:

    • 标签名部分是必须的。
    • 不能多余 63 个字符。
    • 必须由字母、数字开始和结尾。
    • 可以包含字母、数字、减号(-)、下划线(_)、小数点(.)。
    如果省略标签前缀,则标签的 key 就被认为是专属于用户的。Kubernetes 的系统组件(如:kube-scheduler、kube-controller-manager、kube-apiserver、kubectl 或其他第三方组件)向可以的 Kubernetes 对象添加标签的时候,必须指定一个前缀。kubernetes.io/k8s.io/ 这两个前缀是 Kubernetes 核心组件预留的。
  • 标签的 value :

    • 不能多于 63 个字符。
    • 可以为空字符串。
    • 如果不为空,则必须由字母、数字开始和结尾。
    • 如果不为空,可以包含字母、数字、减号(-)、下划线(_)、小数点(.)。
  • 示例:
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels: # 标签
    app: nginx
    environment: prod 
spec:
  containers:
  - name: nginx
    image: nginx

1.7.4 标签选择器

  • 通常来讲,会有多个 Kubernetes 对象包含相同的标签。通过使用标签选择器(label selector),用户/客户端可以选择一组对象。标签选择器是 Kubernetes 中最主要的分类和筛选手段。
  • Kubernetes 的 api-server 支持两种形式的标签选择器,equality-based 基于等式的set-based 基于集合的 。标签选择器可以包含多个条件,并使用逗号进行分隔,此时只要满足所有条件的 Kubernetes对象才会被选中。
  • 基于等式的标签选择器,可以使用三种操作符 ===!=。前两个操作符含义是一样的,都代表相等;后一个操作符代表不相等。
# 选择了标签名为 `environment` 且 标签值为 `production` 的Kubernetes对象
kubectl get pods -l environment=production,tier=frontend
# 选择了标签名为 `tier` 且标签值不等于 `frontend` 的对象,以及不包含标签 `tier` 的对象
kubectl get pods -l tier != frontend
# 选择所有包含 `partition` 标签的对象
kubectl get pods -l partition
# 选择所有不包含 `partition` 标签的对象
kubectl get pods -l !partition
  • 基于集合标签选择器,可以根据标签名的一组值进行筛选。支持的操作符有三种:innotinexists
# 选择所有的包含 `environment` 标签且值为 `production` 或 `qa` 的对象
kubectl get pods -l environment in (production, qa)
# 选择所有的 `tier` 标签不为 `frontend` 和 `backend`的对象,或不含 `tier` 标签的对象
kubectl get pods -l tier notin (frontend, backend)
# 选择包含 `partition` 标签(不检查标签值)且 `environment` 不是 `qa` 的对象
kubectl get pods -l partition,environment notin (qa)
  • 示例:Job、Deployment、ReplicaSet 和 DaemonSet 同时支持基于等式的选择方式和基于集合的选择方式。
apiVersion: apps/v1
kind: Deployment
metadata:
  name:  nginx
  namespace: default
  labels:
    app:  nginx
spec:
  selector:
    matchLabels: # matchLabels 是一个 {key,value} 组成的 map。map 中的一个 {key,value} 条目相当于 matchExpressions 中的一个元素,其 key 为 map 的 key,operator 为 In, values 数组则只包含 value 一个元素。matchExpression 等价于基于集合的选择方式,支持的 operator 有 In、NotIn、Exists 和 DoesNotExist。当 operator 为 In 或 NotIn 时,values 数组不能为空。所有的选择条件都以 AND 的形式合并计算,即所有的条件都满足才可以算是匹配
      app: nginx
    matchExpressions: 
      - {key: tier, operator: In, values: [cache]}
      - {key: environment, operator: NotIn, values: [dev]}
  replicas: 1
  template:
    metadata:
      labels:
        app:  nginx
    spec:
      containers:
      - name:  nginx
        image:  nginx:latest

1.7.5 标签的操作

  • 示例:添加标签
kubectl label pod nginx-pod hello=world
  • 示例:更新标签
kubectl label pod nginx-pod hello=java --overwrite
  • 示例:删除标签
kubectl label pod nginx-pod hello-

1.8 注解 annotations

  • 注解(annotation) 可以用来向 Kubernetes 对象的 meta.annotations 字段添加任意的信息。Kubernetes 的客户端或者自动化工具可以存取这些信息以实现自定义的逻辑。
metadata: 
  annotations:   
    key1: value1   
    key2: value2

1.9 给 VScode 安装插件

  • 推荐在 Vscode 中安装如下的插件,可以加快编写 Kubernetes 的 yaml 的速度:

10.png

11.png

1.10 重新认识 kubectl 和 kubelet

  • 核心文件夹:/etc/kubernetes
  • kubelet 额外参数配置: /etc/sysconfig/kubelet
  • kubelet配置位置: /var/lib/kubelet/config.yaml

第二章:万物基础 -- 容器

2.1 镜像

2.1.1 概述

  • 平时,我们使用 Docker 的镜像非常之简单,类似于下面的命令:
docker pull nginx:latest
  • 其实,完整的写法应该是这样:
docker pull docker.io/library/nginx:latest
  • 如果我们使用自己搭建过 Docker 的私有镜像仓库,可以发现会出现如下的命令:
docker push 192.168.65.100:5000/xudaxian/ubuntu:1.0
  • 说明:

    • 192.168.65.100:镜像仓库的地址。
    • 5000:镜像仓库的端口。
    • xudaxian:镜像仓库的名称。
    • ubuntu:镜像的名称。
    • 1.0:镜像的版本,如果不写,默认就是 latest 。
  • 当然,如果拉取的是 hub.docker.com 中的镜像,那么镜像仓库地址以及端口都可以省略。

2.1.2 Kubernetes 中的镜像

  • 在 Kubernetes 的 Pod 定义容器的时候,必须指定容器所使用的镜像,容器中的 image 字段支持的语法和 docker 命令是一样的,包括私有镜像仓库和标签,如:
# 192.168.65.100:5000/xudaxian/ubuntu:1.0
my-registry.example.com:5000/example/web-example:v1.0
注意:在生产环境中,建议锁定镜像的版本。
  • 示例:
apiVersion: v1
kind: Namespace
metadata:
  name:  demo 
spec: {} 
status: {} 

# 以上是 namespace 
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: demo 
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.20.2 # Docker 的镜像名称,和 Docker 命令一样,my-registry.example.com:5000/example/web-example:v1.0,实际开发中,建议锁定镜像的版本。
    ports:
    - containerPort:  80

  # 以上的 Pod
  • Kubernetes 中的镜像拉取策略:

    • IfNotPresent(默认) :只有当镜像在本地不存在时才会拉取。
    • Always :每当 kubelet 启动一个容器时,kubelet 会查询容器的镜像仓库, 将名称解析为一个镜像摘要。 如果 kubelet 有一个容器镜像,并且对应的摘要已在本地缓存,kubelet 就会使用其缓存的镜像; 否则,kubelet 就会使用解析后的摘要拉取镜像,并使用该镜像来启动容器。
    • Never :Kubelet 不会尝试获取镜像。如果镜像已经以某种方式存在本地, kubelet 会尝试启动容器;否则,会启动失败。
  • 示例:
apiVersion: v1
kind: Namespace
metadata:
  name:  demo 
spec: {} 
status: {} 

# 以上是 namespace 
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: demo 
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.20.2 # Docker 的镜像名称,和 Docker 命令一样,my-registry.example.com:5000/example/web-example:v1.0,实际开发中,建议锁定镜像的版本。
    imagePullPolicy: Always # 镜像拉取策略:IfNotPresent(默认)、Always、Never
    ports:
    - containerPort:  80
  # 以上的 Pod

2.1.3 下载私有仓库的镜像

  • 我们在使用阿里云容器镜像的私有仓库的使用,阿里云要求我们进行登录,如果是 docker 拉取镜像,那么只需要 docker login 之类的就可以了;但是,如果使用 Kubernetes 该怎么办?
  • ① 创建 secret :
# -n demo :表示该密钥将只在指定的名称空间 demo 中生效
# docker-registry aliyun :指定 Docker 镜像仓库的名称
# --docker-server:Docker 镜像仓库的地址
# --docker-username:Docker 镜像仓库的用户名
# --docker-password:Docker 镜像仓库的密码
kubectl create secret -n demo docker-registry aliyun \
       --docker-server=registry.cn-shanghai.aliyuncs.com \
       --docker-username=xudaxian \
       --docker-password=123456
  • ② 在 yaml 中拉取镜像的时候设置镜像拉取的密钥(secret):
apiVersion: v1
kind: Namespace
metadata:
  name:  demo 
spec: {} 
status: {} 

# 以上是 namespace 
---
apiVersion: v1
kind: Pod
metadata:
  name: demo-pod
  namespace: demo 
  labels:
    app: nginx
spec:
  containers:
  imagePullSecrets: # Pull镜像时使用的 secret 名称,以 key:secretkey 格式指定
    - name:  aliyun 
  - name: nginx
    image: nginx:1.20.2 # Docker 的镜像名称,和 Docker 命令一样,my-registry.example.com:5000/example/web-example:v1.0,实际开发中,建议锁定镜像的版本。
    imagePullPolicy: Always # 镜像拉取策略:IfNotPresent(默认)、Always、Never
  - name: arcgis
    image: registry.cn-shanghai.aliyuncs.com/xudaxian/arcgis/v1.0 
    imagePullPolicy: Always
注意:这个肯定运行不了,需要将 secret 的用户名和密码设置为自己的,而且在拉取阿里云私有镜像的时候设置为自己的镜像。

2.2 环境变量

  • 使用 env 用来给 Pod 中的容器设置环境变量,相当于 docker run -e xxx=xxx 中的 -e 参数。
  • 示例:
vim k8s-mysql.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
  namespace: default
  labels:
    app: mysql-pod
spec:
  containers:
  - name: mysql-pod
    image: mysql:5.7
    env: # 环境变量 相当于 docker run -e  xxx = xxx
    - name: MYSQL_ROOT_PASSWORD # root 的密码
      value: "123456"
    - name:  MYSQL_DATABASE # mysql 的 数据库
      value: ssm
  restartPolicy: Always
kubectl apply -f k8s-mysql.yaml

12.gif

2.3 启动命令

  • Docker 的镜像拥有存储镜像信息的相关元数据,如果不设置生命周期命令和参数,容器运行时会运行镜像制作时提供的默认的命令和参数,Docker 原生定义这两个字段为 ENTRYPOINTCMD
  • 如果在创建工作负载时填写了容器的运行命令和参数,将会覆盖镜像构建时的默认命令 EntrypointCMD,规则如下:

    镜像 Entrypoint镜像CMD容器 command容器 args最终执行
    [touch][/root/test]未设置未设置[touch /root/test]
    [touch][/root/test][mkdir]未设置[mkdir]
    [touch][/root/test]未设置[/opt/test][touch /opt/test]
    [touch][/root/test][mkdir][/opt/test][mkdir /opt/test]
  • 换言之,如果在 Kubernetes 的 yaml 中定义了 comand 和 args ,那么就会覆盖 Dockerfile 中的 ENTRPOINT 和 CMD 。
  • 示例:启动 MySQL
vim k8s-mysql.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql-pod
  namespace: default
  labels:
    app: mysql-pod
spec:
  containers:
  - name: mysql-pod
    image: mysql:5.7
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "123456"
    - name: MYSQL_DATABASE
      value: ssm
    args:
      - "--lower_case_table_names=1"
      - "--character-set-server=utf8mb4"
      - "--collation-server=utf8mb4_general_ci"
      - "--default-authentication-plugin=mysql_native_password"    
    ports:
    - containerPort:  3306
  restartPolicy: Always
kubectl apply -f k8s-mysql.yaml

13.gif

2.4 资源限额

  • 器中的程序要运行,肯定会占用一定的资源,比如 CPU 和内存等,如果不对某个容器的资源做限制,那么它就可能吃掉大量的资源,导致其他的容器无法运行。
  • 针对上面的情况,Kubernetes 提供了对内存和 CPU 的资源进行配额的机制,这种机制主要通过 resources 选项实现,它有两个子选项:

    • limits:用于限制运行的容器的最大占用资源,当容器占用资源超过 limits 时会被终止,并进行重启。
    • requests:用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动。
    • cpu:core 数,可以为整数或小数,1 == 1000m。
    • memory:内存大小,可以使用 Gi、 Mi、G、M 等形式。
  • 示例:
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.20.2
    resources: # 资源限制
      limits:
        cpu: 2
        memory: 1500M
      requests:
        cpu: 1
        memory: 1024M
    ports:
    - containerPort:  80
  restartPolicy: Always
标签: K8s

非特殊说明,本博所有文章均为博主原创。

评论啦~



唉呀 ~ 仅有一条评论


  1. 云原生 - GA666666 Blog ~ 个人博客
    云原生 - GA666666 Blog ~ 个人博客

    [...]Kubernetes 概念 Kubernetes(v1.21)工作负载 Kubernetes(v1.21)配置和存储Kubernetes(v1.21)网络Kubernetes(v1.21)调度原理Kubernetes(v1.21)安全K8s - Ingress 限流K8s-Pod重启策略Kubernetes滚动更新解决Mac/Windows版Desktop Docker中自带的K8s无法访问pod[...]

    回复 2024-02-21 11:07