k8s简要学习
一篇简单的快速系统性的了解k8s相关功能的文章,更全面的学习的请查看官方文档!
标签(空格分隔): k8s 学习
一. 什么是k8s
自动化的容器运维工具。
二. k8s的相关概念
cluster集群
Master主控
-
Kubernetes API Service(k8sAPI服务)--对外
-
Kubernetes Controller Manager(k8s控制管理器)--管理和自动修复
-
Kubernetes Scheduler(k8s调度器)--调度pod到节点
-
Etcd(保存集群的所有网络配置和对象状态)
Node节点(节点可以是物理机也可以是虚拟机)
-
Kubelet(处理master节点下发到本节点的任务,管理pod及容器)
-
Kube-proxy(监听节点k8sAPI服务变化-->服务负载均衡)
-
Docker(底层docker负责容器的创建和管理)
Pod(豆荚) --k8s的基本操作单元
Pod由Pause容器和一个或多个业务容器组成。
业务容器共享Pause容器的网络栈和Volume挂载卷(业务容器之间的通信和数据交换更为高效)
同一Pod容器之间仅需通过localhost就能互相通信
Master节点会以Pod为基本单位,调度到Node节点上。
服务
服务可以看做是一组提供相同服务的Pod的对外访问接口,服务作用于哪些Pod通过标签选择器来定义。
拥有一个指定的名称,如mysql-server
拥有一个虚拟的ip地址和端口号,销毁之前不会改变,只能内网访问
提供某种远程服务能力,被映射到提供该服务能力的一组容器应用上
提供对外服务,需要指定公共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的升级版。 其他功能:
-
事件和状态查看
-
回滚
-
版本记录
-
暂停和启动
-
多种升级方案
新版本中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启动时,是在创建容器前)。 原理如下:
-
用户创建带有gitRepo volume的pod;
-
k8s创建一个空目录并将指定的git仓库克隆到其中;
-
pod中的容器启动(卷挂载在路径上) 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可以部署在哪些主机上 |
podAffinity | Pod标签 | In,NotIn,Exists,DoesNotExist | 支持 | 决定Pod可以和哪些Pod部署在同一拓扑域 |
PodAntiAffinity | Pod标签 | 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
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
更多推荐
所有评论(0)