kubectl应用部署命令详解
一、准备工作
Kubernetes提供的集群控制平面(master节点)与Kubernetes APIServer通信的命令行工具——kubectl。kubectl默认配置文件目录$HOME/.kube/config。可以通过 --kubeconfig 参数来指定kubectl的配置文件。
以下操作如果已经做过了,就可以跳过。
1.1、Replication Controller
(1)创建myhello-rc.yaml并写入如下内容:
vim myhello-rc.yaml
内容:
apiVersion: v1
kind: ReplicationController # 副本控制器 RC
metadata:
namespace: default
name: myhello-rc # RC名称,全局唯一
labels:
name: myhello-rc
spec:
replicas: 5 # Pod副本期待数量
selector:
name: myhello-rc-pod
template: # pod的定义模板
metadata:
labels:
name: myhello-rc-pod
spec:
containers: # Pod 内容的定义部分
- name: myhello #容器的名称
image: nongtengfei/hello:1.0.0 #容器对应的 Docker Image
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
通常不会去单独的配置pod,都是通过某一类副本控制器资源去部署pod。原因:如果单独配置pod,当集群升级时需要将当前节点上的所有pod排空,那么会产生问题,因为pod没有任何副本控制器在控制它,集群对他没有预期,当节点排空后,pod将不会被调度和重生。
(2)为RC创建service。
vim myhello-svc.yaml
内容:
apiVersion: v1
kind: Service
metadata:
name: myhello-svc
labels:
name: myhello-svc
spec:
type: NodePort # 对外提供端口
ports:
- port: 80
protocol: TCP
targetPort: 80
name: http
nodePort: 30000
selector:
name: myhello-rc-pod
(3)应用配置。
kubectl apply -f myhello-svc.yaml -f myhello-rc.yaml
1.2、Deployment
(1)创建myapp-deployment.yaml并写入如下内容:
vim myapp-deployment.yaml
内容:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
name: myapp-deploy
spec:
replicas: 5
selector:
matchLabels:
name: myapp-deploy-pod
template:
metadata:
labels:
name: myapp-deploy-pod
spec:
#nodeSelector:
#nodetype: worker
containers: # Pod 内容的定义部分
- name: myhello #容器的名称
image: nongtengfei/hello:1.0.0 #容器对应的 Docker Image
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
resources:
requests:
cpu: 100m
- name: myredis #容器的名称
image: redis #容器对应的 Docker Image
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6379
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
resources:
requests:
cpu: 100m
(2)为deployment创建service。
vim myapp-svc.yaml
内容:
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
labels:
name: myapp-svc
spec:
type: NodePort # 对外提供端口
ports:
- port: 80
protocol: TCP
targetPort: 80
name: http
nodePort: 30001
selector:
name: myapp-deploy-pod
(3)应用配置。
kubectl apply -f myapp-svc.yaml -f myapp-deployment.yaml
1.3、DaemonSet
(1)创建myapp-deployment.yaml并写入如下内容:
vim myapp-ds.yaml
内容:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: myapp-ds
namespace: default
labels:
app: myapp-ds
spec:
selector:
matchLabels:
app: myapp-ds
template:
metadata:
labels:
app: myapp-ds
spec:
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
containers: # Pod 内容的定义部分
- name: myhello #容器的名称
image: nongtengfei/hello:1.0.0 #容器对应的 Docker Image
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
env: # 注入到容器的环境变量
- name: env1
value: "k8s-env1"
- name: env2
value: "k8s-env2"
(2)为DaemonSet创建service。
vim myapp-ds-svc.yaml
内容:
apiVersion: v1
kind: Service
metadata:
name: myapp-ds-svc
labels:
name: myapp-ds-svc
spec:
type: NodePort # 对外提供端口
ports:
- port: 8080
protocol: TCP
targetPort: 80
name: http
nodePort: 30002
selector:
app: myapp-ds
(3)应用配置:
kubectl apply -f myapp-ds-svc.yaml -f myapp-ds.yaml
1.4、查看创建的svc和pod
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 45h
myapp-ds-svc NodePort 10.96.41.180 <none> 8080:30002/TCP 4m3s
myapp-svc NodePort 10.98.20.127 <none> 80:30001/TCP 6m32s
myhello-svc NodePort 10.106.252.61 <none> 80:30000/TCP 14m
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-deployment-5659dbddd8-l6m87 0/2 Pending 0 6m41s
myapp-deployment-5659dbddd8-lxxls 0/2 Pending 0 6m41s
myapp-deployment-5659dbddd8-pqqlx 0/2 Pending 0 6m41s
myapp-deployment-5659dbddd8-xb8xp 0/2 Pending 0 6m41s
myapp-deployment-5659dbddd8-zjgsx 0/2 Pending 0 6m41s
myapp-ds-2zqf9 1/1 Running 0 2m43s
myhello-rc-2tjmr 0/1 Pending 0 12m
myhello-rc-44ksd 0/1 Pending 0 12m
myhello-rc-86g79 0/1 Pending 0 12m
myhello-rc-df225 0/1 Pending 0 12m
myhello-rc-lfbzb 0/1 Pending 0 12m
这里只建立了一个节点,所有只有一个pod。
1.5、kubectl 命令自动补全设置
# 安装自动补全插件
sudo apt-get install -y bash-completion
# 添加.bashrc文件内容
echo "source <(kubectl completion bash)" >> ~/.bashrc
# 加载最新的.bashrc
source ~/.bashrc
二、应用部署命令
2.1、diff
显示目前版本与将要应用的版本之间的差异,仅对比yaml文件所定义的项目。
用法:
kubectl diff -f FILENAME
示例:
# 通过文件对比
kubectl diff -f myapp-deployment.yaml
# 通过输入对比
cat myapp-deployment.yaml | kubectl diff -f -
# 对比当前目录yaml后缀的文件
kubectl diff -f '*.yaml'
2.2、apply
基于文件或标准输入,将新的配置应用到资源上。
用法:
kubectl apply -f FILENAME
示例:
# 将配置应用到资源
kubectl apply -f myapp-deployment.yaml
# 通过输入的方式讲配置应用到资源
cat myapp-deployment.yaml | kubectl apply -f -
# 将当前目录yaml后缀的文件应用到资源
kubectl apply -f '*.yaml'
2.3、replace
基于文件或标准输入,将新的配置已替换的方式应用到资源上。
用法:
kubectl replace -f FILENAME
示例:
# 将配置应用到资源
kubectl replace -f myapp-deployment.yaml
# 通过输入的方式讲配置应用到资源
cat myapp-deployment.yaml | kubectl replace -f -
2.4、rollout
管理资源的上线,支持 deployments、daemonsets、statefulsets等资源对象。
用法:
kubectl rollout SUBCOMMAND
以下是支持的SUBCOMMAND。
2.4.1、history
查看历史修订版本和配置。
用法:
kubectl rollout history (TYPE NAME | TYPE/NAME) [flags]
示例:
# 查看DaemonSet/cadvisor 的发布历史
kubectl rollout history ds/myapp-ds
# 查看修订版本号为3的历史记录详细信息
kubectl rollout history daemonset/myapp-ds --revision=3
2.4.2、pause
将提供的资源标记为已暂停。控制器不会协调暂停的资源。使用“kubectl rollout resume”恢复暂停的资源。
当前仅支持 deployment 资源对象,由于deployment的滚动更新机制,如果在部署过程中使用了pause,将会导致一个部署中的pod版本不一致暂停 Deployment,然后再触发一个或多个更新,最后再继续(resume)该 Deployment。这种做法可以在暂停和继续中间对 Deployment 做多次更新,而无需触发不必要的滚动更新。简而言之:多次修改之后,在执行resume命令之后,对之前的修改一起反映到Pod。但是对服务的扩容和缩容不受暂停约束。
用法:
kubectl rollout pause RESOURCE
示例:
# 暂停部署
kubectl rollout pause deployment myapp-deployment
2.4.3、resume
恢复暂停的资源。
控制器不会协调暂停的资源。通过恢复资源,我们可以再次协调资源。当前仅支持恢复deployment。
用法:
kubectl rollout resume RESOURCE
示例:
kubectl rollout resume deployment myapp-deployment
2.4.4、restart
重启资源对象。
用法:
kubectl rollout restart RESOURCE
示例:
# 重启部署
kubectl rollout restart deployment/myapp-deployment
# 重启守护进程
kubectl rollout restart daemonset/myapp-ds
# 根据selector 重启部署
kubectl rollout restart deployment --selector=name=myapp-deploy
2.4.5、status
查看状态。
用法:
kubectl rollout status (TYPE NAME | TYPE/NAME) [flags]
示例:
# 查看发布状态
kubectl rollout status deployment/myapp-deployment
2.4.6、undo
回滚到之前版本。
用法:
kubectl rollout undo (TYPE NAME | TYPE/NAME) [flags]
示例:
# 回滚deployment/myapp-deployment 到上一个版本
kubectl rollout undo deployment/myapp-deployment
# 回滚到指定版本
kubectl rollout undo daemonset/myapp-ds --to-revision=2
# 演习回滚,查看结果。并未做真正的操作
kubectl rollout undo --dry-run=server deployment/myapp-deployment
注意:连续的undo,并不会一直往前回滚到很老的版本,而会在最近两个版本间来回切换。
示例:
# 分三次修改镜像版本,分别改为:1.0.0 1.0.1 1.0.2
kubectl edit ds/myapp-ds
# 回滚到上一个版本,查看详情镜像版本为:1.0.1
kubectl rollout undo ds/myapp-ds
# 回滚到上一个版本,查看详情镜像版本为:1.0.2
kubectl rollout undo ds/myapp-ds
2.5、scale
为deployment、replica set、 replication controller、statefulset 设置pod的副本数。
用法:
kubectl scale [--resource-version=version] [--current-replicas=count] -- replicas=COUNT (-f FILENAME | TYPE NAME)
示例:
# 修改副本数量为3
kubectl scale --replicas 3 deployment myapp-deployment
# 修改文件定义资源的副本数量为30
kubectl scale --replicas=30 -f myapp-deployment.yaml
# 如果当前副本数为30,则将副本数改为10
kubectl scale --current-replicas=30 --replicas=10 deployment/myapp-deployment
# 将指定 rc 和 deployment的副本数改为6
kubectl scale --replicas=6 rc/myhello-rc deployment/myapp-deployment
2.6、autoscale
创建自动缩放器,自动选择和设置在Kubernetes群集中运行的POD数。支持 deployment、replicaset、stateful set、replication controller等资源对象。当CPU或内存的使用率超过设定值之后,会开始自动扩容。当指标恢复之后,大约5分钟后,会开始缩容。自动伸缩的支持,必须为pod中每个容器设置所需最小资源。
用法:
kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU]
示例:
# 最少2个pod ,最多10个pod,采用默认缩放策略
kubectl autoscale deployment myapp-deployment --min=2 --max=10
# 最多15个pod,目标pod cpu利用率40%
kubectl autoscale deployment myapp-deployment --min=2 --max=15 --cpu-percent=40
# 查看自动扩展器
kubectl get horizontalpodautoscalers
2.6.1、metrics server
自动伸缩,必须安装metrics server。metrics server 用于获取节点指标。metrics server安装条件,k8s集群必须开启聚合层(默认已配置);节点kubelet 服务启用webhook鉴权(默认已启用)。
metrics server 启动项添加 --kubelet-insecure-tls 选项。
文档:
2.6.1、metrics server 安装
components.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: system:aggregated-metrics-reader
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- apiGroups:
- ""
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
k8s-app: metrics-server
spec:
containers:
- args:
- --cert-dir=/tmp
- --kubelet-insecure-tls
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
image: registry.aliyuncs.com/google_containers/metrics-server:v0.6.2
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: https
scheme: HTTPS
periodSeconds: 10
name: metrics-server
ports:
- containerPort: 4443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readyz
port: https
scheme: HTTPS
initialDelaySeconds: 20
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 200Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp-dir
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: metrics-server
volumes:
- emptyDir: {}
name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
labels:
k8s-app: metrics-server
name: v1beta1.metrics.k8s.io
spec:
group: metrics.k8s.io
groupPriorityMinimum: 100
insecureSkipTLSVerify: true
service:
name: metrics-server
namespace: kube-system
version: v1beta1
versionPriority: 100
执行:
kubectl apply -f components.yaml