栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

04-kubernetes核心概念

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

04-kubernetes核心概念

这里写目录标题
  • 第11章 Kubernetes核心概念
    • 11.1 Kubernetes 对象
      • 逻辑层次
    • 11.2 集群资源管理
      • 11.2.0 Node
      • 11.2.1 Namespace
        • 11.2.1.1 案例:Namespace操作
      • 11.2.2 Label
        • 11.2.2.1 案例一: 设置容器 Label
        • 11.2.2.2 案例二: 设置Node Label
    • 11.3 容器控制器 Pod
      • 11.3.1 Pod (容器控制器)
        • 11.3.1.1 案例一:创建Nginx Pod
      • 11.3.2 ReplicationController与ReplicaSet (容器控制器)
        • 11.3.2.1 案例一: 创建ReplicationController
      • 11.3.4 调整RC Pod 数量
        • 11.3.2.2 案例二: 创建ReplicaSet
      • 11.3.3 Deployment
      • 11.3.3 Pod 升级策略与检测机制
        • 11.3.3.1 升级策略:
        • 11.3.3.2 pod 启动与存活机制
        • 11.3.3.3 案例一: 创建Deployment
          • 扩容
      • 11.3.4 DaemonSet(容器控制器)
        • 11.3.4.1 案例一: 创建DaemonSet
      • 11.3.5 StatefulSet
        • 11.3.5.1 案例一:StatefulSet组建Elasticsearch 集群
      • 11.3.6 POD基本操作
      • 11.3.7 POD弹性伸缩
      • 11.3.8 POD的管理方式
      • 11.3.9 pod 状态信息
        • 11.3.9.1 查看pod 运行状态
        • 1.3.9.2 POD重启策略
          • 1.3.9.2.1 配置pod重启策略
    • 11.4 镜像策略
      • 11.4.1 案例一: 配置镜像拉取策略
    • 11.5 定时任务
      • 11.5.1 Job
        • 11.5.1.1 案例一: Job
      • 11.5.2 CronJob
        • 11.5.2.1 案例一: 创建定时任务#定时清理数据
    • 11.6 服务发现
      • 11.6.1 Service
        • 11.6.1.1 案例一: 定义服务的Service
      • 11.6.2 Service 网络代理模式
        • 11.6.2.1 案例一: Node启用IPVS
        • 11.6.2.2案例二: 通过IPVS 访问服务
      • 11.6.3 Service服务类型
      • 11.6.4 Service 端口类型
        • 11.6.5 访问Service方式
    • 11.7 DNS
      • 11.7.1 案例一: 通过Service名称访问服务
    • 11.8 存储- Secret
      • 11.8.1 案例一: 导入Docker Registry认证信息
    • 11.9 基于角色的访问控制- RBAC
      • 11.9.1 RABC 可操作资源列表
      • 11.9.2 资源列表可操作的权限列表
      • 11.9.3 RBAC中的其他对象
        • 11.9.3.1 授权角色绑定图解
      • 11.9.4 案例一:创建登录Dashboard的用户
      • 11.9.5 案例二:创建一个不受限制的SA账号, 用于集群内部的认证
      • 11.9.6 案例三: RBAC之Yaml授权文件讲解
      • 11.9.7 案例四: 实际操作授权命令操作
    • 11.10 Yaml 文件详解
      • 11.10.0 Yaml 是什么?
      • 11.10.1 YAML语法规则
      • 11.10.2 Yaml结构类型图解
      • 11.10.3 Kubernetes
      • 11.10.4 案例一: Kubernetes pod编排文件讲解
      • 11.10.5 案例二: Kubernetes deployment运行
      • 11.10.6 案例三: Kubernetes Services 运行
    • 11.11 ConfigMap
      • 11.11.1 案例一: 将ConfigMap中的所有键值对配置为容器环境变量
      • 11.11.2 案例二: 将 ConfigMap 数据添加到容器中的特定路径
      • 11.11.3 案例三: 将ConfigMap中的所有键值对配置为容器环境变量

第11章 Kubernetes核心概念

在上章完成基本的部署之后,但是对Kubernetes的组件还不能完全理解, 尤其是各个组件的有哪些特征,用到什么位置, 都不是很明确。所以本章节会详细讲解各个组件的核心概念。

11.1 Kubernetes 对象
  • 服务网络访问: Ingress、Services
  • 容器管理类型: Deployment、ReplicaSet、 ReplicationController、DaemonSet、StatefulSet
  • 容器存储类型: Volume、Secret、ConfigMap、PersistentVolume

逻辑层次

11.2 集群资源管理 11.2.0 Node

Node是kubernetes集群的工作节点,可以是物理机也可以是虚拟机。

11.2.1 Namespace

节省资源的一种逻辑隔离技术。

Namespace类似于Linux系统中用户的概念,通过将系统内部的对象分配到不同的Namespace 中,形成逻辑上的区分,便于不同的分组在共享集群资源的同时还能被分别管理。

同一Namespace下的 Kubernetes 对象的Name必须唯一。

命名空间为名称提供了一个范围。 资源的名称需要在命名空间内是唯一的,但不能跨命名空间。命名空间不能嵌套在另外一个命名空间内,而且每个 Kubernetes 资源只能属于一个命名空间。

默认情况下,Kubernetes 集群会在配置集群时实例化一个默认命名空间default,用以存放集群所使用的默认 Pods、Services 和 Deployments 集合。

注意: 不需要使用多个命名空间来分隔轻微的且不同的资源,比如同一项目的不同发行版本。

11.2.1.1 案例:Namespace操作

创建NS

[root@master-1 ~]# kubectl create namespace ns-system	

通过Yaml 文件创建 test-ns.yaml

[root@master-1 test]# cat test-ns.yaml 
apiVersion: v1
kind: Namespace 
metadata:
  name: test-ns

查看NS列表

[root@master-1 ns]# kubectl apply -f test-ns.yaml 
namespace/test-ns created

[root@master-1 ns]# kubectl get namespace
NAME                   STATUS   AGE
default                Active   4d2h
kube-node-lease        Active   4d2h
kube-public            Active   4d2h
kube-system            Active   4d2h
kubernetes-dashboard   Active   3d21h
monitoring             Active   3d6h
test-ns                Active   7s

查看ns详细信息

[root@master-1 ns]# kubectl describe namespace/test-ns
Name:         test-ns
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"test-ns"}}
Status:       Active

No resource quota.

No resource limits.

NS与Service(10.0.0.0/8)关系

  • 创建 Service 时,它会创建相应的 DNS记录。
  • 此记录的格式为..svc.cluster.local,这意味着如果容器只使用 ,它将解析为本地服务到命名空间(default)。
  • 如果要跨命名空间访问, 则需要使用完全限定的域名(FQDN)。
#dns 解析的名称是 svc (service 名称, 非 pod 名称) 
dnstools# nslookup nginx
Server:	10.0.0.2
Address: 10.0.0.2#53

Name:nginx.default.svc.cluster.local
Address: 10.0.0.55

非默认的default, 需要写全名 nginx-n1.kube-system

dnstools# nslookup nginx-n1 Server:	10.0.0.2
Address:	10.0 0.2#53
** server can't find nginx-n1: NXDOMAIN

dnstools# nslookup nginx-n1 Server:	10.0.0.2
Address:	10.0 0.2#53

#解决方法(默认解析为 default 空间)
dnstools# nslookup nginx-n1.kube-system.svc.cluster.local
Server:	10.0.0.2
Address:	10.0 0.2#53

Name:	nginx-n1.kube-system.svc.cluster.local 
Address: 10.0.0.196
11.2.2 Label

Label 机制是Kubernetes 中的一个重要设计,通过Label 进行对象(pod,service,node)的关联,可以灵活地进行分类和选择。

对于Pod而言,需要设置其自身的Label 来进行标识,

Label 是一系列的 Key/value 对,在Pod–>metadata–>labels 中进行设置。Label 的定义是任一的,但是Label 必须具有可标识性,比如设置Pod 的应用名称和版本号等。另外Lable 是不具有唯一性的,为了更准确的标识一个Pod,应该为Pod设置多个维度的label。如下:

  • "release" : "stable", "release" : "canary"
  • "environment" : "dev", "environment" : "uat", "environment" : "production"
  • "partition" : "customerA", "partition" : "customerB"
11.2.2.1 案例一: 设置容器 Label

在 Job、Deployment、ReplicaSet 和DaemonSet 中,通常在容器中使用 metadata.labels字段,来为对象添加 Label, 例如:

配置标签

[root@master-1 ingress]# cat traefik-deploy.yaml 
apiVersion: apps/v1
kind: DaemonSet 
metadata:
  name: traefik-ingress-controller
  labels:
    app: traefik

查看标签

[root@master-1 ingress]# kubectl describe pod traefik-ingress-controller
Name:   traefik-ingress-controller-4cn9t
Namespace:  default
Priority: 0
Node:   192.168.91.21/192.168.91.21
Start Time: Sat, 18 Apr 2020 16:02:08 +0800
Labels: app=traefik
        controller-revision-hash=846985d876
        pod-template-generation=4

界面查看

11.2.2.2 案例二: 设置Node Label

设置Node的label标签为IngressProxy=true

[root@master-1 ingress]# kubectl label nodes 192.168.31.7 IngressProxy=true

检查是否成功

[root@master-1 ~]# kubectl get nodes --show-labels
NAME           STATUS   ROLES    AGE    VERSION   LABELS
192.168.31.7   Ready       4d1h   v1.15.1   IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.7,kubernetes.io/os=linux
192.168.31.8   Ready       4d1h   v1.15.1   IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.8,kubernetes.io/os=linux


[root@master-1 ~]#  kubectl get nodes -l IngressProxy=true
NAME           STATUS   ROLES    AGE    VERSION
192.168.31.7   Ready       4d1h   v1.15.1
192.168.31.8   Ready       4d1h   v1.15.1
[root@master-1 ~]# kubectl label nodes 192.168.31.7 isNode=true
node/192.168.31.7 labeled

[root@master-1 ~]# kubectl get nodes --show-labels
NAME           STATUS   ROLES    AGE    VERSION   LABELS
192.168.31.7   Ready       4d1h   v1.15.1   IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,isNode=true,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.7,kubernetes.io/os=linux
192.168.31.8   Ready       4d1h   v1.15.1   IngressProxy=true,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=192.168.31.8,kubernetes.io/os=linux

[root@master-1 ~]#  kubectl get nodes -l  isNode=true
NAME           STATUS   ROLES    AGE    VERSION
192.168.31.7   Ready       4d1h   v1.15.1
11.3 容器控制器 Pod 11.3.1 Pod (容器控制器)

Pod 是Kubernetes的基本操作的最小单元,也是应用运行的载体。

整个Kubernetes系统都是围绕着Pod 展开的; 比如:如何部署运行Pod、如何保证Pod的数量、如何访问Pod 等。

可以将 Pod 看作单个容器的包装,并且 Kubernetes 直接管理 Pod,而不是容器。

11.3.1.1 案例一:创建Nginx Pod

当kubectl delete操作无效时可以尝试下面几个步骤来排查原因:

  • 检查是否创建了deployments任务:kubectl get deployments
  • 检查是否创建了副本控制器 ReplicationController:kubectl get rc
  • 检查死否创建了副本集 replicasets:kubectl get rs

如果有,先执行kubectl delete deployment|rc|rs $name后在执行kubectl delete pod $pod_name方可真正实现删除目的。

删除之前的nginx pod

[root@master-1 ~]# kubectl delete deployment nginx-demo
[root@master-1 ~]# kubectl delete rs nginx-demo-68749b58dc
[root@master-1 ~]# kubectl delete rc nginx-demo-68749b58dc-xzk5c
[root@master-1 ~]# kubectl delete pods nginx-demo
[root@master-1 ~]# kubectl delete svc nginx-demo-svc
[root@master-1 nginx]# cat nginx.yaml
apiVersion: v1                #pod 接口
kind: Pod                     #控制器名称 pod
metadata:
  name: nginx                 #pod 名称
  labels:
    app: nginx                #pod 标签 app=nginx
spec:
  containers:
    - name: nginx             #容器名称
      image: nginx            #镜像名称
      ports:
        - containerPort: 80   #容器端口
          hostPort: 3000      #node 端口

运行

[root@master-1 nginx]# kubectl apply -f nginx.yaml 
pod/nginx created

查看运行状态

[root@master-1 nginx]# kubectl describe pod nginx 
Name:         nginx
Namespace:    default
Priority:     0
Node:         192.168.31.7/192.168.31.7
Start Time:   Mon, 10 Aug 2020 17:55:55 +0800
Labels:       app=nginx
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"nginx"},"name":"nginx","namespace":"default"},"spec":{"conta...
Status:       Pending
IP:           
Containers:
  nginx:
    Container ID:   
    Image:          nginx
    Image ID:       
    Port:           80/TCP
    Host Port:      3000/TCP
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False
    Restart Count:  0
    Environment:    
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7rdlr (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  default-token-7rdlr:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7rdlr
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                   Message
  ----    ------     ----  ----                   -------
  Normal  Scheduled  10s   default-scheduler      Successfully assigned default/nginx to 192.168.31.7
  Normal  Pulling    9s    kubelet, 192.168.31.7  Pulling image "nginx"
11.3.2 ReplicationController与ReplicaSet (容器控制器)

ReplicationController用来确保容器应用的副本数始终保持在用户定义的副本数(容器数 量),即如果有容器异常退出,会自动创建新的Pod 来替代;而如果异常多出来的容器也会自动回收。

在新版本的 Kubernetes 中建议使用ReplicaSet来取代ReplicationController。ReplicaSet跟ReplicationController没有本质的不同,名称不同,并且ReplicaSet支持集合式(多标签选择)的selector。

11.3.2.1 案例一: 创建ReplicationController
  • 通过template.metadata.labels字段为即将新建的Pod附加Label, 即为app=nginx
  • 通过spec.selector字段来指定这个RC管理哪些Pod
[root@master-1 nginx-rc]# cat nginx-rc.yaml
apiVersion: v1
kind: ReplicationController     #容器控制器 RC 
metadata:
  name: nginx-rc                #RC 名称
spec:
  replicas: 1                   #副本数 1
  selector:
    app: nginx-rc               #控制器选择 app=nginx-rc (label)
  template:
    metadata:
      labels:
        app: nginx-rc                 #模板的 label: app=nginx
    spec:
      containers:
        - name: nginx-rc            #容器名称
          image: nginx              #镜像名称
          ports:
            - containerPort: 80     #容器端口

部署RC

[root@master-1 nginx]# kubectl apply -f nginx-rc.yaml 
replicationcontroller/nginx-rc created

查看状态

[root@master-1 nginx]# kubectl get rc
NAME       DESIRED   CURRENT   READY   AGE
nginx-rc   1         1         1       94s

[root@master-1 nginx]# kubectl describe rc nginx-rc
Name:         nginx-rc
Namespace:    default
Selector:     app=nginx-rc
Labels:       app=nginx-rc
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","kind":"ReplicationController","metadata":{"annotations":{},"name":"nginx-rc","namespace":"default"},"spec":{"replicas"...
Replicas:     1 current / 1 desired
Pods Status:  1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=nginx-rc
  Containers:
   nginx-rc:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  
    Mounts:       
  Volumes:        
Events:
  Type    Reason            Age   From                    Message
  ----    ------            ----  ----                    -------
  Normal  SuccessfulCreate  2m1s  replication-controller  Created pod: nginx-rc-2rf4q

访问测试

[root@master-1 ~]# kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools dnstools# curl 172.17.98.13
11.3.4 调整RC Pod 数量
[root@master-1 nginx]# kubectl get pod
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-6d6f7ff69f-bk95b   1/1     Running   1          3d7h
nginx                                     1/1     Running   0          13m
nginx-rc-2rf4q                            1/1     Running   0          4m8s


[root@master-1 nginx]# kubectl scale rc nginx-rc --replicas=3
replicationcontroller/nginx-rc scaled

[root@master-1 nginx]# kubectl get pod
NAME                                      READY   STATUS              RESTARTS   AGE
nfs-client-provisioner-6d6f7ff69f-bk95b   1/1     Running             1          3d7h
nginx                                     1/1     Running             0          15m
nginx-rc-2rf4q                            1/1     Running             0          5m17s
nginx-rc-dvgqb                            0/1     ContainerCreating   0          27s
nginx-rc-gmddb                            0/1     ContainerCreating   0          27s

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5s7z2vRL-1634538453109)(assets/CA49DA8A169A40A7B3A598161165D374.png)]

pod 不支持扩容(命令扩容)

[root@master-1 nginx]# kubectl scale pod nginx --replicas=2
error: could not find proper group-version for scale subresource of /v1, Resource=pods: could not find scale subresource for /v1, Resource=pods in discovery information

pod 不支持扩容(yaml)

[root@master-1 nginx1]# cat nginx.yaml
apiVersion: v1 
kind: Pod 
metadata:
    name: nginx	        #pod 名称
    labels:	            #label 标签
        app: nginx	    #定义 pod 的 label: app=nginx
spec:
    replicas: 2                     # 容器数量
    containers:
        - name: nginx               #容器名称
        image: nginx                #镜像名称
        ports:
            - containerPort: 80	    #容器端口
            hostPort: 3000	        #node 接口端口

出现错误,接口不支持replicas

[root@master-1 nginx]# kubectl apply -f nginx.yaml 
error: error validating "nginx.yaml": error validating data: ValidationError(Pod.spec): unknown field "replicas" in io.k8s.api.core.v1.PodSpec; if you choose to ignore these errors, turn validation off with --validate=false
11.3.2.2 案例二: 创建ReplicaSet
  • selector除了可以使用matchLabels,还支持集合式的操作。
  • 通过修改.spec.replicas的值可以实时修改RS运行的Pod数量。
  • 镜像下载有问题
apiVersion: apps/v1 
kind: ReplicaSet 
metadata:
    name: frontend 
    labels:
        app: guestbook 
        tier: frontend
spec:
    replicas: 3 
    selector:
        matchLabels: 
            tier: frontend
        matchexpressions:
            - {key: tier, operator: In, values: [frontend]} 
    template:
        metadata: 
            labels: #定义多个 Label 
                app: guestbook 
                tier: frontend
        spec:
            containers:
                - name: php-redis
                image: gcr.io/google_samples/gb-frontend:v3 
                resources:
                    requests: 
                        cpu: 100m
                        memory: 100Mi
                env:
                    -name: GET_HOSTS_FROM 
                    value: dns
                ports:
                    -containerPort: 80

查看是否启动成功

 [root@master-1 ~]# kubectl describe rs/frontend
11.3.3 Deployment

Deployment同样为Kubernetes的一个核心内容,主要职责同样是为了保证pod的数量和健康,90% 的功能与Replication Controller完全一样,可以看做新一代的Replication Controller。但是,它又具备了Replication Controller之外的新特性:

  1. Deployment继承了上面描述的Replication Controller(副本数保持与扩容)全部功能。
  2. 容器在升级或者创建的过程中,可以查看详细进度和状态。
  3. 当升级pod镜像或者相关参数的过程中,如果出现问题,可以使用回滚操作回滚到上一个版本或者指定的版本。
  4. 每一次对Deployment的操作,都能保存下来(有操作记录),便于之后的回滚.
  5. 每一次pod升级,都能够随时暂停和启动(容易控制)。
  6. pod多种升级方案:
    • Recreate:删除所有已存在的pod,重新创建新的;
    • RollingUpdate:滚动升级,逐步替换的策略,同时滚动升级时,支持更多的附加参数,例如设置最大不可用pod数量,最小升级间隔时间等等。

容器控制器创建pod流程

  1. 使用Deployment来创建ReplicaSet, ReplicaSet则在在后台创建pod; 检查pod启动状态,是否成功。
  2. 通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。之后会创建一个新的ReplicaSet,
    Deployment会按照默认的更新策略(RollingUpdate 所需副本数的25%, 生产建议配置为:1) 先启动新的ReplicaSet.
  3. 如果新的ReplicaSet启动失败(检查端口策略), 则旧的ReplicaSet还会继续存在。
  4. 如果扩容成功, 则会清理掉旧的ReplicaSet

系统查看Deployment

[root@master-1 ~]# kubectl get deployment
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           3d9h
redis-tcp                1/1     1            1           96s

查看Deployment详细信息

[root@master-1 ~]# kubectl describe pod redis-tcp
Name:           redis-tcp-5fcb54cd64-52p4d
Namespace:      default
Priority:       0
Node:           192.168.31.7/192.168.31.7
Start Time:     Mon, 10 Aug 2020 19:54:01 +0800
Labels:         app=redis-tcp
                pod-template-hash=5fcb54cd64
Annotations:    
Status:         Running
IP:             172.17.14.13
Controlled By:  ReplicaSet/redis-tcp-5fcb54cd64
Containers:
  redis-tcp:
    Container ID:   docker://bafe30e1911b6a4ae80aca46cbd240d693e7ab7bf2ffb3e9c3a38f582712aacc
    Image:          redis
    Image ID:       docker-pullable://redis@sha256:09c33840ec47815dc0351f1eca3befe741d7105b3e95bc8fdb9a7e4985b9e1e5
    Port:           6379/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 10 Aug 2020 19:55:26 +0800
    Ready:          True
    Restart Count:  0
    Environment:    
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-7rdlr (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-7rdlr:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-7rdlr
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                   Message
  ----    ------     ----  ----                   -------
  Normal  Pulling    118s  kubelet, 192.168.31.7  Pulling image "redis"
  Normal  Scheduled  117s  default-scheduler      Successfully assigned default/redis-tcp-5fcb54cd64-52p4d to 192.168.31.7
  Normal  Pulled     33s   kubelet, 192.168.31.7  Successfully pulled image "redis"
  Normal  Created    33s   kubelet, 192.168.31.7  Created container redis-tcp
  Normal  Started    33s   kubelet, 192.168.31.7  Started container redis-tcp

11.3.3 Pod 升级策略与检测机制 11.3.3.1 升级策略:
strategy:
    type: RollingUpdate	#默认更新策略Deployment
    rollingUpdate:
    maxSurge: 1         # Pod的总数最多比所需的Pod数多1个
    maxUnavailable: 1   # 更新过程中最多1个不可用Pod数
11.3.3.2 pod 启动与存活机制

pod 就绪探测 (Deployment控制器)

readinessProbe: #来确定容器是否已经启动正常
    tcpSocket:
        port: 8080	            #检查端口
    initialDelaySeconds: 5      # kubelet 会在容器启动 5 秒后发送第一个就绪探测
    periodSeconds: 10           #每 10 秒执行一次存活探测

如果探测成功,这个 Pod 会被标记为就绪状态,kubelet 将继续每隔 10 秒运行一次检测。

pod 存活探测 (Deployment控制器)

livenessProbe: #存活探测 
    tcpSocket:
        port: 8080 
    initialDelaySeconds: 15     #kubelet 会在容器启动 15 秒后进行第一次存活探测 
    periodSeconds: 20           #每10秒执行一次存活探测

与就绪探测一样,Kubelet会尝试连接容器的 8080 端口。如果存活探测失败,这个容器会被重新启动。

11.3.3.3 案例一: 创建Deployment
[root@master-1 demo]# cat nginx-deployment.yaml 
apiVersion: apps/v1	    #控制器接口版本
kind: Deployment	    #控制器类型
metadata:
  name: nginx-deployment    # Deployment 控制器名称
  labels:
    app: nginx-deployment # Deployment 控制器标签
spec:
  replicas: 3	              # Deployment 副本数(容器数量) 
  selector:
    matchLabels:
      app: nginx-deployment               #标签选择器
  minReadySeconds: 1                      #pod 准备时间
  strategy:
    type: RollingUpdate                   #pod 升级策略
    rollingUpdate:
      maxSurge: 1                         #最大允许 1 个pod 升级
      maxUnavailable: 1                   #最多允许 1 个pod 失效
  template:
    metadata:
      labels:
        app: nginx-deployment             #模板标签
    spec:
      containers:
        - name: nginx-deployment              #容器名称
          image: nginx:latest                 #镜像名称
          ports:
            - containerPort: 80               #容器端口
          readinessProbe:                 #容器就绪检测
            tcpSocket:
              port: 80                    #检测端口
            initialDelaySeconds: 5      #容器启动之后 5 秒检测
            periodSeconds: 10           #容器初始化之后每隔 10 秒检测

部署

[root@master-1 deployment]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created

界面查看更新策略

查看状态

[root@master-1 deployment]# kubectl get pods -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-6d6f7ff69f-bk95b   1/1     Running   2          3d9h
nginx                                     1/1     Running   1          140m
nginx-deployment-8568b96ddb-f4fnc         1/1     Running   0          2m8s
nginx-deployment-8568b96ddb-ljq9k         1/1     Running   0          2m8s
nginx-deployment-8568b96ddb-qfgx7         1/1     Running   0          2m8s
nginx-rc-2rf4q                            1/1     Running   1          130m
nginx-rc-dvgqb                            1/1     Running   1          125m
nginx-rc-gmddb                            1/1     Running   1          125m
redis-tcp-5fcb54cd64-52p4d                1/1     Running   0          22m
[root@master-1 deployment]# kubectl describe deployment.apps/nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Mon, 10 Aug 2020 20:13:54 +0800
Labels:                 app=nginx-deployment
Annotations:            deployment.kubernetes.io/revision: 1
                        kubectl.kubernetes.io/last-applied-configuration:
                          {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"nginx-deployment"},"name":"nginx-deployment","na...
Selector:               app=nginx-deployment
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        1
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  app=nginx-deployment
  Containers:
   nginx-deployment:
    Image:        nginx:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Readiness:    tcp-socket :80 delay=5s timeout=1s period=10s #success=1 #failure=3
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  
NewReplicaSet:   nginx-deployment-8568b96ddb (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  2m38s  deployment-controller  Scaled up replica set nginx-deployment-8568b96ddb to 3
扩容

scale 支持容器控制器类型Deployment, ReplicaSet, Replication Controller, Job

[root@master-1 deployment]# kubectl scale deployment nginx-deployment --replicas 10
deployment.extensions/nginx-deployment scaled

查看Deployments

查看RS控制器

pod 正在扩容创建

  1. 修改配置文件, 检测更新策略
  2. 把镜像修改为不存在的镜像
  3. image: nginx111111:latest
[root@master-1 ~]# kubectl	apply -f nginx-deployment.yaml

会创建一个新的RS

新的RS关联的pod出错

根据更新的策略,还会存在2个旧的pod,因为应用了新的配置文件,所以原来的10个pod, 只会留下3个,其中1个正在更新,所以只能看到两个pod是正常的.

查看更新的过程

[root@master-1 deployment]# kubectl describe deployment nginx-deployment
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Mon, 10 Aug 2020 20:13:54 +0800
Labels:                 app=nginx-deployment
Annotations:            deployment.kubernetes.io/revision: 2
                        kubectl.kubernetes.io/last-applied-configuration:
                          {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"nginx-deployment"},"name":"nginx-deployment","na...
Selector:               app=nginx-deployment
Replicas:               3 desired | 2 updated | 4 total | 2 available | 2 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        1
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  app=nginx-deployment
  Containers:
   nginx-deployment:
    Image:        nginx1111:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Readiness:    tcp-socket :80 delay=5s timeout=1s period=10s #success=1 #failure=3
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    ReplicaSetUpdated
OldReplicaSets:  nginx-deployment-8568b96ddb (2/2 replicas created)
NewReplicaSet:   nginx-deployment-84c85b9846 (2/2 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  2m52s  deployment-controller  Scaled down replica set nginx-deployment-8568b96ddb to 3
  Normal  ScalingReplicaSet  2m52s  deployment-controller  Scaled up replica set nginx-deployment-84c85b9846 to 1
  Normal  ScalingReplicaSet  2m52s  deployment-controller  Scaled down replica set nginx-deployment-8568b96ddb to 2
  Normal  ScalingReplicaSet  2m52s  deployment-controller  Scaled up replica set nginx-deployment-84c85b9846 to 2

删除nginx

[root@master-1 ~]# kubectl delete deployment.apps/nginx-deployment 

[root@master-1 deployment]# kubectl delete -f nginx-deployment.yaml 
deployment.apps "nginx-deployment" deleted
11.3.4 DaemonSet(容器控制器)

一个DaemonSet 对象能确保其创建的 Pod 在集群中的每一台(或指定 Label)Node 上都运行一个副本。

  • 如果集群中动态加入了新的 Node,DaemonSet 中的 Pod 也会被添加在新加入 Node 上运行。
  • 删除一个 DaemonSet 也会级联删除所有其创建的Pod。

使用场景:

  1. 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
  2. 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。

  1. 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter

11.3.4.1 案例一: 创建DaemonSet
apiVersion: extensions/v1beta1 
kind: DaemonSet
metadata:
  name: log-pilot 
  namespace: kube-system 
  labels:
    k8s-app: log-pilot 
    kubernetes.io/cluster-service: "true"
spec:
  template: 
    metadata:
      labels:
        k8s-app: log-es 
        kubernetes.io/cluster-service: "true" 
        version: v1.22

log-pilot

每个节点运行一个pod

11.3.5 StatefulSet

Kubernetes从v1.4版本开始引入了PetSet这个新的资源对象,并且在v1.5版本时更名为StatefulSet,从本质上来讲,可以看作Deployment/RC的一个特殊类型。

  • StatefulSet 适合有状态的服务;
  • StatefulSet有唯一的pod名称标识,支持持久化存储(集群需要存储数据)与滚动更新。

假设StatefulSet运行集群的名字叫elasticsearch,那么第一个Pod叫elasticsearch-0,第二个Pod叫elasticsearch -1,以此类推。正是因为有序的pod 的名称, 才能够组件集群(需要安装DNS)。

11.3.5.1 案例一:StatefulSet组建Elasticsearch 集群
apiVersion: apps/v1beta1 
kind: StatefulSet 
metadata:
  name: elasticsearch 
  namespace: kube-system 
  labels:
    kubernetes.io/cluster-service: "true"
spec:
  replicas: 2
  serviceName: "elasticsearch-service" 
  selector:
    matchLabels: 
      app: es
  template: 
    metadata:
      labels:
        app: es

11.3.6 POD基本操作
  • 创建: kubectl create -f xxx.yaml
  • 查询列表: kubectl get pod(资源类型)
    • 获取pod详细信息:
      • kubectl describe pod nginx
    • 获取pod所在节点与IP:
      • kubectl get pods -o wide
    • 监听pods状态:
      • kubectl get pods -w
    • 列出所有pod :
      • kubectl get pods -A
    • 根据标签获取pod (run=nginx):
      • kubectl get pods -l app=nginx-deployment
    • 进入到pod:
      • kubectl exec nginx-demo-68749b58dc-rr9rj -i -t bash -n default
    • 查看pod内容(非进入) :
      • kubectl exec nginx-deployment-8568b96ddb-psr74 -n default -i -t -- cat /etc/resolv.conf
      • kubectl exec coredns-66db855d4d-26bvw -n kube-system -i -t -- cat /etc/resolv.conf
  • 删除: kubectl delete pod yourPodName
  • 更新: kubectl apply /path/to/yourNewYaml.yaml
  • 日志: kubectl log -f yourPodName (容器日志在控制台显示,才能看到内容)
    • kubectl logs --tail=20 nginx
11.3.7 POD弹性伸缩

注意:POD 所支持弹性伸缩的类型: Deployment, ReplicaSet, ReplicationController

弹性伸缩是指适应负载变化,以弹性可伸缩的方式提供资源。反映到Kubernetes 中,指的是可根据负载的高低动态调整Pod 的副本数量。

调整Pod 的副本数是通过修改RC中Pod 的副本是来实现的,示例命令如下:

#扩容Pod 的副本数目到10
[root@master-1 ~]# kubectl scale replicationcontroller nginx-deployment --replicas=10
11.3.8 POD的管理方式 11.3.9 pod 状态信息
  1. 挂起(Pending):Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
  2. 运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
  3. 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
  4. 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
  5. 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
11.3.9.1 查看pod 运行状态
[root@master-1 job]# kubectl get pod
NAME	                                READY	STATUS	    RESTARTS	AGE
demo-app-57756548d8-sltsg	            1/1	    Running	    1	        3d11h
dnstools	                            1/1	    Running	    0	        122m
nfs-client-provisioner-5978c5f69c-k9lkb	1/1	    Running	    1	        5d
1.3.9.2 POD重启策略

当某个容器异常退出或者健康检查失败, kubelet将根据RestartPolicy的设置来进行相应的操作,重启策略有Always , OnFailure, Never

  1. Always: 当容器失效时, 由kubelet自动重启该容器;
  2. OnFailure: 当容器终止运行且退出码不为0时, 由kubelet自动重启该容器;
  3. Never: 不论容器运行状态如何, kubelet都不会重启该容器;

重启策略使用场景

  • Deployment、RC和DaemonSet:必须设置为Always,需要保证该容器持续运行。
  • Job和CronJob:OnFailure或Never,确保容器执行完成后不再重启。
  • kubelet:在Pod失效时自动重启它,不论将RestartPolicy设置为什么值,也不会对Pod进行健康检查。
1.3.9.2.1 配置pod重启策略
  • RC控制器和DeamonSet控制器建议设置为Always,需要保证该容器持续运行。
  • Job: OnFailure或Never, 确保容器执行完成后不再重启。
[root@linux-master1 ~]# vim nginx-deployment.yaml 
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: nginx-deployment 
  namespace: default 
  labels:
    app: nginx 
spec:
  selector: 
    matchLabels:
      app: nginx 
  replicas: 1 
  template:
    metadata: 
      labels:
        app: nginx 
    spec:
      restartPolicy: Always #容器重启策略
      containers:
        - name: nginx 
          image: nginx:1.12
          imagePullPolicy: IfNotPresent	#镜像拉取策略
          ports:
            - containerPort: 80
11.4 镜像策略

默认的镜像拉取策略是“IfNotPresent”,在镜像已经存在的情况下,kubelet将不在去拉取镜像。

  • 如果总是想要拉取镜像,必须设置拉取策略为“Always”或者设置镜像标签为“:latest”。
  • 如果没有指定镜像的标签,它会被假定为“:latest”,同时拉取策略为“Always”.

在生产环境中, 运行应用的时候(微服务),建议设置为Always

注意在拉取自建私有仓库镜像时, 需要通过创建Secret, 才能拉取镜像。在kubernetes 中有以下三种下载策略:

  • Always:每次都下载最新的镜像。 微服务建议用此项
  • Never:只使用本地镜像,从不下载。 单节点
  • IfNotPresent:只有当本地没有的时候才下载镜像。 开源的第三方的应用建议用此项
11.4.1 案例一: 配置镜像拉取策略
[root@linux-master1  ~]#  vim nginx-deployment.yaml
apiVersion: apps/v1 
kind: Deployment 
metadata:
  name: nginx-deployment 
  namespace: default 
  labels:
    app: nginx-deployment 
spec:
  selector: 
    matchLabels:
      app: nginx-deployment 
    replicas: 1
  template: 
    metadata:
      labels:
        app: nginx-deployment 
    spec:
      restartPolicy: Always 
      containers:
        - name: nginx-deployment
          image: nginx:1.12 
          imagePullPolicy: IfNotPresent 
          ports:
            - containerPort: 80
11.5 定时任务 11.5.1 Job

Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。

使用场景: 清理数据, 同步数据

11.5.1.1 案例一: Job

Job 配置文件,只包含一个 pod,输出圆周率小数点后 2000 位,运行时间大概为 10s

[root@master-1 test]# kubectl create -f job.yaml 
apiVersion: batch/v1
kind: Job
metadata: 
  name: pi
spec:
  template: 
    spec:
      containers:
        - name: pi 
          image: perl
          command: ["perl",	"-Mbignum=bpi", "-wle", "print bpi(2000)"] 
      restartPolicy: Never
  backoffLimit: 4

注意:perl镜像880M左右,需要提前下载到node节点上

[root@node-1 ~]# docker load < perl.tar
461719022993: Loading layer [==================================================>]  119.2MB/119.2MB
f1d420c2af1a: Loading layer [==================================================>]  17.11MB/17.11MB
a3c1026c6bcc: Loading layer [==================================================>]  17.85MB/17.85MB
d35c5bda4793: Loading layer [==================================================>]  149.9MB/149.9MB
46829331b1e4: Loading layer [==================================================>]  520.3MB/520.3MB
28c01f06325c: Loading layer [==================================================>]  3.584kB/3.584kB
416facee2664: Loading layer [==================================================>]  55.49MB/55.49MB
Loaded image ID: sha256:aebad195b013823cf83716d32039e016f7fa4e6acbd5d1eca2e494b42c85d2fa

运行

[root@master-1 job]# kubectl apply -f job.yaml 
job.batch/pi created

查看任务

[root@master-1 job]# kubectl describe jobs/pi
Name:           pi
Namespace:      default
Selector:       controller-uid=73adcf03-0cf7-46cb-b583-ec7a2ce9f8e5
Labels:         controller-uid=73adcf03-0cf7-46cb-b583-ec7a2ce9f8e5
                job-name=pi
Annotations:    kubectl.kubernetes.io/last-applied-configuration:
                  {"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"pi","namespace":"default"},"spec":{"backoffLimit":4,"template":...
Parallelism:    1
Completions:    1
Start Time:     Mon, 10 Aug 2020 23:03:16 +0800
Pods Statuses:  1 Running / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  controller-uid=73adcf03-0cf7-46cb-b583-ec7a2ce9f8e5
           job-name=pi
  Containers:
   pi:
    Image:      perl
    Port:       
    Host Port:  
    Command:
      perl
      -Mbignum=bpi
      -wle
      print bpi(2000)
    Environment:  
    Mounts:       
  Volumes:        
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  14s   job-controller  Created pod: pi-xcv2b

获取job

[root@master-1 test]# pods=$(kubectl get pods 
--selector=job-name=pi --output=jsonpath={.items..metadata.name})

[root@master-1 ~]# echo $pods
pi-xcv2b

获取结果

[root@master-1 job]# kubectl get pods | grep $pods
pi-t596w    0/1     Completed   0   3m29s
[root@master-1 job]# kubectl logs $pods
3.1415926535897932384626433832795028841971693993751058209749445923078164062
862089986280348253421170679821480865132823066470938446095505822317253594081
28481117450284102701938521105559644622948954930381964428810975665933446128

容器的状态为Completed

[root@master-1 ~]# kubectl get pods | grep $pods 
pi-xcv2b                                  0/1     Completed   0          10m

查看结果

[root@master-1 ~]# kubectl log $pods
log is DEPRECATED and will be removed in a future version. Use logs instead.
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901
11.5.2 CronJob

CronJob是用来管理基于时间的Job,即:

  1. 在给定的时间点运行一次Job
  2. 周期性的在给定的时间点运行
  3. Crontab的基本格式
    • <分钟> <小时> <日> <月份> <星期> <命令>
    • 分钟值从 0 到 59.
    • 小时值从 0 到 23.
    • 日值从 1 到 31.
    • 月值从 1 到 12.
    • 星期值从 0 到 6, 0 代表星期日

多个时间可以用逗号隔开,范围可以用连字符给出,*可以作为通配符。空格用来分开字段。

11.5.2.1 案例一: 创建定时任务#定时清理数据

每个一分钟echo “Hello from the Kubernetes cluster”

[root@master-1 test]#cat cronjob.yaml 
apiVersion: batch/v1beta1
kind: CronJob 
metadata:
  name: hello 
spec:
  schedule: "*/1 * * * *" 
  jobTemplate:
    spec:
      template: 
        spec:
          containers:
            - name: hello 
              image: busybox 
              args:
                - /bin/sh
                - -c
                - date; echo Hello from the Kubernetes cluster 
          restartPolicy: onFailure

创建任务

[root@master-1 cronjob]# kubectl apply -f cronjob.yaml 
cronjob.batch/hello created

获取任务列表

[root@master-1 cronjob]# kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     1        34s             46s

获取任务

[root@master-1 cronjob]# kubectl get jobs
NAME               COMPLETIONS   DURATION   AGE
hello-1597072680   0/1           37s        37s
pi                 1/1           2m38s      15m

获取job

[root@master-1 job]# pods=$(kubectl get pods --selector=job-name=hello-1597072680  --output=jsonpath={.items..metadata.name})
[root@master-1 cronjob]# echo $pods   
hello-1597072680-rc7hx

获取结果

[root@master-1 cronjob]# kubectl logs $pods
Mon Aug 10 15:19:27 UTC 2020
Hello from the Kubernetes cluster

通过界面查看任务

定时任务输出的结果

删除Cron Job

[root@master-1 cronjob]# kubectl delete -f cronjob.yaml 
cronjob.batch "hello" deleted
11.6 服务发现 11.6.1 Service

此Service不能直译,在kubernetes中为了更好的定位每一个或者每组POD (Label 标签),才出现了Service的概念。

因为我们知道POD 的IP地址是在每次重启或者是容器重新部署之后是有变化的。而且容器的IP地址是无法固定的,所有需要Service来定位POD。

11.6.1.1 案例一: 定义服务的Service

通过节点的Nodeport 端口访问应用

[root@master-1 java]# cat provider-passport-service.yaml 
apiVersion: v1
kind: Service 
metadata:
  name: passport-svc   #Service 名 称
spec:
  type: NodePort
  ports:
    - port: 8081            #Service 端口类型
      targetPort: 8081      #容器端口
      protocol: TCP         #端口协议
    selector:               #根据 Label 选择
      app: passport
11.6.2 Service 网络代理模式

用户通过Service访问服务的时候, 实际是通过node节点上kube-proxy访问pod 服务,那么Kube-Proxy有以下的工作模式:

  • Iptables(默认模式),
  • IPVS模式,
  • userspace

在 Kubernetes v1.2 中,kube-proxy 的 iptables 模式成为默认设置。 Kubernetes v1.8添加了 ipvs 代理模式。

Iptables模式

  1. Node节点客户端直接访问ServiceIP,Linux根据Iptables协议栈规则策略匹配。
  2. ServiceIP根据标签直接访问Backend Pod。

IPVS 代理模式

IPVS是LVS一个组件,提供高性能、高可靠性的四层负载均衡器。IPVS 是IP Virtual Server的简写。

  • IPVS构建在netfilter上,作为Linux 内核的一部分,从传输层实现了负载均衡。
  • IPVS 能直接转发 基于Services的TCP 和UDP到真实服务器。
  • IPVS能直接构建一个VIPs 并通过负载均衡算法,把请求转发到backend Pod。

IPVS支持的负载均衡算法:

  • rr: 轮询
  • lc: 最小连接数
  • dh: 目的地址hash
  • sh: 源地址hash
  • sed: 最短期望延迟
  • nq: 无须队列等待
11.6.2.1 案例一: Node启用IPVS

注意:

  • 要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前使 IPVS Linux 在节点上可用。
  • 当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。

安装ipvsadm、conntrack

 [root@master-1 java]# yum -y install ipvsadm conntrack-tools

加载ipvs模块

[root@master-1 java]# cat > /etc/sysconfig/modules/ipvs.modules < 

查看内核模块加载

[root@master-1 java]# cat >>/etc/sysctl.conf < 

生效

[root@master-1 ipvs]# sysctl -p
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

修改kube-proxy 配置文件

增加配置

[root@node-1 ~]# cat /etc/kubernetes/cfg/kube-proxy
--masquerade-all=true                       #确保反向流量通过
--feature-gates=SupportIPVSProxyMode=true   #打开支持 ipvs 模式
--proxy-mode=ipvs                           # kube-proxy 最后配置
--ipvs-scheduler=rr                         #明确代理模式为 ipvs

选择调度方式为轮询调度

[root@node-1 ~]# cat /etc/kubernetes/cfg/kube-proxy
KUBE_PROXY_OPTS="--logtostderr=true 
--v=4 --metrics-bind-address=0.0.0.0 
--hostname-override=192.168.91.146 
--masquerade-all=true 
--feature-gates=SupportIPVSProxyMode=true 
--proxy-mode=ipvs 
--ipvs-scheduler=rr 
--cluster-cidr=10.0.0.0/24 
--kubeconfig=/etc/kubernetes/cfg/kube-proxy.kubeconfig"

查看转发列表与IP

[root@node-1 ~]# ipvsadm -L -n | grep 8080
TCP     10.0.0.136:8080 rr
    -> 172.17.25.2:8080         Masq    1   0   0
    -> 172.17.67.9:8080         Masq    1   0   0
TCP     10.0.0.220:8080 rr
    -> 172.17.25.7:8080         Masq    1   0   0

查看 IP

[root@node-1 ~]# ip a | grep 136
    inet 10.0.0.136/32 brd 10.0.0.136 scope global kube-ipvs0
11.6.2.2案例二: 通过IPVS 访问服务

获取节点的pod地址

[root@master-1 ~]# kubectl get pod -A -o wide | grep 146
default demo-app-57756548d8-sltsg 1/1 Running 1 3d9h 172.17.25.7 192.168.91.146  

获取146节点的svc地址

[root@master-1 ~]# kubectl get svc
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP     PORT(S)     AGE
demo-app    ClusterIP   10.0.0.220                8080/TCP    3d9h

访问146节点的SVC

dnstools# curl 10.0.0.220:8080
Hello! My name is demo-app-57756548d8-sltsg. I have served 202 requests so far.

注意: 如果发现有nodeport 类型的端口在被修改完成了ipvs 模式的节点上,需要使用 iptables -F 清空iptables 表, 或者是直接在机器上使用curl访问.

11.6.3 Service服务类型
  1. ClusterIP:通过集群的内部IP暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType。
  2. NodePort:通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到 ClusterIP 服务,这个 ClusterIP 服务会自动创建。通过请求 :,可以从集群的外部访问一个 NodePort 服务。
  3. LoadBalancer:使用云提供商的负载局衡器,可以向外部暴露服务。外部的负载均衡器可以路由到 NodePort 服务和 ClusterIP 服务。
11.6.4 Service 端口类型
  • port: service的的端口
  • targetport: pod也就是容器的端口
  • nodeport: 容器所在宿主机的端口(实质上也是通过service暴露给了宿主机)
11.6.5 访问Service方式

Service 的虚拟IP 是由Kubernetes 虚拟出来的内部网络,外部是无法寻址到的。但是有些 服务又需要被外部访问到,例如web 前端。这时候就需要添加一层网络转发,即外网到内网的转发。

Kubernetes 提供了NodePort、LoadBalancer、Ingress 三种方式访问Service。

访问方式图解:

  1. NodePort, Kubernetes会在每一个Node上暴露出一个端口:NodePort,外部网络可以通过[NodeIP]:[NodePort]访问到后端的Service。
  2. LoadBalancer,在NodePort基础上,Kubernetes可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发。该模式需要底层云平台(例如GCE)支持。
  3. Ingress,是一种HTTP方式的路由转发机制,由Ingress Controller 和HTTP 代理服务器组合而成。Ingress Controller 实时监控Kubernetes API,实时更新HTTP 代理服务器的转发规则。HTTP 代理服务器有GCE Load-Balancer、HaProxy、Nginx 等开源方案。
    • 本质上是反向代理。
11.7 DNS

DNS 服务器监视着创建新 Service 的 Kubernetes API,从而为每一个 Service 创建一组DNS记录。 如果整个集群的 DNS 一直被启用,那么所有的Pod 应该能够自对Service 进行名称解析。

例如,有一个名称为 “my-service” 的 Service,它在 Kubernetes 集群中名为 “myns” 的 Namespace 中,为 “my-service.my-ns” 创建了一条 DNS 记录。 在名称为 “myns” 的 Namespace中的Pod应该能够简单地通过名称查询找到 “my-service”。

11.7.1 案例一: 通过Service名称访问服务

获取Service名称

[root@master-1 job]# kubectl get svc
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP     PORT(S)     AGE
demo-app        ClusterIP   10.0.0.220                8080/TCP    3d11h
kubernetes      ClusterIP   10.0.0.1                  443/TCP     9d

访问服务

服务访问的正确格式: SERVICE_NAME.NS

[root@master-1 job]# kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
dnstools# curl demo-app.default:8080
Hello! My name is demo-app-57756548d8-sltsg. I have served 2279 requests so far.

注意:Service 在没有修改的情况下,是不会修改的; 而cluster ip 在每次重建Service的时 候,会修改的。所以建议使用service name 连接内部服务。这也是为什么需要安装DNS的 原因。

11.8 存储- Secret

Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。

Secret有三种类型:

  1. Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
  2. Opaque:base64编码格式的Secret,用来存储密码、密钥等;
  3. kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息。
11.8.1 案例一: 导入Docker Registry认证信息

在Kubernetes中需要导入Docker私有镜像仓库的登录信息,才能从私有仓库拉取镜像,

登录信息的存储使用Secret加密存储。

  1. 创建 secret 密钥
#创建 secret (注意解析 docker-server (hosts))
[root@master-1 ~]# kubectl create secret docker-registry registry-secret --docker-server=reg.abc.com  --docker-username=user --docker-password=Aa123456 --docker-email=user@abc.com 
secret/registry-secret created
  1. 下载密钥
[root@master-1 ~]# kubectl get secret registry-secret -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJyZWcuYWJjLmNvbSI6eyJ1c2VybmFtZSI6InVzZXIiLCJwYXNzd29yZCI6IkFhMTIzNDU2IiwiZW1haWwiOiJ1c2VyQGFiYy5jb20iLCJhdXRoIjoiZFhObGNqcEJZVEV5TXpRMU5nPT0ifX19
kind: Secret
metadata:
  creationTimestamp: "2020-08-11T00:55:20Z"
  name: registry-secret
  namespace: default
  resourceVersion: "142965"
  selflink: /api/v1/namespaces/default/secrets/registry-secret
  uid: bf406ed7-a8de-41d7-ab2a-1e1791023162
type: kubernetes.io/dockerconfigjson
  1. 修改为需要导入的格式apiVersion: v1
kind: Secret 
metadata:
  name: regis-secre 
  namespace: default
data:
  .dockerconfigjson: eyJhdXRocyI6eyJyZWcuYWJjLmNvbSI6eyJ1c2VybmFtZSI6InVzZXIiLCJwYXNzd29yZCI6IkFhMTIzNDU2IiwiZW 1haWwiOiJ1c2VyQGFiYy5jb20iLCJhdXRoIjoiZFhObGNqcEJZVEV5TXpRMU5nPT0ifX19
type: kubernetes.io/dockerconfigjson
  1. kubectl create -f registry-secret.yaml
[root@master-1 ~]# cat registry-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: regsecret
  namespace: default
data:
  .dockerconfigjson:eyJhdXRocyI6eyJyZXBvLmhvc3RzY2MuY29tIjp7InVzZXJuYW1lIjoidXNlciIsInBhc3N3b3JkIjoiQWExMjM0NTY3OCIsImVtYWlsIjoidXNlckBhYmMuY29tIiwiYX
11.9 基于角色的访问控制- RBAC

基于角色(Role)的访问控制(RBAC)是一种基于企业中用户的角色来调节控制对计算 机或网络资源的访问方法。

  1. RBAC 使用 rbac.authorization.k8s.io API Group 来实现授权决策,允许 管理员通过 Kubernetes API 动态配置策略.
  2. 启用 RBAC,需要在 apiserver 配置文件中添加参数–authorizationmode=RBAC
11.9.1 RABC 可操作资源列表
  • Pods: 容器
  • ConfigMaps: 配置
  • Deployments: 容器控制器
  • Nodes: 节点
  • Secrets: 凭证
  • Namespaces: 命名空间
11.9.2 资源列表可操作的权限列表

Create、get、delete、list、update、edit、watch、exec

资源列表与权限关系:

11.9.3 RBAC中的其他对象
  1. Rule:规则,规则是一组属于不同 API Group 资源上的一组操作的集合;
  2. Role 和 ClusterRole:角色和集群角色,这两个对象都包含上面的 Rules 元素,
    • 二者的区别在于,
    • 在 Role中,定义的规则只适用于单个命名空间,也就是和 namespace 关联的,
    • 而 ClusterRole 是集群范围内的,因此定义的规则不受命名空间的约束。
  3. Subject:主题,对应在集群中尝试操作的对象,集群中定义了3种类型的主题资源:
    • User Account:用户,这是有外部独立服务进行管理的,管理员进行私钥的分配,用户可以使用 KeyStone或者 Goolge 帐号,甚至一个用户名和密码的文件列表也可以。对于用户的管理集群内部没有一个关联的资源对象,所以用户不能通过集群内部的 API 来进行管理;
    • Group:组,这是用来关联多个账户的,集群中有一些默认创建的组,比如clusteradmin;
    • Service Account:服务帐号,通过Kubernetes API来管理的一些用户帐号,和namespace进行关联的,适用于集群内部运行的应用程序,需要通过API来完成权限认证,所以在集群内部进行权限操作,都需要使用到 ServiceAccount.
  4. RoleBinding 和 ClusterRoleBinding:角色绑定和集群角色绑定,简单来说就是把声明的 Subject 和我们的 Role 进行绑定的过程(给某个用户绑定上操作的权限),
    • 二者的区别也是作用范围的区别:
    • RoleBinding 只会影响到当前 namespace 下面的资源操作权限,
    • 而 ClusterRoleBinding 会影响到所有的 namespace。
11.9.3.1 授权角色绑定图解

Service Account 集群的内部的鉴权.

11.9.4 案例一:创建登录Dashboard的用户

创建登录dashboard的用户, 并且只能操作kube-system这个命名空间下面的 pods 和 deployments,所以需要创建ServiceAccount对象.

创建SA对象

[root@master-1 ~]# kubectl create sa demo-sa -n kube-system
serviceaccount/demo-sa created

创建角色kube-role

[root@master-1 ~]# cat kube-sa-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: kube-sa-role
  namespace: kube-system
rules:
  - apiGroups: [""]                     #找不到资源 pods 对应的 apiGroup
    resources: ["pods"]                 #可以操作的资源
    verbs: ["get", "watch", "list"]     #对资源可以操作的列表
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

常用的apiGroups列表查阅: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/

[root@master-1 ~]# cat kube-sa-rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: kube-sa-rolebinding
  namespace: kube-system
subjects:
  - kind: ServiceAccount
    name: demo-sa
    namespace: kube-system
roleRef:
  kind: Role
  name: kube-sa-role
  apiGroup: rbac.authorization.k8s.io

ServiceAccount 会生成一个Secret对象和它进行映射,这个Secret里面包含一个token,如果dashboard也时属于kube-system, 则这个token 可以用来登录到dashboard

[root@master-1 rabc]# kubectl apply -f kube-sa-role.yaml 
role.rbac.authorization.k8s.io/kube-sa-role created

[root@master-1 rabc]# kubectl apply -f kube-sa-rolebinding.yaml 
rolebinding.rbac.authorization.k8s.io/kube-sa-rolebinding created

获取token

[root@master-1 rabc]# kubectl get secret -n kube-system |grep demo-sa
demo-sa-token-njvtq                      kubernetes.io/service-account-token   3      2m41s

获取base64

[root@master-1 rabc]# kubectl get secret demo-sa-token-njvtq -o jsonpath={.data.token} -n kube-system |base64 -d     
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkZW1vLXNhLXRva2VuLW5qdnRxIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImRlbW8tc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5YmI2ZTFiMi1iMWU5LTRhZjUtYmMyYy02ODNkNjc2YmQ1ODMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06ZGVtby1zYSJ9.MCgiXFjxbYEC2HqtBJsKpS-5EWCmw2kULsOZqIYLwxFXpR8rAPzpjzU5WuIDNCguebxOXK_3VnIY-5kLI5TlvyImvM8KEOZkn2JpmJp3EgPzOzypIoqADDCO9rxRTTzGhxS0O1oskuGJu2IZaIGZhrk6GdJ-dc1Mc94wOaqaLHDQXLbZSJmSQvFliDRxYvJZ4fVxztICAUjnTvUMrXgf6RT6nqR6ZFt7m46gLBoxrOiOVHJzBFmqlIXYqk2l-vwaufTS_Vw5oKcEXNItl3g9SydG5Ezp1fb14mnN2YnM_XsCJxRzSOU2H_GPEe-3sgiBbfzdh1HrhBAORUCSqIxT5g

登录dashbosh,输入上面生成的token

输入kube-system 命名空间

11.9.5 案例二:创建一个不受限制的SA账号, 用于集群内部的认证

创建SA

[root@master-1 job]# cat super-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: super-sa
  namespace: kube-system

创建账号

[root@master-1 rabc]# kubectl apply -f super-sa.yaml
serviceaccount/super-sa created

创建ClusterRole (控制权限)

  • 使用的cluster-admin这个对象,这是Kubernetes集群内置的 ClusterRole 对象, 无需创建。

查看cluster-admin 定义的权限

  • 所有的资源不受限制, 相当于超级管理员
[root@master-1 rabc]# kubectl get clusterrole cluster-admin -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2020-08-06T07:05:39Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
  resourceVersion: "39"
  selflink: /apis/rbac.authorization.k8s.io/v1/clusterroles/cluster-admin
  uid: 8a74bf28-5875-4c66-bcfb-a49dce6d1aa4
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'

创建角色绑定

  • RoleBinding 与 ClusterRoleBinding, 最大的不同就是, RoleBingding 受限制于NS, ClusterRoleBinding反 之.
[root@master-1 job]# cat super-sa-ClusterRoleBinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: super-sa-clusterrolebinding
subjects:
  - kind: ServiceAccount
    name: super-sa
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
[root@master-1 rabc]# kubectl apply -f super-sa.yaml
serviceaccount/super-sa unchanged

[root@master-1 rabc]# kubectl apply -f super-sa-ClusterRoleBinding.yaml 
clusterrolebinding.rbac.authorization.k8s.io/super-sa-clusterrolebinding created

获取base64编码与案例一中相同

[root@master-1 ~]# kubectl get secret -n kube-system
super-sa-token-wqjz6                     kubernetes.io/service-account-token   3      71s

获取token

[root@master-1 rabc]# kubectl get secret super-sa-token-wqjz6 -o jsonpath={.data.token} -n kube-system | base64 -d     
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJzdXBlci1zYS10b2tlbi13cWp6NiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJzdXBlci1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjI1ZTAzY2QxLTY3N2EtNDAyYy04ZGIzLTVmYjE0NjFkYjA0ZCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTpzdXBlci1zYSJ9.cvBz0uv717Z6OKw3S_ahFxrtF_5CdG-KKOwoQIm7YSZsdKwk0Fovxgf-cKaFILFOb1uKHsbU7Sk2e3VUJx0fdI4ugv6jo53Bi7WO6HPVRoCSxhEoYffzb8GFcRZ0sObPcHqvv35nb572Ll8B-krd3aJ_uUmsPp4QH6LsakXVeQFkAQ-MJBzvX_KcisBqTp87dnvmZJMLbUhsZea0UexGvbwUMR2NLQNelhjJRPfyhlk5TLOpVfycN59BkXtcoD8Ayd8EHWW9T6Dpa1ZXWN-wjJOwl_RT6c1GPARyjOydGIVCAW7sWQAZR-NQmxuWonHyQu-qLjW8e1HhMvn_GE6b3A

使用上面生成的token 登录系统

11.9.6 案例三: RBAC之Yaml授权文件讲解
[root@master-1 job]# cat prometheus-rabc.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: prometheus-rbac
subjects:
  - kind: ServiceAccount
    name: prometheus-k8s
    namespace: monitoring
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
11.9.7 案例四: 实际操作授权命令操作
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous

解释

  • 集群角色绑定用户system:anonymous, 拥有cluster-admin的权限, 集群角色名称为 system:anonymous
11.10 Yaml 文件详解 11.10.0 Yaml 是什么?

Yaml 是一种用来写配置文件的语言。结构上它有两种可选的类型:Lists 和 Maps。

  • List 用 -(破折号)来定义每一项,
  • Map 则是一个 key:value 的键值对来表示。
11.10.1 YAML语法规则
  • 大小写敏感;
  • 使用缩进表示层级关系;
  • 缩进时不允许使用Tal键,只允许使用空格;
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;
  • "#"表示注释,从这个字符一直到行尾,都会被解析器忽略;
  • “—”" 为可选的分隔符;
11.10.2 Yaml结构类型图解

在Kubernetes中,Yaml支持两种结构类型即可:Lists、Maps

  1. Yaml 转 Properties (https://www.toyaml.com/index.html)
  2. Yaml 转 Json (http://nodeca.github.io/js-yaml/)

11.10.3 Kubernetes

通过Yaml创建资源 如果需要通过yaml 文件创建Kubernetes 对象,需要配置如下的字段:

  • apiVersion: 创建该对象所使用的 Kubernetes API 的版本
  • kind: 想要创建的对象的类型
  • metadata: 帮助识别对象唯一性的数据,包括一个 name 字符串、UID 和可选的 namespace
11.10.4 案例一: Kubernetes pod编排文件讲解

Pod在程序中运行的必须的编排文件

apiVersion: v1      #指定 api 版本,此值必须在 kubectl apiversion 中
kind: Pod           #指定创建资源的角色/类型
metadata:           #资源的元数据/属性
  name: test-pod    #资源的名字,在同一个 namespace 中必须唯一
  labels:           #设定资源的标签
    k8s-app: apache
    version: v1
  annotations:      #自定义注解列表
    - name: String  #自定义注解名字
spec:               #specification of the resource content 指定该资源的内容
  restartPolicy: Always     #表明该容器一直运行,默认 k8s 的策略,在此容器退出后,会立即创建一个相同的容器
  nodeSelector:             #节点选择,先给主机打标签 kubectl label nodes kube-node1 zone=node1
    zone: node1
  containers:
    - name: test-pod                                #容器的名字
      image: 10.192.21.18:5000/test/chat:latest     #容器使用的镜像地址
      imagePullPolicy: Never        # Kubernetes 拉取镜像策略
      command: ['sh']               #启动容器的运行命令,将覆盖容器中的 Entrypoint,对应 Dockefile 中的 ENTRYPOINT
      args: ["$(str)"]              #启动容器的命令参数,对应 Dockerfile 中 CMD 参数
      env:                          #指定容器中的环境变量
        - name: str                 #变量的名字
          value: "/etc/run.sh"      #变量的值
      resources:                  #资源管理
        requests:                 #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行
          cpu: 0.1                #CPU 资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为 0.001 核(1m)
          memory: 32Mi            #内存使用量
        limits:                   #资源限制
          cpu: 0.5
          memory: 1000Mi
      ports:
        - containerPort: 80       #容器开发对外的端口
          name: httpd             #名称
          protocol: TCP
      livenessProbe:            #pod 内容器健康检查的设置
        httpGet:                #通过 httpget 检查健康,返回 200-399 之间,则认为容器正常
          path: /               #URI 地址
          port: 80
          scheme: HTTP
        initialDelaySeconds: 180    #表明第一次检测在容器启动后多长时间后开始
        timeoutSeconds: 5           #检测的超时时间
        periodSeconds: 15           #检查间隔时间
        #也可以用这种方法
        #exec: 执行命令的方法进行监测,如果其退出码不为 0,则认为容器正常
        #  command:
        #    - cat
        #    - /tmp/health
        #也可以用这种方法
        #tcpSocket: //通过 tcpSocket 检查健康
        #  port: number
      lifecycle:                    #生命周期管理
        postStart:                  #容器运行之前运行的任务
          exec:
            command:
              - 'sh'
              - 'yum upgrade -y'
        preStop:#容器关闭之前运行的任务
          exec:
            command: ['service httpd stop']
      volumeMounts:             #挂载持久存储卷
        - name: volume          #挂载设备的名字,与 volumes[*].name 需要对应
          mountPath: /data      #挂载到容器的某个路径下
          readOnly: True
    volumes:                  #定义一组挂载设备
      - name: volume          #定义一个挂载设备的名字
        #meptyDir: {}
        hostPath:
          path: /opt          #挂载设备类型为 hostPath,路径为宿主机下的/opt,这里设备类型支持很多种
          #nfs
11.10.5 案例二: Kubernetes deployment运行
apiVersion: apps/v1         # 1.9.0 之前的版本使用 apps/v1beta2,可通过命令 kubectl api-versions 查看
kind: Deployment            #指定创建资源的角色/类型
metadata:                   #资源的元数据/属性
  name: web-server          #资源的名字,在同一个 namespace 中必须唯一
spec:
  replicas: 2               #pod 副本数量
  selector:                 #定义标签选择器
    matchLabels:
      app: web-server       #符合目标的 pod 的标签
  template:                 # Deployment 扩容 pod 的时候根据此模板
    metadata:
      labels:               #Pod 的 label
        app: web-server     #pod 副本的标签,selector 根据此标签选择 pod 副本
    spec:                   #指定该资源的内容
      containers:           #pod 内容器定义的部分
        - name: nginx       #容器的名字
          image: nginx:1.12.1       #容器的镜像地址
          ports:
            - containerPort: 80     #容器暴露的端口
[root@master ~]# kubectl create -f nginx.yaml
11.10.6 案例三: Kubernetes Services 运行
[root@master ~]# cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service       #service 名称
spec:
  selector:
    app: web-server         #匹配 service 选择器标签的 pod
  ports:
    - protocol: TCP
      port: 80              #service 端口
      targetPort: 80        #pod端口    
11.11 ConfigMap

ConfigMap 允许您将配置文件与属性文件分离,以使容器化的应用程序具有可移植性。

  1. Kubernetes 空间都可以使用;
  2. 可以作为变量或者路径文件使用;
  3. Pod支持自动更新内容;

获取系统中的ConfigMap

[root@master-1 configmap]# kubectl get configmap
NAME             DATA   AGE
traefik-config   1      4d11h
11.11.1 案例一: 将ConfigMap中的所有键值对配置为容器环境变量

创建一个包含多个键值对的 ConfigMap。

[root@master-1 configmap]# cat configmap-multikeys.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  SPECIAL_LEVEL: L1
  SPECIAL_TYPE: Nginx

创建ConfigMap

[root@master-1 configmap]# kubectl apply -f configmap-multikeys.yaml 
configmap/special-config created

查看ConfigMap

[root@master-1 configmap]# kubectl get configmap/special-config -n default
NAME             DATA   AGE
special-config   2      31s

查看详细内容

[root@master-1 configmap]# kubectl describe configmap special-config
Name:         special-config
Namespace:    default
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","data":{"SPECIAL_LEVEL":"L1","SPECIAL_TYPE":"Nginx"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"special-co...

Data
====
SPECIAL_LEVEL:
----
L1
SPECIAL_TYPE:
----
Nginx
Events:  

创建容器引用ConfigMap

[root@master-1 configmap]# cat pod-configmap.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-test-configmap
spec:
  containers:
    - name: pod-test-configmap
      image: busybox
      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: SPECIAL_LEVEL
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: SPECIAL_TYPE
  restartPolicy: Never

创建pod

[root@master-1 configmap]# kubectl apply -f pod-configmap.yaml 
pod/pod-test-configmap created

查看pod日志

[root@master-1 configmap]# kubectl log pod-test-configmap
log is DEPRECATED and will be removed in a future version. Use logs instead.
L1 Nginx
11.11.2 案例二: 将 ConfigMap 数据添加到容器中的特定路径

Nginx pod 文件

[root@master-1 configmap]# cat nginx.yaml
apiVersion: apps/v1beta2    # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx-configmap
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx-configmap
    spec:
      containers:
        - name: nginx-configmap
          image: nginx
          volumeMounts:
            - name: config-volume
              mountPath: /mnt/
          ports:
            - containerPort: 80
      volumes:
        - name: config-volume
          configMap:
            name: special-config
            items:
              - key: SPECIAL_LEVEL
                path: keys

启动

[root@master-1 configmap]# kubectl apply -f nginx.yaml 
deployment.apps/nginx-deployment created

[root@master-1 configmap]# kubectl get pod | grep nginx-deployment
nginx-deployment-69fd86756f-f6bhw         1/1     Running     0          115s

查看容器内容

[root@master-1 configmap]# kubectl exec -it nginx-deployment-69fd86756f-f6bhw bash
root@nginx-deployment-69fd86756f-f6bhw:/# cd /mnt
root@nginx-deployment-69fd86756f-f6bhw:/mnt# ls
keys
root@nginx-deployment-69fd86756f-f6bhw:/mnt# cat keys
L1root

修改ConfigMap 内容(验证pod自动更新)

  • 修改内容
[root@master-1 configmap]# cat configmap-multikeys.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  SPECIAL_LEVEL: L111
  SPECIAL_TYPE: Nginx

应用新配置

[root@master-1 configmap]# kubectl apply -f configmap-multikeys.yaml 
configmap/special-config configured

[root@master-1 configmap]# kubectl describe configmap special-config
Name:         special-config
Namespace:    default
Labels:       
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","data":{"SPECIAL_LEVEL":"L111","SPECIAL_TYPE":"Nginx"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"special-...

Data
====
SPECIAL_LEVEL:
----
L111
SPECIAL_TYPE:
----
Nginx
Events:  

查看容器是否可以自动更新

  • 需要等待1分钟(默认)
[root@master-1 configmap]# kubectl exec -it nginx-deployment-69fd86756f-f6bhw -- cat /mnt/keys
L111
11.11.3 案例三: 将ConfigMap中的所有键值对配置为容器环境变量

定义配置文件

  • kustomize 应用配置管理
[root@master-1 redis]# cat kustomization.yaml
configMapGenerator:
  - name: redis-master-config
    files:
      - redis-config
resources:
  - redis-pod.yaml

定义redis配置文件

[root@master-1 redis]# cat redis-config
maxmemory 2mb
maxmemory-policy allkeys-lru

定义redis pod 文件

[root@master-1 redis]# cat redis-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  hostNetwork: true
  containers:
    - name: redis
      image: redis:5.0.4
      command:
        - redis-server
        - "/redis-master/redis.conf"
      env:
        - name: MASTER
          value: "true"
      ports:
        - containerPort: 6379
      resources:
        limits:
          cpu: "0.1"
      volumeMounts:
        - mountPath: /redis-master-data
          name: data
        - mountPath: /redis-master
          name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: redis-master-config
        items:
          - key: redis-config
            path: redis.conf

由于ingress章节中创建了redis-tcp的pod,6379端口被占用。需要删除该pod

创建redis

[root@master-1 redis]# ll
total 12
-rw-r--r-- 1 root root 120 Aug 11 10:33 kustomization.yaml
-rw-r--r-- 1 root root  43 Aug 11 10:29 redis-config
-rw-r--r-- 1 root root 652 Aug 11 10:31 redis-pod.yaml

[root@master-1 redis]# kubectl apply -k .
configmap/redis-master-config-k66gtchdm4 unchanged
pod/redis created

获取redis节点地址

[root@master-1 redis]# kubectl get pods -o wide | grep redis
redis   1/1     Running     0       6m10s       192.168.91.21       192.168.91.21         

连接访问Redis

[root@master-2 ~]# redis-cli -h 192.168.91.21 -p 6379
192.168.91.21:6379> ConFIG GET maxmemory
1) "maxmemory"
2) "2097152"    #字节
192.168.91.21:6379> ConFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/332184.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号