Core Concept 部分, 在整个CKAD 考试中占比是非常大的, 占13%,因此熟练地掌握这些核心概念以及操作, 是非常重要的, 今天先来学习第一部分, kubectl CLI, 也即是Kubernetes 提供的命令行接口.
Kubectl 自动补全首先需要做的, 就是要启用Kubernetes kubectl CLI的自动补全, 这不仅能加快考试答题的速度, 还可以避免错误; 同时, 这在我们日常工作中也是非常有用的.
kubectl 本身提供了自动补全命令, 用法是: kubectl completion bash | zsh
这个根据不同的安装环境, 需要的操作也有所不同, 因此:
操作系统
命令
补充
macOS
对于Mac 自带的Bash 3.2:
brew install bash-completion
对于Bash 4, 使用
brew install bash-completion@2
==> Pouring bash-completion-1.3_3.big_sur.bottle.tar.gz
==> Caveats
Add the following line to your ~/.bash_profile:
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
==> Summary
/usr/local/Cellar/bash-completion/1.3_3: 189 files, 608KB
Linux
source <(kubectl complition bash)
或者写入bash_profile:
kubectl complition bash > ~/.kube/completion.bash.inc
printf "
# Kubectl shell completion
source '$HOME/.kube/completion.bash.inc'
" >> $HOME/.bash_profile
source $HOME/.bash_profile
source的方式, 对当前Shell 有效
第二种是先写入到一个文件里面, 然后再追加到当前用户的.bash_profile 文件中, 这样每次用户登录的时候, 都会执行这个.bash_profile, 从而是的自动补全功能生效
Kubectl 语法书Kubectl 是Kubernetes CLI, 同时也是管理Kubernetes 的"瑞士军刀", 不仅可以用部署和管理Kubernetes上的应用, 还可以用来执行脚本, 搭建更高一层的框架.
Kubectl 命令很多, 目前来看主要分为5个方面:
种类
用法
描述
声明式资源管理
开发和部署(例如GitOps)
使用Resource Config 管理Kubernetes 负荷资源, 这是推荐用法,
主要使用 apply
命令式资源管理
只用来做开发
使用命令行参数和标识, 运行命令来管理Workload
打印工作负荷资源状态
调试
打印Workload 信息
与容器交互
调试
Exec, Attach, Cp, Logs
集群管理
Cluster Ops
维护集群状态
在继续熟悉kubectl 之前, 首先来明确Resource, Workload, Controller 这几个概念之间的区别.
理清Resource与Workload , Controller之间的区别先来看看什么是Resource
Resource
Kubernetes上所有的对象(Object), 都可以称之为Resource, 比如Deployment, Services, Namespaces等.用户通过Resource API , 把在yaml文件中声明的Resource对象, 应用到Kubernetes 集群中, 这些用来定义资源对象的文件, 就叫做Resource Config. Resource Config的结构, 如下图所示
Resource 对象通过下面几个属性, 唯一性地标识资源对象:- apiVersion 其实包括API Type Group 和Version两个部分- kind API 类型名称- metadata.namespace 实例对象的命名空间- metadata.name 实例对象的名字
在基本理解了Resource 之后, 再来看看Workload ,工作负载对象.
Workload
那么什么是Workload, 工作负载对象呢? 原来Workload 就是指那些运行容器的对象, 比如Deployment, StatefulSets, Jobs, CronJobs, DaemonSets最后, 来看看一个资源文件的例子
apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deployment labels: app: nginxspec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15.4这种工作负载对象的定义文件, 我们之前已经看过好多遍了, 为了更牢固的记忆, 可以把这个文件分成几个部分:
从上面的图中, 可以看到一个工作负载对象基本可以分成三个部分, 第一部分是类型元数据;第二部分是工作负荷的实例对象的元数据部分; 第三部分是工作负荷实例对象的定义(specification), 因为工作负载对象基本上是围绕着管理Pod 而产生的高级对象, 因此在spec.template 部分, 就会包括一个对Pod 的声明, 也即是蓝线包裹起来的部分, 其中又分为Pod的元数据(命名, 工作空间等), 以及Pod的定义(deploy.spec.template.spec), 这基本上就是一个三明治的结构.
Workload 的三明治结构
Pod 一般由更高一层的抽象来管理, 这其中的管理关注点包括复制(replication), 识别(identity), 持久化存储(persistent storage), 自定义调度(custom scheduling), 滚动发布(rollig update)等等, 而最常见的开箱即用的Workload API 包括:
Deployment( 无状态应用)StatefulSets(有状态应用)Jobs(批处理作业)CronJobs(可调度的批处理作业)DaemonSet(按节点调度)Controller
Controller, 控制器, 就是Kubernetes系统上的激活API, 每种Workload 背后, 都会有一个对应的Controller API, 这些控制器会关注两种类型的状态变化, 一种是Resource 对象的期望状态的变化, 例如资源的创建, 更新以及删除; 另外还会关注系统的状态变化, 例如某个Pod 或者Node 的死亡等.
Controller API在观察到需要的变化之后, 就会实施这些无论是由资源配置文件, 还是有系统自动产生的变化, 把相应的状态应用到Kubernetes 集群中.
例如, 用户创建一个Deployment后,Deployment控制器将看到该Deployment还没有存在,因此就会验证其期望的状态, 并判断相应ReplicaSet是否存在。 Controller将看到ReplicaSet不存在,并将创建一个ReplicaSet, 然后又ReplicaSet 来负责相应的Pod 的创建.。
注意: 控制器是异步运行的,因此在一般的CRUD响应中将不会出现诸如容器映像错误或计划外的Pod之类的问题。 工具必须促进监视系统状态的过程,直到控制器完全执行更改为止。 一旦更改被完全激活,以使所需状态与观察到的状态相匹配,就认为该资源已结算。
在更深一层次地理解Kubernetes中的Resource, Workload 与Controller 之后, 我们来看看如何使用Kubectl 来操作这些对象, 用Kuberenetes 的术语就是, Reconcile.
使用Kubectl 来创建对象kubectl 创建对象, 有两种风格, 一种是使用声明文件, 文件格式可以是yaml或者json, 后缀名可以是.yaml,.yml, 和.json.
通过kubectl apply -f, 后面可以跟具体的文件名, 例如:
kubectl apply -f ./my-manifest.yamlkubectl 后面可以指定多个yaml文件:
kubectl apply -f ./my1.yaml -f ./my2.yamlkubectl 后面还可以指定一个目录:
kubectl apply -f ./dir同时, kubectl 可以指定从一个网络资源上创建:
kubectl apply -f https://git.io/vPieo
另外, 使用Kubectl的命令式风格, 可以在命令行直接创建一个Deployment, 包含3个单实例的nginx Pod对象:
kubectl create deployment nginx --image=nginx --replicas=3可以使用kubectl create 直接创建的资源, 常用的有configmap, cronjob, deployment, job, namespace, secret, service等, 格式是:
kubectl create <resource-type> resource-name --flags
例如我们来创建一个打印一次"Hello World" 字符串的Job:
kubectl create job helloJob --image=busybox -- echo "Hello World"再来创建一个每分钟打印一次"Hello World" 字符串的CronJob:
kubectl create cronjob hellocronjob --image=busybox --schedule="*/1 * * * *" -- echo "Hello World"创建一个命名空间:
kubectl create ns test-nskubect create 练习题题目:
Create a namespace called 'mynamespace' and a pod with image nginx called nginx on this namespace
操作:
kubectl create ns mynamespacekubectl run nginx --restart=Never --image=nginx --namespace=mynamespace题目:
把上面创建的Pod 用yaml 文件来描述
如果需要yaml, 可以在kubectl create的时候, 指定--dry-run和-o yaml参数. 通过这两个参数, 可以自动生成资源配置文件, 简化编写的时间而且不容易出错.
$ kubectl run nginx --image=nginx --restart=Never --namespace=mynamespace --dry-run=client -o yaml >pod.yaml
题目: 创建一个busybox 的Pod, 并在里面的命令行里执行env 命令, 并查看相应的输出结果
Create a busybox pod (using YAML) that runs the command "env". Run it and see the output
操作:
$kubectl run busybox --image=busybox --command --restart=Never -- env$kubectl logs busybox输出:
题目: 使用yaml文件创建一个busybox 的Pod, 并在里面的命令行里执行env 命令, 并查看相应的输出结果
Create a busybox pod (using YAML) that runs the command "env". Run it and see the output
操作:
$ kubectl run busybox --image=busybox --restart=Never --command --dry-run=client -o yaml -- env > busyboxpod.yaml题目:
Get the YAML for a new namespace called 'myns' without creating it
操作:
kubectl create namespace myns --dry-run=client -o yaml >myns.yaml题目:
Get the YAML for a new ResourceQuota called 'myrq' with hard limits of 1 CPU, 1G memory and 2 pods without creating it
操作:
kubectl create quota myrq --hard=cpu=1,memory=1G,pods=2 --dry-run=client -o yaml >quota.yaml题目:
Get pods on all namespaces
操作:
$ kubectl get po --all-namespaces$ kubectl get po -A题目:
Create a pod with image nginx called nginx and expose traffic on port 80
操作:
$ kubectl run nginx --image=nginx --restart=Never --port=80好了, 今天只练习使用kubectl create来创建资源, 一些修改和在容器中执行的操作,等到下一篇再学习吧!
回顾今天认识了Kubernetes 中Resource对象的结构, 并区分了Resource对象与Workload对象, Controller API之间的关系.
并通过几个例子, 练习了kubectl create和kubectl run的用法:
当在Pod中创建容器时, 使用Kubectl run 命令;当创建高级概念如Deployment 时, 使用Kubectl create;当不创建资源,只是生成yaml 文件时候, 使用--dry-run=client -o yaml 参数你学到了吗?