命令使用

kubectl命令

核心点:

通过 yaml 配置文件 定义了 我在 平台上运行什么命令

然后 k8s 通过 配置 文件的命令配置 保存起来,调用自己的接口 来 开启容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
kubectl create -f centos-readiness.yaml
# 创建一个实例

kubectl exec -it centos-5d  -- bash
# 进入实例 bash界面

# 查看详细信息
kubectl get po  -owide
kubectl get po  -oyaml


# logs查看 日志
kubectl logs -f  nginx-xxoo-1

# 查看详细日志
kubectl logs exec -it xxxx -- tail -f /xxx.log

kubectl 命令解释

kubectl get po -oyaml -w

-oyaml输出 yaml格式信息

-w watch 该对象后续变化

-owide 以详细列表的格式查看对象

在k8s 里面 ,不需要 再ssh了,直接用客户端连到容器里面,更加方便

命令式(imperative) vs 声明式(declarative)

命令式系统关注 “如何做” 在软件工程领域,命令式系统是写出解决某个问题、 完成某个任务或者达到某个目标的明确步骤。此方法 明确写出系统应该执行某指令,并且期待系统返回期 望结果。

声明式系统关注“做什么” 在软件工程领域,声明式系统指程序代码描述系统应该 做什么而不是怎么做。仅限于描述要达到什么目的,如 何达到目的交给系统。

https://img.draveness.me/2019-03-05-CronJob-Topology.png

参考资料

kubectl参考博客

参考视频

在线练习k8s网站

命令原理

实践–使用k8s管理业务应用

最小调度单元 Pod

docker调度的是容器,在k8s集群中,最小的调度单元是Pod(豆荚)

image-20220403214908272

为什么引入Pod
  • 与容器引擎解耦

    Docker、Rkt。平台设计与引擎的具体的实现解耦

  • 多容器共享网络|存储|进程 空间, 支持的业务场景更加灵活

可以理解为 Pod 是容器的容器

kubectl 命令工作流程

核心组件

  • ETCD:分布式高性能键值数据库,存储整个集群的所有元数据
  • ApiServer: API服务器,集群资源访问控制入口,提供restAPI及安全访问控制
  • Scheduler:调度器,负责把业务容器调度到最合适的Node节点
  • Controller Manager:控制器管理,确保集群资源按照期望的方式运行
    • Replication Controller
    • Node controller
    • ResourceQuota Controller
    • Namespace Controller
    • ServiceAccount Controller
    • Tocken Controller
    • Service Controller
    • Endpoints Controller
  • kubelet:运行在每运行在每个节点上的主要的“节点代理”个节点上的主要的“节点代理”
    • pod 管理:kubelet 定期从所监听的数据源获取节点上 pod/container 的期望状态(运行什么容器、运行的副本数量、网络或者存储如何配置等等),并调用对应的容器平台接口达到这个状态。
    • 容器健康检查:kubelet 创建了容器之后还要查看容器是否正常运行,如果容器运行出错,就要根据 pod 设置的重启策略进行处理.
    • 容器监控:kubelet 会监控所在节点的资源使用情况,并定时向 master 报告,资源使用数据都是通过 cAdvisor 获取的。知道整个集群所有节点的资源情况,对于 pod 的调度和正常运行至关重要
  • kubectl: 命令行接口,用于对 Kubernetes 集群运行命令 https://kubernetes.io/zh/docs/reference/kubectl/
  • CNI实现: 通用网络接口, 我们使用flannel来作为k8s集群的网络插件, 实现跨节点通信

image-20220403215109204

  1. 用户准备一个资源文件(记录了业务应用的名称、镜像地址等信息),通过调用APIServer执行创建Pod
  2. APIServer收到用户的Pod创建请求,将Pod信息写入到etcd中
  3. 调度器通过list-watch的方式,发现有新的pod数据,但是这个pod还没有绑定到某一个节点中
  4. 调度器通过调度算法,计算出最适合该pod运行的节点,并调用APIServer,把信息更新到etcd中
  5. kubelet同样通过list-watch方式,发现有新的pod调度到本机的节点了,因此调用容器运行时,去根据pod的描述信息,拉取镜像,启动容器,同时生成事件信息
  6. 同时,把容器的信息、事件及状态也通过APIServer写入到etcd中
核心组件

静态Pod的方式:

1
2
## etcd、apiserver、controller-manager、kube-scheduler
$ kubectl -n kube-system get po

systemd服务方式:

1
systemctl status kubelet

kubectl:二进制命令行工具

kubectl的使用

类似于docker,kubectl是命令行工具,用于与APIServer交互,内置了丰富的子命令,功能极其强大。 https://kubernetes.io/docs/reference/kubectl/overview/

1
2
3
4
kubectl -h
kubectl get -h
kubectl create -h
kubectl create namespace -h

kubectl如何管理集群资源

1
kubectl get po -v=7

创建一个 nginx pod

配置文件格式参考

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: ns-test
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  containers:
    - name: my-nginx
      images: nginx
      resources:
        limits:
          memory: "128M" # 限制内存使用
          cpu: "500M" # 设置 cpu 500毫秒的执行时间
  
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
1
kubectl create -f nginx.yaml

容器什么周期时间设置处理函数

容器生命周期钩子使它能够感知其自身生命周期管理中的事件,并在相应的时刻到来时运行由用户指定的处理程序代码。k8s为容器提供了两种生命周期钩子:

postStart:于容器创建完成之后立即运行的钩子处理器(handler),不过k8s无法确保它一定会于容器中的entrypoint之前运行

preStop:于容器终止操作之前立即运行的钩子处理器,它以同步的方式调用,因此在其完成之前会阻塞删除容器的操作调用。

钩子处理器的实现方法由Exec和HTTP两种,前一种在钩子事件触发时直接在当前容器中运行由用户定义的命令,后一种则是在当前容器中向某url发起http请求。postStart和preStop处理器定义在spec.lifecycle嵌套字段中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
      preStop:
        exec:
          command: ["/usr/sbin/nginx","-s","quit"]
1
2
3
4
5
6
7
8
9
 containers:
    - name: hadoop
      image: "{{ .Values.image.hadoop.repository }}:{{ .Values.image.hadoop.tag }}"
      imagePullPolicy: {{ .Values.image.hadoop.pullPolicy | quote }}
      lifecycle:
        preStop:
          httpGet:
            port: 8080
            path: shutdown           #这个请求发送到http://<Pod_IP>:8080/shutdown 

init容器

Pod 能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 Init 容器。

Init 容器与普通的容器非常像,除了如下两点:

Init 容器总是运行到成功完成为止。 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
kind: Pod # 创建一个 pod
metadata:
  name: test-init-main
  labels:
    app: myapp
    version: v1
spec:
  containers:
    - name: my-busybox
      image: busybox
      command: ['sh','-c','echo Main app is running && sleep 3600']
  initContainers:
    - name: init-myservice
      image: busybox
      command: ['sh','-c','until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
    - name: init-mydb
      image: busybox
      command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

k8s 用探针检查 pod的健康性

对线上业务来说,保证服务的正常稳定是重中之重,对故障服务的及时处理避免影响业务以及快速恢复一直是开发运维的难点。Kubernetes提供了健康检查服务,对于检测到故障服务会被及时自动下线,以及通过重启服务的方式使服务自动恢复。

探针的作用

探针是 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用容器实现 的Handler 处理程序。

有3种处理程序:

ExecAction: 容器内执行指定命令。如果命令退出时返回码为0,则认为诊断错误 tcpSocketAction: 对容器的Ip地址上的指定端口执行TCP检查。 如果端口打开,则诊断为是成功的 HttpGetAction: 调用http请求

https://img-blog.csdnimg.cn/20190531223756606.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dhbmc3MjU=,size_16,color_FFFFFF,t_70

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http-wfq
spec:
  containers:
  - name: liveness
    image: googlecontainer/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: X-Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

为 容器和PODS 分配 CPU资源

创建命名空间

创建一个命名空间,将资源隔离

1
kubectl create namespace cpu-example

创建一个容器的POD,容器会请求 0.5个CPU,而且最多限制使用一个 CPu,参考

参考文章

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Pod
metadata:
  name: nginx2
spec:
  containers:
  - name: nginx2
    image: nginx:test
    ports:
    - containerPort: 80
    resources:
      limits:
        cpu: 200m
        memory: 128Mi
      requests:
        cpu: 200m
        memory: 128Mi