注: 每天5分钟玩转kubernetes(CloudMan)编著, 学习笔记
一、常用命令
kubectl get nodes # 节点
hostname # kubectl所在主机名
kubectl cluster-info # 集群信息: kubernetes master, heapster, kubernetes-dashboard, monitoring-grafana, monitoring-influxdb组件运行url地址
kubectl cluster-info dump # 保存到本地
kubectl run kubernetes-bootcamp --image=docker.io/jocatalin/kubernetes-bootcamp:v1 --port=8080 # 创建deployment(应用)部署单元, 运行pod
kubectl get pods # 查看pods, pod中的容器共享ip/port, 在同一个network namespace中, 调度的最小单位,始终在一起被调度(一组紧密相关的容器放在一起,容器的集合), 应用Deployment的Pod
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port=8080 # 容器8080端口映射到宿主机,service "kubernetes-bootcamp" exposed
kubectl get services # 查看应用被映射到节点的哪个端口, 自带负载均衡
curl hostname:nodeport # 外部访问pod服务
kubectl get deployments # 查看副本数
kubectl scale deployments/kubernetes-bootcamp --replicas=3 # 改变pod数量,增加(减少)应用节点数
kubectl get pods # 查看当前pod数量
kubectl get pod --all-namespaces -o wide # 查看所有ns下的pod
kubectl describe pod --namespace=kube-system # 查看pod状态
kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 # 滚动升级 v1->v2
kubectl rollout undo deployments/kubernetes-bootcamp # 回滚 v2->v1
二、常用术语
1. Cluster: 计算、存储、网络资源的集合,k8s基于这些资源运行基于容器的应用
2. Master: 调度,决定将应用放在哪里运行。多个master实现高可用
3. Node: 运行容器应用。根据Master要求管理容器生命周期,监控并汇报容器状态。 (Master和Node可以部署在同一个节点上)
4. Pod: 作为一个整体被Master调度到一个Node上运行, k8s最小工作单元
5. Controller: k8s通过Controller管理Pod, Controller中定义了Pod的部署特性(几个副本、在什么样的Node上运行)。
(1)Deployment: 可以管理Pod的多个副本,确保Pod按照期望的状态运行
(2)ReplicaSet: 实现了Pod的多副本管理, Deployment会自动创建ReplicaSet并通过RS管理Pod的多个副本
(3)DaemonSet: 作为daemon使用,每个Node最多一个Pod
(4)StatefulSet: 保证Pod副本在整个生命周期名称不变,按固定顺序启动、更新、删除。Pod发生故障需删除并重启时名称会变化
(5)Job: 一次性,运行结束即删除。
6. Service: 定义外界访问一组特定Pod的方式。Service有自己的IP:PORT, 为Pod提供负载均衡(Pod频繁销毁、重启,IP会发生变化)
Controller: 运行容器;Service: 访问容器
7. Namespace: 将一个物理Cluster逻辑上划分为多个虚拟Cluster(即Namespace),当多用户、项目组使用同一个k8s Cluster时,对Controller/Pod等资源分开。
默认2个Namespace: default(创建资源时未指定); kube-system: k8s自己创建的系统资源
三、部署k8s Cluster
1. Master节点 + Node节点
2. Docker: Master + Node
3. kubelet, kubeadm, kubectl: Master + Node
(1)kubelet: 启动Pod和容器
(2)kubeadm: 初始化Cluster
(3)kubectl: k8s命令行工具。使用kubectl可以部署和管理应用,查看各种资源,创建、删除、更新各种组件
4. 创建Cluster:
kubeadm: 集群;kubelet: 容器; kubectl: 客户端
(1)初始化Master: kubeadm init --apiserver-advertise-address 192.168.75.100 --pod-network-cidr=10.244.0.0/16(flannel网络方案cidr要求)(--apiserver-advertise-address: 使用哪个网卡的ip地址与Cluster其他节点通信;--pod-network-cidr: Pod网络范围。)
kubeadm执行初始化前检查 --> 生成token/证书 --> 生成KubeConfig文件(kubectl使用它与Master通信) --> 下载Master组件docker镜像并安装 --> 安装附加组件kube-proxy,kube-dns --> Master初始化成功 -->配置kubelet -->安装Pod网络 --> 注册其他节点。
(2)配置kubectl: 管理Cluster的命令行工具, 在Master初始化后进行配置
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u) : $(id -g) $HOME/.kube/config
echo "source < (kubectl completion bash)" >> ~/.bashrc # 自动补全
(3)Pod网络: kubectl apply -f xxx/kube-flannel.yaml # 创建flannel网络,Pod之间通信使用
(4) 添加Node节点: kubeadm join --token
kubectl get nodes #查看节点状态。每个节点都需启动若干组件,在pod中运行,需下载相关镜像
Pending/ContainerCreating/ImagePullBackOff表明Pod没有就绪
kubectl describe pod
四、k8s架构
kubectl -> api server -> controller manager(如deployment) -> scheduler -> k8s Node kubectl -> create/run pod
应用配置、当前状态信息在etcd中,执行kubectl get pod时api server会在etcd中读取数据
1. Master节点的组件: 运行着Daemon服务: kube-apiserver, kube-scheduler, kube-controller-manager, etcd, pod network, kubelet, kube-proxy
Master也可用作Node: kubectl taint node k8s-master node-role.kubernetes.io/master-
恢复only master: kubectl taint node k8s-master node-role.kubernetes.io/master="":NoSchedule
(1)api server: 提供HTTP(S) RESTFUL API,即kubernetes-api, Cluster的前端接口,供CLI、UI等客户端工具、其他组件管理CLUSTER各种资源
(2)Scheduler: 综合cluster的拓扑结构、各节点的负载、高可用、性能、数据亲和性的考虑,决定将Pod放在哪个Node上运行
(3)Controller Manager: 管理Cluster的各种资源, 保证资源处于预期状态。由多个controller组成(replication controller: Deployment/StatefulSet/DaemonSet生命周期, namespace controller: Namespace资源, endpoints controller, serviceaccounts controller)
(4)etcd: 保存Cluster的配置信息、各种资源的状态信息。数据变化时,通知k8s相关组件
(5)Pod network: Pod间相互通信
2. Node节点组件: Pod运行的地方,支持docker/rkt等容器runtime。组件有kubelet, kube-proxy, pod network
(1)kubelet: Node的agent, Scheduler确定在某个Node上运行Pod后,将Pod配置信息(image/volume等)发送给该Node上的kubelet, kubelet根据这些信息创建和运行容器,向Master报告运行状态
(2)kube-proxy: 有负载均衡能力,将访问service(逻辑上代表了后端的多个Pod)的TCP/UDP数据流转发到后端的容器
(3)pod network: Pod间相互通信
几乎所有的kubernetes组件都运行在pod中:kubectl get pod --all-namespaces -o wide
kube-dns为Cluster提供dns服务,执行kubeadm init时作为附件组件安装的
kubelet是唯一没有以pod形式运行的k8s组件,通过linux系统systemd服务运行。
五、运行应用
对象命名方式:子对象名字 = 父对象名字 + 随机字符串/数字
(一) 1. Deployment: pod ->(controlled by) replicaset -> (controlled by )deployment -> (created by) kubectl
kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
kubectl get deployment nginx-deployment
kubectl describe deployment nginx-deployment
kubectl get replicaset
kubectl describe replicaset
kubectl get pod
kubectl describe pod
2. 两种创建资源方式
(1) kubectl 命令行通过参数指定资源属性
(2) 配置文件(yaml) 和 kubectl apply(kubectl create, kubectl replace, kubectl edit, kubectl patch)
资源属性写在配置文件中,格式yaml。提供创建资源的模板、可重复部署、像管理代码一样管理部署、适合正式的跨环境的规模化部署。
kubectl apply -f nginx.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: web-server
spec:
containers:
- name: nginx
image: nginx:1.7.9
说明:
apiVersion: 配置格式版本
kind: 资源类型Deployment
metadata: 该资源(Deployment)的元数据
spec: 该资源(Deployment)的规格说明
replicas: Pod副本数量
template: Pod模板
metadata: Pod元数据
labels: Pod标签,至少一个label, key:value任意
spec: Pod规格, 定义Pod中每个容器的属性
containers: Pod中容器的属性, name 和 image必需
3. 删除资源
kubectl delete deployment nginx-deployment
kubectl delete -f nginx.yaml
4. 弹性伸缩: 在线增加/减少Pod副本数
nginx.yaml中replicas: 5改成5个
kubectl apply -f nginx.yaml
kubectl get pod -o wide
修改为3个: replicas: 3
kubectl apply -f nginx.yaml
kubectl get po -o wide
5. Failover
关闭k8s-node2: halt -h
k8s-node2上的Pod状态: Unknown
Pod调度到k8s-node1上
k8s-node2恢复后: Unknown状态的Pod会被删除, k8s-node1上正常运行的Pod不会被重新调回k8s-node2
6. 控制Pod调度到指定Node: 大量磁盘I/O的Pod部署到配置了SSD的Node上,Pod需要GPU部署到配置了GPU的Node上。
label实现调度到指定Node上。默认Scheduler会调度到所有可用的Node上。
label: key-value对,各种资源都要以设置label,添加自定义属性
kubectl label node k8s-node1 disktype=ssd
kubectl get node --show-labels # 查看节点label
Node上也有kubernetes自己维护的label
指定Pod部署到k8s-node1上: Pod模板上的spec中添加nodeSelector属性 disktype: ssd
kubectl apply -f nginx-deployment
kubectl label node k8s-node1 disktype- # 删除标签
-: 删除的语法
nginx.yaml中删除nodeSelector后重新apply重新部署,重新调度
(二) 7. DaemonSet: 每个Node最多只运行一个副本
(1) 集群每个节点运行存储Daemon: glusterd, ceph
(2) 集群每个节点运行日志收集Daemon: flunentd, logstash
(3) 集群每个节点运行监控Daemon: Prometheus Node Exporter, collectd
kubectl get daemonset --namespace=kube-system # 查看k8s系统组件, flannel, kube-proxy
kube-flannel.yaml:
# flannel DaemonSet
apiVersion: extensions/v1beta1
kind: DaemonSet # 指定资源类型
metadata:
name: kube-flannel-ds
namespace: kube-system
labels:
tier: node
app: flannel
spec:
template:
metadata:
labels:
tier: node
app: flannel
spec:
hostNetwork: true # 使用宿主机网络
nodeSelector:
beta.kubernetes.io/arch: amd64
containers: # DaemonSet要运行的容器
- name: kube-flannel
image: quay.io/coreos/flannel:v0.8.0-amd64
command: ["/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr"]
- name: install-cni
image: quay.io/coreos/flannel:v0.8.0-amd64
command: ["/bin/sh", "-c", "set -e -x; cp -f /etc/kube-flannel/cni-conf.json xxxx"]
kube-proxy:
kubectl edit daemonset kube-proxy --namespace=kube-system # 查看kube-proxy的daemonset配置
kubectl edit deployment nginx-deployment # 查看资源配置及运行状态
8. prometheus node exporter: prometheus是流行的系统监控方案, node exporter是prometheus的agent, 以daemonset的形式运行在每个node上
docker方式:
docker run -d -v "/proc:/host/proc" -v "/sys:/host/sys" -v "/:/rootfs" --net=host prom/node-exporter --path.procfs /host/proc --path.sysfs /host/sys --collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"
pod方式: node_exporter.yaml
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: node-exporter-daemonset
sepc:
template:
metadata:
labels:
app: prometheus
spec:
hostNetwork: true
containers:
- name: node-exporter
image: prom/node-exporter
imagePullPolicy: IfNotPresent
command:
- /bin/node_exporter
- --path.procfs
- /host/proc
- --path.sysfs
- /host/sys
- --collector.filesystem.ignored-mount-points
- ^/(sys|proc|dev|host|etc)($|/)
volumeMounts:
- name: proc
mountPath: /host/proc
- name: sys
mountPath: /host/sys
- name: root
mountPath: /rootfs
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name:
hostPath:
path: /
(三)Job
服务类:http server, daemon等,一直运行,持续提供服务。Deployment/ReplicaSet/DaemonSet
工作类: 一次性任务: 批处理程序等,完成后容器就退出。Job
9. myjob.yaml
apiVersion: batch/v1beta1 # 资源版本号
kind: Job # 资源类型
metadata:
name: myjob
spec:
template:
metadata:
name: myjob
spec:
containers:
- name: hello
image: busybox
command: ["echo", "hello k8s job!"]
restartPolicy: Never # 重启策略, Job 只能 Never or OnFailure;其他controller还有Always
kubectl apply -f myjob.yaml
kubectl get job # 查看job状态
kubectl get pod
kubectl get pod --show-all # 已经退出的容器,使用--show-all才能查看,状态Completed
kubectl logs
10. Pod失败
myjob.yaml中command改为 ["invalid-command", "hello k8s job!"] 故意引入一个错误
kubectl delete -f myjob.yaml
kubectl apply -f myjob.yaml
kubectl get job # 可查看到当前successful的pod数量为0
kubectl get pod --show-all # 可查看到多个pod, 状态均不正常
kubectl describe pod
多个pod原因: 第一个pod启动时,容器失败退出。restartPolicy: Never此容器不会被重启,但Job Desired的Pod为1,目前successful 为0, 永远到不了1,Job controller只能一直创建新的pod。只有删除Job才能终止此行为。
kubectl delete -f myjob.yaml
restartPolicy: OnFailure # 修改为失败重启策略,容器失败后会重启
kubectl apply -f myjob.yaml
kubectl get job # successful 仍为0
kubectl get pod --show-all # 只有1个pod,restarts数量会一直增加
11. Job 并行
completions, parallelism默认值为1
同时运行多个Pod,提升Job执行效率
Job spec规格中添加parallelism配置:
parallelism: 2 # 2个Pod并行执行
kubectl apply -f myjob.yaml
kubectl get job # successful数量为2
kubectl get pod --show-all # pod数量为2, age相同
spec规格中添加completions配置:
completions: 6 # 设置Job成功完成Pod总数为6, 每次运行2个,直至6个pod成功完成。
12. 定时Job
kubernetes中的CronJob提供类似linux中的cron功能
开启方式:
(1) kubectl api-versions # 查找batch/v2alpha1
(2) vi /etc/kubernetes/manifests/kube-apiserver.yaml中spec -> containers ->command中添加:
--runtime-config=batch/v2alpha1=true
(3) systemctl restart kubelet.service # kubelet会重启kube-apiserver Pod
# cronjob.yaml
apiVersion: batch/v2alpha1 # cronjob版本号
kind: CronJob # 资源类型
metadata:
name: hello
spec:
schedule: "*/1 * * * *" # 每分钟启动1次
jobTemplate: # job模板
spec:
template:
spec:
containers:
- name: hello
image: busybox
command: ["echo", "hello k8s job!"]
restartPolicy: OnFailure
kubectl apply -f cronjob.yaml
kubectl get cronjob # 查看cronjob状态
kubectl get jobs # 查看job执行情况
kubectl get pod --show-all
kubectl logs