标签(空格分隔): k8s 学习


一. 什么是k8s

自动化的容器运维工具。

二. k8s的相关概念

cluster集群

Master主控

  1. Kubernetes API Service(k8sAPI服务)--对外

  2. Kubernetes Controller Manager(k8s控制管理器)--管理和自动修复

  3. Kubernetes Scheduler(k8s调度器)--调度pod到节点

  4. Etcd(保存集群的所有网络配置和对象状态)

Node节点(节点可以是物理机也可以是虚拟机)

  1. Kubelet(处理master节点下发到本节点的任务,管理pod及容器)

  2. Kube-proxy(监听节点k8sAPI服务变化-->服务负载均衡)

  3. Docker(底层docker负责容器的创建和管理)

Pod(豆荚) --k8s的基本操作单元

Pod由Pause容器和一个或多个业务容器组成。

  1. 业务容器共享Pause容器的网络栈和Volume挂载卷(业务容器之间的通信和数据交换更为高效)

  2. 同一Pod容器之间仅需通过localhost就能互相通信

  3. Master节点会以Pod为基本单位,调度到Node节点上。

服务

服务可以看做是一组提供相同服务的Pod的对外访问接口,服务作用于哪些Pod通过标签选择器来定义。

  1. 拥有一个指定的名称,如mysql-server

  2. 拥有一个虚拟的ip地址和端口号,销毁之前不会改变,只能内网访问

  3. 提供某种远程服务能力,被映射到提供该服务能力的一组容器应用上

提供对外服务,需要指定公共ip和Node端口或外部负载均衡。

默认下容器的数据是非持久化的。卷的生命周期与Pod绑定。

持久化的存储卷,可以再Pod删除时,依然存在

命名空间

k8s集群启动后,会创建一个默认的default命名空间。

通过分配系统内部对象的命名空间,可以形成不同项目,小组或用户组

三. k8s相关命令

3.1 kubectl命令管理各种资源

kubectl help

kubectl controls the Kubernetes cluster manager.
​
 Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/

Basic Commands (Beginner): (初级命令)
  create         Create a resource from a file or from stdin.
  expose         使用 replication controller, service, deployment 或者 pod 并暴露它作为一个 新的
Kubernetes Service
  run            在集群中运行一个指定的镜像
  set            为 objects 设置一个指定的特征
​
Basic Commands (Intermediate): (中级命令)
  explain        查看资源的文档
  get            显示一个或更多 resources
  edit           在服务器上编辑一个资源
  delete         Delete resources by filenames, stdin, resources and names, or by resources and label selector
​
Deploy Commands:(部署命令)
  rollout        Manage the rollout of a resource
  scale          Set a new size for a Deployment, ReplicaSet or Replication Controller
  autoscale      自动调整一个 Deployment, ReplicaSet, 或者 ReplicationController 的副本数量
​
Cluster Management Commands:(集群管理命令)
  certificate    修改 certificate 
  cluster-info   显示集群信息
  top            Display Resource (CPU/Memory/Storage) usage.
  cordon         标记 node 为 unschedulable
  uncordon       标记 node 为 schedulable
  drain          Drain node in preparation for maintenance
  taint          更新一个或者多个 node 上的 taints
​
Troubleshooting and Debugging Commands: (调试相关命令)
  describe       显示一个指定 resource 或者 group 的 resources 详情
  logs           输出容器在 pod 中的日志
  attach         Attach 到一个运行中的 container
  exec           在一个 container 中执行一个命令
  port-forward   Forward one or more local ports to a pod
  proxy          运行一个 proxy 到 Kubernetes API server
  cp             复制 files 和 directories 到 containers 和从容器中复制 files 和 directories.
  auth           Inspect authorization
​
Advanced Commands: (高级命令)
  diff           Diff live version against would-be applied version
  apply          通过文件名或标准输入流(stdin)对资源进行配置
  patch          使用 strategic merge patch 更新一个资源的 field(s)
  replace        通过 filename 或者 stdin替换一个资源
  wait           Experimental: Wait for a specific condition on one or many resources.
  convert        在不同的 API versions 转换配置文件
  kustomize      Build a kustomization target from a directory or a remote url.
​
Settings Commands: (设置命令)
  label          更新在这个资源上的 labels
  annotate       更新一个资源的注解
  completion     Output shell completion code for the specified shell (bash or zsh)
​
Other Commands: (其他命令)
  api-resources  Print the supported API resources on the server
  api-versions   Print the supported API versions on the server, in the form of "group/version"
  config         修改 kubeconfig 文件
  plugin         Provides utilities for interacting with plugins.
  version        输出 client 和 server 的版本信息
​
Usage:
  kubectl [flags] [options]
​
Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

资源对象类型

cluster --集群

componentstatus(cs)--组件对象状态

configmap(cm)--可以保存相关属性,数据可以再pod中使用

endpoint(ep)--实现实际任务的端点集合

event(ev,事件)--记录集群产生的各种事件

pod(po,豆荚) --k8s最小操作单元

replicaSet(rs,复制集) --代用户创建指定数量的pod副本,支持滚动式自动扩容和缩容(新) replicationController(复制控制器)--旧

Deployment(deploy,部署、调度)--是k8s中的一种控制器,是比ReplicaSet更高级的概念,最重要的特性是支持pod与ReplicaSet声明式升级,声明式升级比其他升级更安全可靠

statefulSet(状态集)

daemonSet(ds,守护程序集) --能够让所有或一些特定的node节点运行同一个pod

job(工作、任务)

cronJob --周期性任务

horizontalPodAutoscaling(自动水平缩放)

node(no,节点)

namespace(ns,命名空间)

service(svc,服务)

ingress(入口) --k8s集群中一个api资源对象,扮演边缘路由器的角色 Label(标签) customResourceDefinition(自定义资源)

存储对象 Volume、PersistentVolume、Secret、ConfigMap 策略对象 SecurityContext、ResourceQuota、LimitRange 身份对象 ServiceAccount、Role、ClusterRole

kubectl输出格式

默认输出格式为纯文本,可以通过-o或者--output选项指定如下格式: name --只输出资源名称 wide --输出更多信息 json、yaml --以json、yaml格式显示结果

其他jsonpath= 、jsonpath-file= 、custom-columns=<spec>、custom-columns-file=<filename>

基本命令举例

create 通过文件或者标准输入创建一个资源对象

kubectl create -f nginx.yaml kubectl get pods -o wide //获取详细信息

kubectl get pods -A //-A从所有命名空间中查询

NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE        NOMINATED NODE   READINESS GATES
webservices-556c7fbc7f-5gblb   1/1     Running   0          78m   10.244.0.25   gaungfa-pc   <none>           <none>

get 获取一个或多个资源对象

获取所有调度(集群通过调度下发node节点启动pod) kubectl get deployments

root@gaungfa-PC:/opt/k8s# kubectl get deployments
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
webservices   1/1     1            1           22h

//资源+s(componentstatus+es) kubectl get services

root@gaungfa-PC:/opt/k8s# kubectl get services
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.1.0.1     <none>        443/TCP   4d14h

describe显示一个或多个资源对象的详细信息

exec用于在pod中的容器中执行命令

使用 kubectl exec --help查看 进入容器内部(-it表示标准输出,t表示终端)(退出exit) kubectl exec -it webservices-556c7fbc7f-5gblb /bin/bash

注:有时没有这个命令(基础镜像不同)导致不能进入,可以看到打包的是/bin/sh kubectl exec -it webservices-556c7fbc7f-5gblb /bin/sh

root@gaungfa-PC:/opt/k8s# docker history webservices
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
84e244a476d9        3 days ago          /bin/sh -c #(nop)  CMD ["/bin/sh" "-c" "java…   0B                  
62a5c8db0f27        3 days ago          /bin/sh -c #(nop)  EXPOSE 8080                  0B                  
bedf3d8ad0a5        3 days ago          /bin/sh -c #(nop) COPY file:4220b36ffeafeb93…   20MB                
f7a292bbb70c        10 months ago       /bin/sh -c set -x  && apk add --no-cache   o…   79.4MB 

不进入容器,但在容器中运行的命令 kubectl exec webservices-556c7fbc7f-5gblb ls

run创建一个应用(与create区别)

run使用命令行的形式 kubectl run --image=nginx nginx --port=8080

delete删除集群中的资源

完整删除一个pod的流程

deployment /dɪˈplɔɪmənt/ 调度部署 kubectl get deployment

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
hello              0/1     1            0           45h
nginx-deployment   0/1     1            0           3h25m
webservices        0/1     1            0           43h

kubectl delete deployment hello

deployment.apps "hello" deleted

kubectl get pods

NAME                                READY   STATUS             RESTARTS   AGE
nginx-deployment-778c8864b4-26dhf   0/1     ImagePullBackOff   0          3h27m
webservices-7f88f48c97-sh2sl        0/1     ImagePullBackOff   0          44h

3.2 kubeadm安装、部署k8s集群

kubeadm help

    ┌──────────────────────────────────────────────────────────┐
    │ KUBEADM                                                  │
    │ Easily bootstrap a secure Kubernetes cluster             │
    │                                                          │
    │ Please give us feedback at:                              │
    │ https://github.com/kubernetes/kubeadm/issues             │
    └──────────────────────────────────────────────────────────┘
​
Example usage:
​
    Create a two-machine cluster with one control-plane node
    (which controls the cluster), and one worker node
    (where your workloads, like Pods and Deployments run).
​
    ┌──────────────────────────────────────────────────────────┐
    │ On the first machine:                                    │
    ├──────────────────────────────────────────────────────────┤
    │ control-plane# kubeadm init                              │
    └──────────────────────────────────────────────────────────┘
​
    ┌──────────────────────────────────────────────────────────┐
    │ On the second machine:                                   │
    ├──────────────────────────────────────────────────────────┤
    │ worker# kubeadm join <arguments-returned-from-init>      │
    └──────────────────────────────────────────────────────────┘
​
    You can then repeat the second step on as many other machines as you like.
​
Usage:
  kubeadm [command]
​
Available Commands:
  alpha       Kubeadm experimental sub-commands
  completion  Output shell completion code for the specified shell (bash or zsh)
  config      Manage configuration for a kubeadm cluster persisted in a ConfigMap in the cluster
  help        Help about any command
  init        Run this command in order to set up the Kubernetes control plane
  join        Run this on any machine you wish to join an existing cluster
  reset       Performs a best effort revert of changes made to this host by 'kubeadm init' or 'kubeadm join'
  token       Manage bootstrap tokens
  upgrade     Upgrade your cluster smoothly to a newer version with this command
  version     Print the version of kubeadm
​
Flags:
      --add-dir-header           If true, adds the file directory to the header
  -h, --help                     help for kubeadm
      --log-file string          If non-empty, use this log file
      --log-file-max-size uint   Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
      --rootfs string            [EXPERIMENTAL] The path to the 'real' host root filesystem.
      --skip-headers             If true, avoid header prefixes in the log messages
      --skip-log-headers         If true, avoid headers when opening log files
  -v, --v Level                  number for the log level verbosity
​
Use "kubeadm [command] --help" for more information about a command.

四. 运行应用

4.1 Deployment(部署、调度)

主要职责:保证pod的数量和健康。可以认为是ReplicationController的升级版。 其他功能:

  1. 事件和状态查看

  2. 回滚

  3. 版本记录

  4. 暂停和启动

  5. 多种升级方案

新版本中ReplicaSet代替ReplicationController,通过Deployment来自动管理ReplicaSet,用户无需直接管理ReplicaSet

运行Deployment

使用run命令运行Deployment

kubectl run --image=nginx nginx --port=8080 kubectl describe deployment nginx kubectl get replicaset

root@gaungfa-PC:/opt/k8s# kubectl describe deployment webservices
Name:                   webservices
Namespace:              default
CreationTimestamp:      Fri, 27 Mar 2020 14:24:17 +0800
Labels:                 run=webservices
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               run=webservices
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  run=webservices
  Containers:
   webservices:
    Image:        webservices
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   webservices-556c7fbc7f (1/1 replicas created)
Events:          <none>

基于文件的形式运行Deployment

//创建
$ kubectl create -f docs/user-guide/nginx-deployment.yaml --record
//创建或更新
$ kubectl apply -f docs/user-guide/nginx-deployment.yaml

Yaml文件参数介绍

apiVersion: apps/v1beta1           #表示配置文件版本号
kind: Deployment                   #指定资源类型为Deployment
metadata:                          #用来定义Deployment本身的属性
  name: nginx-deployment
spec:                              #用来定义Deployment的规格
  replicas: 3                         #定义pod副本数(可用于扩容和缩容)
  template:                           #定义pod模板
    metadata:                             #定义pod模板本身的属性
      labels:
        app: nginx
    spec:                                 #定义pod模板规格
      containers:                           #定义pod中容器的各种属性
      - name: nginx                            #容器名称
        image: nginx:1.7.9                     #容器对应的镜像
        ports:
        - containerPort: 80

扩容缩容

也可以通过命令行完成

kubectl scale deployment nginx-deployment --replicas=4 

故障转移

故障转移是自动的,也就是节点A崩溃后,对应pod会调度到节点B运行,但是节点A恢复后,不会重新调度到节点A,单节点删除后,会重新调度到节点A运行

通过节点标签指定pod位置

默认,集群下是负载均衡的. 标签可以标记任何资源。

kubectl get nodes -o wide //获取节点信息
kubectl label node gaungfa-pc mem=large //根据节点名称标记为large
# 在spec属性中增加nodeSelector选项
spec:
   template:
      nodeSelector:
         mem:large
#查看节点是否有标签
kubectl get node --show-labels
#删除标签
kubectl label node gaungfa-pc mem-

删除deployment

会同时删除ReplicaSet和pod

DaemonSet

DaemonSet创建的Pod只会运行在同一个节点,并且最多只有一个副本。 DaemonSet主要用来创建一些系统性的pod,如日志管理、存储或者域名服务器等。 k8s本身的一些DaemonSet都位于kube-system命名空间中,如kube-proxy,kube-flannel-ds等。 实例:如添加节点监控程序node-exporter

1. 创建命名空间monitoring
kubectl create namespace monitoring
2.编辑node-exporter-daemonset.yaml
apiVersion: extensions/v1beta1           #表示配置文件版本号
kind: DaemonSet                          #指定资源类型为DaemonSet
metadata:
   namespace:monitoring                    #指定命名空间
...
spec:
   hostNetwork: true                        #指定网络模式为主机网络

4.2 Job(工作、任务)

非持久性的任务

apiVersion: batch/v1                  #表示配置文件版本号
kind: Job                             #指定资源类型为Job

Job的并行处理

apiVersion: batch/v1                  #表示配置文件版本号
kind: Job                             #指定资源类型为Job
spec:
   parallelism: 3                        #设置并行数

Job的定时执行

apiVersion: batch/v2                 #表示配置文件版本号
kind: CronJob                        #指定资源类型为CronJob
spec:
   schedule: "*/1 * * * *"              #设置schedule规则

五. 通过服务访问应用

5.1 服务及其功能

服务是k8s的一个核心概念。借助服务,用户可以方便的实现应用的服务发现与负载均衡并实现应用的零怠机升级

使用ReplicaSet能够动态的创建和销毁Pod,扩容和缩容时,新的pod被创建,意味着Pod的ip地址并不总是稳定和可靠的。

举例:用于方便一组前端pod服务,可以稳定的连接一组提供后端pod服务。

# 服务创建
apiVersion: v1                       #表示配置文件版本号
kind: Service                        #指定资源类型为Service
spec:
  type: ClusterIP & nodePort & loadBalancer
  selector: []                        #标签选择器,用来选择服务可代理的pod
  ports:                              #用来指定service的服务端口与Pod端口之间的映射
    - name: http                        #类似于--tcp=<port>:<targetPort>
      protocol: TCP
      port: 80                          #对外的service端口
      targetPort: 80                    #关联的Pod端口
    

服务类型: ClusterIP:为默认的类型,提供一个集群内部的虚拟ip,与Pod不在一个网段,用于集群内部Pod之间的通信。 nodePort:使用宿主机端口,外部客户通过节点ip和端口即可访问 loadBalancer:使用外接负载均衡完成服务到负载的分线。需要再spec.status.loadBalancer中定义指定负载均衡器的ip及定义nodePort和ClusterIP。

5.2 服务管理

kubectl create -f service.yaml
kubectl get svc -o wide #可以查看服务的集群ip
kubectl get endpoints web-service #可查看服务代理的pod信息
kubectl delete -f service.yaml
kubectl delete service my-cs

5.3 外部网络访问服务

使用kube-proxy结合ClusterIP访问

k8s的api提供外部访问ClusterIP的能力

http://masterip:8080/api/v1/proxy/namespaces/<namespace>/services/<service-name>
:<port-name>/

通过NodePort访问

定义spec.type=NodePort 查询宿主机端口对应容器内部端口(查看容器内的端口对应的宿主机端口映射) kubectl get svc -o wide

获取服务的nodePort端口与宿主机节点端口的映射

使用 http://<宿主机节点ip>:<宿主机映射后的端口>/ 访问

通过负载均衡访问服务

通过外部的负载均衡比如nginx等配置转发内部服务端口

5.4 通过CoreDNS访问服务

kube-dns所遇到的问题

需要预先知道服务的ClusterIP或查找到服务在宿主机上的NodePort,存在一定的局限性

CoreDNS实现服务发现

CoreDNS是一个通用、权威的DNS服务器,解决了kube-dns所遇到的问题。 安装访问:使用Helm软件包管理工具部署、使用Yaml文件部署

//查询是否安装coredns
root@gaungfa-PC:/opt/k8s# kubectl get pod --namespace=kube-system
NAME                                READY   STATUS    RESTARTS   AGE
coredns-9d85f5447-5444v             1/1     Running   3          5d
coredns-9d85f5447-558cb             1/1     Running   3          5d
etcd-gaungfa-pc                      1/1     Running   4          5d
kube-apiserver-gaungfa-pc            1/1     Running   8          5d
kube-controller-manager-gaungfa-pc   1/1     Running   29         5d
kube-flannel-ds-amd64-mdtvj         1/1     Running   3          4d23h
kube-proxy-mr6gl                    1/1     Running   3          5d
kube-scheduler-gaungfa-pc            1/1     Running   30         5d
//举例创建一个nginx的deployment及service(创建两个)
//coredns自动域名解析

如何使用

Label和Label Selector共同构成了Kubernetes系统中最核心的应用模型,使得对象能够精细分组,同时实现了集群的高可用性

六. 存储管理

6.1 存储卷(Volume)

是k8s持久化数据的最基本的功能单元。 k8s适配各种存储系统。包括本地存储EmptyDir和HostPath,网络存储NFS、ClusterFS以及PV/PVC等。 EmptyDir:是宿主机上的一个空目录,不会随着容器销毁而销毁,但与Pod生命周期一致。 HostPath:是将宿主机上一个已经存在的目录,共享给容器Pod的容器。 NFS:通过局域网让不同注解之间共享文件或目录。 Secret卷:用来保存小片敏感数据的存储卷。相比于之间存储在pod或定义在镜像中更加安全。

Secret卷独立于pod,以数据卷的形式挂载到Pod中,容器通过文件(key-value)读取获取需要的数据

//同理增删改查
root@gaungfa-PC:/opt/k8s# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-gzc5l   kubernetes.io/service-account-token   3      5d

ISCSI卷:将现有的ISCSI磁盘挂载到Pod中

empty卷

emptyDir卷,就是从一个空目录开始,运行在pod内的应用程序可以写入它需要的任何文件。其生命周期是和pod捆绑,随着pod创建而创建;删除而销毁,卷的内容将会丢失。emptyDir卷适用于同一个pod中运行的容器之间共享文件。 举例:

volumes:
  - name: emptyDir1
    emptyDir: {} 

两个容器挂载同一个卷进行共享:

spec:
  template:
     containers:
        - name: container1
          image: test/image1
          volumeMounts:
          - name: emptyDir1
            mountPath: /var/dir1
        - name: container2
          image: test/image2
          volumeMounts:
          - name: emptyDir1
            mountPath: /dev/doc/dir2
            readOnly: true
          ports:
          - containerPort: 80
            protocol: TCP
     volumes:
     - name: emptyDir1
       emptyDir: {} 

第一个容器为container1,运行镜像test/image1,名为emptyDir1的卷挂载在容器的/var/dir1路径中;第二个容器胃container2,运行镜像test/image2,与第一个容器相同的卷挂载在/dev/doc/dir2路径上,且为只读。

通常对应的磁盘位置 /var/lib/kubelet/pods/<pod uuid>/volumes

gitRepo卷

  gitRepo卷是一种emptyDir卷,通过克隆Git仓库并在pod启动时,检查出特定版本来填充数据(注意:pod启动时,是在创建容器前)。 原理如下:

  1. 用户创建带有gitRepo volume的pod;

  2. k8s创建一个空目录并将指定的git仓库克隆到其中;

  3. pod中的容器启动(卷挂载在路径上) gitRepo原理图 gitRepo volume有一个缺陷:每次将更改推送到gitRepo时,都需要删除pod才可以拉取到最新版本的信息,即本地目录和git仓库无法同步。当然,这个缺陷可以通过同步容器来实现。

hostPath卷

   hostPath卷指向节点文件系统上的特定文件或目录,某些系统级别的pod可以通过挂载hostPath卷去读取节点的文件或使用节点文件系统对节点进行访问。在同一个节点上运行并在其hostPath卷中使用相同路径的pod可以看到相同的文件。    hostPath卷属于持久性存储,删除pod1后,卷里面的文件继续保持,不丢失,新的pod2如果使用了指向主机相同路径的hostPath卷,则pod2就能够发现pod1留下的文件和数据(前提,pod2能够被调度到pod1相同的节点)。   pod对预定规划的节点敏感, 基于这种前提,因为卷的内容存储在特定节点的文件系统,所以pod被重新调度到其他节点时,就无法访问到原数据,hostPath卷不适合作为存储数据库数据的目录。hostPath卷通常用于尝试单节点集群中的持久化存储,仅当需要在节点上读取或写入系统文件时才会使用hostPath,不用做持久化跨pod的数据。

spec:
  template:
     containers:
        - name: container1
          image: test/image1
          volumeMounts:
          - name: test-hostpath
            mountPath: /data
     volumes:
      - name: test-hostpath
        hostPath:
          path: /root/data 

6.2 持久化存储卷方案。

存储卷在可管理性方面存在很大的缺陷。k8s提出了持久化存储卷方案。 持久化存储卷有着独立的生命周期。

静态绑定

apiVersion: v1                       #表示配置文件版本号
kind: PersistentVolumeClaim          #指定资源类型:持久化卷声明
metadata:
  name: my-pvc
spec:
   accessModes:                        #指定访问模式
     - ReadWriteMany
   resources:
     requests:
        storage:1Gi                         #指定卷容量为1G
apiVersion: v1                       #表示配置文件版本号
kind: PersistentVolume               #指定资源类型:持久化卷
apiVersion: v1                       #表示配置文件版本号
kind: Deployment                     #指定资源类型为Deployment
spec:
   template:
      spec:
         volumes:
         -name:<name>
          persistentVolumeClaim:
             claimName: my-pvc

动态绑定

动态卷允许集群管理员不必预先创建存储卷,而是根据用户的需求进行创建。

七. 软件包管理

7.1 Helm

helm是k8s生态中的软件包管理工具。类似于yum、apt、rpm等,通过软件包管理工具可以方便的对当前系统的软件包进行管理。Helm 使用 Chart 来管理 Kubernetes manifest 文件。

安装 Helm

1、使用官方脚本安装最新版

curl -L https://git.io/get_helm.sh | bash

2、为 Tilier 添加权限,参考 role-based-access-control 新建 rbac-config.yaml,然后执行 kubectl create -f rbac-config.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
 - kind: ServiceAccount
    name: tiller
    namespace: kube-system

3、初始化

helm init \
--upgrade \
--history-max 200 \
--stable-repo-url http://mirror.azure.cn/kubernetes/charts/ \
--service-account tiller \
--tiller-image registry.cn-hangzhou.aliyuncs.com/google_containers/tiller:v2.14.2
stable: http://mirror.azure.cn/kubernetes/charts/
incubator: http://mirror.azure.cn/kubernetes/charts-incubator/

4、查看 Helm 版本号

helm version
Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}

Helm 工作原理

1、基本概念

  • Chart:包含了创建一个 Kubernetes 应用的必要信息

  • Repository:Helm package 存储仓库

  • Release:是一个 chart 及其配置的一个运行实例 2、组成结构 Helm Client 是用户命令行工具,其主要负责如下:

  • 本地 chart 开发

  • 仓库管理

  • 与 Tiller sever 交互

  • 发送预安装的 chart

  • 查询 release 信息

  • 要求升级或卸载已存在的 release Tiller Server 是一个部署在 Kubernetes 集群内部的 server,其与 Helm client、Kubernetes API server 进行交互。Tiller server 主要负责如下:

  • 监听来自 Helm client 的请求

  • 通过 chart 及其配置构建一次发布

  • 安装 chart 到 Kubernetes 集群,并跟踪随后的发布

  • 通过与 Kubernetes 交互升级或卸载 chart 简单的说,client 管理 charts,而 server 管理发布 release 3、helm charts Helm 使用 Chart 来管理 Kubernetes manifest 文件。每个 chart 都至少包括 应用的基本信息 Chart.yaml 一个或多个 Kubernetes manifest 文件模版(放置于 templates/ 目录中),可以包括 Pod、Deployment、Service 等各种 Kubernetes 资源 模板默认值 values.yaml (可选) 示例 Chart : Mysql 4、依赖管理 Helm 支持两种方式管理依赖的方式:

  • 直接把依赖的 package 放在 charts/ 目录中

  • 使用 requirements.yaml 并用 helm dep up foochart 来自动下载依赖的 packages

dependencies:
  - name: apache
    version: 1.2.3
    repository: http://example.com/charts
  - name: mysql
    version: 3.2.1
    repository: http://another.example.com/charts

5、插件管理 插件提供了扩展 Helm 核心功能的方法,它在客户端执行,并放在 $(helm home)/plugins 目录中。一个典型的 helm 插件格式为

$(helm home)/plugins/
  |- keybase/
      |
      |- plugin.yaml
      |- keybase.sh
而 plugin.yaml 格式为
name: "keybase"
version: "0.1.0"
usage: "Integreate Keybase.io tools with Helm"
description: |-
  This plugin provides Keybase services to Helm.
ignoreFlags: false
useTunnel: false
command: "$HELM_PLUGIN_DIR/keybase.sh"

这样,就可以用 helm keybase 命令来使用这个插件。 Helm 常用命令 ☆ 查询 charts helm search mysql ☆ 查询 package 详细信息 helm inspect stable/mysql ☆ 部署 package helm install stable/mysql 部署之前可以自定义 package 的选项:

# 查询支持的选项
helm inspect values stable/mysql
# 自定义 password 持久化存储
helm install --name db-mysql --set mysqlRootPassword=anoyi  stable/mysql
注意: 如果出现无可用 PV, 即 kubectl get pv 提示 No resources found. 需要创建 PV,步骤如下:
① 新建文件夹 mkdir /k8s
② 新建文件 local-pv.yaml,storage 大小依据当前主机的磁盘大小来修改,查看磁盘使用命令 df -lh
apiVersion: "v1"
kind: "PersistentVolume"
metadata:
  name: "local-pv"
spec:
  capacity:
    storage: "20Gi"
  accessModes:
    - "ReadWriteOnce"
  persistentVolumeReclaimPolicy: Recycle
  hostPath:
    path: /k8s
③ 创建 PV
kubectl create -f local-pv.yaml
☆ 查看 Release 列表
helm ls
☆ 升级 / 回滚 Release
# 升级
helm upgrade --set mysqlRootPassword=passwd db-mysql stable/mysql
# 回滚
helm rollback db-mysql 1
☆ 删除 Release
helm delete --purge db-mysql
☆ 管理 repo
# 添加 incubator repo
helm repo add my-repo https://kubernetes-charts-incubator.storage.googleapis.com/
# 查询 repo 列表
helm repo list
# 生成 repo 索引(用于搭建 helm repository)
helm repo index
☆ 管理 chart
# 创建一个新的 chart
helm create hello-chart
# validate chart
helm lint
# 打包 chart 到 tgz
helm package hello-chart

相关资料 Helm 官方文档 官方 Charts 仓库 在 kubernetes 集群中创建本地 PV Helm UI

八. 网络管理

8.1 k8s的网络基础

8.2 k8s的网络实现

8.3 flannel

Kubernetes-基于flannel的集群网络_Kubernetes中文社区 在默认情况,Docker使用bridge网络模式,bridge网络驱动的示意图如下,此文以bridge模式对Docker的网络进行说明。

 

 

九. Dashboard仪表盘

9.1 Dashboard配置文件

角色控制

十.实际问题 ---k8s调度

QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node-role.kubernetes.io/master:NoSchedule
                 node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason            Age                 From               Message
  ----     ------            ----                ----               -------
  Warning  FailedScheduling  37s (x12 over 12m)  default-scheduler  0/1 nodes are available: 1 node(s) didn't match node selector.

如上查看处于pending中的节点详情,为调度问题

查看节点的所有标签

wangshouchao@wangshouchaodeMacBook-Pro myhelm % kubectl get node --show-labels               
NAME             STATUS   ROLES    AGE   VERSION   LABELS
docker-desktop   Ready    master   33h   v1.15.5   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=docker-desktop,kubernetes.io/os=linux,node-role.kubernetes.io/master=

给节点增加标签

Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  69s (x8 over 10m)  default-scheduler  0/1 nodes are available: 1 node(s) had volume node affinity conflict.

经检查pv需要节点亲和

不能绑定持久化存储卷

Events:
  Type     Reason            Age                From               Message
  ----     ------            ----               ----               -------
  Warning  FailedScheduling  84s (x3 over 92s)  default-scheduler  pod has unbound immediate PersistentVolumeClaims
  Warning  FailedScheduling  7s (x2 over 82s)   default-scheduler  0/1 nodes are available: 1 node(s) had volume node affinity conflict.

调度扫盲

一种是全局的调度策略,要在启动调度器时配置,包括kubernetes调度器自带的各种predicates和priorities算法,具体可以参看上一篇文章;

另一种是运行时调度策略,包括nodeAffinity(主机亲和性),podAffinity(POD亲和性)以及podAntiAffinity(POD反亲和性)。

nodeAffinity 主要解决POD要部署在哪些主机,以及POD不能部署在哪些主机上的问题,处理的是POD和主机之间的关系。

podAffinity 主要解决POD可以和哪些POD部署在同一个拓扑域中的问题(拓扑域用主机标签实现,可以是单个主机,也可以是多个主机组成的cluster、zone等。)

podAntiAffinity主要解决POD不能和哪些POD部署在同一个拓扑域中的问题。它们处理的是Kubernetes集群内部POD和POD之间的关系

nodeSelector

1.分配pod到node的方法

通过node label selector实现约束pod运行到指定节点,有两种方法 nodeSelector 以及affinity

2.nodeSelector 是k8s早起提供的节点选择器实现

1)首先为nodes打对应的label kubectl label nodes master disktype=ssd 2)创建yaml文件,nginx-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
12345678910

创建pod

kubectl create -f nginx-pod.yaml 节点默认的label kubectl get nodes -o yaml 可以看到默认节点的label,也可以使用这些label进行约束

alpha.kubernetes.io/fluentd-ds-ready: "true"
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
disktype: ssd
kubeadm.alpha.kubernetes.io/role: master
kubernetes.io/hostname: master
123456

亲和性和反亲和性

根据类型有

nodeAffinity(主机亲和性), podAffinity(POD亲和性) podAntiAffinity(POD反亲和性)。

三种亲和性和反亲和性策略的比较如下表所示:

策略名称匹配目标支持的操作符支持拓扑域设计目标
nodeAffinity主机标签In,NotIn,Exists,DoesNotExist,Gt,Lt不支持决定Pod可以部署在哪些主机上
podAffinityPod标签In,NotIn,Exists,DoesNotExist支持决定Pod可以和哪些Pod部署在同一拓扑域
PodAntiAffinityPod标签In,NotIn,Exists,DoesNotExist支持决定Pod不可以和哪些Pod部署在同一拓扑域

对于亲和性和反亲和性,每种都有三种规则可以设置:

RequiredDuringSchedulingRequiredDuringExecution :在调度期间要求满足亲和性或者反亲和性规则,如果不能满足规则,则POD不能被调度到对应的主机上。在之后的运行过程中,如果因为某些原因(比如修改label)导致规则不能满足,系统会尝试把POD从主机上删除(现在版本还不支持)。

RequiredDuringSchedulingIgnoredDuringExecution :在调度期间要求满足亲和性或者反亲和性规则,如果不能满足规则,则POD不能被调度到对应的主机上。在之后的运行过程中,系统不会再检查这些规则是否满足。

PreferredDuringSchedulingIgnoredDuringExecution :在调度期间尽量满足亲和性或者反亲和性规则,如果不能满足规则,POD也有可能被调度到对应的主机上。在之后的运行过程中,系统不会再检查这些规则是否满足。

使用场景介绍

nodeAffinity使用场景 :

  • 将S1服务的所有Pod部署到指定的符合标签规则的主机上。

  • 将S1服务的所有Pod部署到除部分主机外的其他主机上。

podAffinity使用场景 :

  • 将某一特定服务的pod部署在同一拓扑域中,不用指定具体的拓扑域。

  • 如果S1服务使用S2服务,为了减少它们之间的网络延迟(或其它原因),把S1服务的POD和S2服务的pod部署在同一拓扑域中。

podAntiAffinity使用场 景:

  • 将一个服务的POD分散在不同的主机或者拓扑域中,提高服务本身的稳定性。

  • 给POD对于一个节点的独占访问权限来保证资源隔离,保证不会有其它pod来分享节点资源。

  • 把可能会相互影响的服务的POD分散在不同的主机上。

NodeAffinity

参考:https://k8smeetup.github.io/docs/concepts/configuration/assign-pod-node/#node-%E4%BA%B2%E5%92%8C%E6%80%A7beta-%E7%89%B9%E6%80%A7

requiredDuringSchedulingIgnoredDuringExecution的示例

下面这个例子使用nodeAffinity把POD部署到主机mesos-slave1和mesos-slave2上面

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
  annotations:
    scheduler.alpha.kubernetes.io/affinity: >
      {
        "nodeAffinity": {
          "requiredDuringSchedulingIgnoredDuringExecution": {
            "nodeSelectorTerms": [
              {
                "matchExpressions": [
                  {
                    "key": "kubernetes.io/hostname",
                    "operator": "In",
                    "values": [“mesos-slave1″,”mesos-slave2”]
                  }
                ]
              }
            ]
          }
        }
      }
    another-annotation-key: another-annotation-value
spec:
  containers:
  - name: with-node-affinity
    image: gcr.io/google_containers/pause:2.0

我们可以看到NodeSelectorTerms可以有多个,之间是或的关系,满足任意一个既满足,,MatchExpressions也可以有多个,他们之间是且的关系 必须都满足。

preferredDuringSchedulingIgnoredDuringExecution 例子

apiVersion: v1
kind: Pod
metadata:
  name: with-labels
  annotations:
    scheduler.alpha.kubernetes.io/affinity: >
    {
       "nodeAffinity": {
          "preferredDuringSchedulingIgnoredDuringExecution": [
                {
                    "weight" : 1,
                    "preference": {
                        "matchExpressions": [
                            {
                                "key": "disktype",
                                "operator": "In",
                                "values": ["ssd"]
                            }
                        ]
                    }
                }
            ]
        }
    }
    another-annotation-key: another-annotation-value
spec:
  containers:
  - name: test-affinity
    env:
      - name: MYSQL_ROOT_PASSWORD
        value: pass
    image: mysql

preferredDuringSchedulingIgnoredDuringExecution值为列表,根据权重决定顺序 MatchExpressions 值为列表 关系为且,必须都满足

Inter-pod affinity and anti-affinity

Inter-pod affinity 是根据通过已运行在节点上的pod的标签而不是node的标签来决定被调度pod的运行节点,因为pod运行在指定的namespace所以需要自己指定运行pod的namesapce

anti-affinity 和Inter-pod affinity相反

在下面这个例子中,定义了一个Pod亲和性和一个Pod反亲和性规则。其中Pod亲和性规则是一定要满足的,Pod反亲和性规则是参考满足的。

Pod亲和性规则的含义是:Pod必须部署在一个节点上,这个节点上至少有一个正在运行的Pod,这个Pod的security属性取值是“S1”,并且要求部署的节点同正在运行的Pod所在节点都在相同的云服务区域中,也就是“topologyKey:failure-domain.beta.kubernetes.io/zone”。换言之,一旦某个区域出了问题,我们希望这些 Pod 能够再次迁移到同一个区域。

Pod反亲和性规则的含义是,Pod不能部署在一个节点上,这个节点上正在运行的Pod中security属性取值是“S2”,并且新部署的Pod不能同security属性取值是“S2”的Pod在相同的主机上,也就是“topologyKey: kubernetes.io/hostname”。

matchExpressions中operator的取值包括In、NotIn、Exists、DoesNotExist、Gt和Lt。

DoesNotExist实现反亲密的示例

 affinity:
   nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
       nodeSelectorTerms:
       - matchExpressions:
         - key: error
           operator: DoesNotExist

topologyKey的取值包括:

kubernetes.io/hostname       同一个主机
1
failure-domain.beta.kubernetes.io/zone      同一个云服务区
1
failure-domain.beta.kubernetes.io/region    同一个区域
1
apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
  annotations:
    scheduler.alpha.kubernetes.io/affinity: >
        {
          "podAffinity": {
            "requiredDuringSchedulingIgnoredDuringExecution": [
              {
                "labelSelector": {
                  "matchExpressions": [
                    {
                      "key": "security",
                      "operator": "In",
                      "values": ["S1"]
                    }
                  ]
                },
                "topologyKey": "failure-domain.beta.kubernetes.io/zone"
             }
            ]
           },
          "podAntiAffinity": {
            "requiredDuringSchedulingIgnoredDuringExecution": [
              {
                "labelSelector": {
                  "matchExpressions": [
                    {
                      "key": "security",
                      "operator": "In",
                      "values": ["S2"]
                    }
                  ]
                },
                "topologyKey": "kubernetes.io/hostname"
             }
            ]
           }
         }
spec:
  containers:
  - name: with-pod-affinity
    image: gcr.io/google_containers/pause:2.0

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐