k8s的YAML与集群访问

2022-10-12 15:46:58 浏览数 (1)

一. 常用命令

含义

命令

部署应用

kubectl apply -f app.yaml

查看 pod

kubectl get pod -o wide

查看 pod 详情

kubectl describe pod pod-name

查看 log

kubectl logs pod-name

查看deployment

kubectl get deployment

查看service

kubectl get svc

查看service详情

kubectl describe svc test-k8s

获取service的endpoints的信息

kubectl get endpoints

获取service的endpoints的详细信息

kubectl get endpoints service-name -o yaml

查看statefulset的状态

kubectl get statefulsets

删除全部资源

kubectl delete all --all

删除部署

kubectl delete deployment test-k8s

删除service

kubectl delete svc test-k8s

进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。

kubectl exec -it pod-name -- bash

伸缩扩展副本

kubectl scale deployment test-k8s --replicas=5

把集群内端口映射到节点

kubectl port-forward pod-name 8090:8080

其他命令

含义

命令

查看全部

kubectl get all

重新部署

kubectl rollout restart deployment test-k8s

命令修改镜像,--record 表示把这个命令记录到操作历史中

kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record

暂停运行,暂停后,对 deployment 的修改不会立刻生效,恢复后才应用设置

kubectl rollout pause deployment test-k8s

恢复

kubectl rollout resume deployment test-k8s

输出到文件

kubectl get deployment test-k8s -o yaml >> app2.yaml

查看历史

kubectl rollout history deployment test-k8s

回到上个版本

kubectl rollout undo deployment test-k8s

回到指定版本

kubectl rollout undo deployment test-k8s --to-revision=2

二. Service

1. 集群内访问

代码语言:txt复制
apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  type: ClusterIP
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口

应用配置 kubectl apply -f service.yaml

查看服务 kubectl get svc

查看服务详情 kubectl describe svc test-k8s ,可以发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点。

服务的默认类型是 ClusterIP ,只能在集群内部访问,我们可以进入到 Pod 里面访问:

kubectl exec -it pod-name -- bash

curl http://test-k8s:8080

如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):

kubectl port-forward service/test-k8s 8888:8080

2. 集群外访问

代码语言:txt复制
apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s
  # 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
  type: NodePort
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口
      nodePort: 31000   # 节点端口,范围固定 30000 ~ 32767

应用配置 kubectl apply -f service.yaml

在节点上,我们可以 curl http://localhost:31000/hello/easydoc 访问到应用

并且是有负载均衡的,网页的信息可以看到被转发到了不同的 Pod

代码语言:txt复制
hello easydoc 

IP lo172.17.0.8, hostname: test-k8s-68bb74d654-962lh

如果你是用 minikube,因为是模拟集群,你的电脑并不是节点,节点是 minikube 模拟出来的,所以你并不能直接在电脑上访问到服务

Loadbalancer 也可以对外提供服务,这需要一个负载均衡器的支持,因为它需要生成一个新的 IP 对外服务,否则状态就一直是 pendding,这个很少用了,后面我们会讲更高端的 Ingress 来代替它。

3. 总结

ClusterIP

默认的,仅在集群内可用

NodePort

暴露端口到节点,提供了集群外部访问的入口

端口范围固定 30000 ~ 32767

三. YAML关键字

字段名

字段类型

说明

version

string

RESTFul API的版本,目前基本上是v1,可以通过kubectl api-versions命令去查询所有的API的version

kind

string

定义的资源类型和角色,例如Pod

metadata

object

元数据对象,固定值就写metadata

metadata.name

string

元数据对象的名字,例如Pod的名字

metadata.namespace

string

元数据对象的命名空间,不指定则默认是default空间

spec

objec

详细定义对象,固定值就写Spec

spec.containers[]

list容器列表

spec.containers[].name

string

这里定义容器的名字

spec.containers[].image

string

这里定义容器要用到的镜像名称

spec.containers[].imagePullPolicy

string

镜像拉取策略,有Always/Never/IfNotPresent三个可选,默认是Always

spec.containers[].command[]

list

指定容器启动命令,不指定则使用镜像打包时的启动命令

spec.containers[].args[]

list

指定容器启动命令参数,因为是数组所以可以指定多个

spec.containers[].workingDir

string

指定容器的工作目录

spec.containers[].volumeMounts[]

list

存储卷配置

spec.containers[].volumeMounts[].name

string

spec.containers[].volumeMounts[].mountPath

string

spec.containers[].volumeMounts[].readOnly

string

spec.containers[].ports[]

list

容器需要的端口列表

spec.containers[].ports[].name

string

端口名称

spec.containers[].ports[].containerPort

string

容器需要监听的端口号

spec.containers[].ports[].hostPort

string

主机需要监听的端口号,默认跟上面的containersPort一致,设置了以后不能在同一台宿主机上启动第二个副本

spec.containers[].ports[].protocol

string

端口协议,TCP/UDP,默认是TCP

spec.containers[].env[]

list

环境变量

spec.containers[].env[].name

string

环境变量名称

spec.containers[].env[].value

string

环境变量值

spec.containers[].resources

object

限制资源的使用上限,后面详细讲

spec.restartPolicy

string

Pod的重启策略,可选Always/OnFailure/Never,默认值为Always

spec.nodeSelector

object

定义Node的label过滤标签,键值对格式指定

spec.imagePullSecrets

object

定义pull镜像时使用的密钥,键值对格式指定

spec.hostNetwork

Boolean

定义是否使用主机网络。默认为false表示不使用宿主机网络,只用docker网桥。设置了true将无法在同一台宿主机上启动第二个副本

举例:

四. yaml文件的固定结构

代码语言:txt复制
COPY每个文件必须的结构如下:
apiVersion: apps/v1  # api版本
kind: xxxx   # 要创建的资源类型,如Deployment/Pod/ReplicaSet/StatefulSet/DaemonSet/Job/Cronjob/Service/Ingress...
metadata:    # 元数据对象,该资源的基本属性和信息
  name: xxx  # 定义该资源的名称
  namespace: xxx  # 命名空间,默认放到default空间
  lables:    # 标签,在下一行定义键值对,可以是多对键值对
    xxx: xxxx
    xxx: xxxx
  annotations # 资源注解
    xxx: xxxx
spec:   # 定义期望状态,详细的创建信息
  containers:  # 容器列表
  - name: xxx   # 容器名
    image: xxxx  # 容器镜像
status: # 当前状态,由k8s集群维护,不可以自定义

1. Controller定义部分

代码语言:txt复制
COPY必须定义名字
------------------------------------------
apiVersion: apps/v1   # api版本(必须的)
kind: Deployment   # 表示要创建的Controller资源类型
metadata:   # 元数据对象,该资源的基本属性和信息(必须的)
  name: nginx-deployment  # 定义该资源的名称(必须的),同一命名空间内,必须唯一
  namespace: xxxx  # 命名空间,默认放到default空间(可选)
  labels:  # 标签,用来定位一个或多个资源,键值对方式进行定义,下方使用的selector会与这里的键值对对应,作为selector的挑选条件
    app: nginx  # 设置key为app,value为nginx
------------------------------------------

2. 资源的特点

也就是kind所创建的资源的信息

代码语言:txt复制
COPY------------------------------------------
spec:  # 描述该资源的创建信息,对应kind资源类型的信息
  revisionHistoryLimit: 10  # 回滚时会用到,用来保留最近10的版本
  replicas: 2  # 创建2个应用实例
  selector:  
  # 标签选择器,与上面的标签共用,这个部分是17版本开始加的,必须与上面的labels对应
    matchLabels: # 选择包含标签app:nginx的资源
    # 正确的Deployment,让matchLabels 和template.metadata.lables完全匹配才能不报错
    # 直接不写spec.mathlabels创建直接报错缺少缺少必要字段selector
    # 当把matchLables匹配的和下面pod模板不相对应,也会直接报错:选择的标签和模板标签不匹配
    # matchLabel是pod的标签选择器。 由此选择其pod的现有ReplicaSet(副本集)将受此部署影响的副本。
      app: nginx
------------------------------------------

matchLabels总结

1、在Deployment中必须写matchLabels

2、在定义模板的时候必须定义labels,因为Deployment.spec.selector是必须字段,而又必须和template.labels对应

3、templdate里面定义的内容会应用到下面所有的副本集里面,在template.spec.containers里面不能定义labels标签

3. Pod的模板

代码语言:txt复制
COPY必须定义labels
------------------------------------------
  template:  # 选择或创建的Pod模板
    metadata: # Pod的元数据,Pod的信息
      labels: # Pod标签
        app: nginx
------------------------------------------

4. Container的模板

代码语言:txt复制
COPY------------------------------------------
    spec:  # 期望Pod实现的功能(在Pod中部署什么)
      strategy:  # 在滚动更新Pod时的启动Pod数量比值
        rollingUpdate:
          maxSurge: 35%
          maxUnavailable: 35%
      nodeSelector:  # 指定pod运行在哪个集群节点
      restartPolicy: # 容器重启策略(Never/Always/OnFailure)
      hostNetwork: true  # 表示直接使用节点中的主机网络,相当于docker的host网络
      containers:   # 在Pod中生成容器,容器列表,可写入多个镜像的实例
      - name: xxxx   # 定义容器名
        image: xxxx  # 容器使用的镜像
      - name: xxxx
        image: xxxx
        imagePullPolicy:  
        # 镜像下载策略(IfNotPresent/Never/Always)
        # 分别代表,没有镜像时下载,从不下载,总是下载
        command: # 运行程序==dockerfile中的ENTRYPOINT,或者docker run时最后跟的/bin/bash等命令,会替代dockerfile中cmd和ENTRYPOINT执行的命令
        - echo
        - 'hello world'
        args: # 向docker镜像中传递命令,通常用来给command传参,也可以单独使用,与dockerfile中的CMD作用一样,如果yml中只写了args,将会给dockerfile中的ENTRYPOINT传参,dockerfile中的CMD会失效。
        - xxx
        - xxx 
        ports:  # 用来暴露端口,并不是端口映射,仅仅为了可以看到容器中使用了哪两个端口
        - name: xxx
          containerPort: 80  # 容器中提供服务的端口
          protocol: TCP/UDP # 默认是tcp
        - name: xxx
          containerPort: 443
        volumeMounts: # 用来指定容器内的路径
        - name: nginxconf
          mountPath: /usr/local/nginx/conf
        - name: nginxhtml
          mountPath: /usr/local/nginx/html
          readOnly: True  # 设置容器内只读,默认是读写
      volumes:   # 指定对应name的物理机路径,缩进与上方的containers对齐
      - name: nginxconf
        hostPath: 
          path: /nginx/conf
      - name: nginxhtml
        hostPath: 
          path: /nginx/html
      - name: xxx
        emptyDir: {}
      - name: xxx   
        persistentVolumeClaim:   # 使用PVC存储资源
          claimName: xxxxx-xxx
        LivenessProbe:   # 存活检测,判断文件是否存在,检测失败重启容器
          exec:
            command:
              - cat
              - /tmp/healthy
        readinessProbe:  # 读取检测,判断文件是否存在,检测失败,标记为不可用,将不会被Service所负载
          exec:
            command:
              - cat
              - /tmp/healthy
------------------------------------------

五. 常见问题

如果你运行 kubectl describe pod/pod-name 发现 Events 中有下面这个错误

代码语言:txt复制
networkPlugin cni failed to set up pod "test-k8s-68bb74d654-mc6b9_default" network: open /run/flannel/subnet.env: no such file or directory

在每个节点创建文件 /run/flannel/subnet.env 写入以下内容,配置后等待一会就好了

代码语言:txt复制
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
image.pngimage.png

参考文章

  1. 【Kubernetes 004】用yaml文件创建自己的第一个pod
  2. Kubernetes之yaml文件详解(汇总-详细)

0 人点赞