基础对象
对象 | 说明 |
---|---|
Pod | k8s 最小单位 |
Service | 网络、自动发现 |
Volume | 存储 |
Namespace | 命名空间 |
基于基础对象抽象出以下 Controllers
对象 | 说明 |
---|---|
ReplicaSet | |
Deployment | 无状态服务 |
StatefulSet | 有状态服务 |
master 组件
对象 | 说明 |
---|---|
kube-apiserver | 暴露 Kubernetes api |
etcd 用来存储所有的集群数据 | |
kube-scheduler | 调度 pods |
kube-controller-manager | 控制 Controller |
cloud-controller-manager
Node 组件, node 的组件在每个节点都会有
对象 | 说明 |
---|---|
kubelet | 保证容器跑在 pod 里 并且保证 pod 的健康,kubelet 只管理用 Kubernetes 创建的容器。 |
kube-proxy | 网络和连接转发 |
Container Runtime |
插件 Addons
Client Libraries: 自己写代码调用 Kubernetes API
YAML 写法
- YAML spec pod
- YAML spec deployment
- Namespaces
使用场景: 多团队或者多项目 , 如果只是为了区分服务, 使用 labels 就可以了. 区分开发, 测试, 预发布, 正式环境
通过 Resource Quotas 分配集群资源
创建和删除 namespaces
- # 查看命名空间
- kubectl get namespaces
- # 设置命名空间
- kubectl --namespace=<insert-namespace-name-here> run nginx --image=nginx
- kubectl --namespace=<insert-namespace-name-here> get pods
- # 设置默认使用哪个命名空间
- kubectl config set-context $(kubectl config current-context) --namespace=<insert-namespace-name-here>
创建 Service 的时候会创建对应的 dns, dns 的入口是..svc.cluster.local, 这表示 dns 只解析本的命名空间请求, 这在使用命名空间区分测试, 预发布, 正式环境很有用. 如果你需要跨命名空间访问则需要域名.
并不是所有的 Kubernetes 资源都在同一个命名空间里, 可以使用以下的命令查看
- # 在 namespace 里的资源
- kubectl API-resources --namespaced=true
- # 不在 namespace 里的资源
- kubectl API-resources --namespaced=false
- Labels and Selectors
Labels 对 object 而言的 key 是唯一的.
一个合理的 key 应该由前缀和名称组成, 使用 / 分隔.
名称不超过 63 个字符, 可以使用 - _ . 分隔
前缀是可选的, 如果指定了不超过 253 个字符 并且以 / 结尾
value 不超过 63 个字符, 不要有除 - _ . 外的特殊字符.
labels 搜索
操作 | 说明 | 示例 |
---|---|---|
= | 等于 | environment=production |
== | 等于 | environment==production |
!= | 不等于 | environment!=production |
in | in | environment in (production, qa) |
notin | notin | tier notin (frontend, backend) |
exists | exists 只检测 key 有没有存在 | partition |
noexists | exists 只检测 key 有没有存在 | !partition |
多个合并操作 environment=production,tier!=frontend |
- # 查询 environment=production&&tier=frontend
- kubectl get pods -l environment=production,tier=frontend
- kubectl get pods -l 'environment in (production),tier in (frontend)'
- # 查询 key 是 environment && environment 值不是 frontend
- kubectl get pods -l 'environment,environment notin (frontend)'
- #matchExpressions,key,operator,values ,operator 支持 In,NotIn,Exists,DoesNotExist
- selector:
- matchLabels:
- component: Redis
- matchExpressions:
- - {key: tier, operator: In, values: [cache]}
- - {key: environment, operator: NotIn, values: [dev]}
- node selection
- Annotations
Labels 用来搜索 object 和 object 集合, 相反 Annotations 用来注释让其他工具或者类库可以检索到 metadata.
- #annotations 可以包含 labels 中不允许的字符
- "metadata": {
- "annotations": {
- "key1" : "value1",
- "key2" : "value2"
- }
- }
- Field Selectors
使用 resource 字段值查询 Kubernetes resource 比如:
- metadata.name=my-service
- metadata.namespace!=default
- status.phase=Pending
- # 使用 --field-selector 查询 pod 为 Running 状态
- kubectl get pods --field-selector status.phase=Running
支持的 fields 因不同的资源类型而不通, 所有的资源类型都支持 metadata.name 和 metadata.namespace
但其他的 fields 就不一定, 如果遇到不支持的 fields 会报错.
操作符支持 =,== 和!=
kubectl get services --field-selector metadata.namespace!=default
链式操作
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
同时搜索多资源
kubectl get statefulsets,services --field-selector metadata.namespace!=default
推荐做法
有状态服务
- apiVersion: apps/v1
- kind: StatefulSet
- metadata:
- labels:
- App.kubernetes.io/name: MySQL #名称
- App.kubernetes.io/instance: WordPress-abcxzy #唯一名称, 标识应用程序
- App.kubernetes.io/version: "5.7.21" #版本
- App.kubernetes.io/component: database #架构中的组件
- App.kubernetes.io/part-of: WordPress #哪个程序的一部分
- App.kubernetes.io/managed-by: helm #用什么工具管理
无状态服务 labels 例子:
- #Deployment
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- labels:
- App.kubernetes.io/name: myservice
- App.kubernetes.io/instance: myservice-abcxzy
- ...
- #Service
- apiVersion: v1
- kind: Service
- metadata:
- labels:
- App.kubernetes.io/name: myservice
- App.kubernetes.io/instance: myservice-abcxzy
- ...
- # 注意同一个服务里的 Deployment 和 Service 里的 labels 是一样
包含数据库的 web 应用
- #Deployment
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- labels:
- App.kubernetes.io/name: WordPress
- App.kubernetes.io/instance: WordPress-abcxzy
- App.kubernetes.io/version: "4.9.4"
- App.kubernetes.io/managed-by: helm
- App.kubernetes.io/component: server
- App.kubernetes.io/part-of: WordPress
- ...
- #Service
- apiVersion: v1
- kind: Service
- metadata:
- labels:
- App.kubernetes.io/name: WordPress
- App.kubernetes.io/instance: WordPress-abcxzy
- App.kubernetes.io/version: "4.9.4"
- App.kubernetes.io/managed-by: helm
- App.kubernetes.io/component: server
- App.kubernetes.io/part-of: WordPress
- ...
- #MySQL StatefulSet
- apiVersion: apps/v1
- kind: StatefulSet
- metadata:
- labels:
- App.kubernetes.io/name: MySQL
- App.kubernetes.io/instance: WordPress-abcxzy
- App.kubernetes.io/managed-by: helm
- App.kubernetes.io/component: database
- App.kubernetes.io/part-of: WordPress
- App.kubernetes.io/version: "5.7.21"
- ...
- #MySQL Service
- apiVersion: v1
- kind: Service
- metadata:
- labels:
- App.kubernetes.io/name: MySQL
- App.kubernetes.io/instance: WordPress-abcxzy
- App.kubernetes.io/managed-by: helm
- App.kubernetes.io/component: database
- App.kubernetes.io/part-of: WordPress
- App.kubernetes.io/version: "5.7.21"
- ...
Kubernetes 对象管理
管理技巧
Warning: Kubernetes 对象有多种管理技巧, 不要混用.
命令行管理
- # 创建 Deployment 对象
- kubectl run nginx --image nginx
- kubectl create deployment nginx --image nginx
- # 创建 Deployment
- kubectl run
- # 创建 Service 对象
- kubectl expose
- # 创建一个可自动扩缩容的 controller, 比如 Deployment
- kubectl autoscale
- # 指定子命令
- create <objecttype> [<subtype>] <instancename>
- kubectl create service nodeport <myservicename>
- # 查看帮助
- kubectl create service nodeport -h
- # 水平扩容
- kubectl scale
- # 添加或者删除注释
- kubectl annotate
- # 添加或者删除 label
- kubectl label
- # 设置 object 里的字段
- kubectl set <field>
- # 直接用编辑器打开配置修改
- kubectl edit
- # 使用 patch 来修改 object
- kubectl patch
- # 使用 set 命令在创建 objects 之前修改内容
- #kubectl create service -o YAML --dry-run 这个命令不会发送给 Kubernetes 而是输出 YAML 内容到标准输出, 通过管道发送给下一个命令
- #kubectl set selector --local -f - -o YAML 从管道接收配置然后写入到 YAML
- #kubectl create -f - 执行创建命令
- kubectl create service clusterip my-svc --clusterip="None" -o YAML --dry-run | kubectl set selector --local -f - 'environment=qa' -o YAML | kubectl create -f -
- # 使用 --edit 在创建前修改 objects
- kubectl create service clusterip my-svc --clusterip="None" -o YAML --dry-run> /tmp/srv.YAML
- kubectl create --edit -f /tmp/srv.YAML
Imperative object configuration 命令式对象配置
- # 创建 objects
- kubectl create -f <filename|url>
- kubectl create -f nginx.YAML
- # 更新 objects
- kubectl replace -f <filename|url>
- kubectl replace -f nginx.YAML
replace 局限性:
1. 从一个配置文件里创建一个 object
2. 用其他方式修改 object 里的某些字段
3. 再修改第 1 步的配置文件然后使用 replace 执行, 这样第 2 步修改的内容就会丢失.
所以要注意不要用多种方式管理同一个 object . 如果你想用多个文件管理同一个 object 要使用 kubectl apply 来管理.
- # 删除 objects
- kubectl delete -f <filename|url>
- kubectl delete -f nginx.YAML -f Redis.YAML
- kubectl delete <type>/<name>
- kubectl delete deployment/nginx
- # 查看 objects , -o YAML 输出完整的 object 配置, 使用 kubectl get -h 查看详细内容
- kubectl get -f <filename|url> -o YAML
- # 查看 pod 的输出或者错误
- kubectl logs
- # 修改 object 但不保存在配置文件里
- kubectl create -f <url> --edit
- # 从命令行管理转成配置管理 imperative object configuration
- #1. 导出 object 配置到本地文件
- kubectl get <kind>/<name> -o YAML --export> <kind>_<name>.YAML
- #2 从导出的配置文件中删除 status 字段
- #3 使用 replace 更新
- kubectl replace -f <kind>_<name>.YAML
定义 controller selectors 和 PodTemplate labels
警告: 强烈建议不要修改 controller 的 selectors, 推荐的方法是使用 PodTemplate
- selector:
- matchLabels:
- controller-selector: "extensions/v1beta1/deployment/nginx"
- template:
- metadata:
- labels:
- controller-selector: "extensions/v1beta1/deployment/nginx"
Declarative object configuration 声明式对象配置
- # 创建 objects
- kubectl apply -f <directory>/
- #simple_deployment.YAML
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: nginx-deployment
- spec:
- selector:
- matchLabels:
- App: nginx
- minReadySeconds: 5
- template:
- metadata:
- labels:
- App: nginx
- spec:
- containers:
- - name: nginx
- image: nginx:1.7.9
- ports:
- - containerPort: 80
- # 查看变动, 类似 Git diff
- kubectl diff -f simple_deployment.YAML
- # 执行变动
- kubectl apply -f simple_deployment.YAML
- # 打印配置信息
- kubectl get -f simple_deployment.YAML -o YAML
- # 递归查看变动
- kubectl diff -R -f configs/
- # 递归执行变动
- kubectl apply -R -f configs/
- # 使用 kubectl scale 扩容
- kubectl scale deployment/nginx-deployment --replicas=2
- # 删除 objects
- # 推荐使用 imperative command 去删除 objects
- kubectl delete -f <filename>
- #prune 还处于 alpha 阶段, 后续版本可能会修改, 并且该命令是查询 label 来删除的~ 所以可能删除其他东西
- kubectl apply -f <directory/> --prune -l <labels>
- # 查看 object 配置
- kubectl get -f <filename|url> -o YAML
kubectl apply 如何计算差异并合并修改内容
Nodes
Node Status 包含以下信息
对象 | 包含内容 |
---|---|
Addresses | HostName, 可以使用 kubelet --hostname-override 修改 < br ztid="321" ow="0" oh="0">ExternalIP: 集群外 IP InternalIP: 集群内 IP |
Condition | OutOfDisk: 添加新 pod 空间不足为 True,否则为 False |
Capacity | 描述 node 上的可用资源: CPU,内存以及可以在节点上调度的最大 pod 数 |
Info | node 的一般信息比如内核版本、Kubernetes 版本、Docker 版本、OS 名称。由 Kubelet 从 node 收集。 |
管理 node
Kubernetes 本身不创建 node, 他通过外部提供者创建, 比如本地物理机, 虚拟机, 谷歌云等. 所以 Kubernetes 创建 node 的时候其实是创建一个 object 来表示 node. 一旦创建成功, Kubernetes 会检查 node 是否有效. 比如如果你用下面的内容创建 node:
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "10.240.79.157",
- "labels": {
- "name": "my-first-k8s-node"
- }
- }
- }
Kubernetes 创建一个内部 node 对象, 并且通过 metadata.name 检查 node 是否健康. 如果 node 有效, 所有的服务都会执行. 否则集群会忽略它直到 node 变成有效. Kubernetes 会不断的检查无效的 node 对象. 你必须删除 node 才能停止检查.
node controller, kubelet 和 kubectl 三个组件和 Kubernetes node 接口交互.
Node Controller
node controller 是 Kubernetes 的主要组件, 管理 node 的各方面.
node controller 在 node 的生命周期里扮演多个角色.
1. 注册的时候为 node 分配 CIDR 块 (如果 CIDR 开启).
2.node controller 云服务商的可用集群列表最新的内部节点列表, 当在云环境里执行的时候, 每当 node unhealthy, node controller 会请求云服务商 那个 node 的 VM 是否依旧可用. 如果不可用, node controller 会从 node 列表里把这个 node 删除.
3. 监控 nodes 的健康.
来源: https://yq.aliyun.com/articles/697387