k8s基础应用

1.集群与节点信息

查看集群信息

[root@master ~]# kubectl cluster-info
Kubernetes control plane is running at https://172.20.251.148:6443
CoreDNS is running at https://172.20.251.148:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

查看节点信息

[root@master ~]# kubectl get nodes
NAME               STATUS   ROLES                  AGE     VERSION
master.novalocal   Ready    control-plane,master   43m     v1.23.6
node1              Ready    <none>                 10m     v1.23.6
node2              Ready    <none>                 9m50s   v1.23.6

查看节点详细信息

[root@master ~]# kubectl get nodes -o wide
NAME               STATUS   ROLES                  AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION                CONTAINER-RUNTIME
master.novalocal   Ready    control-plane,master   44m   v1.23.6   172.20.251.148   <none>        CentOS Linux 8 (Core)   4.18.0-193.6.3.el8_2.x86_64   docker://20.10.14
node1              Ready    <none>                 11m   v1.23.6   172.20.251.123   <none>        CentOS Linux 8 (Core)   4.18.0-193.6.3.el8_2.x86_64   docker://20.10.14
node2              Ready    <none>                 10m   v1.23.6   172.20.251.120   <none>        CentOS Linux 8 (Core)   4.18.0-193.6.3.el8_2.x86_64   docker://20.10.14

描述节点详细信息

[root@master ~]# kubectl describe node master
...

node节点管理集群

[root@node1 ~]# kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?
# node节点查询报错
[root@node1 ~]# mkdir /root/.kube
# 在node节点root用户家目录创建.kube文件夹
[root@node1 ~]# scp master:/etc/kubernetes/admin.conf /root/.kube/config
The authenticity of host 'master (172.20.251.148)' can't be established.
ECDSA key fingerprint is SHA256:y4GFkbzewn4PujQNgjHnRTd63vTDo7NsAy0jEBZa3o8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'master' (ECDSA) to the list of known hosts.
admin.conf 
# 复制master节点配置文件
[root@node1 ~]# kubectl get nodes
NAME               STATUS   ROLES                  AGE   VERSION
master.novalocal   Ready    control-plane,master   47m   v1.23.6
node1              Ready    <none>                 14m   v1.23.6
node2              Ready    <none>                 14m   v1.23.6
# 验证结果

节点标签

[root@master ~]# kubectl get node --show-labels
NAME               STATUS   ROLES                  AGE   VERSION   LABELS
master.novalocal   Ready    control-plane,master   48m   v1.23.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master.novalocal,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
node1              Ready    <none>                 15m   v1.23.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node1,kubernetes.io/os=linux
node2              Ready    <none>                 15m   v1.23.6   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux
# 查看节点标签信息
[root@master ~]# kubectl label node node1 node-role.kubernetes.io/node=
node/node1 labeled
[root@master ~]# kubectl label node node2 node-role.kubernetes.io/node=
node/node2 labeled
# 设置节点标签信息
[root@master ~]# kubectl get nodes 
NAME               STATUS   ROLES                  AGE   VERSION
master.novalocal   Ready    control-plane,master   50m   v1.23.6
node1              Ready    node                   17m   v1.23.6
node2              Ready    node                   17m   v1.23.6
# 验证结果

多维度标签

[root@master ~]# kubectl label node node1 zone=A business=game --overwrite
node/node1 labeled
[root@master ~]# kubectl label node node2 zone=B business=game --overwrite    
node/node2 labeled
[root@master ~]# kubectl get nodes --show-labels
# 验证
[root@master ~]# kubectl get nodes -L zone
NAME               STATUS   ROLES                  AGE   VERSION   ZONE
master.novalocal   Ready    control-plane,master   53m   v1.23.6   
node1              Ready    node                   20m   v1.23.6   A
node2              Ready    node                   20m   v1.23.6   B
# 显示节点相对应的标签
[root@master ~]# kubectl label node node1 zone-
node/node1 unlabeled
# 取消标签信息

标签选择器

[root@master ~]# kubectl get node -l "zone in (A,B)" 
NAME    STATUS   ROLES   AGE   VERSION
node1   Ready    node    22m   v1.23.6
node2   Ready    node    22m   v1.23.6

2.Namespace

在 Kubernetes 中,“名字空间(Namespace)”提供一种机制,将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一,但跨名字空间时没有这个要求。 名字空间作用域仅针对带有名字空间的对象,例如 Deployment、Service 等, 这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等。
对于同一种资源的不通版本,就可以直接使用label来划分即可,不需要使用namespace来区分

查看namespace信息

[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   160m
# pod未指定的情况下分配到default
kube-node-lease   Active   160m
# 节点资源
kube-public       Active   160m
# 此命名空间下的资源可以被所有人访问
kube-system       Active   160m
# 所有有kubernetes系统创建的资源都处于这个命名空间
# namespace可以简写成ns

创建namespace

[root@master ~]# kubectl create namespace test1
namespace/test1 created
# 命令创建
[root@master ~]# kubectl edit namespace test1
# 可以通过edit修改namespace的yaml文件
[root@master ~]# kubectl get namespace test1 -o yaml
# 只查询使用这种方法
[root@master ~]# vim create_namespace.yml 
apiVersion: v1
kind: Namespace
metadata:
  name: test2
保存退出
[root@master ~]# kubectl apply -f create_namespace.yml 
namespace/test2 created
# 通过yaml文件创建
[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   165m
kube-node-lease   Active   166m
kube-public       Active   166m
kube-system       Active   166m
test1             Active   3m22s
test2             Active   20s
# 验证

删除namespace
注意:删除一个namespace会自动删除所有属于该namespace的资源

[root@master ~]# kubectl delete namespace test1
namespace "test1" deleted
# 命令删除
[root@master ~]# kubectl delete -f create_namespace.yml           
namespace "test2" deleted
# yaml文件删除
[root@master ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   168m
kube-node-lease   Active   168m
kube-public       Active   168m
kube-system       Active   168m
验证

3.工作负载(workloads)

工作负载是在 Kubernetes 上运行的应用程序。
无论你的负载是单一组件还是由多个一同工作的组件构成,在 Kubernetes 中你 可以在一组 Pods 中运行它。在 Kubernetes 中,Pod 代表的是集群上处于运行状态的一组 容器。

Kubernetes Pods 有确定的生命周期。 例如,当某 Pod 在你的集群中运行时,Pod 运行所在的 节点 出现致命错误时, 所有该节点上的 Pods 都会失败。Kubernetes 将这类失败视为最终状态: 即使该节点后来恢复正常运行,你也需要创建新的 Pod 来恢复应用。

不过,为了让用户的日子略微好过一些,你并不需要直接管理每个 Pod。 相反,你可以使用 负载资源 来替你管理一组 Pods。 这些资源配置 控制器 来确保合适类型的、处于运行状态的 Pod 个数是正确的,与你所指定的状态相一致。

workloads分为pod与controllers
pod通过控制器实现应用的运行,如何伸缩,升级等
controllers 在集群中管理pod
pod与控制器之间通过label-selector相关联,是唯一的关联方式
比如:

labels:
  app: nginx
# 在pod的yaml里指定
labels:
  app: nginx
# 在控制器的yaml里指定

4.Pod

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。

Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。

除了应用容器,Pod 还可以包含在 Pod 启动期间运行的 Init 容器。 你也可以在集群中支持临时性容器 的情况下,为调试的目的注入临时性容器。

就 Docker 概念的术语而言,Pod 类似于共享名字空间和文件系统卷的一组 Docker 容器。

Pod分类
无控制器管理的自主式pod 没有副本控制器控制,删除自主式pod后
不会重新创建
控制器管理的pod 控制器会按照定义的策略控制pod的数量,发现
pod数量少了,会立即自动建立出来新的pod;一旦发现pod多了,也
会自动杀死多余的Pod。

YAML格式查找帮助方法(需掌握)

[root@master ~]# kubectl api-versions
# 查看api版本
[root@master ~]# kubectl explain pod
KIND:     Pod
VERSION:  v1
...
# 查看资源写法,VERSION即yaml文件中的apiVersion
[root@master ~]# kubectl explain pod.spec
# 查看下级资源写法

创建一个自主式Pod

[root@master ~]# vim pod1.yml              
apiVersion: v1
# api版本号
kind: Pod
# 资源类型
metadata:
  name: nginx-test1
# Pod名称
spec:
  containers:
  - name: test
# 容器名称
    image: nginx:latest
# 容器镜像
# 生产环境不建议使用latest,刚使用还好,使用久了就没分不清是哪个版本,也不好更新
    imagePullPolicy: IfNotPresent
# 容器拉取策略
# 默认为always,即总是下载,IfNotPresent表示优先使用本地镜像,否则下载,Nerver表示仅使用本地镜像
    ports:
    - name: nginx-port
# 端口号名称
      containerPort: 80
# 容器需要监听的端口号
保存退出
[root@master ~]# kubectl apply -f pod1.yml 
pod/nginx-test1 created
# 应用yaml文件创建
[root@master ~]# kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
nginx-test1   1/1     Running   0          62s   10.3.2.2   node2   <none>           <none>
# 查询pod详细信息
[root@master ~]# curl 10.3.2.2
# 验证
[root@master ~]# kubectl describe pod nginx-test1
# 描述pod详细信息

Pod标签
为pod设置lebel,用于控制器通过label与pod关联

[root@master ~]# kubectl label pod nginx-test1 zone=A
pod/nginx-test1 labeled
# 为nginx-test1打上zone=A的标签
[root@master ~]# kubectl get pods --show-labels
NAME          READY   STATUS    RESTARTS   AGE     LABELS
nginx-test1   1/1     Running   0          7m34s   zone=A
# 查看pod标签
[root@master ~]# kubectl get pods -l zone=A
NAME          READY   STATUS    RESTARTS   AGE
nginx-test1   1/1     Running   0          8m30s
# 通过标签查询pod
[root@master ~]# kubectl get pods -l "zone in (A,B)"
NAME          READY   STATUS    RESTARTS   AGE
nginx-test1   1/1     Running   0          9m1s
# 通过集合查询
[root@master ~]# kubectl label pod nginx-test1 zone-
pod/nginx-test1 unlabeled
# 删除标签
[root@master ~]# kubectl get pods --show-labels      
NAME          READY   STATUS    RESTARTS   AGE     LABELS
nginx-test1   1/1     Running   0          9m54s   <none>
# 验证
pod的label与node的label操作方式几乎相同
node的label用于pod调度到指定label的node节点
pod的label用于controller关联控制的pod

删除Pod

[root@master ~]# kubectl delete pod nginx-test1
pod "nginx-test1" deleted
# 也可以通过yaml文件删除,加上-f参数

Pod资源限制

[root@node1 ~]# kubectl explain pod.spec.containers.resources
# 查看资源写法
[root@master ~]# vim pod1.yml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test1
spec:
  containers:
  - name: test
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx-port
      containerPort: 80
    resources:
      limits:
        memory: "100Mi"
        # 最大内存限制为100M
      requests:
        memory: "50Mi"
        # 最小内存限制为50M

Pod重启策略(重要)
Always:表示容器挂了总是重启,这是默认策略
OnFailures:表容器状态为错误时才重启,也就是容器正常终止时才重

Never:表示容器挂了不予重启
对于Always这种策略,容器只要挂了,就会立即重启,这样是很耗费
资源的。所以Always重启策略是这么做的:第一次容器挂了立即重
启,如果再挂了就要延时10s重启,第三次挂了就等20s重启… 依次
类推

一个Pod包含多个容器

[root@master ~]# vim pod2.yml                      
apiVersion: v1
kind: Pod
metadata:
  name: busybox-test1
spec:
  containers:
  - name: test1
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command:
      - sleep
      - "3600"
  - name: test2
  # 注意容器名不要重复
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command:
      - sleep
      - "3600"
保存退出
[root@master ~]# kubectl apply -f pod2.yml 
pod/nginx-test1 created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods
NAME          READY   STATUS    RESTARTS     AGE
busybox-test1   2/2     Running   1 (4s ago)   11s
# 验证

不交互直接执行命令

[root@master ~]# kubectl exec -it busybox-test1 -c test1 -- touch /111 
# -c容器名为可选项,如果一个pod中只有一个容器,可以不用指定

和容器交互操作

[root@master ~]# kubectl exec -it busybox-test1 -c test1 -- /bin/sh  
# 和docker exec几乎一致,只是多了--和指定容器
/ # ls
111   bin   dev   etc   home  proc  root  sys   tmp   usr   var

删除pod

[root@master ~]# kubectl delete pod busybox-test1
pod "busybox-test1" deleted

Pod调度(重要)
我们为了实现容器主机资源平衡使用, 可以使用约束把pod调度到指定的
node节点
nodeName 用于将pod调度到指定的node名称上
nodeSelector 用于将pod调度到匹配Label的node上

[root@master ~]# vim pod1.yml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test1
spec:
  nodeName: node1
  # 通过nodeName调度到node1节点
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx-port
      containerPort: 80
保存退出
[root@master ~]# kubectl apply -f pod1.yml 
pod/nginx-test1 created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods -o wide                 
NAME          READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
nginx-test1   1/1     Running   0          74s   10.3.1.4   node1   <none>           <none>
# 验证
[root@master ~]# kubectl delete pod nginx-test1
pod "nginx-test1" deleted
# 删除pod
[root@master ~]# kubectl label node node1 zone=A --overwrite
node/node1 not labeled
# 给node1节点打标签
[root@master ~]# vim pod1.yml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test1
spec:
  nodeSelector: 
  # nodeSelector节点选择器
    zone: A
    # 指定调度到标签为zone=A的节点
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx-port
      containerPort: 80
保存退出
[root@master ~]# kubectl apply -f pod1.yml                             
pod/nginx-test1 created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE   IP         NODE    NOMINATED NODE   READINESS GATES
nginx-test1   1/1     Running   0          5s    10.3.1.5   node1   <none>           <none>
# 验证
[root@master ~]# kubectl delete pod nginx-test1
pod "nginx-test1" deleted
# 删除pod

5.Pod的生命周期

有些pod(比如跑nginx服务),正常情况下会一直运行中,但如果手动删除
它,此pod会终止
也有些pod(比如执行计算任务),任务计算完后就会自动终止
上面两种场景中,pod从创建到终止的过程就是pod的生命周期。

Pod阶段
Pod 的 status 字段是一个 PodStatus 对象,其中包含一个 phase 字段。

Pod 的阶段(Phase)是 Pod 在其生命周期中所处位置的简单宏观概述。 该阶段并不是对容器或 Pod 状态的综合汇总,也不是为了成为完整的状态机。

取值描述
Pending(悬决)Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。
Running(运行中)Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
Succeeded(成功)Pod 中的所有容器都已成功终止,并且不会再重启。
Failed(失败)Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
Unknown(未知)因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。

如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的 phase 设置为 Failed。

容器启动

  1. pod中的容器在创建前,有初始化容器(init container)来进行初始化环境
  2. 初化完后,主容器(main container)开始启动
  3. 主容器启动后,有一个post start的操作(启动后的触发型操作,或者叫启
    动后钩子)
  4. post start后,就开始做健康检查

第一个健康检查叫存活状态检查(liveness probe ),用来检查主容
器存活状态的

第二个健康检查叫准备就绪检查(readyness probe),用来检查主容
器是否启动就绪

容器终止

  1. 可以在容器终止前设置pre stop操作(终止前的触发型操作,或者叫终止
    前钩子)
  2. 当出现特殊情况不能正常销毁pod时,大概等待30秒会强制终止
  3. 终止容器后还可能会重启容器(视容器重启策略而定)。

HealthCheck健康检查

方式说明
LivenessProbe(存活状态探测)检查后不健康,重启pod
readinessProbe(就绪型探测)检查后不健康,将容器设置为Notready;如果使用service来访问,流量不会转发给此种状态的pod

Probe探测方式

方式说明
Exec执行命令
HTTPGethttp请求某一个URL路径
TCPtcp连接某一个端口

liveness-exec

[root@node1 ~]# kubectl explain pod.spec.containers.livenessProbe
# 查询资源写法
[root@master ~]# vim pod-liveness-exec.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat   
        - /tmp/healthy
      initialDelaySeconds: 5
      #  pod启动延迟5秒后探测
      periodSeconds: 5
      # 每5秒探测一次
保存退出
[root@master ~]# kubectl apply -f pod-liveness-exec.yaml 
pod/liveness-exec created
# 应用yaml文件创建pod
[root@master ~]# kubectl describe pod liveness-exec
...
# 验证
[root@master ~]# kubectl delete pod liveness-exec
pod "liveness-exec" deleted
# 删除pod

liveness-httpget

[root@master ~]# vim pod-liveness-httpget.yml 
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
spec:
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx
      containerPort: 80
    livenessProbe:
      httpGet:
        port: nginx
        # 指定端口名,也可以直接写80端口
        path: /index.html
      initialDelaySeconds: 3
      # 延迟3秒开始探测
      periodSeconds: 5
      # 每隔5秒探测一次
保存退出  
[root@master ~]# kubectl apply -f pod-liveness-httpget.yml 
pod/liveness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
# 非交互式删除nginx主页文件
[root@master ~]# kubectl get pods
NAME               READY   STATUS    RESTARTS     AGE
liveness-httpget   1/1     Running   1 (5s ago)   2m46s
# 注意5秒前已经RESTART过一次
[root@master ~]# kubectl delete pod liveness-httpget
pod "liveness-httpget" deleted
# 删除pod

liveness-tcp

[root@master ~]# vim pod-liveness-tcp.yml 
apiVersion: v1
kind: Pod
metadata:
  name: liveness-tcp
spec:
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx
      containerPort: 80
    livenessProbe:
      tcpSocket:
        port: 80
        # 连接80端口进行探测
      initialDelaySeconds: 3
      periodSeconds: 5
保存退出
[root@master ~]# kubectl apply -f pod-liveness-tcp.yml 
pod/liveness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it liveness-tcp -- /usr/sbin/nginx -s stop
2022/04/25 07:08:22 [notice] 36#36: signal process started
# 关闭nginx
[root@master ~]# kubectl get pods
NAME           READY   STATUS    RESTARTS      AGE
liveness-tcp   1/1     Running   1 (26s ago)   41s
# 验证
[root@master ~]# kubectl delete pod liveness-tcp
pod "liveness-tcp" deleted
# 删除pod

readiness

[root@master ~]# vim pod-readiness-httpet.yml 
apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget
spec:
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx
      containerPort: 80
    readinessProbe:
    # 替换为readinessProbe
      httpGet:
        port: nginx
        path: /index.html
      initialDelaySeconds: 3
      periodSeconds: 5
保存退出
[root@master ~]# kubectl apply -f pod-readiness-httpet.yml 
pod/readiness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html
# 删除nginx主页
[root@master ~]# kubectl get pods
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   0/1     Running   0          76s
# 验证
[root@master ~]# kubectl exec -it readiness-httpget -- touch /usr/share/nginx/html/index.html 
# 创建nginx主页
[root@master ~]# kubectl get pods
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   1/1     Running   0          2m16s
# 验证

readiness+liveness综合

[root@master ~]# vim pod-readiness-liveness-httpget.yml 
apiVersion: v1
kind: Pod
metadata:
  name: readiness-liveness-httpget
spec:
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx
      containerPort: 80
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
    readinessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
保存退出
[root@master ~]# kubectl apply -f pod-readiness-liveness-httpget.yml 
pod/readiness-liveness-httpget created
# 应用yaml文件创建pod
[root@master ~]# kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
readiness-httpget            1/1     Running   0          75m
readiness-liveness-httpget   0/1     Running   0          35s
# 验证
[root@master ~]# kubectl delete pod readiness-httpget
pod "readiness-httpget" deleted
[root@master ~]# kubectl delete pod readiness-liveness-httpget
pod "readiness-liveness-httpget" deleted
# 删除pod

post-start

[root@master ~]# vim pod-poststart.yml 
apiVersion: v1
kind: Pod
metadata:
  name: poststart
spec:
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx
      containerPort: 80
    lifecycle:
    # 生命周期事件
      postStart:
        exec:
          command: ["touch", "/usr/share/nginx/html/test1"]
保存退出
[root@master ~]# kubectl apply -f pod-poststart.yml 
pod/poststart created
# 应用yaml文件创建pod
[root@master ~]# kubectl exec -it poststart -- ls /usr/share/nginx/html
50x.html  index.html  test1
# 验证

pre-stop

[root@master ~]# vim pod-prestop.yml 
apiVersion: v1
kind: Pod
metadata:
  name: prestop
spec:
  containers:
  - name: test1
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx
      containerPort: 80
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "sleep 60000"]
          # 容器终止前sleep 60000秒
保存退出
[root@master ~]# kubectl apply -f pod-prestop.yml 
pod/prestop created
# 应用yaml文件创建pod
[root@master ~]# kubectl delete pod prestop
pod "prestop" deleted
# 验证,删除需要很久

注意: 当出现特殊情况不能正常销毁pod时,大概等待30秒会强制终止

6.Pod控制器

controller用于控制pod
控制器主要分为:
ReplicationController(相当于ReplicaSet的老版本,现在建议使用
Deployments加ReplicaSet替代RC)
ReplicaSet 副本集,控制pod扩容,裁减
Deployments 控制pod升级,回退
StatefulSets 部署有状态的pod应用
DaemonSet 运行在所有集群节点(包括master), 比如使用
filebeat,node_exporter
Jobs 一次性
Cronjob 周期性

Deployment&ReplicaSet
Replicaset控制器的功能:
支持新的基于集合的selector(以前的rc里没有这种功能)
通过改变Pod副本数量实现Pod的扩容和缩容

Deployment控制器的功能:
Deployment集成了上线部署、滚动升级、创建副本、回滚等功能
Deployment里包含并使用了ReplicaSet

Deployment用于部署无状态应用

无状态应用的特点:
所有pod无差别
所有pod中容器运行同一个image
所有pod可以运行在集群中任意node上
所有pod无启动顺序先后之分
随意pod数量扩容或缩容
例如简单运行一个静态web程序

创建deployment

[root@master ~]# kubectl create deployment nginx1 --image=nginx:latest --port=80 --replicas=1 
# --replicas=1意为副本数为1
deployment.apps/nginx1 created
# 命令创建deployment
[root@master ~]# kubectl get deployment
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx1   1/1     1            1           4m11s
[root@master ~]# kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE    IP         NODE    NOMINATED NODE   READINESS GATES
nginx1-568c8cbc8c-7hsr4   1/1     Running   0          151m   10.3.1.9   node1   <none>           <none>
# 验证
[root@master ~]# kubectl explain deployment
# 查询资源写法
[root@master ~]# vim nginx2-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx2
  # deployment名
spec:
  replicas: 1
  # 副本集,deployment里使用了replicaset
  selector:
    matchLabels:
      app: nginx
      # 匹配的pod标签,表示deployment和rs控制器控制带有此标签的pod
  template:
  # 代表pod的配置模板
    metadata:
      labels:
        app: nginx
        # pod的标签
    spec:
      containers:
      # 以下为pod里的容器定义
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
保存退出
[root@master ~]# kubectl apply -f nginx2-deployment.yml 
deployment.apps/nginx2 created
# 应用yaml文件创建deployment
[root@master ~]# kubectl get deployment
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx1   1/1     1            1           173m
nginx2   1/1     1            1           2m28s
# 验证
[root@master ~]# kubectl delete deployment nginx2
deployment.apps "nginx2" deleted
# 删除deployment,里面的pod也会被自动删除

访问deployment

[root@master ~]# kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE    IP         NODE    NOMINATED NODE   READINESS GATES
nginx1-568c8cbc8c-7hsr4   1/1     Running   0          175m   10.3.1.9   node1   <none>           <none>
# 查看pod的ip地址
[root@master ~]# curl 10.3.1.9
# 验证
[root@node1 ~]# curl 10.3.1.9
# 任一集群内节点皆可访问,集群外机器不行

删除deployment中的pod

[root@master ~]# kubectl delete pod nginx1-568c8cbc8c-7hsr4
pod "nginx1-568c8cbc8c-7hsr4" deleted
# 删除deployment中的pod
[root@master ~]# kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
nginx1-568c8cbc8c-nm6m7   1/1     Running   0          2m58s
# 可以看到,即使删除还是会重新启动一个新的pod,但是更改了IP,因此IP不是固定的
# 比如把整个集群关闭再启动,pod也会自动启动,但是IP地址还是变化了

既然IP地址不是固定的,所以需要一个固定的访问endpoint给用户,那么这种方式就是service

Pod版本升级

[root@master ~]# kubectl set image -h
# 查看帮助
[root@master ~]# kubectl describe pod nginx1-568c8cbc8c-nm6m7 |grep Image
    Image:          nginx:latest
    Image ID:       docker-pullable://nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31
# 验证nginx版本
[root@master ~]# kubectl set image deployment nginx1 nginx=nginx:1.16 --record 
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx1 image updated
# deployment nginx1代表名为nginx1的deployment
# nginx=nginx:1.16,nginx为容器名
# --record表示会记录,不建议使用此参数,因为将在未来移除,暂时没有替代方案
[root@master ~]# kubectl get deployment nginx1 -o yaml
# 查看容器名
[root@master ~]# kubectl rollout status deployment nginx1
deployment "nginx1" successfully rolled out
[root@master ~]# kubectl exec -it nginx1-78f4ffd896-xbfnh -- nginx -v
nginx version: nginx/1.16.1
# 验证

Pod版本回退

[root@master ~]# kubectl rollout history deployment nginx1  
deployment.apps/nginx1 
REVISION  CHANGE-CAUSE
1         kubectl set image deployment nginx1 nginx1=nginx:1.16 --record=true
2         kubectl set image deployment nginx1 nginx=nginx:1.16 --record=true
# 查看版本历史信息[root@master ~]# kubectl rollout history deployment nginx1 --revision=1
deployment.apps/nginx1 with revision #1
Pod Template:
  Labels:       app=nginx1
        pod-template-hash=568c8cbc8c
  Annotations:  kubernetes.io/change-cause: kubectl set image deployment nginx1 nginx1=nginx:1.16 --record=true
  Containers:
   nginx:
    Image:      nginx:latest
    Port:       80/TCP
    Host Port:  0/TCP
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>
# 定义要回退的版本(还需要执行才是真的回退版本)
[root@master ~]# kubectl rollout undo deployment nginx1 --to-revision=1
deployment.apps/nginx1 rolled back
# 执行回退
[root@master ~]# kubectl exec -it nginx1-568c8cbc8c-d6q2b -- nginx -v            
nginx version: nginx/1.21.5
# 验证

副本扩容

[root@master ~]# kubectl scale -h
# 查看帮助
[root@master ~]# kubectl scale deployment nginx1 --replicas=2
deployment.apps/nginx1 scaled
# 定义nginx1副本数为2
[root@master ~]# kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP          NODE    NOMINATED NODE   READINESS GATES
nginx1-568c8cbc8c-d6q2b   1/1     Running   0          3m22s   10.3.2.16   node2   <none>           <none>
nginx1-568c8cbc8c-fmgct   1/1     Running   0          27s     10.3.1.11   node1   <none>           <none>
# 验证
[root@master ~]# kubectl scale deployment nginx1 --replicas=1
deployment.apps/nginx1 scaled
# 副本裁剪
[root@master ~]# kubectl get pods -o wide                    
NAME                      READY   STATUS    RESTARTS   AGE     IP          NODE    NOMINATED NODE   READINESS GATES
nginx1-568c8cbc8c-d6q2b   1/1     Running   0          4m21s   10.3.2.16   node2   <none>           <none>
# 验证

多副本滚动更新

[root@master ~]# kubectl scale deployment nginx1 --replicas=16
deployment.apps/nginx1 scaled
# 扩容为16个副本
[root@master ~]# kubectl get pods
# 验证
[root@master ~]# kubectl set image deployment nginx1 nginx=nginx1.16 --record
Flag --record has been deprecated, --record will be removed in the future
deployment.apps/nginx1 image updated
# 滚动更新
[root@master ~]# kubectl rollout status deployment nginx1
Waiting for deployment "nginx1" rollout to finish: 8 out of 16 new replicas have been updated...
# 验证

YAML单独创建replicaset

[root@node1 ~]# kubectl explain replicaset
# 查询资源写法
[root@master ~]# vim replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-rs
spec:
# replicaset的spec
  replicas: 2
  # 副本数
  selector:
  # 标签选择器,对应pod的标签
    matchLabels:
      app: nginx
      # 匹配的label
  template:
    metadata:
      name: nginx
      # pod名
      labels:
      # 对应上面定义的标签选择器selector里面的内容
        app: nginx
    spec:
    # pod的spec
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
保存退出                                                                                                                                                        
[root@master ~]# kubectl apply -f replicaset.yml 
replicaset.apps/nginx-rs created
[root@master ~]# kubectl get replicaset
NAME                DESIRED   CURRENT   READY   AGE
nginx-rs            2         2         2       2m11s
nginx1-568c8cbc8c   1         1         1       3h37m
nginx1-774b7d5bd6   1         1         0       14m
nginx1-78f4ffd896   0         0         0       31m
[root@master ~]# kubectl get deployment
NAME     READY   UP-TO-DATE   AVAILABLE   AGE
nginx1   1/1     1            1           3h42m
# 找不到deployment,说明创建replicaset并没有创建deployment
7.Pod控制器进阶

DaemonSet:
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

DaemonSet 的一些典型用法:

在每个节点上运行集群守护进程
在每个节点上运行日志收集守护进程
在每个节点上运行监控守护进程
一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。

[root@node1 ~]# kubectl explain daemonset
# 查询资源写法
[root@master ~]# vim nginx-daemonset.yml              
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
spec:
  selector:
    matchLabels:
      name: nginx-test
  template:
    metadata:
      labels:
        name: nginx-test
    spec:
      tolerations:
      # 代表容忍
      - key: node-role.kubernetes.io/master
      # 能容忍的污点key
        effect: NoSchedule
        # 能容忍的污点effect
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
保存退出
[root@master ~]# kubectl apply -f nginx-daemonset.yml 
daemonset.apps/nginx-daemonset created
# 应用yaml文件创建daemonset
[root@master ~]# kubectl get daemonset
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
nginx-daemonset   3         3         3       3            3           <none>          3m16s
[root@master ~]# kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP          NODE               NOMINATED NODE   READINESS GATES
nginx-daemonset-7t5zh   1/1     Running   0          3m59s   10.3.0.2    master.novalocal   <none>           <none>
nginx-daemonset-jhfpd   1/1     Running   0          3m59s   10.3.2.33   node2              <none>           <none>
nginx-daemonset-kwj8h   1/1     Running   0          3m59s   10.3.1.27   node1              <none>           <none>
# 验证
[root@master ~]# kubectl delete daemonset nginx-daemonset
daemonset.apps "nginx-daemonset" deleted
# 删除daemonset

Job
Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。

一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。

你也可以使用 Job 以并行的方式运行多个 Pod。

[root@node1 ~]# kubectl explain job
# 查询资源写法
[root@master ~]# vim job.yml 
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
  # job名
spec:
  template:
    metadata:
      name: pi
      # pod名
    spec:
      containers:
      - name: pi
      # 容器名
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
        imagePullPolicy: IfNotPresent
      restartPolicy: Never
      # 执行完后不重启
# 计算圆周率2000位的小案例
[root@master ~]# kubectl get jobs
NAME          COMPLETIONS   DURATION   AGE
pi            1/1           2m21s      9m20s
[root@master ~]# kubectl logs pi-pznvw
3.14159265358979323...
# 验证
[root@master ~]# vim job2.yml
apiVersion: batch/v1
kind: Job
metadata:
  name: busybox-job
spec:
  completions: 10
  # 执行job的次数
  parallelism: 1
  # 执行job的并发数
  template:
    metadata:
      name: busybox-job-pod
    spec:
      containers:
      - name: busybox
        image: busybox
        imagePullPolicy: IfNotPresent
        command: ["echo", "test"]
      restartPolicy: Never
保存退出          
# 创建固定次数job小案例
[root@master ~]# kubectl apply -f job2.yml 
job.batch/busybox-job created 
# 应用yaml文件创建job 
[root@master ~]# kubectl get job
NAME          COMPLETIONS   DURATION   AGE
busybox-job   3/10          34s        34s
# 验证

CronJob
CronJob 创建基于时隔重复调度的 Jobs。

一个 CronJob 对象就像 crontab (cron table) 文件中的一行。 它用 Cron 格式进行编写, 并周期性地在给定的调度时间执行 Job。

[root@node1 ~]# kubectl explain cronjob
# 查询资源写法
[root@master ~]# vim cronjob.yml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *"
  # 同linux定时任务写法一致
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
            imagePullPolicy: IfNotPresent
          restartPolicy: OnFailure
保存退出
[root@master ~]# kubectl apply -f cronjob.yml 
cronjob.batch/hello created
# 应用yaml文件创建cronjob
[root@master ~]# kubectl get pods
NAME                   READY   STATUS      RESTARTS   AGE
hello-27514895-plsfx   0/1     Completed   0          98s
hello-27514896-rhxwf   0/1     Completed   0          38s
# 验证,每分钟整点执行一次

8.Service

将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Kubernetes,你无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡。

Service作用:
通过service为pod客户端提供访问pod方法,即可客户端访问pod入口
通过标签动态感知pod IP地址变化等
防止pod失联
定义访问pod访问策略
通过label-selector相关联
通过Service实现Pod的负载均衡(TCP/UDP 4层)
底层实现主要通过iptables和IPVS二种网络模式

Service底层实现原理:
底层流量转发与负载均衡实现均可以通过iptables或ipvs实现

对比:

  1. Iptables:
    灵活,功能强大(可以在数据包不同阶段对包进行操作)
    规则遍历匹配和更新,呈线性时延
  2. IPVS:
    工作在内核态,有更好的性能
    调度算法丰富:rr,wrr,lc,wlc,ip hash

Service类型
Service类型分为:

  1. ClusterIP
    默认,分配一个集群内部可以访问的虚拟IP
  2. NodePort
    在每个Node上分配一个端口作为外部访问入口
  3. LoadBalancer
    工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack
  4. ExternalName
    表示把集群外部的服务引入到集群内部中来,即实现了集群内部pod和集群外部的服务进行通信

ClusterIP类型
ClusterIP根据是否生成ClusterIP又可分为普通Service和Headless Service
两类:

  1. 普通Service:
    为Kubernetes的Service分配一个集群内部可访问的固定虚拟
    IP(Cluster IP), 实现集群内的访问。
  2. Headless Service:
    该服务不会分配Cluster IP, 也不通过kube-proxy做反向代理和负载均
    衡。而是通过DNS提供稳定的网络ID来访问,DNS会将headless
    service的后端直接解析为podIP列表。

CluserIP

[root@master ~]# kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.2.0.1     <none>        443/TCP   11h
# 默认只有kubernetes本身自己的services
[root@master ~]# kubectl expose deployment nginx1 --port=80 --target-port=80 --protocol=TCP
service/nginx1 exposed
# 命令创建,nginx1的deployment映射端口
# 默认是--type=ClusterIP,也可以使用--type="NodePort"
[root@master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.2.0.1      <none>        443/TCP   11h
nginx1       ClusterIP   10.2.141.14   <none>        80/TCP    78s
[root@master ~]# kubectl get endpoints
NAME         ENDPOINTS             AGE
kubernetes   172.20.251.148:6443   11h
nginx1       10.3.1.32:80          99s
[root@master ~]# curl 10.2.141.14
# 验证
# 集群内部任一节点皆可访问,集群外机器无法访问
[root@node1 ~]# kubectl explain service
# 查询资源写法
[root@master ~]# vim nginx_service.yml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  clusterIP: 10.2.1.2
  # 这个IP可以不知道,让它自动分配,需要与集群分配的网络对应
  type: ClusterIP
  # ClusterIP类型,也可以不指定,默认为ClusterIP
  ports:
  # 指定service,端口及容器端口
  - port: 80
    # service ip中的端口
    protocol: TCP
    targetPort: 80
    # pod中的端口
  selector:
  # 指定后端pod标签(不是deployment的标签)
    app: nginx
    # 可使用命令kubectl get pod -l app=nginx查询
保存退出
[root@master ~]# kubectl apply -f nginx_service.yml 
service/my-service created
# 应用yaml文件创建service
[root@master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.2.0.1      <none>        443/TCP   11h
my-service   ClusterIP   10.2.1.2      <none>        80/TCP    2m37s
nginx1       ClusterIP   10.2.141.14   <none>        80/TCP    16m
[root@master ~]# kubectl get pod -l app=nginx           
NAME                      READY   STATUS    RESTARTS   AGE
nginx2-66857ff745-d8hfg   1/1     Running   0          57s
nginx2-66857ff745-vbbk4   1/1     Running   0          57s
[root@master ~]# curl 10.2.1.2
...
# 验证
[root@master ~]# kubectl exec -it nginx2-66857ff745-d8hfg -- /bin/bash
root@nginx2-66857ff745-d8hfg:/# echo web1> /usr/share/nginx/html/index.html
root@nginx2-66857ff745-d8hfg:/# exit
exit
[root@master ~]# kubectl exec -it nginx2-66857ff745-d8hfg -- /bin/bash
root@nginx2-66857ff745-d8hfg:/# echo web2> /usr/share/nginx/html/index.html 
root@nginx2-66857ff745-d8hfg:/# exit
exit
# 两个pod做成不同主页测试负载均衡
[root@master ~]# curl 10.2.1.2
web2
# 多次访问测试负载均衡,但是算法紊乱

sessionAffinity

[root@master ~]# kubectl patch svc my-service -p '{"spec": {"sessionAffinity":"ClientIP"}}'
service/my-service patched
# 设置sessionAffinity为Clientip (类似nginx的ip_hash算法,lvs的source hash算法)
[root@master ~]# curl 10.2.1.2
web1
# 多次访问,会话粘贴
[root@master ~]# kubectl patch svc my-service -p '{"spec": {"sessionAffinity":"None"}}'
service/my-service patched
# 设置回sessionAffinity为None
[root@master ~]# curl 10.2.1.2
web2
# 测试多次访问,负载均衡

修改为ipvs调度方式

[root@master ~]# kubectl edit configmap kube-proxy -n kube-system
     36       scheduler: "rr"
     # 修改ipvs算法为rr
     44     mode: "ipvs"
     # 默认为空,加上ipvs
保存退出
# 修改kube-proxy的配置文件
[root@master ~]# kubectl get pods -n kube-system |grep kube-proxy
kube-proxy-h8hqn                           1/1     Running   0             11h
kube-proxy-n9dc9                           1/1     Running   0             12h
kube-proxy-t66mh                           1/1     Running   0             11h
# 查看kube-system的namespace中kube-proxy有关的pod
[root@master ~]# kubectl logs kube-proxy-h8hqn -n kube-system|grep "proxy mode"
I0425 02:37:45.742994       1 server_others.go:561] "Unknown proxy mode, assuming iptables proxy" proxyMode=""
# 验证,还未修改过来
[root@master ~]# kubectl delete pods -n kube-system kube-proxy-h8hqn 
pod "kube-proxy-h8hqn" deleted
[root@master ~]# kubectl delete pods -n kube-system kube-proxy-n9dc9
pod "kube-proxy-n9dc9" deleted
[root@master ~]# kubectl delete pods -n kube-system kube-proxy-t66mh
pod "kube-proxy-t66mh" deleted
# 删除kube-proxy-xxx的所有pod,让它重新拉取新的kube-proxy-xxx的pod
[root@master ~]# kubectl logs kube-proxy-ssnhb -n kube-system|grep ipvs
I0425 14:25:59.868775       1 server_others.go:269] "Using ipvs Proxier"
I0425 14:25:59.868807       1 server_others.go:271] "Creating dualStackProxier for ipvs"
# 验证,已经修改为ipvs
[root@master ~]# dnf -y install ipvsadm
# 安装ipvsadm查看规则
[root@master ~]# ipvsadm -Ln
TCP  10.2.1.2:80 rr
  -> 10.3.1.33:80                 Masq    1      0          0         
  -> 10.3.2.45:80                 Masq    1      0          0  
[root@master ~]# curl 10.2.1.2
web1
# 多次访问验证rr算法

headless service
有时不需要或不想要负载均衡,以及单独的 Service IP。 遇到这种情况,可以通过指定 Cluster IP(spec.clusterIP)的值为 “None” 来创建 Headless Service。

你可以使用无头 Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。

对这无头 Service 并不会分配 Cluster IP,kube-proxy 不会处理它们, 而且平台也不会为它们进行负载均衡和路由。 DNS 如何实现自动配置,依赖于 Service 是否定义了选择算符。
普通的ClusterIP service是service name解析为cluster ip,然后cluster ip对
应到后面的pod ip
而无头service是指service name 直接解析为后面的pod ip

[root@master ~]# vim headless-service.yml
apiVersion: v1
kind: Service
metadata:
  name: headless-service
spec:
  clusterIP: None
  # None代表无头服务
  type: ClusterIP
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
  # 指定后端pod标签
    app: nginx
保存退出
[root@master ~]# kubectl apply -f headless-service.yml 
service/headless-service created
# 应用yaml文件创建service
[root@master ~]# kubectl get svc
NAME               TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
headless-service   ClusterIP   None         <none>        80/TCP    26s
kubernetes         ClusterIP   10.2.0.1     <none>        443/TCP   21h
# 验证
[root@master ~]# kubectl get svc -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.2.0.10    <none>        53/UDP,53/TCP,9153/TCP   21h
# 查看kube-dns服务的IP
# 看到coreDNS的服务地址是10.2.0.10
[root@master ~]# kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE   IP          NODE    NOMINATED NODE   READINESS GATES
nginx1-568c8cbc8c-hgprl   1/1     Running   0          10h   10.3.1.32   node1   <none>           <none>
nginx2-66857ff745-d8hfg   1/1     Running   0          9h    10.3.1.33   node1   <none>           <none>
nginx2-66857ff745-vbbk4   1/1     Running   0          9h    10.3.2.45   node2   <none>           <none>
# 查询

NodePort类型
如果你将 type 字段设置为 NodePort,则 Kubernetes 控制平面将在 --service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)。 每个节点将那个端口(每个节点上的相同端口号)代理到你的服务中。 你的服务在其 .spec.ports[*].nodePort 字段中要求分配的端口。

如果你想指定特定的 IP 代理端口,则可以设置 kube-proxy 中的 --nodeport-addresses 参数 或者将kube-proxy 配置文件 中的等效 nodePortAddresses 字段设置为特定的 IP 块。 该标志采用逗号分隔的 IP 块列表(例如,10.0.0.0/8、192.0.2.0/25)来指定 kube-proxy 应该认为是此节点本地的 IP 地址范围。

[root@master ~]# kubectl edit service my-service
     31   type: NodePort
保存退出
# 修改类型为NodePort
[root@master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.2.0.1     <none>        443/TCP        21h
my-service   NodePort    10.2.1.2     <none>        80:31483/TCP   102s
[root@master ~]# curl 172.20.251.148:31483
web1
# 验证

LoadBalancer
在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 “LoadBalancer”, 将为 Service 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去。
例:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
      - ip: 192.0.2.127

ExternalName 类型
类型为 ExternalName 的服务将服务映射到 DNS 名称,而不是典型的选择器,例如 my-service 或者 cassandra。 你可以使用 spec.externalName 参数指定这些服务。
例:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值