k8s 概念-Pod Service Deploy常用命令

370 阅读8分钟

k8s概述与特性

1. 概述

  1. 集群化管理,使用部署更加简洁高效
  2. 支持容器化部署
  3. 应用扩展

2. 特点

  • 自动装箱: 自动部署
  • 自我修复: 节点异常自动重新调度与重启
  • 水平扩展: 简单命令-扩展或裁剪规模 ,cpu内存等硬件扩展
  • 服务发现: 负载均衡,根据规则自动转发
  • 滚动更新: 可以批量更新
  • 版本回退: 支持历史版本回退
  • 密码与配置管理: 不用重启,热更新秘钥与配置
  • 存储编排: 本地目录,网络存储,公共云存储
  • 批处理: 一次性或 定时任务的批处理

2. 架构组件

image.png

master组件 主节点

  • APIserver :集群统一入口,restful风格
  • etcd : 持久化存储相关配置信息
  • scheduler : 节点的调度,根据策略选择节点服务器
  • controller-manager: 处理集群的后台任务,一个资源对应一个controller

node组件 工作节点

  • kubelet :管理 当前工作服务器中的容器
  • kube-proxy 提供网络代理, 负载均衡

3.搭建k8s

1. 平台规划

  • 单集群 :1个master
  • 多集群 :多个master + master负载均衡

2. 配置要求

测试

  • master :2核+4g + 20g
  • node :master*2

正式

  • 比测试更高

3.kubeadm搭建

参考 juejin.cn/post/720363…

master

kubeadm init

安装 kubeadm docker kubectl

node

kubeadm join

安装 kubeadm docker kubelet

要求

禁止 swap

部署网络插件CNI

kubectl apply -f kube-flannel.yml

4.二进制部署

官方参考: kubernetes.io/zh-cn/docs/…

参考: juejin.cn/post/720373…

master部署

  1. 安装docker
  2. 使用cfssl生成根证书
  3. 搭建etcd
  • 生成etcd证书
  • 下载etcd程序
  • 配置etcd conf,并导入证书
  • 设置systemd服务,并启动
  • etcd是一个键值数据库
  1. 下载k8s的server包(包含node需要的库)
  • 复制  apiserver,controller-manager 
  1. 生成k8s使用的证书
  2. 搭建apiserver
  • 配置conf和导入证书
  • 设置systemd服务,并启动
  • 设置授权请求证书
  1. 搭建kube-controller-manager 
  • 配置conf和导入证书
  • 设置systemd服务,并启动
  1. 搭建kube-scheduler
  • 配置conf和导入证书
  • 设置systemd服务,并启动

node部署

  1. 安装docker
  2. 复制 kubelet kube-proxy  kubectl  
  3. 配置kubelet
  • 配置kubelet.conf
  • 配置kubelet-config.yml
  • 同步master端的ssl 信息 配置到 node
  • 生成 bootstrap.kubeconfig
  • 设置systemd服务,并启动
  • master 上 批准kubelet证书申请并加入集群(Master操作)
  1. 配置kube-proxy
  • kube-proxy.conf
  • kube-proxy-config.yml
  • kube-proxy.kubeconfig
  • 设置systemd服务,并启动

配置网络集群

  1. node节点:下载cni-plugins-linux-amd64-v0.8.6.tgz
  2. master执行
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

4.yaml

资源编排清单

包含

  • 控制器定义
  • 被控制对象

常见字段

  • apiVersion API版本
  • kind 资源类型
  • metadata 资源元数据
  • spec 资源规格
  • replicas 副本数量
  • selector 标签选择器
  • template Pod模板
  • metadata Pod元数据
  • spec Pod规格
  • containers 容器配置

语法格式

  • 通过缩进表示层级关系
  • 不能使用Tab进行缩进,只能使用空格
  • 一般开通缩进两个空格
  • 字符后缩进一个空格,比如冒号,逗号等后面
  • 使用---表示新的yam文件开始
  • 使用#代表注释

5.Pod

1.存在的意义

  • 传统docker ,一个应用,一个容器,一个进程,不同进程互相独立
  • pod 可以实现多进程管理
  • 亲密应用
  1. 两个应用之间调用
  2. 网络之间调用
  3. 两个应用高频访问

2.特性

  • 最小部署单元
  • 生命周期短
  • 一组容器的集合
  • 共享网络
  • 共享资源

3.实现机制

linux隔离原理

  • namespace : cpu内存隔离
  • group :数据隔离

共享资源与网络

  • 每个pod都会创建一个pause容器:在同一个namespace下pod都共享网络
  • 共享资源:通过数据卷实现持久化共享

4.测试例子

apiVersion: v1  
kind: Pod  
metadata:  
  name: my-pod  
spec:  
  containers:  
  - name: write  
    image: centos  
    command: ["bash","-c","for in (1..100);do echo $i >> /data/hello;sleep 1;done"]  
    volumeMounts:  
      - name: data  
        mountPath: /data  
  - name: read  
    image: centos  
    command: ["bash","-c","tail -f /data/hello"]  
    volumeMounts:  
      - name: data  
        mountPath: /data  
  volumes:  
  - name: data  
    emptyDir: {}

5.状态

  • Pending 镜像下载中
  • Running 下载完成,正在启动或重启
  • Completed 启动完成
  • failed 启动失败
  • unknown 未知错误

6.label

通过label 让service和RS 与pod产生关联

matchLabels:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      name: newkubia
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx
        name: nginx

6.常用配置

拉取策略

apiVersion: v1  
kind: Pod  
metadata:  
  name: mypod  
spec:  
  containers:  
    - name: nqinx  
      image: nqinx:1.14  
      imagePullPolicy: Always
  • IfnotPresent:默认值,镜像在宿主机上不存在时才拉取
  • Always:每次创建 Pod 都会重新拉取一次镜像
  • Never Pod水远不会主动拉取这个镜像

容器检查

livenessProbe存活检查

livenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。

apiVersion: v1  
kind: Pod  
metadata:  
  name: liveness-exec  
  labels:  
    app: liveness  
spec:  
  containers:  
  - name: liveness  
    image: busybox  
    args:                       #创建测试探针探测的文件  
    - /bin/sh  
    - -c  
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600  
    livenessProbe:  
      initialDelaySeconds: 10   #延迟检测时间  
      periodSeconds: 5          #检测时间间隔  
      exec:                     #使用命令检查  
        command:                #指令,类似于运行命令sh  
        - cat                   #sh 后的第一个内容,直到需要输入空格,变成下一行  
        - /tmp/healthy          #由于不能输入空格,需要另外声明,结果为sh cat"空格"/tmp/healthy

存活检查 HTTP

containers:  
        - name: xxx  
          image: xxx  
  
          # 存活检查  
          livenessProbe:  
            httpGet:  
              scheme: HTTP             # 协议  
              path: /actuator/health   # 路径  
              port: 8080               # 端口  
            initialDelaySeconds: 30    # 延迟探测时间(秒) 【 在k8s第一次探测前等待秒 】  
            periodSeconds: 10          # 执行探测频率(秒) 【 每隔秒执行一次 】  
            timeoutSeconds: 1          # 超时时间  
            successThreshold: 1        # 健康阀值   
            failureThreshold: 3        # 不健康阀值

存活检查 TCP

containers:  
        - name: xxx  
          image: xxx  
  
          # 存活检查  
          livenessProbe:  
            tcpSocket:                  # TCP  
              port: 8090                # 端口  
            initialDelaySeconds: 50    # 延迟探测时间(秒) 【 在k8s第一次探测前等待秒 】  
            periodSeconds: 10          # 执行探测频率(秒) 【 每隔秒执行一次 】  
            timeoutSeconds: 1          # 超时时间  
            successThreshold: 1        # 健康阀值   
            failureThreshold: 3        # 不健康阀值

readinessProbe就绪检查

readinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。

containers:  
        - name: xxx  
          image: xxx  
  
          # 就绪检查  
          readinessProbe:  
            httpGet:  
              scheme: HTTP             # 协议  
              path: /actuator/health   # 路径  
              port: 8080               # 端口  
            initialDelaySeconds: 30    # 延迟探测时间(秒)【 在k8s第一次探测前等待秒 】  
            periodSeconds: 2          # 执行探测频率(秒) 【 每隔秒执行一次 】  
            timeoutSeconds: 1          # 超时时间  
            successThreshold: 1        # 健康阀值   
            failureThreshold: 3        # 不健康阀值

startupProbe探针

如果三个探针同时存在,先执行startupProbe探针,其他两个探针将会被暂时禁用,直到pod满足startupProbe探针配置的条件,其他2个探针启动,如果不满足按照规则重启容器

startupProbe:  
  httpGet:  
    path: /test  
    prot: 80  
failureThreshold: 60  
initialDelay:5  
periodSeconds: 5

分发node策略

nodeSelector 标签选择器

# 创建标签
kubectl label node k8snode1 env_role=prod   
# 查看标签
kubectl get node --show-labels   
# 设置nodeSelector
-   nodeSelector  
      env_role: dev

资源限制

resources:  
      requests:  
        memory: "64Mi"  
        cpu: "250m"  
      limits:  
        memory: "128Mi"  
        cpu: "500m"
  • requests:运行的基本条件
  • limits::限制最大

nodeAffinity亲和

  1. required强策略 :必须匹配,不满足一直重试
  2. preferred软策略 :尝试满足,不确定
  3. 条件 In NotIn Exists Gt Lt DoesNotExists 例子
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hello-deployment
  namespace: chenqiang-ns1
  labels:
    app: nginx-hello
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-hello
  template:
    metadata:
      labels:
        app: nginx-hello
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: tester
                operator: NotIn
                values:
                - chenqiang
      containers:
      - name: nginx-hello
        image: docker-registry.saicstack.com/chenqiang/nginx-hello:v2.0
        ports:
        - containerPort: 80
      imagePullSecrets:
      - name: regcred

污点+容忍度

原理
  1. 通过在node节点设置污点
  2. 在yaml文件设置容忍度规则
Taints污点

nodeSelector和nodeAffinity: Pod调度到某些节点上,Pod属性,调度时候实现 Taint污点:节点不做普通分配调度 ,是节点属性

# 查看
  kubectl describe nodes master | grep Taints
# 添加污点
  kubectl taint nodes node1 key=value:NoSchedule
# 删除 使用减号
  kubectl taint nodes node1 key1:NoSchedule-

常用属性

  • NoSchedule:一定不被调度
  • PreferNoSchdule:尽量不被调度
  • NoExecute:不会调度,并且还会驱逐Node已有Pod
容忍度tolerations
 tolerations:- key: "key1"  operator: "Equal"  value: "value1"  effect: "NoExecute"  tolerationSeconds: 3600

6.Controller

  • 早期使用 Replication Controller
  • 后期Replica Set
  • 最新使用Deployment 集成RS功能

特性

确保预期的副本数量 有状态应用部署 无状态应用部署 确保所有node在运行同一个pod 一次性与定时任务

定义

  1. 就是管理容器的对象,即kubectl
  2. 使用kubectl才能创建pod,伸缩,滚动升级
  3. pod和controller 通过类型deployment + 标签label+selector建立关系

例子

spec:
  repicas: 1
  selector:
      matchLabels:
        app: web
  template: 
    metadata:
      labels:
        app: web

Deployment应用场景

deployment就是 rs的一个升级,管理副本数概念

deployment等价于 docker-compse

  1. 管理无状态应用 :web应用 ,微服务
  2. 管理pod和replicaSet
  3. 部署,滚动升级
# 更新
 # 查看kubectl get svc
 # 版本滚动更新 注意下面设置的nginx2 是 svc里的
 kubectl set image deployment nginx2 nginx=nginx:1.15
# 回滚  
# 查看升级状态
kubectl rollout status deployment nginx
# 查看历史升版本
kubectl rollout history deployment nginx
# 回滚上个版本
kubectl rollout undo deployment nginx
# 回滚 指定版本 参数--to-revision 为history查询的版本号
kubectl rollout undo deployment nginx --to-revision=2

使用流程

kubectl create deployment nginx2 --image=nginx -o yaml --dry-run=client > test.yaml

kubectl apply -f test.yaml
kubectl expose deployment nginx2 --port=80 --type=NodePort --target-port=3499 --name=nginx2
kubectl get deployment nginx2 -o yaml > nginx.yaml
# port自动原来系统的端口
# --target-port 是service的内部端口
# 设置type=NodePort 会把80 做随机端口的映射到外部

例子

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      name: newkubia
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx
        name: nginx

7.Service

作用

定义pod的访问规则

存在的意义

  1. 实现服务发现 : 防止pod失联,通过service做统筹
  2. 实现负载均衡

和pod的关系

  1. 一个service关联多个pod
  2. 根据label和selector建立关系

例子

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx2
  name: nginx2
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8000
  selector:
    app: nginx2
  type: NodePort
status:
  loadBalancer: {}

service类型

  1. ClusterIP 集群内使用
  2. NodePort 对外访问
  3. Loadbalancer 对外,公有云 等价于 自己部署了nginx转发 ClusterIP 内部的IP和服务

8.statefulSet

无状态与有状态区别

无状态

  • pod都是一样
  • 无顺序
  • 不考虑指定node运行
  • 随意扩展 伸缩

有状态

  • 每个pod独立
  • 保存pod启动的唯一性 ,生成规则: 主机名称.service名称.名称空间.svc.cluster.local
  • 保持pod的有启动顺序,如mysql 主从服务
  • 唯一网络标识,做持久化

部署有状态

无service

  • ClusterIP:none
  • 无ip
  • kind:StatefulSet

9.SaemonSet

守护进程

确保每一个node 都会运行一份的指定程序,不能多分。如每台机器日志或数据采集

kind: DaemonSet

10.Job

  • 一次性执行的任务
  • 配合command执行

11.CronJob

  • 定时执行的任务
  • 配合command执行

12.Secret

加密配置

  • 存储在etcd
  • pod 挂载Volume
  • 场景 : 凭证的使用

例子

apiVersion: v1
kind: Secret
metadata: 
  name: mysecret
type: Opaque
data:  
user: YWRtaW4=  
pass: MWYyZDFlMmU2N2Rm

env环境变量挂载


#pod-secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-env
spec:
  containers:
  - name: myapp
image: busybox
args:
    - sleep
    - "86400"
env:
    - name: SECRET_USERNAME
      valueFrom:
        secretKeyRef:
          name: mysecret
          key: user
    - name: SECRET_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysecret
          key: pass
  restartPolicy: Never

数据卷挂载

apiVersion: v1
kind: Pod
metadata:
  name: test-projected-volume 
spec:
  containers:
  - name: test-secret-volume
    image: busybox
    args:
    - sleep
    - "86400"
    volumeMounts:
    - name: mysql-cred
      mountPath: "/projected-volume"
      readOnly: true
  volumes:
  - name: mysql-cred
    projected:
      sources:
      - secret:
          name: user
      - secret:
          name: pass

12.ConfigMap

非加密配置存储

例子

#redis.properties
redis.host=127.0.0.1
redis.port=63793
redis.password=123456

# 创建
kubectl create configmap redis-config --from-file=redis.properties
kubectl describe cm redis-config

13.服务端与节点重置

master

# 设置节点为 维护模式
kubectl drain k8snode2 --delete-local-data --force --ignore-daemonsets node/k8snode2 
kubectl drain k8snode1 --delete-local-data --force --ignore-daemonsets node/k8snode1 
# 删除节点
kubectl delete node k8snode2
# 确认是否已经删除
kubectl get nodes

# 生成永久Token(node加入的时候会用到)
kubeadm token create --ttl 0 --print-join-command

# 查看token
kubeadm token list
# 只要token
kubeadm token list | awk -F" " '{print $1}' |tail -n 1 
# 查看当前的节点
kubectl get nodes 
 # 检查健康
kubectl get cs
# 查看启动的服务
kubectl get pods -n kube-system -o wide

# 查看某个节点的完整状态
kubectl describe node k8snode2

node

# 停掉kubelet
systemctl stop kubelet

# 删除之前的相关文件
rm -rf /etc/kubernetes/*

# 依旧有异常 设置这个信息
kubeadm reset 
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
# 查看日志
journalctl -xeu kubelet


# 重新加入xxxxxxxx 通过 master获取
kubeadm join 192.168.0.13:6443 --token xxxxxxxx --discovery-token-unsafe-skip-ca-verification

14.命令描述

基础命令

create # 通过文件名或标准输入创建资源
expose # 将一个资源公开为一个新的Service

run # 在集群中运行一个特定的镜像
set # 在对象上设置特定的功能
get # 显示一个或多个资源
explain # 文档参考资料
edit # 使用默认的编辑器编辑一个资源。
delete # 通过文件名、标准输入、资源名称或标签选择器来删除资源。

部署命令

rollout # 管理资源的发布
rolling-update # 对给定的复制控制器滚动更新
scaleautoscale # 扩容或缩容Pod数量,Deployment、ReplicaSet、RC或Job创建一个自动选择扩容或缩容并设置Pod数量

集群管理命令

certificate # 修改证书资源
cluster-info # 显示集群信息
top # 显示资源(CPU/Memory/Storage)使用。需要Heapster运行
cordon# 标记节点不可调度
uncordon# 标记节点可调度
drain # 驱逐节点上的应用,准备下线维护
taint# 修改节点taint标记

高级命令

apply # 通过文件名或标准输入对资源应用配置
patch # 使用补丁修改、更新资源的字段
replace # 通过文件名或标准输入替换一个资源
convert # 不同的API版本之间转换配置文件

设置命令

label # 更新资源上的标签
annotate # 更新资源上的注释
completion # 用于实现kubect1工具自动补全

其他命令

api-versions # 打印受支持的API版本 
config # 修改kubeconfig文件(用于访问AP1,比如配置认证信息)
help # 所有命令帮助
plugin # 运行一个命令行插件
version # 打印客户端和服务版本信息

官方说明


Basic Commands (Beginner):
  create        Create a resource from a file or from stdin.
  expose        Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service
  run           Run a particular image on the cluster
  set           Set specific features on objects

Basic Commands (Intermediate):
  explain       Documentation of resources
  get           Display one or many resources
  edit          Edit a resource on the server
  delete        Delete resources by filenames, stdin, resources and names, or by resources and label selector

Deploy Commands:
  rollout       Manage the rollout of a resource
  scale         Set a new size for a Deployment, ReplicaSet or Replication Controller
  autoscale     Auto-scale a Deployment, ReplicaSet, or ReplicationController

Cluster Management Commands:
  certificate   Modify certificate resources.
  cluster-info  Display cluster info
  top           Display Resource (CPU/Memory/Storage) usage.
  cordon        Mark node as unschedulable
  uncordon      Mark node as schedulable
  drain         Drain node in preparation for maintenance
  taint         Update the taints on one or more nodes

Troubleshooting and Debugging Commands:
  describe      Show details of a specific resource or group of resources
  logs          Print the logs for a container in a pod
  attach        Attach to a running container
  exec          Execute a command in a container
  port-forward  Forward one or more local ports to a pod
  proxy         Run a proxy to the Kubernetes API server
  cp            Copy files and directories to and from containers.
  auth          Inspect authorization

15.常用命令

namespace

# 查看
kubectl get ns 
# 删除
kubectl delete ns/nginx-01

node

# 查看当前的节点
kubectl get nodes
# 查看节点 其他信息
kubectl get node o wide
# 查看节点 labels
kubectl get node --show-labels
# 显示node描述
kubectl describe node k8smaster 

pod

# 查看 默认读取default
kubectl get pods
# 查看 所有pod
kubectl get pods -A

# 输出额外信息
kubectl get pods -o=wide
# 输出yml文件
kubectl get pods etcd-k8smaster -o=yml
# 显示pod信息
kubectl get pods nginx-f89759699-4r8sf  -o yaml
# 暴露端口
kubectl expose deployment nginx --port=8076 --type=NodePort
# 删除所有 Pod
kubectl delete pod --all
# 重启 pod
kubectl get pod <POD名称> -n <NAMESPACE名称> -o yaml | kubectl replace --force -f -

deployment

# 创建
kubectl create deployment nginx --image=nginx

# 执行create 同时 输出yaml 
kubectl create deployment nginx2 --image=nginx -o yaml
# 不执行create只输出yaml
kubectl create deployment nginx2 --image=nginx -o yaml --dry-run=client
# 不执行create只输出yaml 同时输出文件
kubectl create deployment nginx2 --image=nginx -o yaml --dry-run=client > ngiinx.yaml

# get 输出yaml 
kubectl get deployment nginx2 -o yaml

# get 输出yaml 同时输出文件
kubectl get deployment nginx2 -o yaml > nginx.yaml

# 查看已部署
kubectl get deployments  
 
## 弹性伸缩 
kubectl scale deployment nginx2 --replicas=3
 
# 伸缩 pod  也可以做删除处理,设置为0即可
kubectl scale deploy/nginx-1 --replicas=0
kubectl scale deploy/nginx-1 --replicas=1
 

controller

# run创建
kubectl run nginx --image=nginx:latest --imagePullPolicy=IfNotPresent --replicas=3
# create创建
kubectl create -f nginx.yaml
# 查看控制器
kubectl get rc 
# 删除
kubectl delete rc/nginx 
# rs 复制对象 ReplicaSet 
kubectl get rs 

service

# 暴露端口 注意8000不是对外的端口 只是pause容器端口,最终对外是随机的
kubectl expose deployment nginx2 --port=80 --type=NodePort --target-port=8000 --name=nginx2
# 暴露端口 不执行并导出文件
kubectl expose deployment nginx2 --port=80 --type=NodePort --target-port=8000 --name=nginx2 --dry-run=client -o yaml > nginx8.yaml

# 端口映射
kubectl expose rc rc-name --type=ClusterIP --target-port=80 --port=80
# yaml方式
kubectl create -f nginx-service.yaml
# 修改网络类型
kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'
# 删除
kubectl delete svc/nginx

rollout

# 查看
kubectl get svc
# 版本滚动更新 注意下面设置的nginx2 是 svc里的
kubectl set image deployment nginx2 nginx=nginx:1.15
# 查看升级状态
kubectl rollout status deployment nginx
# 查看历史升版本
kubectl rollout history deployment nginx
# 回滚上个版本
kubectl rollout undo deployment nginx
# 回滚 指定版本 参数--to-revision 为history查询的版本号
kubectl rollout undo deployment nginx --to-revision=2

其他

# exec  
kubectl exec -it redis-master-cln81 -- bash

# logs
kubectl logs <pod-name>
# 实时查看日志
kubectl logs -f <pod-name> 

# 查看节点 labels
kubectl get node --show-labels
# 设置label标签
kubectl label k8snode1 env_role=prod

# 查看 endpoint 列表
kubectl get endpoints
# 删除资源
kubectl delete 资源类型 -l name=<label-name>

# describe 的详细信息
kubectl describe node k8smaster 
kubectl describe pod  nginx

# csr
# 获取当前证书
kubectl get csr