文章目录
一、优化命令行
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
二、kubernetes带来的变革
k8s与docker的关系:
docker是容器,k8s是一个容器化管理平台
1、对于开发人员
由于公司业务多,开发环境、测试环境、预生产环境和生产环境都是隔离的,而且除了生产环境,为了节省成本,其他环境可能是没有日志收集的,在没有用 k8s 的时候,查看线下测试的日志,需要开发或者测试人员,找到对应的机器,在找到对应的容器,然后才能查看日志,在用了 k8s 之后,开发和测试可以直接在 k8s 的dashboard 到对应的 namespace,即可定位到业务的容器,然后可以直接通过控制台查看到对应的日志,大大降低了操作时间。
目前我们使用 jenkins、gitrunner 进行发版或者回滚等,从开发环境到测试环境,到生产环境,完全遵守一次构建,多集群、多环境部署,通过不同的启动参数、不同的环境变量、不同的配置文件实现区分不同的环境。目前已经实现 Python、Java、PHP、NodeJS、Go、.NET Core、Python等多种语言的一键式发版、一键式回滚,大大提高了开发人员的开发效率。
1、对于开发人员的作用
# 在用了 k8s 之后,开发和测试可以直接在 k8s 的dashboard 到对应的 namespace,即可定位到业务的容器,然后可以直接通过控制台查看到对应的日志,大大降低了操作时间。
2、对于运维人员
如果你是一名运维人员,可能经常因为一些重复、繁琐的工作感觉厌倦。比如:这个需要一套新的测试环境,那个需要一套新的测试环境,之前可能需要装系统、装依赖环境、开通权限等等。而如今,可以直接用镜像直接部署一套新的测试环境,甚至全程无需自己干预,开发人员通过 jenkins 或者自动化运维平台即可一键式创建,大大降低了运维成本。
一开始,公司业务故障,可能是因为基础环境不一致、依赖不一致、端口冲突等等问题,现在实现 Docker镜像部署,k8s 编排,所有的依赖、基础都是一样的,并且环境的自动化扩容、健康检查、容灾、恢复都是全自动的,大大减少了因为这类基础问题引发的故障。也有可能公司业务是由于服务器宕机、网络等问题,造成服务不可用,此类情况均需要运维人员及时去修复,而如今,可能在你收到告警信息的时候,k8s 已经帮你恢复了。
在没有使用 k8s 时,业务应用的扩容和缩容,都需要人工去处理,从采购服务器、上架、到部署依赖环境,不仅需要大量的人力物力,而且非常容易在中间过程出现问题,又要花费大量的时间去查找问题。成功上架后,还需要在前端反代端添加或该服务器,而如今,可以利用 k8s 的弹性计算,一键式进行扩容和缩容,不仅大大提高了运维效率,而且还节省了不少的服务器资源,提高了资源利用率。
1、对于运维人员的作用
# 1、对于反代配置方面
比如可能你并不会,或者对 nginx 的配置规则并不熟悉,一些高级的功能你也不会实现,而如今,利用 k8s的ingress即可简单的实现那些复杂的逻辑。并且也不会在遇到 nginx 少加一个斜杠和多加一个斜杠的问题。
# 2、对于负载均衡方面
之前负载均衡可能是 Nginx、LVS、HAProxy、F5 等,云上可能是云服务商提供的不在均衡机制。每次添加删除节点时,都需要手动去配置前端负载均衡,手动去匹配后端节点,而如今,使用 k8s内部的 service 可以动态发现实现自动管理节点,并且支持自动扩容缩容。之前遇到高峰流量时,经常服务器性能不够,需要临时加服务器面对高峰流量,而如今对于高性能 k8s 集群加上 serverless,基本实现无需管理,自动扩容。
# 3、 对于高可用方面
k8s 天生的高可用功能,彻底释放了双手,无需再去创建各类高可用工具、检测检查脚本。k8s 支持进程接口级别的健康检查,如发现接口超时或者返回值不正确,会自动处理该问题。
# 4、对于中间件搭建方面
根据定义好的资源文件,可以实现秒级搭建各类中间件高可用集群,并且支持一键式扩缩容,如Redis、Zookeeper 等,并且大大减少了出错的概率。
# 5、对于应用端口方面
传统行业中,一个服务器可能跑了很多进程,每个进程都有一个端口,需要人为的去配置端口,并且还需要考虑端口冲突的问题,如果有防火墙的话,还需要配置防火墙,在 k8s 中,端口统一管理统一配置,每个应用的端口都可设置成一样的,之后通过 service 进行负载均衡,大大降低了端口管理的复杂度和端口冲突。
三、实战入门
# k8s掌握的五部件
# 1、Namespace 命名空间
# 2、Pod kubernetes集群进行管理的最小单元
# 3、Label 标签
# 4、控制器
deployment(部署长期运行、无状态应用)
DaemonSet(一般用来监控、收集日志)
# 5、Service 负载均衡
k8s中的名称空间(命名空间)
1、k8s中名称空间是用来隔离集群资源,而k8s中的资源也分为名称空间级资源以及集群级资源。
2、namespace是命名空间,用来做集群资源隔离的(业内默认的标准,一个微服务一个namespace)
# 1、k8s中的命名规范
1、必须小写
2、必须以字母开头
3、名称当中只能够包含字母、数字和中划线(-)
# 2、k8s集群中:
1、集群级资源:所有命名空间都能够使用
2、命名空间级资源:只能在同一个命名空间内使用
mysql 客户端 kubectl
mysqld 服务端 kubernetes
# kubectl是k8s客户端,它跟k8s没有任何关系。
# kubectl get [资源名称] 获取集群资源的命令
# 注:部署应用一般是部署在自己的名称空间之内
1、namespace
Namespace是kubernetes系统中的一种非常重要资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。
默认情况下,kubernetes集群中的所有的Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互相的访问,那此时就可以将两个Pod划分到不同的namespace下。kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的"组",以方便不同的组的资源进行隔离使用和管理。
可以通过kubernetes的授权机制,将不同的namespace交给不同租户进行管理,这样就实现了多租户的资源隔离。此时还能结合kubernetes的资源配额机制,限定不同租户能占用的资源,例如CPU使用量、内存使用量等等,来实现租户可用资源的管理。
kubernetes在集群启动之后,会默认创建几个namespace
[root@k8s-m-01 ~]# kubectl get namespace (缩写ns)
NAME STATUS AGE
default Active 45h # 所有未指定Namespace的对象都会被分配在default命名空间
kube-node-lease Active 45h # 集群节点之间的心跳维护,v1.13开始引入
kube-public Active 45h # 此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system Active 45h # 所有由Kubernetes系统创建的资源都处于这个命名空间
1、查看
# 1 查看所有的ns
命令:kubectl get ns
[root@k8s-m-01 ~]# kubectl get ns
NAME STATUS AGE
default Active 45h
kube-node-lease Active 45h
kube-public Active 45h
kube-system Active 45h
# 2 查看指定的ns
命令:kubectl get ns ns名称
[root@k8s-m-01 ~]# kubectl get ns default
NAME STATUS AGE
default Active 45h
[root@k8s-m-01 ~]# kubectl get ns -n default
NAME STATUS AGE
default Active 3d9h
kube-node-lease Active 3d9h
kube-public Active 3d9h
kube-system Active 3d9h
# 3 指定输出格式
命令:kubectl get ns ns名称 -o 格式参数
# kubernetes支持的格式有很多,比较常见的是wide、json、yaml
[root@k8s-m-01 ~]# kubectl get ns default -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2021-05-08T04:44:16Z"
name: default
resourceVersion: "151"
selfLink: /api/v1/namespaces/default
uid: 7405f73a-e486-43d4-9db6-145f1409f090
spec:
finalizers:
- kubernetes
status:
phase: Active
# 4 查看ns详情
命令:kubectl describe ns ns名称
[root@k8s-m-01 ~]# kubectl describe ns default
Name: default
Labels: <none>
Annotations: <none>
Status: Active # Active 命名空间正在使用中 Terminating 正在删除命名空间
# ResourceQuota 针对namespace做的资源限制
# LimitRange针对namespace中的每个组件做的资源限制
No resource quota.
No LimitRange resource.
2、创建
# 创建namespace
[root@k8s-m-01 ~]# kubectl create ns dev
namespace/dev created
3、 删除
# 删除namespace
[root@k8s-m-01 ~]# kubectl delete ns dev
namespace "dev" deleted
4、配置方式
首先准备一个yaml文件:ns-dev.yaml
[root@k8s-m-01 ~]# vim ns-dev.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
然后就可以执行对应的创建和删除命令了:
# 创建:kubectl create -f ns-dev.yaml
# 删除:kubectl delete -f ns-dev.yaml
2、Pod
1、k8s集群中部署的最小单元
2、Pod最主要的功能管理是将一个业务或者一个调用链的所有服务(容器)
3、包含多个容器(一组容器的集合)
4、一个Pod中容器共享网络命名空间,Pod是短暂的
Pod是在集群中运行部署应用或服务的最小单元,他是可以支持很多容器的。Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
比如:你运行一个操作系统发行版的软件仓库,一个nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块工作才能提供一个微服务,这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。这就是k8s中的Pod。
目前k8s中业务主要可以分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application);分别对应的小机器人控制器为Deployment、Job、DaemonSet 和 StatefulSet。
# Pod是k8s中最小部署单元,用来管理一个调用链的容器,它之中的主容器(pause)为整个调用链的容器提供基础网络,共享存储,监控业务容器的运行状态
kubernetes在集群启动之后,集群中的各个组件也都是以Pod方式运行的。可以通过下面命令查看:
[root@k8s-m-01 ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-978bbc4b6-rh2v6 1/1 Running 13 3d18h
coredns-978bbc4b6-sz8v2 1/1 Running 13 3d18h
etcd-k8s-m-01 1/1 Running 14 3d18h
kube-apiserver-k8s-m-01 1/1 Running 14 3d18h
kube-controller-manager-k8s-m-01 1/1 Running 16 3d18h
kube-flannel-ds-6l7w7 1/1 Running 14 3d18h
kube-flannel-ds-cqhqm 1/1 Running 13 3d18h
kube-flannel-ds-rtq5n 1/1 Running 12 3d18h
kube-proxy-2m7sg 1/1 Running 13 3d18h
kube-proxy-2v25n 1/1 Running 11 3d18h
kube-proxy-nc9j5 1/1 Running 12 3d18h
kube-scheduler-k8s-m-01 1/1 Running 15 3d18h
1、创建并运行
kubernetes没有提供单独运行Pod的命令,都是通过Pod控制器来实现的
# 命令格式: kubectl run (pod控制器名称) [参数]
# --image 指定Pod的镜像
# --port 指定端口
# --namespace 指定namespace
[root@k8s-m-01 ~]# kubectl create ns dev
namespace/dev created
[root@k8s-m-01 ~]# kubectl run nginx --image=nginx --port=80 --namespace dev
pod/nginx created
2、 查看pod信息
# 1、查看Pod基本信息
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 43s
# 2、查看Pod的详细信息
[root@k8s-m-01 ~]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 117s 10.244.2.9 k8s-n-02 <none> <none>
# 3、查看Pod的描述信息
[root@k8s-m-01 ~]# kubectl describe pod -n dev
Name: nginx
Namespace: dev
Priority: 0
Node: k8s-n-02/192.168.15.113
Start Time: Tue, 03 Aug 2021 08:50:05 +0800
Labels: run=nginx
Annotations: <none>
Status: Running
IP: 10.244.2.9
IPs:
IP: 10.244.2.9
Containers:
nginx:
Container ID: docker://1e04252e591895b3c195c957ea52d17946bcfc782c1cafa1259b903243d70f59
Image: nginx
Image ID: docker-pullable://nginx@sha256:8f335768880da6baf72b70c701002b45f4932acae8d574dedfddaf967fc3ac90
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 03 Aug 2021 08:50:26 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-rvwtl (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-rvwtl:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m4s default-scheduler Successfully assigned dev/nginx to k8s-n-02
Normal Pulling 4m2s kubelet Pulling image "nginx"
Normal Pulled 3m43s kubelet Successfully pulled image "nginx" in 18.954550282s
Normal Created 3m43s kubelet Created container nginx
3、 访问Pod
# 1、获取podIP
[root@k8s-m-01 ~]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 5m16s 10.244.2.9 k8s-n-02 <none> <none>
# 2、访问POD
[root@k8s-m-01 ~]# curl http://10.244.2.9:80 (默认是80端口)
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
4、删除指定Pod
# 1、删除指定Pod
[root@k8s-m-01 ~]# kubectl delete pod nginx -n dev
pod "nginx" deleted
# 此时,显示删除Pod成功,但是再查询,发现又新产生了一个
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 21s
# 这是因为当前Pod是由Pod控制器创建的,控制器会监控Pod状况,一旦发现Pod死亡,会立即重建
# 此时要想删除Pod,必须删除Pod控制器
# 2、先来查询一下当前namespace下的Pod控制器
[root@k8s-m-01 ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 9m7s
# 3、 接下来,删除此PodPod控制器
[root@k8s-m-01 ~]# kubectl delete deploy nginx -n dev
deployment.apps "nginx" deleted
# 4、 稍等片刻,再查询Pod,发现Pod被删除了
[root@k8s-m-01 ~]# kubectl get pods -n dev
No resources found in dev namespace.
# 5、删除namespace
[root@k8s-m-01 ~]# kubectl delete ns dev
namespace "dev" deleted
5、配置操作
创建一个pod-nginx.yaml,内容如下:
# 1、创建命名空间
[root@k8s-m-01 ~]# kubectl create ns dev
namespace/dev created
# 2、编写yaml文件
[root@k8s-m-01 ~]# vi pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
# 3、生成pod
[root@k8s-m-01 ~]# kubectl create -f pod-nginx.yam
pod/nginx created
# 4、查看
[root@k8s-m-01 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 38s
然后就可以执行对应的创建和删除命令了:
# 创建:kubectl create -f pod-nginx.yaml
# 删除:kubectl delete -f pod-nginx.yaml
3、Label标签
标签可以称之为资源的标示,一般用于发现资源
Label是kubernetes系统中的一个重要概念。
# 它的作用就是在资源上添加标识,用来对它们进行区分和选择。
1、Label的特点:
- 一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等等
- 一个资源对象可以定义任意数量的Label ,同一个Label也可以被添加到任意数量的资源对象上去
- Label通常在资源对象定义时确定,当然也可以在对象创建后动态添加或者删除
可以通过Label实现资源的多维度分组,以便灵活、方便地进行资源分配、调度、配置、部署等管理工作。
2、 一些常用的Label 示例如下
- 1、版本标签:“release” : “stable” , “release” : “canary”
- 2、环境标签:“environment” : “dev” , “environment” : “production”
- 3、架构标签:“tier” : “frontend” , “tier” : “backend” , “tier” : “middleware”
- 4、分区标签:“partition” : “customerA” , “partition” : “customerB”
- 5、质量管控标签:“track” : “daily” , “track” : “weekly”
标签定义完毕之后,还要考虑到标签的选择,这就要使用到Label Selector,即:
Label用于给某个资源对象定义标识
Label Selector用于查询和筛选拥有某些标签的资源对象
- 当前有两种Label Selector:
1、基于等式的Label Selector
2、基于集合的Label Selector
- 1、基于等式的Label Selector
name = slave: 选择所有包含Label中key="name"且value="slave"的对象
env != production: 选择所有包括Label中的key="env"且value不等于"production"的对象
- 2、基于集合的Label Selector
name in (master, slave): 选择所有包含Label中的key="name"且value="master"或"slave"的对象
name not in (frontend): 选择所有包含Label中的key="name"且value不等于"frontend"的对象
标签的选择条件可以使用多个,此时将多个Label Selector进行组合,使用逗号","进行分隔即可。例如:
name=slave,env!=production
name not in (frontend),env!=production
1、命令方式
# docker中的TAG = 仓库URL/名称空间/仓库名称:版本号
# k8s当做标签是用来管理(识别一系列)容器,方便与管理和监控拥有同一标签的所有容器 #标签是指pod,但是pod是管理容器的
# 1、为pod资源打标签
[root@k8s-m-01 ~]# kubectl label pod nginx-pod version=1.0 -n dev
pod/nginx-pod labeled
# 2、为pod资源更新标签
[root@k8s-m-01 ~]# kubectl label pod nginx-pod -n dev version-
pod/nginx-6799fc88d8-mdgbc labeled
[root@k8s-m-01 ~]# kubectl label pod nginx-pod version=2.0 -n dev --overwrite
pod/nginx-pod labeled
# 3、查看标签
[root@k8s-m-01 ~]# kubectl get pod nginx-pod -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-pod 1/1 Running 0 10m version=2.0
# 4、筛选标签
[root@k8s-m-01 ~]# kubectl get pod -n dev -l version=2.0 --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-pod 1/1 Running 0 17m version=2.0
[root@k8s-m-01 ~]# kubectl get pod -n dev -l version!=2.0 --show-labels
No resources found in dev namespace.
# 5、删除标签
[root@k8s-m-01 ~]# kubectl label pod nginx-pod version- -n dev
pod/nginx-pod labeled
# 6、版本
stable 稳定版本
beta 公测版本
alpha 内测版本
2、配置方式
# 1、编写yaml文件
[root@k8s-m-01 ~]# vi pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
# 2、然后就可以执行对应的更新命令了
[root@k8s-m-01 ~]# kubectl apply -f pod-nginx.yam
pod/nginx configured
# 3、查看标签
[root@k8s-m-01 ~]# kubectl get pod -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 1 39m env=test,version=3.0
4、控制器
k8s中控制器分为:deployment、DaemonSet、Statufluset
控制器的作用是用来管理Pod
# 1、Deployment:一般用来部署长期运行的、无状态的应用
特点:集群之中,随机部署(每一次请求都不依赖历史数据,也无数据持久化需求)
# 2、DaemonSet:每一个节点上部署一个Pod,删除节点自动删除对应的POD(zabbix-agent)
特点:每一台上有且只有一台
# 3、StatudfluSet: 部署有状态应用
特点:有启动顺序 (依赖历史数据,且具有数据持久化需求,扩容后续工作复杂)
# Deploymnet:
在Deployment对象中描述所需的状态,然后Deployment控制器将实际状态以受控的速率更改为所需的状态。
1、deployment(部署长期运行、无状态应用)
在kubernetes中,Pod是最小的控制单元,但是kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成的。Pod控制器用于pod的管理,确保pod资源符合预期的状态,当pod的资源出现故障时,会尝试进行重启或重建pod。
1、 命令操作
# 命令格式: kubectl create deployment 名称 [参数]
--image 指定pod的镜像
--port 指定端口
--replicas 指定创建pod数量
--namespace 指定namespace
# 1、创建deployment
[root@k8s-m-01 ~]# kubectl create deploy nginx --image=nginx:latest --port=80 --replicas=3 -n dev
deployment.apps/nginx created
# 2、查看创建的Pod
[root@k8s-m-01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx-585449566-jsjx4 1/1 Running 0 58s
nginx-585449566-mfhcr 1/1 Running 0 58s
nginx-585449566-w2rtm 1/1 Running 0 58s
# 3、查看deployment的信息
[root@k8s-m-01 ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 2m42s
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
[root@k8s-m-01 ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx 3/3 3 3 2m51s nginx nginx:latest run=nginx
# 4、查看deployment的详细信息
[root@k8s-m-01 ~]# kubectl describe deploy nginx -n dev
Name: nginx
Namespace: dev
CreationTimestamp: Wed, 08 May 2021 11:14:14 +0800
Labels: run=nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
# 5、查看标签
[root@k8s-m-01 ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-585449566-jsjx4 1/1 Running 0 6m39s app=nginx,pod-template-hash=585449566
nginx-585449566-mfhcr 1/1 Running 0 6m39s app=nginx,pod-template-hash=585449566
nginx-585449566-w2rtm 1/1 Running 0 6m39s app=nginx,pod-template-hash=585449566
# 6、删除
[root@k8s-m-01 ~]# kubectl delete deploy nginx -n dev
deployment.apps "nginx" deleted
2、配置操作
[root@k8s-m-01 ~]# vim deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
protocol: TCP
# 创建:kubectl create -f deploy-nginx.yaml
# 删除:kubectl delete -f deploy-nginx.yaml
3、deployment详解
1、主要功能是保证有足够的Pod正常对外提供服务
2、集群之中,随机部署
# 1、deployment:在deployment对象中描述所需状态,然后deployment控制器将实际状态以受控的速率更改为所需的状态(自愈)
一般用来部署长期运行的,无状态的应用(对启动顺序没有要求的(php nginx))
总结:主要功能是保证有足够的Pod正常对外提供服务
特点:集群之中,随机部署
# 2、创建deployment.yaml
[root@k8s-m-01 ~]# vim deployment.yaml
apiVersion: apps/v1 # kubectl explain deployment查看deployment版本号:apps/v1
kind: Deployment #类型
metadata: #元数据
name: deployment #deployment的名称
spec: #定义容器的详细信息
replicas: 1 #创建Pod的副本数(默认)
selector: #标签选择器:定义Deployment如何找到要管理的Pod,与template的label(标签)对应
matchLabels: #精确匹配
release: stable #对应Pod标签
template: #创建Pod的模板---------以下是Pod信息
metadata: #Pod元数据
name: test-tag #Pod名称(可不定义,随机生成)
labels: #标签
release: stable
spec: #定义容器详细信息
containers: #容器列表
- name: nginx
image: nginx
# 3、创建deployment
[root@k8s-m-01 ~]# kubectl apply -f deployment.yaml #创建deployment
deployment.apps/deployment created
[root@k8s-m-01 ~]# kubectl get deployment #查看deployment
NAME READY UP-TO-DATE AVAILABLE AGE
deployment 1/1 1 1 51s
# 4、查看pods
[root@k8s-m-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
deployment-7bf4d6cd75-nxsjg 1/1 Running 0 2m24s
test-tag 1/1 Running 0 41m
# 5、删除deployment
[root@k8s-m-01 ~]# kubectl delete pod deployment-7bf4d6cd75-nxsjg
# 6、重新查看pods
[root@k8s-m-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
deployment-7bf4d6cd75-cm2jn 1/1 Running 0 21s
test-tag 1/1 Running 0 42m
# 7、查看部署详情
[root@k8s-m-01 ~]# kubectl describe deployments.apps
Name: deployment
Namespace: default
CreationTimestamp: Sat, 24 Jul 2021 10:52:32 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: release=stable
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: release=stable
Containers:
nginx:
Image: nginx
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: deployment-7bf4d6cd75 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 75s deployment-controller Scaled up replica set deployment-7bf4d6cd75 to 1
4、弹性扩容的3种方法
# 1.修改配置清单
[root@k8s-m-01 ~]# kubectl edit deployments deployment #推荐
# deployments是资源类型 资源名称是deployment
spec:
progressDeadlineSeconds: 600
replicas: 10 # 修改这个参数
revisionHistoryLimit: 10
selector:
matchLabels:
release: stable
[root@k8s-m-01 ~]# kubectl get pods -w #监控pod状态(自动创建10个)
NAME READY STATUS RESTARTS AGE
deployment-7bf4d6cd75-cm2jn 1/1 Running 0 6m59s
test-tag 1/1 Running 0 48m
deployment-7bf4d6cd75-c25tl 0/1 Pending 0 0s
deployment-7bf4d6cd75-c25tl 0/1 Pending 0 0s
deployment-7bf4d6cd75-vvgff 0/1 Pending 0 0s
deployment-7bf4d6cd75-ghlvr 0/1 Pending 0 0s
deployment-7bf4d6cd75-j7zpk 0/1 Pending 0 0s
deployment-7bf4d6cd75-ck57d 0/1 Pending 0 0s
deployment-7bf4d6cd75-tk6sw 0/1 Pending 0 0s
deployment-7bf4d6cd75-8kljt 0/1 Pending 0 0s
deployment-7bf4d6cd75-vvgff 0/1 Pending 0 0s
deployment-7bf4d6cd75-ghlvr 0/1 Pending 0 0s
#2.命令行打标签
[root@k8s-m-01 ~]# kubectl patch deployments.apps deployment -p '{"spec":{"replicas":4}}' #自动缩容到4台-
# deployments.apps 资源全称
deployment.apps/deployment patched
[root@k8s-m-01 ~]# kubectl get pods -w #实时监控
NAME READY STATUS RESTARTS AGE
deployment-7bf4d6cd75-cm2jn 1/1 Running 0 11m
deployment-7bf4d6cd75-j7zpk 1/1 Running 0 4m21s
deployment-7bf4d6cd75-mrlj7 1/1 Running 0 4m21s
deployment-7bf4d6cd75-tk6sw 1/1 Running 0 4m21s
test-tag 1/1 Running 0 53m
[root@k8s-m-01 ~]# kubectl patch deployments.apps deployment -p '{"spec":{"replicas":40}}' #自动扩容到40台
deployment.apps/deployment patched
# 3.scale
[root@k8s-m-01 ~]# kubectl scale deployment/deployment --replicas=2
# 资源类型/资源名称
deployment.apps/deployment scaled
[root@k8s-m-01 ~]# kubectl get pods #查看pods
NAME READY STATUS RESTARTS AGE
deployment-7bf4d6cd75-cm2jn 1/1 Running 0 14m
deployment-7bf4d6cd75-j7zpk 1/1 Running 0 7m36s
test-tag 1/1 Running 0 56m
5、更新(首先要存在低版本才可以更新)
# 1.编辑django.yaml(基础版本)
[root@k8s-m-01 ~]# vi djiaogo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: django
spec:
replicas: 1
selector:
matchLabels:
app: stable
template:
metadata:
labels:
app: stable
spec:
containers:
- name: nginx1
image: nginx:1.17.10
#2.创建Pod
[root@k8s-m-01 ~]# kubectl apply -f django.yaml
deployment.apps/django created
# 1—监控中 (获取podid)
[root@k8s-m-01 ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
deployment-7bf4d6cd75-cm2jn 1/1 Running 0 18m
test-tag 1/1 Running 0 60m
django-54bb9d4cd6-m6pgm 0/1 Pending 0 0s
django-54bb9d4cd6-m6pgm 0/1 Pending 0 0s
django-54bb9d4cd6-m6pgm 0/1 ContainerCreating 0 0s
# 2-进入容器查看版本号
[root@k8s-m-01 ~]# kubectl exec -it django-54bb9d4cd6-m6pgm -- bash
root@django-54bb9d4cd6-m6pgm:/# nginx -v
nginx version: nginx/1.17.10
# 3.更新镜像
方式一:打标签
## 打标签
[root@k8s-m-01 ~]# kubectl patch deployments.apps django -p '{"spec":{"template":{"spec":{"containers":[{"image":"nginx:1.18.0", "name":"nginx"}]}}}}'
deployment.apps/django patched
# 验证
[root@k8s-m-01 ~]# kubectl exec -it django-6c5b55f69f-qnb6d -- bash
Defaulted container "nginx" out of: nginx, nginx1
root@django-6c5b55f69f-qnb6d:/# nginx -v
nginx version: nginx/1.18.0
方式二:修改配置清单
# 修改配置清单
[root@k8s-m-01 ~]# vim django.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: django
spec:
replicas: 1
selector:
matchLabels:
app: stable
template:
metadata:
labels:
app: stable
spec:
containers:
- name: nginx
image: nginx:1.19.9
##验证
[root@k8s-m-01 ~]# kubectl exec -it deployment-5849786498-6zpws -- bash
root@deployment-5849786498-6zpws:/# nginx -v
nginx version: nginx/1.19.9
方式三:
##设置镜像(重点)
[root@k8s-m-01 ~]# kubectl set image deployment/django nginx=nginx:1.16.0
##验证
[root@k8s-m-01 ~]# kubectl exec -it django-65b6bd487f-qtrv9 -- bash
Defaulted container "nginx" out of: nginx, nginx1
root@django-65b6bd487f-qtrv9:/# nginx -v
nginx version: nginx/1.16.0
方式四:
## edit
[root@k8s-m-01 ~]# kubectl edit deployment.apps django
template:
metadata:
creationTimestamp: null
labels:
app: stable
spec:
containers:
- image: nginx:1.19.0 #修改版本号
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
##验证
[root@k8s-m-01 ~]# kubectl exec -it django-65c9b58dfb-zwg6z -- bash
Defaulted container "nginx" out of: nginx, nginx1
root@django-65c9b58dfb-zwg6z:/# nginx -v
nginx version: nginx/1.19.0
3、回滚
# 1、查看资源历史
[root@k8s-m-01 ~]# kubectl rollout history deployment django
deployment.apps/django
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
4 <none>
5 <none>
6 <none>
7 <none>
# 2、回滚到上一级
[root@k8s-m-01 ~]# kubectl rollout undo deployment django
deployment.apps/django
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
4 <none>
5 <none>
8 <none>
9 <none>
注:目前是到第7级,回滚是回滚到6,回滚后7不显示,显示成6,6与7内容一样
# 3、回滚指定版本
[root@k8s-m-01 ~]# kubectl rollout undo deployment django --to-revision=1
deployment.apps/django rolled back
[root@k8s-m-01 ~]# kubectl rollout history deployment django
deployment.apps/django
REVISION CHANGE-CAUSE
2 <none>
3 <none>
4 <none>
5 <none>
8 <none>
9 <none>
10 <none>
# 注:回滚到1版本,1不展示,变成10
2、DaemonSet(一般用来监控、收集日志)
在集群中所有的节点上部署只部署一个Pod
# 在集群中所有的节点上部署只部署一个Pod,删除节点自动删除对应得Pod
# 特点:每台上有且只有一个
[root@k8s-m-01 ~]# vim zabbix-agent.yaml
apiVersion: apps/v1 #kubectl explain DaemonSet 查看版本号
kind: DaemonSet
metadata:
name: zabbix-agent
spec:
selector:
matchLabels:
app: zabbix-agent
template:
metadata:
labels:
app: zabbix-agent
spec:
containers:
- name: zabbix-agent
image: zabbix/zabbix-agent:5.2.6-centos
[root@k8s-m-01 ~]# kubectl apply -f zabbix-agent.yaml
# 更新
1、修改配置文件
[root@k8s-m-01 ~]# kubectl edit daemonsets.apps zabbix-agent
spec:
containers:
- image: zabbix/zabbix-agent:centos-5.2.5 #修改版本
daemonset.apps/zabbix-agent edited
2、打标签的方式
[root@k8s-m-01 ~]# kubectl patch daemonsets.apps zabbix-agent -p '{"spec":{"template":{"spec":{"containers":[{"image":"zabbix/zabbix-agent:centos-5.2.4", "name":"zabbix-agent"}]}}}}'
daemonset.apps/zabbix-agent patched
3、设置镜像
[root@k8s-m-01 ~]# kubectl set image daemonset/zabbix-agent zabbix-agent=zabbix/zabbix-agent:centos-5.2.3
daemonset.apps/zabbix-agent image updated
4、查看记录
[root@k8s-m-01 ~]# kubectl rollout history daemonset zabbix-agent
daemonset.apps/zabbix-agent
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
4 <none>
## 回滚到上一个版本
[root@k8s-m-01 ~]# kubectl rollout history daemonset zabbix-agent
daemonset.apps/zabbix-agent
REVISION CHANGE-CAUSE
1 <none>
2 <none>
4 <none>
5 <none>
## 回滚到指定版本
[root@k8s-m-01 ~]# kubectl rollout undo daemonset zabbix-agent --to-revision=1
daemonset.apps/zabbix-agent rolled back
3、扩展
# 1、k8s-m-01节点执行
[root@k8s-m-01 ~]# kubectl get nodes # master监控
NAME STATUS ROLES AGE VERSION
k8s-m-01 Ready control-plane,master 8d v1.21.2
k8s-n-01 Ready <none> 8d v1.21.2
k8s-n-02 Ready <none> 11s v1.21.2
[root@k8s-m-01 ~]# kubectl delete nodes k8s-n-02 #删除k8s-n-02节点
node "k8s-n-02" deleted
[root@k8s-m-01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m-01 Ready control-plane,master 8d v1.21.2
k8s-n-01 Ready <none> 8d v1.21.2
# 2、k8s-n-2节点执行
[root@k8s-n-02 ~]# kubeadm reset
[root@k8s-n-02 ~]# rm -rf /etc/kubernetes/
# 3、k8s-m-01节点生成token
[root@k8s-m-01 ~]# kubeadm token create --print-join-command
kubeadm join 192.168.15.111:6443 --token uqvjwm.lr9e35a0brzl1r9f --discovery-token-ca-cert-hash sha256:e9a22201e9fb0575a7281b42c53377c119880e0aca5217a7134fe474e5cd7422
# 4、k8s-n-02节点重新加入集群
[root@k8s-n-02 ~]# kubeadm join 192.168.15.111:6443 --token uqvjwm.lr9e35a0brzl1r9f --discovery-token-ca-cert-hash sha256:e9a22201e9fb0575a7281b42c53377c119880e0aca5217a7134fe474e5cd7422
# 5、重新查看master节点监控
[root@k8s-m-01 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-m-01 Ready control-plane,master 8d v1.21.2
k8s-n-01 Ready <none> 8d v1.21.2
k8s-n-02 Ready <none> 11s v1.21.2
5 、Service
虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题:
# 1、Pod IP 会随着Pod的重建产生变化
# 2、Pod IP 仅仅是集群内可见的虚拟IP,外部无法访问
这样对于访问这个服务带来了难度。因此,kubernetes设计了Service来解决这个问题。
Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡
1、 操作一:创建集群内部可访问的Service
# 1、暴露Service
[root@k8s-m-01 ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed
# 2、查看service
[root@k8s-m-01 ~]# kubectl get svc svc-nginx1 -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx1 ClusterIP 10.104.69.173 <none> 80/TCP 3m51s run=nginx
# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[root@k8s-m-01 ~]# curl 10.104.69.173:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body>
<h1>Welcome to nginx!</h1>
.......
</body>
</html>
2、操作二:创建集群外部也可访问的Service
# 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问
# 如果需要创建外部也可以访问的Service,需要修改type为NodePort
[root@k8s-m-01 ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
# 此时查看,会发现出现了NodePort类型的Service,而且有一对Port(80:31928/TC)
[root@k8s-m-01 ~]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx1 ClusterIP 10.104.69.173 <none> 80/TCP 7m27s
svc-nginx2 NodePort 10.104.249.148 <none> 80:30593/TCP 4s
# 接下来就可以通过集群外的主机访问 节点IP:31928访问服务了
# 例如在的电脑主机上通过浏览器访问下面的地址
http://192.168.15.111:30593/
3、 删除Service
# 1、删除service
[root@k8s-m-01 ~]# kubectl delete svc svc-nginx-1 -n dev
service "svc-nginx-1" deleted
# 2、删除namespace
[root@k8s-m-01 ~]# kubectl delete ns dev
namespace "dev" deleted
4、配置方式
创建一个svc-nginx.yaml,内容如下:
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
clusterIP: 10.109.179.231 #固定svc的内网ip
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: ClusterIP
# 创建:kubectl create -f svc-nginx.yaml
# 删除:kubectl delete -f svc-nginx.yaml
5、扩展(删除默认空间及yam已创建的文件)
# 1、查看默认空间的服务
[root@k8s-m-01 ~]# kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
django-54bb9d4cd6-nw4rn 1/1 Running 0 6s
nginx-6799fc88d8-mdgbc 1/1 Running 1 10h
zabbix-agent-bpnmj 1/1 Running 0 6m26s
zabbix-agent-p5lck 1/1 Running 0 23m
# 2、查看控制器
[root@k8s-m-01 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
django 1/1 1 1 35m
nginx 1/1 1 1 2d22h
[root@k[root@k8s-m-01 ~]# kubectl get daemonsets
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
# 3、删除服务所对应的控制器
[root@k8s-m-01 ~]# kubectl delete deployment nginx
deployment.apps "nginx" deleted
[root@k8s-m-01 ~]# kubectl delete deployment django
deployment.apps "django" deleted
[root@k8s-m-01 ~]# kubectl delete daemonsets.apps zabbix-agent
daemonset.apps "zabbix-agent" deleted
# 4、重新查看 (已删除)
[root@k8s-m-01 ~]# kubectl get pod
6、小结
至此,已经掌握了Namespace、Pod、Deployment、Service资源的基本操作,有了这些操作,就可以在kubernetes集群中实现一个服务的简单部署和访问了,但是如果想要更好的使用kubernetes,就需要深入学习这几种资源的细节和原理。