Kubernetes安装及学习笔记
环境准备:
节点 | IP地址 | 系统 | 配置 |
---|---|---|---|
master | 192.168.43.4 | centos7.9 | 2C2G 基础设施服务器或者最小化安装 |
node01 | 192.168.43.5 | centos7.9 | 2C2G 基础设施服务器或者最小化安装 |
node02 | 192.168.43.6 | centos7.9 | 2C2G 基础设施服务器或者最小化安装 |
必坑总结:
docker和kubelet、kubeadm、kubectl的版本需要指定,版本不匹配安装失败;
calico的版本必须和kubernetes版本一致,否则创建失败;
calico版本查询https://docs.tigera.io/archive
cgroup必须一致
1、设置主机名
[root@localhost ~]# hostnamectl set-hostname master01 [root@localhost ~]# hostnamectl set-hostname work01 [root@localhost ~]# hostnamectl set-hostname work02
2、设置hosts文件,原有的hosts文件不要删除
cat >> /etc/hosts << EOF
192.168.217.100 master01
192.168.217.101 work01
192.168.217.102 work02
EOF
3、安装依赖
cd /etc/yum.repos.d/ mkdir bak mv *.repo bak wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
安装依赖包
yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp yum install -y utils device-mapper persistent-data lvm2 yum-utils device-mapper-persistent-data yum install -y wget jg pamisc vim net-tools telnet
4、关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
5、关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0
6、关闭swap分区
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab swapoff -a
7、将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/kubernetes.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF
加载
modprobe br_netfilter
查看是否加载
sysctl --system
8、开启ipvs
cat > /etc/sysconfig/modules/ipvs.modules <<EOF #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF
授权
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
查看是否加载
lsmod | grep -e ipvs -e nf_conntrack_ipv4
9、设置limit参数
cat >> /etc/security/limits.conf <<EOF * soft nofile 655360 * hard nofile 131072 * soft nproc 655350 * hard nproc 655350 * soft memlock unlimited * hard memlock unlimited EOF
10、设置时间同步
yum install ntpdate -y
ntpdate time.windows.com
设置定时任务
crontab -e */5 * * * * ntpdate time.windows.com
11、设置时区
timedatectl
将时区设置为上海
timedatectl set-timezone 'Asia/Shanghai'
重新加载
systemctl restart chronyd.service
12、安装docker
设置镜像源
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
安装docker
yum -y install docker-ce-18.06.3.ce-3.el7
设置开启启动
systemctl enable docker && systemctl start docker
设置镜像加速器
sudo tee /etc/docker/daemon.json <<-'EOF' { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": ["https://j75wwuc0.mirror.aliyuncs.com"], "live-restore": true, "log-driver":"json-file", "log-opts": {"max-size":"500m", "max-file":"3"} } EOF
13、设置kubernetes镜像源
cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
14、安装kubelet、kubeadm、kubectl
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
设置cgroup,为了实现Docker使用的cgroup drvier和kubelet使用的cgroup drver一致,建议修改"/etc/sysconfig/kubelet"文件的内容:
vim /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS="--cgroup-driver=systemd" KUBE_PROXY_MODE="ipvs"
设置开机启动
systemctl enable kubelett
15、重启主机
reboot
16、初始化(主节点执行)
kubeadm init \ --apiserver-advertise-address=192.168.43.4 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.18.0 \ --service-cidr=10.96.0.0/12 \ --pod-network-cidr=10.244.0.0/16
按照提示执行命令(master节点)
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
17、加入node节点(两个node节点执行)
kubeadm join 192.168.43.4:6443 --token tolr60.4dh29vzk7vf6e8n6 \ --discovery-token-ca-cert-hash sha256:d2ee143bacaf8db0b9176a04c9a344eb0a16224d81b16f133c24f288a6fc1171
18、部署网络插件(master节点执行),这块一定要看版本,不同的kubernetes对应不同的calico版本
在安装calci之前,coredns的状态是不正常的
https://docs.tigera.io/archive/v3.14/getting-started/kubernetes/requirements
目前安装的版本只能安装3.14的版本,如果版本高则无法启动
curl https://docs.projectcalico.org/v3.14/manifests/calico.yaml -O
修改calico.yaml的这个地方
# - name: CALICO_IPV4POOL_CIDR # value: "192.168.0.0/16"
修改后为初始化时候定义的网络(--pod-network-cidr=10.244.0.0/16),修改时候删除#号后需要上下文对齐
- name: CALICO_IPV4POOL_CIDR value: "10.244.0.0/16"
创建pod
kubectl apply -f calico.yaml
19、查看各种状态
查看calcio的状态:
kubectl get pod -n kube-system
查看node状态
[root@master01 ~]# kubectl get node NAME STATUS ROLES AGE VERSION master01 Ready master 83m v1.18.0 work01 Ready <none> 80m v1.18.0 work02 Ready <none> 79m v1.18.0
查看组件的健康状况
[root@master01 ~]# kubectl get componentstatus NAME STATUS MESSAGE ERROR etcd-0 Healthy {"health":"true"} controller-manager Healthy ok scheduler Healthy ok
可以简写
[root@master01 ~]# kubectl get cs NAME STATUS MESSAGE ERROR etcd-0 Healthy {"health":"true"} controller-manager Healthy ok scheduler Healthy ok
20、kubectl命令补全
yum install -y bash-completion source /usr/share/bash-completion/bash_completion source <(kubectl completion bash) echo “source <(kubectl completion bash)” >> ~/.bashrc vim /root/.bashrc source /usr/share/bash-completion/bash_completion source <(kubectl completion bash)
21、创建一个pod,1.18版本后不支持run命令创建pod
kubectl run nginx-dep --image=nginx:1.14-alpine
查看创建的pod
[root@master01 ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-dep 1/1 Running 0 4m8s 10.244.205.194 work01 <none> <none> nginx-deploy 1/1 Running 0 6m36s 10.244.75.67 work02 <none> <none>
访问nginx
[root@master01 ~]# curl 10.244.205.194 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>
22、创建一个deployment
kubectl create deployment nginx-app2 --image=nginx:1.14
给deployment增加副本梳理
kubectl scale --replicas=3 deployment nginx-app2
23、创建一个service
kubectl expose pod nginx-deploy --name=nginx --port=8080 --target-port=80
查看创建的service
[root@master01 ~]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h6m nginx ClusterIP 10.102.102.181 <none> 8080/TCP 5s
通过service访问:
[root@master01 ~]# curl 10.102.102.181:8080 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; }
创建一个service关联deployment
kubectl expose deployment nginx-app2 --port=8082 --target-port=80
23、编辑服务
kubectl set image deployment nginx-app nginx=nginx:1.16
24、回滚升级的版本
kubectl rollout undo deployment nginx-app
25、将service改为集群外部访问,将ClusterIP改为NodePort
[root@master01 ~]# kubectl get service -owide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30h <none> nginx ClusterIP 10.102.102.181 <none> 8080/TCP 27h run=nginx-deploy nginx-app ClusterIP 10.98.50.94 <none> 8081/TCP 24h app=nginx-app nginx-app2 ClusterIP 10.99.44.169 <none> 8082/TCP 24h app=nginx-app2 [root@master01 ~]# kubectl edit service nginx-app service/nginx-app edited
改完后查看
[root@master01 ~]# kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 30h nginx ClusterIP 10.102.102.181 <none> 8080/TCP 27h nginx-app NodePort 10.98.50.94 <none> 8081:30666/TCP 24h nginx-app2 ClusterIP 10.99.44.169 <none> 8082/TCP 24h
从浏览器访问work节点
26、Kubernetes资源总结
工作负载性workload:Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob
服务发现及负载均衡类:Service、Ingress
配置与存储相关的资源:Volume、CSI、ConfigMap、secret
集群级别资源:NameSpace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding
元数据类型:HPA、PodTemper、LimitRange
大部分资源的配置清单: kubectl explain pods用这个命令查看个配置的说明
apiVersion: group/version (用命令kubectl api-versions查看)
kind:资源类别
metadata:元数据 name、namespace、labels
spec(Specification 规范规格):期望的状态disired status
status:当前状态current status
27、编写一个pod 的yam
apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 - name: busybox image: busybox:latest command: - "/bin/sh" - "-c" - "echo $(date) >> /usr/share/nginx/html/index.html; sleep 5"
通过yaml创建pod
kubectl apply -f pod.yaml
28、查看pod的标签
[root@master01 moneyfast]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-app-58dfddb994-bdxd5 1/1 Running 2 36h app=nginx-app,pod-template-hash=58dfddb994 nginx-app-58dfddb994-j9mm9 1/1 Running 2 36h app=nginx-app,pod-template-hash=58dfddb994 nginx-app2-55bbbcdb99-ll54m 1/1 Running 3 2d13h app=nginx-app2,pod-template-hash=55bbbcdb99 nginx-app2-55bbbcdb99-mx8dq 1/1 Running 3 2d13h app=nginx-app2,pod-template-hash=55bbbcdb99 nginx-app2-55bbbcdb99-vkjfq 1/1 Running 3 2d13h app=nginx-app2,pod-template-hash=55bbbcdb99 nginx-deploy 1/1 Running 4 2d16h run=nginx-deploy nginx-yy 1/1 Running 3 2d13h run=nginx-yy pod-demo 1/2 CrashLoopBackOff 109 22h app=myapp,tier=frontend
29、给pod打标签
[root@master01 moneyfast]# kubectl label pods pod-demo release=canary pod/pod-demo labeled [root@master01 moneyfast]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-app-58dfddb994-bdxd5 1/1 Running 2 36h app=nginx-app,pod-template-hash=58dfddb994 nginx-app-58dfddb994-j9mm9 1/1 Running 2 36h app=nginx-app,pod-template-hash=58dfddb994 nginx-app2-55bbbcdb99-ll54m 1/1 Running 3 2d13h app=nginx-app2,pod-template-hash=55bbbcdb99 nginx-app2-55bbbcdb99-mx8dq 1/1 Running 3 2d13h app=nginx-app2,pod-template-hash=55bbbcdb99 nginx-app2-55bbbcdb99-vkjfq 1/1 Running 3 2d13h app=nginx-app2,pod-template-hash=55bbbcdb99 nginx-deploy 1/1 Running 4 2d16h run=nginx-deploy nginx-yy 1/1 Running 3 2d14h run=nginx-yy pod-demo 1/2 CrashLoopBackOff 110 22h app=myapp,release=canary,tier=frontend
选择有release标签的pod
[root@master01 moneyfast]# kubectl get pod -l release NAME READY STATUS RESTARTS AGE pod-demo 1/2 CrashLoopBackOff 111 22h
选择标签,使用等值判断
[root@master01 moneyfast]# kubectl get pod -l release!=canary NAME READY STATUS RESTARTS AGE nginx-app-58dfddb994-bdxd5 1/1 Running 2 37h nginx-app-58dfddb994-j9mm9 1/1 Running 2 37h nginx-app2-55bbbcdb99-ll54m 1/1 Running 3 2d13h nginx-app2-55bbbcdb99-mx8dq 1/1 Running 3 2d13h nginx-app2-55bbbcdb99-vkjfq 1/1 Running 3 2d13h nginx-deploy 1/1 Running 4 2d16h nginx-yy 1/1 Running 3 2d14h
使用判断语句
[root@master01 moneyfast]# kubectl get pod -l "release in (canary,beat)" NAME READY STATUS RESTARTS AGE pod-demo 1/2 CrashLoopBackOff 112 22h
使用notin
[root@master01 moneyfast]# kubectl get pod -l "release notin (canary,beat)" NAME READY STATUS RESTARTS AGE nginx-app-58dfddb994-bdxd5 1/1 Running 2 37h nginx-app-58dfddb994-j9mm9 1/1 Running 2 37h nginx-app2-55bbbcdb99-ll54m 1/1 Running 3 2d13h nginx-app2-55bbbcdb99-mx8dq 1/1 Running 3 2d13h nginx-app2-55bbbcdb99-vkjfq 1/1 Running 3 2d13h nginx-deploy 1/1 Running 4 2d16h nginx-yy 1/1 Running 3 2d14h
30、给node打标签
[root@master01 moneyfast]# kubectl label nodes master01 disktype=ssd
node/master01 labeled
给node删除标签
[root@master01 moneyfast]# kubectl label nodes master01 disktype-
node/master01 labeled
31、nodeSelector节点标签选择器
apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 - name: busybox imagePullPolicy: IfNotPresent image: busybox:latest command: - "/bin/sh" - "-c" - "sleep 50" nodeSelector: #节点标签选择器 disktype: ssd #选择磁盘标签为ssd的node
32、Pod状态
状态: Pengding,Running,Failed,Succeeded,Unknown
Pod生命周期的重要行为:
容器初始化;
容器探测:
liveness;
readiness;
33、Pod的重启策略
Always默认,Onfailure停止状态,每次重启都会有时间的延迟,最大300s,Never不重启,
34、Pod的探针
查看Pod的探针
[root@master01 ~]# kubectl explain pod.spec.containers livenessProbe <Object> Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes readinessProbe <Object> Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
kubectl explain pod.spec.containers.livenessProbe.exec
exec,执行命令探测
apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1 - name: busybox imagePullPolicy: IfNotPresent image: busybox:latest command: - "/bin/sh" - "-c" - "sleep 50" nodeSelector: disktype: ssd
httpGet探测
kubectl explain pod.spec.containers.livenessProbe.httpGet
apiVersion: v1 kind: Pod metadata: name: liveness-httpget-pod namespace: default spec: containers: - name: liveness-httpget-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 livenessProbe: httpGet: port: http path: /index.html initialDelaySeconds: 1 periodSeconds: 3
readness探测
apiVersion: v1 kind: Pod metadata: name: readiness-httpget-pod namespace: default spec: containers: - name: readiness-httpget-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 readinessProbe: httpGet: port: http path: /index.html initialDelaySeconds: 1 periodSeconds: 3
两者的区别
Liveness 指针是存活指针,它用来判断容器是否存活、判断 pod 是否 running。如果 Liveness 指针判断容器不健康,此时会通过 kubelet 杀掉相应的 pod,并根据重启策略来判断是否重启这个容器。如果默认不配置 Liveness 指针,则默认情况下认为它这个探测默认返回是成功的。
Readiness 指针用来判断这个容器是否启动完成,即 pod 的 condition 是否 ready。如果探测的一个结果是不成功,那么此时它会从 pod 上 Endpoint 上移除,也就是说从接入层上面会把前一个 pod 进行摘除,直到下一次判断成功,这个 pod 才会再次挂到相应的 endpoint 之上。
对于检测失败上面来讲 Liveness 指针是直接杀掉这个 pod,而 Readiness 指针是切掉 endpoint 到这个 pod 之间的关联关系,也就是说它把这个流量从这个 pod 上面进行切掉。
35、pod参数回顾
apiVersion,kind,metadata,spec,status(只读)
spec:
containers,nodeSelector,nodeName,restartPolicy:Always,Never,onFailure
containers:name,image,imagePullPolicy:Always、Never、IfNotPresent
ports:name,containerPort:livenessPorbe,readnessProbe
探测方法:ExecAction(exec)、TCPSocketAction(tcpSocket)、HTTPGetAction(httpGet)
36、Pod控制器
ReplocationController:
ReplicaSet:
Deployment:
DaemonSet::每个node上启动一个pod
Job: 一次性运行
Cronjob:周期性运行
StatefulSet: 有状态服务
37、replicaSet
ReplicaSet: 代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。
ReplicaSet主要三个组件组成:
- 用户期望的pod副本数量
- 标签选择器,判断哪个pod归自己管理
- 当现存的pod数量不足,会根据pod资源模板进行新建
帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。
ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet, 除非你需要自定义更新业务流程或根本不需要更新。
这实际上意味着,你可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义你的应用
apiVersion: apps/v1 kind: ReplicaSet metadata: name: mysapp namespace: default spec: replicas: 2 selector: matchLabels: #匹配pod app: myapp release: canary #pod的labels是canary才会被接管 template: metadata: name: myapp-pod labels: app: myapp release: canary environment: qa spec: containers: - name: myapp-container image: ikubernetes/app:v1 ports: - name: http containerPort: 80
创建replicSet
kubectl create -f rsdame.yaml
38、Deployment,deployment创建的时候同步创建replicaset,
Deployment是建构在rs之上的,可以控制多个rs滚动式自定义,自控制的更新;同时在实现自动更新时还能实现控制更新节奏和更新逻辑
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 2 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80
创建deployment:
kubectl create -f deploy.yaml
通过patch的方式更改配置
kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'
更新deployment的镜像
[root@master01 deploytest]# kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v3 deployment.apps/myapp-deploy image updated
39、Replicaset和Deployment的区别
replicaset:
核心作用在于帮助用户创建指定数量的pod副本,并确保pod副本一直处于满足用户期望的数量,起到多退少补的作用,并且还具有自动扩容缩容等机制;
他有三部分组成:
- 用户期望的pod副本数:用来定义由这个控制器管控的pod副本有几个
- 标签选择器:当pod挂掉的时候,replicaset就通过标签选择器,选择指定标签的pod模板,再通过pod模板创建pod。
- pod资源模板:定义一个Pod模板,且需要给pod模板设置标签。给标签选择器使用
deployment:
1、ReplicaSet并不是我们直接使用的控制器,kubernetes建议我们使用Deployment
2、Deployment控制器是工作在ReplicaSet之上的,Deployment通过控制ReplicaSet来控制pod,并不是直接控制pod。
3、Deployment有ReplicaSet的所有功能
4、Deployment支持自动扩容缩容,滚动更新和回滚等机制,并提供了一个声明式的定义功能,这种声明式定义使得我们将来创建资源时可以基于声明的逻辑来定义,我们那些所有定义的资源可以随时重新进行声明,随时改变我们在apiserver上的定义的目标期望状态,只要那些资源支持动态运行时修改,都能修改是帮我们管理无状态的应用的最好的控制器;
5、Deployment是帮我们管理无状态的应用的最好的控制器
6、pod副本数量可以大于节点数量的,那么可能一个节点上就会运行多个pod副本,它们之间没有精确的对应关系
40、几种新版本的发布方式
蓝绿部署:
是指同时运行两个版本的应用,如上图所示,蓝绿部署的时候,并不停止掉老版本,而是直接部署一套新版本,等新版本运行起来后,再将流量切换到新版本上。但是蓝绿部署要求在升级过程中,同时运行两套程序,对硬件的要求就是日常所需的二倍,比如日常运行时,需要5台服务器支撑业务,那么使用蓝绿部署,你就需要购置10台服务器。
滚动升级:
所谓滚动升级,就是在升级过程中,并不一下子启动所有新版本,是先启动一台新版本,再停止一台老版本,然后再启动一台新版本,再停止一台老版本,直到升级完成,这样的话,如果日常需要10台服务器,那么升级过程中也就只需要11台就行了。但是滚动升级有一个问题,在开始滚动升级后,流量会直接流向已经启动起来的新版本,但是这个时候,新版本是不一定可用的,比如需要进一步的测试才能确认。那么在滚动升级期间,整个系统就处于非常不稳定的状态,如果发现了问题,也比较难以确定是新版本还是老版本造成的问题。为了解决这个问题,我们需要为滚动升级实现流量控制能力。
金丝雀发布:
先启动一个新版本应用,但是并不直接将流量切过来,而是测试人员对新版本进行线上测试,启动的这个新版本应用,就是我们的金丝雀。如果没有问题,那么可以将少量的用户流量导入到新版本上,然后再对新版本做运行状态观察,收集各种运行时数据,如果此时对新旧版本做各种数据对比,就是所谓的A/B测试。
当确认新版本运行良好后,再逐步将更多的流量导入到新版本上,在此期间,还可以不断地调整新旧两个版本的运行的服务器副本数量,以使得新版本能够承受越来越大的流量压力。直到将100%的流量都切换到新版本上,最后关闭剩下的老版本服务,完成灰度发布。如果在灰度发布过程中(灰度期)发现了新版本有问题,就应该立即将流量切回老版本上,这样,就会将负面影响控制在最小范围内。
deployment升级过程中使用金丝雀发布的方式:
kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v2 && kubectl rollout pause deployment myqpp-deploy
执行命令后我们观察pod的变化,
[root@master01 ~]# kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-559ff5c66-4948n 1/1 Running 0 5m11s myapp-deploy-559ff5c66-7mjmz 1/1 Running 0 4m59s myapp-deploy-559ff5c66-d6l77 1/1 Running 0 4m52s myapp-deploy-559ff5c66-g9wnf 1/1 Running 0 4m57s myapp-deploy-559ff5c66-hgm7c 1/1 Running 0 5m9s myapp-deploy-559ff5c66-k7f96 1/1 Running 0 5m11s myapp-deploy-6b9865d969-jpclq 1/1 Running 1 12h
也可以用其他命令监视:
[root@master01 ~]# kubectl rollout status deployment myapp-deploy Waiting for deployment "myapp-deploy" rollout to finish: 1 old replicas are pending termination...
如果更新没有问题,则更新剩下的:
[root@master01 ~]# kubectl rollout resume deployment myapp-deploy
deployment.apps/myapp-deploy resumed
41、deployment的回滚
查看其所有的版本:
[root@master01 ~]# kubectl rollout history deployment myapp-deploy deployment.apps/myapp-deploy REVISION CHANGE-CAUSE 1 <none> 4 <none> 5 <none>
回滚到版本1
[root@master01 ~]# kubectl rollout undo deployment myapp-deploy --to-revision=1 deployment.apps/myapp-deploy rolled back