Kubernetes快速入门

kubectl使用基础与示例

Kubernetes API 是管理其各种资源对象的唯一入口,它提供了一个 RESTful 风格的 CRUD (Create 、 Read 、 Update 和 Delete)接口用于查询和修改集群状态,并将结果存储于集群状态存储系统 etcd 中 。 事实上,API server 也是用于更新 etcd 中资源对象状态的唯一途径, Kubernetes 的其他所有组件和客户端都要通过它来完成查询或修改操作,如下图所示,它们都算得上是 API server 的客户端。

任何 RESTful 风格 API 中的核心概念都是“资源”( resource ),它是具有类型、API Server 通过认证( Authentication )、 授权( Authorization )和准入控制( Admission Control )等来管理对资源的访问请求,因此,来自于任何客户端(如 kubectl、kubelet、kube-proxy 等)的访问请求都必须事先完成认证之后方可进行后面的其他操作。 API Server 支持多种认证方式,客户端可以使用命令行选项或专用的配置文件(称为 kube-config )提供认证信息。 相关的内容将在后面的章节中给予详细说明。
kubectl 的核心功能在于通过 API Server 操作 Kubernetes 的各种资源对象,它支持三种 操作方式,其中直接命令式( Imperative commands )的使用最为简便,是了解 Kubernetes 集 群管理的一种有效途径。

控制平面系统组件介绍

1.apiserver
apiserver默认监听在主机的6443端口,6443是https协议(早期的apiserver提供两个端口,一个http的8080和https的6443,考虑到8080 http协议不安全所以给去掉了),apiserver的6443是唯一接入master的端口,apiserver默认情况下它要做用户认证(双向认证),如果认证不通过的,则没有权限在kubernetes之上做任何操作。

2.scheduler
如果我们要创建一个Pod,就要被scheduler所调度到它评估后的Node上进行创建。

3.Controller-manager
运行中的Pod,如果有需要扩容缩容等其它操作,都依靠自Controller控制器,Controller还能进行Pod的故障自愈。

kubernetes集群重要组件

Pod:用来运行容器的Pod。
Pod Controller:Pod控制器,包含多种ReplicationControllerReplicaSetDeploymentStatefulSetJob等。
Service:用来代理Pod的中间层。

数据平面核心工作

数据平面即为Node,在Node上最核心的两件事情如下:

  1. 运行Pod
  2. 把Pod相关的Service转换为当前节点上的iptables或则ipvs(由kube-proxy组件来完成,kube-proxy也是控制平面apiserver的客户端,kube-proxy也是始终监视watch着apiserver的资源变动(尤其是service的变动,它会把每一个service上每一个跟当前Pod有关的资源变动转换为iptables或则ipvs规则))。

Pod的创建方式:

  1. 直接创建Pod(自己负责Pod的健康状态)。
  2. 通过Pod Controller创建,Pod Controller将负责Pod的健康状态监测及故障自愈。

Kubectl常用管理命令

kubectl –help 查看帮助信息

类型 命令 描述
基础命令 create 通过文件名或标准输入创建资源
基础命令 expose 将一个资源公开为一个新的Service
基础命令 run 在集群中运行一个特定的镜像
基础命令 set 在集群中运行一个特定的镜像
基础命令 get 显示一个或多个资源
基础命令 explain 文档参考资料
基础命令 edit 使用默认的编辑器编辑一个资源
基础命令 delete 通过文件名、标准输入、资源名称或标签选择器来删除资源
类型 命令 描述
部署命令 rollout 管理资源的发布
部署命令 rolling-update 对给定的复制控制器滚动更新
部署命令 scale 扩容或缩容Pod数量,Deployment、ReplicaSet、RC或Job
部署命令 autoscale 创建一个自动选择扩容或缩容并设置Pod数量
类型 命令 描述
集群管理命令 certificate 修改证书资源
集群管理命令 cluster-info 显示集群信息
集群管理命令 top 显示资源(CPU/Memory/Storage)使用。需要Heapster运行
集群管理命令 cordon 标记节点不可调度
集群管理命令 uncordon 标记节点可调度
集群管理命令 drain 驱逐节点上的应用,准备下线维护
集群管理命令 taint 修改节点taint标记
类型 命令 描述
故障诊断和调试命令 describe 显示特定资源或资源组的详细信息
故障诊断和调试命令 logs 在一个Pod中打印一个容器日志。如果Pod只有一个容器,容器名称是可选的
故障诊断和调试命令 attach 附加到一个运行的容器
故障诊断和调试命令 exec 执行命令到容器
故障诊断和调试命令 port-forward 转发一个或多个本地端口到一个pod
故障诊断和调试命令 proxy 运行一个proxy到Kubernetes API server
故障诊断和调试命令 cp 拷贝文件或目录到容器中
故障诊断和调试命令 auth 检查授权
类型 命令 描述
高级命令 apply 通过文件名或标准输入对资源应用配置
高级命令 patch 使用补丁修改、更新资源的字段
高级命令 replace 通过文件名或标准输入替换一个资源
高级命令 convert 不同的API版本之间转换配置文件
类型 命令 描述
设置命令 label 更新资源上的标签
设置命令 annotate 更新资源上的注释
设置命令 completion 用于实现kubectl工具自动补全
类型 命令 描述
其它命令 api-versions 打印受支持的API版本
其它命令 config 修改kubeconfig文件(用于访问API,比如配置认证信息)
其它命令 help 所有命令帮助
其它命令 plugin 运行一个命令行插件
其它命令 version 打印客户端和服务版本信息

查看Kubernetes集群所支持的资源类型

此命令列出的内容都为kubernetes的资源类型,我们通过kubectl get [资源类型],这种方式都可以看到相应的资源类型信息

kubectl api-resources

获取集群状态相关信息

1.获取集群节点状态信息

kubectl get nodes

2.获取k8s集群组件版本信息

kubectl version --short=true
kubelet --version
kubeadm version

3.获取k8s集群服务接口

kubectl cluster-info

kubectl get 常用的输出格式

我们默认使用kubectl get [资源对象] 只能看到极少的信息,kubernetes提供了 -o 选项来支持我们自定义输出格式,选项如下

输出格式 格式说明
-o wide 以长格式显示资源对象信息
-o name 仅打印资源的名称
-o yaml YAML 格式化输出 API 对象信息
-o json JSON 格式化输出 API 对象信息
-o go-template 以自定义的 go 模板格式化输出 AP!对象信息
-o custom-columns 自定义要输出的字段

kubernetes名称空间管理

在kubernetes上,资源有两个级别,node就是集群级别,pod是名称空间级别的资源;整个集群又划分为多个名称空间,所以在此使用kubectl get namespaces来获取名称空间,kubenetes安装完默认有三个名称空间:
kube-system名称空间:系统级别的Pod都运行在此名称空间中
default默认名称空间:假如说你创建了一个Pod没有指定名称空间,默认在default名称空间当中
kube-public公共名称空间:公开的名称空间,任何人都可以访问

1.查询所有名称空间

kubectl get ns              #简写
kubectl get namespaces      #全写

2.显示指定名称空间

#简写显示的两种方法
kubectl get ns kube-system
kubectl get ns/kube-system

#全写显示的两种方法
kubectl get namespaces kube-system
kubectl get namespaces/kube-system

3.指定输出格式显示名称空间

#查看所有的名称空间并指定格式输出
kubectl get ns -o [yaml|json|wide|name]

#查看指定名称空间并指定格式输出
kubectl get ns/kube-system -o [yaml|json|wide|name]

4.创建名称空间
默认创建 namespace 后,namespace 中是空的,namespace是资源逻辑组合,我们在创建其它资源对象的时候可以指定到我们创建的名称空间中。

kubectl create ns production            #简写
kubectl create namespace production     #全写

5.删除名称空间
删除名称为production的名称空间(如果此名称空间下有其它资源对象,例如Pod将会被一并删除)

#一次删除一个名称空间
##简写
kubectl delete ns production
##全写
kubectl delete namespace production

#一次删除多个名称空间
##简写
kubectl delete ns/test ns/production
kubectl delete ns test production
##全写
kubectl delete namespace test production
kubectl delete namespace/test namespace/production

deployments控制器管理

我们创建Pod的时候一般不直接创建Pod,而是通过deployments控制器去创建Pod,先创建deployments控制器,然后deployments去自动去创建Pod。
控制器也属于资源对象,同时属于在名称空间级别下的资源,我们创建的控制器也要在一个名称空间当中

1.查看默认名称空间下的deploymentk控制器

kubectl get deploy          #简写
kubectl get deployment      #全写

2.查看指定名称空间下的所有deployment控制器
我们查看指定名称空间下的控制器需要使用 -n [namespace] 选项来指定名称空间

kubectl get deploy -n production            #简写
kubectl get deployment -n production        #全写

3.指定格式查看deployment控制器

#指定格式查看default名称空间下的deploy控制器
kubectl get deploy -o [yaml|json|wide|name]

#指定格式查看指定名称空间下的deploy控制器
kubectl get deploy -n production -o [yaml|json|wide|name]

4.创建deployment控制器
下面创建deployment控制器没有指定名称空间(默认在default名称空间中)

#创建一个名称为nginx-deploy的控制器,--image指定容器运行的镜像
kubectl create deployment nginx-deploy --image=nginx:1.14-alpine

5.查看创建的deployment
这里我们查看为 -n default 指定名称空间下的 deploy/nginx-deploy 指定deploy控制器

kubectl get deploy/nginx-deploy -n default -o wide

6.查看被nginx-deploy控制器自动创建的pod

kubectl get pods -n default -o wide | grep nginx-deploy

7.销毁或删除pod
通过deployment创建的pod会被master节点的Controller组件所管理,如果我们对pod进行了删除,销毁等操作,Controller组件会立刻重建相应的pod,使其与我们期望的pod数量一致。

#删除pod, pods为资源对象 nginx-deploy-788b9c6b69-n54m7 为pod名称
kubectl delete pods/nginx-deploy-788b9c6b69-n54m7 -n default

#删除pod后,我们再次查看此pod,会发现此pod已经被Controller组件重建(可以注意下pods运行时间)
kubectl get pods -n default -o wide | grep nginx-deploy

8.访问pod
Pod删除之后deployments控制器会再次快速生成一个一样Pod,虽然说我们执行命令进行了删除,但是控制器还会再次生成,生成后的Pod,改变了Pod名称,IP等等,但是镜像还是不变,我们无法再通过上个Pod地址访问到Pod。
我们使用 kubectl get pods -n default -o wide | grep nginx-deploy 命令可以获取到刚才创建pods的IP地址,在宿主机可直接访问。

curl http://10.244.3.10

9.删除deployments控制器
删除deployment控制器后,Pod也会被随之删除,不会再进行恢复

kubectl delete deploy -n default nginx-deploy

10.显示同一个名称空间下的多个资源对象
上面我们创建了nginx-deploy控制器,然后控制器自动创建了pod,都同隶属于default名称空间下,那么我们如何显示同一名称空间下的控制器和pod呢?

#显示多个资源对象中间使用逗号分隔即可
kubectl get pods,deploy -n default -o wide

Pod管理

上面我们使用deployment控制器创建了pod,下面介绍如果简单的操作pod中的容器
1.显示Pod的详细信息
通过 kubectl describe [资源对象] 命令可以展示资源的详情,包括运行状态、事件等信息。

kubectl describe pods/nginx-deploy-788b9c6b69-tfcrx -n default

2.显示Pod中容器日志
查看 Pod 对象中容器输出在控制台的日志信息。如果在Pod中运行有多个容器时,需要使用选项“-c”指定容器名。
需要注意的是,日志查看命令仅能用于打印存在于 Kubernetes 系统上的 Pod 中容器的日志,对于已经删除的 Pod 对象,其容器日志信息将无从获取。

#查看pod中单个容器日志
kubectl logs nginx-deploy-788b9c6b69-tfcrx -n default

#查看pod中指定容器日志
kubectl logs nginx-deploy-788b9c6b69-tfcrx -c nginx -n default

3.不进入容器执行命令
通过kubectl exec命令指定pod,-c指定容器名称,-n指定名称空间,-- 指定执行的命令来进行操作容器

kubectl exec nginx-deploy-788b9c6b69-tfcrx -c nginx -n default -- ps aux

4.进入容器
还是通过kubectl exec命令指定相应的参数,然后通过 -i -t 来分配一个伪终端和交互式接口,指定 /bin/sh 命令进入容器

kubectl exec nginx-deploy-788b9c6b69-tfcrx -c nginx -n default -i -t -- /bin/sh

Service管理

Service作为Pod的代理,将访问Service的请求转发给Pod,这里我们还需要再依赖与deployments控制器,然后将Service映射到deployments控制器上,才能对Pod进行代理转发(这一功能集于kube-proxy组件实现,kube-proxy组件一直监听apiserver的资源变动,特别是service资源变动,当kube-proxy监听到有关本机的变动,则对应生成iptables或则ipvs规则进行转发)

1.创建Service
创建service以下演示两种方式

#通过端口暴漏
##kubectl expose:通过端口暴漏方式
##deployment/nginx-deploy -n default:指定在控制器名称以及控制器所在的名称空间
##--type:指定端口暴漏的方式,可选 [clusterip|nodeport|loadbalancer|externalname],四种为不同的暴漏方式(以后章节中会讲解,这里选择 clusterip 方式),表示为service生成一个集群IP
##--port:指定暴漏的端口
##--name:定义service的名称
kubectl expose deployment/nginx-deploy -n default --type=ClusterIP --port=80 --name=nginx-svc

#通过控制器映射
##kubectl create service:创建一个service
##clusterip:采用clusterip方式,与暴漏端口方式的 --type 一致
##nginx-deploy:指定service名称(此名称要与要代理的pod控制器一致)
##--tcp:指定映射的端口,第一个80为clusterip的端口,第二个80为pod要开放的端口
kubectl create service clusterip nginx-deploy --tcp=80:80

2.查看创建的Service
如下可以看到我们创建的两个service,并且都采用clusterip方式,各自分配了一个service集群IP

kubectl get service -n default -o wide
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE   SELECTOR
nginx-deploy   ClusterIP   10.105.98.155   <none>        80/TCP    66s   app=nginx-deploy
nginx-svc      ClusterIP   10.96.62.172    <none>        80/TCP    15m   app=nginx-deploy

3.查看Service的详细信息

kubectl describe service -n default
Name:              nginx-deploy         #service名称
Namespace:         default              #service所属的名称空间
Labels:            app=nginx-deploy     #service的标签
Annotations:       <none>               #service的注解
Selector:          app=nginx-deploy     #当前Service对象使用的标签选择器,用于选择关联的Pod对象
Type:              ClusterIP            #即Servic巳的类型,其值可以是ClusterIP、NodePort和LoadBalancer等其中之一
IP:                10.105.98.155        #当前Service对象的ClusterIP
Port:              80-80  80/TCP        #暴露的端口,即当前Service用于接收并响应请求的端口
TargetPort:        80/TCP               #容器中的用于暴露的目标端口,由Service Port路由请求至此端口
Endpoints:         10.244.3.11:80       #后端端点,即被当前Service的Selector调中的所有Pod的IP及其端口,代理的pod,(如果控制器有多个pod,这里将有多个pod的地址)
Session Affinity:  None                 #是否启用会话粘性
Events:            <none>               #外部流量的调度策略


Name:              nginx-svc
Namespace:         default
Labels:            app=nginx-deploy
Annotations:       <none>
Selector:          app=nginx-deploy
Type:              ClusterIP
IP:                10.96.62.172
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.3.11:80
Session Affinity:  None
Events:            <none>

4.通过service的clusterip访问至代理的pod

#通过nginx-deploy service的集群ip访问
k8sops@k8s-master01:~$ curl http://10.105.98.155 -I
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Wed, 06 May 2020 08:42:51 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 10 Apr 2019 01:08:42 GMT
Connection: keep-alive
ETag: "5cad421a-264"
Accept-Ranges: bytes

#通过nginx-svc service的集群ip访问
k8sops@k8s-master01:~$ curl http://10.96.62.172 -I
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Wed, 06 May 2020 08:42:59 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 10 Apr 2019 01:08:42 GMT
Connection: keep-alive
ETag: "5cad421a-264"
Accept-Ranges: bytes

5.通过域名访问Service
假如我们的Service IP发生了变化,或者Service发生了Down机,更或则Service也需要多台进行负载呢?这个时候就需要使用域名来访问到Pod,域名不会发生改变。
用域名访问Service需要添加CoreDNS将本机可以解析到Service层面,因为本机并没有使用k8s的网络插件进行配置,我们在pod中可以直接使用域名进行访问service,而在集群的宿主机中则需要添加CoreDNS来进行解析。

在Pod中直接访问Service域名进行调度

#Setp1 :进入容器
kubectl exec pods/nginx-deploy-788b9c6b69-tfcrx -n default -it -- /bin/sh

#Setp2 :通过域名访问nginx-svc和nginx-deploy service; nginx-svc和nginx-deploy为service
wget -O - -q http://nginx-svc.default   
wget -O - -q http://nginx-deploy.default

#Setp3 :以上域名为简写,全写应为以下
wget -O - -q http://nginx-svc.default.svc.cluster.local
wget -O - -q http://nginx-deploy.default.svc.cluster.local

#default为名称空间,我们创建service的时候也没有指定名称空间,所以默认也是在default下,
#svc为固定后缀,意思为服务
#cluster.local 为当前kubernetes集群所在域的域名,在我们初始化k8s时可以指定--service-dns-domain= 参数来进行绑定,如果没有指定则为 cluster.local

#Setp4 :查看当前容器的dns配置文件,可以看到如下dns为CoreDNS的地址,搜索域为cluster.local,这也是在容器中可以简写就能访问到service的原因
cat /etc/resolv.conf
nameserver 10.96.0.10   
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

在宿主机中添加CoreDNS进行访问Service域名进行调度

#查看CoreDNS服务器地址,CoreDNS的Service在kube-system名称空间中
kubectl describe service/kube-dns -n kube-system

#将CoreDNS地址添加到/etc/resolv.conf中
echo 'nameserver 10.96.0.10' >> /etc/resolv.conf

#在宿主机访问service的域名,因为我们没有在宿主机中添加搜索域,所以只能对全写域名进行访问
curl http://nginx-svc.default.svc.cluster.local
curl http://nginx-deploy.default.svc.cluster.local

6.删除Service和重建
删除service之后将无法通过serviceip进行访问,删除service不影响Pod的运行

#Setp1 :删除nginx-deploy和nginx-svc两个service
kubectl delete service/nginx-deploy service/nginx-svc -n default

#Setp2 :这个时候我们无法通过service的集群IP及域名访问到Pod

#Setp3 :重建service,通过上面同样的方法创建出service
kubectl expose deployment/nginx-deploy -n default --type=ClusterIP --port=80 --name=nginx-svc
kubectl create service clusterip nginx-deploy --tcp=80:80

#Setp4 :查看创建的service,这个时候service的IP信息已经发生改变
kubectl describe service -n default
Name:              nginx-deploy
Namespace:         default
Labels:            app=nginx-deploy
Annotations:       <none>
Selector:          app=nginx-deploy
Type:              ClusterIP
IP:                10.96.231.27
Port:              80-80  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.3.11:80
Session Affinity:  None
Events:            <none>


Name:              nginx-svc
Namespace:         default
Labels:            app=nginx-deploy
Annotations:       <none>
Selector:          app=nginx-deploy
Type:              ClusterIP
IP:                10.106.189.68
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.3.11:80
Session Affinity:  None
Events:            <none>

#Setp5 :通过Service域名再次访问Pod服务(这时通过域名访问service还是正常)
curl http://nginx-svc.default.svc.cluster.local
curl http://nginx-deploy.default.svc.cluster.local

7.Service nodeport 端口映射
通过这种方法不仅可以实现通过域名访问,还可以集群内的任何一台机器的映射端口

#创建nodeport方式的端口映射
kubectl expose deployment/nginx-deploy -n default --type=NodePort --port=80 --name=nginx-svc-port
kubectl delete service/nginx-deploy -n default          
kubectl create service nodeport nginx-deploy --tcp=80:80

#查看创建的nodeport端口映射的service
kubectl describe service/nginx-svc-port -n default
Name:                     nginx-svc-port
Namespace:                default
Labels:                   app=nginx-deploy
Annotations:              <none>
Selector:                 app=nginx-deploy
Type:                     NodePort
IP:                       10.111.40.24
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  31339/TCP            #nginx-svc-port service将端口映射到了宿主机的31339端口,我们访问宿主机的31339端口首先会代理到service的80端口,然后service的80端口代理到pod的80端口
Endpoints:                10.244.3.11:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

kubectl describe service/nginx-deploy -n default    
Name:                     nginx-deploy
Namespace:                default
Labels:                   app=nginx-deploy
Annotations:              <none>
Selector:                 app=nginx-deploy
Type:                     NodePort
IP:                       10.100.66.121
Port:                     80-80  80/TCP
TargetPort:               80/TCP
NodePort:                 80-80  30390/TCP              #nginx-deploy service将端口映射到了宿主机的30390端口,我们访问宿主机的30390端口首先会代理到service的80端口,然后service的80端口代理到pod的80端口
Endpoints:                10.244.3.11:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>


#通过集群内的任何一台机器的31339端口将会被代理到nginx-svc-port service上
curl http://192.168.31.221:31339 -I
curl http://192.168.31.222:31339 -I
curl http://192.168.31.223:31339 -I
curl http://192.168.31.231:31339 -I
curl http://192.168.31.232:31339 -I
curl http://192.168.31.233:31339 -I

#通过集群内的任何一台机器的30390端口将会被代理到nginx-deploy service上
curl http://192.168.31.221:30390 -I
curl http://192.168.31.222:30390 -I
curl http://192.168.31.223:30390 -I
curl http://192.168.31.231:30390 -I
curl http://192.168.31.232:30390 -I
curl http://192.168.31.233:30390 -I

每创建一个service都会在对应的Node上创建对应的iptables规则
以上配置完成后,整个访问浏览应该如下图所示

Pod扩缩容

所谓的Pod扩容和缩容是Kubernetes提供的一个动态添加Pod的功能,可以在相同Pod运行的时候添加或则删除Pod数量,上面实例中创建的 deployment 资源对象默认仅创建一个pod对象,其所能够承载的访问请求数量即受限于这单个Pod对象的服务容量,请求流量上升到接近或超出其容量之前,用户可以通过 Kubernetes 的“扩容机制”来扩展 Pod 的副本数量,从而提升其服务容量。
1.pod扩容
将default名称空间下的 nginx-deploy deployment控制器所创建的pod由原来的1个扩容至6个

kubectl scale --replicas=6 deployment/nginx-deploy -n default

#查看扩容后的pod
kubectl get pods -n default -o wide | grep nginx-deploy
nginx-deploy-788b9c6b69-gvdg2       1/1     Running   0          70s    10.244.5.22   k8s-node03   <none>           <none>
nginx-deploy-788b9c6b69-j4wgq       1/1     Running   0          70s    10.244.3.12   k8s-node01   <none>           <none>
nginx-deploy-788b9c6b69-jgjsh       1/1     Running   0          70s    10.244.2.13   k8s-node02   <none>           <none>
nginx-deploy-788b9c6b69-ncfvp       1/1     Running   0          70s    10.244.5.23   k8s-node03   <none>           <none>
nginx-deploy-788b9c6b69-tfcrx       1/1     Running   0          128m   10.244.3.11   k8s-node01   <none>           <none>
nginx-deploy-788b9c6b69-zltmr       1/1     Running   0          70s    10.244.2.14   k8s-node02   <none>           <none>

2.pod缩容
Pod缩容只需要将对应的–replicas参数等于你想要的Pod数量即可

kubectl scale --replicas=2 deployment/nginx-deploy -n default

#查看缩容后的pod
kubectl get pods -n default -o wide | grep nginx-deploy
nginx-deploy-788b9c6b69-ncfvp       1/1     Running   0          4m52s   10.244.5.23   k8s-node03   <none>           <none>
nginx-deploy-788b9c6b69-tfcrx       1/1     Running   0          131m    10.244.3.11   k8s-node01   <none>           <none>

3.查看service的详细信息
这个时候可以发现,service的 Endpoints 已经动态的由一台pod变为了我们扩容再缩容后的两台

kubectl describe service/nginx-deploy -n default
Name:                     nginx-deploy
Namespace:                default
Labels:                   app=nginx-deploy
Annotations:              <none>
Selector:                 app=nginx-deploy
Type:                     NodePort
IP:                       10.100.66.121
Port:                     80-80  80/TCP
TargetPort:               80/TCP
NodePort:                 80-80  30390/TCP
Endpoints:                10.244.3.11:80,10.244.5.23:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

4.通过nginx-deploy service访问后端pod
开三个ssh窗口,第一个窗口进行curl访问后端pod,第二个和第三个窗口分别查看两个pod的日志

curl http://nginx-deploy.default.svc.cluster.local

上面可以看到,我访问了三次,前两次都被调度到了第三个窗口上,第三次被调度到了第二个窗口上,这种请求负责是由service进行调度,不是采用轮询,而是随机进行调度,后面如果使用了ipvs规则后,我们可以定义调度算法。

版本更新

我们使用Deployment控制器来创建了Pod,又使用Service对Pod做了代理(ClusterIP、NodePort),使Pod可以被外部主机可访问(NodePort可被外部主机访问,ClusterIP还需要做LB来进行负载,我们上面演示了在集群内部的宿主机通过ClusterIP的方式访问了Pod内的容器);在我们平常工作中,肯定会出现开发版本发布或则更新的情况,在容器中更新版本,之需要将我们新版本的代码打包至镜像,然后我们通过重新部署新版本镜像替代掉老版本镜像即可。

kubectl edit

#1.查看我们创建的控制器
kubectl get deploy -n default -o wide

#2.然后通过命令 kubectl edit [资源对象/资源对象名称] 
kubectl edit deploy/nginx-deploy

#3.搜索image就可以定位到你所使用的镜像版本

kubectl edit 命令不仅可以编辑deployment的yaml配置文件,只要是资源对象都可以使用 kubectl edit 来编辑

升级例子
我们上面在Pod中部署的Nginx容器镜像版本是1.14.2,我们现在把Nginx容器升级至latest最新版本。

上面我们是通过curl访问得知我们的nginx容器使用的是1.14.2版本

#升级语法如下
#set:在资源对象上设定特定功能
#image:在资源对象上设定镜像
#deploy/nginx-deploy:指定我们资源及资源名称
#-n default:指定名称空间
#nginx:为容器名称
#nginx:latest:为镜像版本,这里我们升级为latest最新版本
kubectl set image deploy/nginx-deploy -n default nginx=nginx:latest

#升级过程,我们升级的nginx-deploy本来只有一个pod,上面我们给这个pod做了扩容,现在变为了两个pod ,下面升级过程中,是在升级其中的一个pod ContainerCreating
kubectl get pods -n default | grep nginx-deploy
nginx-deploy-788b9c6b69-ncfvp       1/1     Running             1          45h
nginx-deploy-788b9c6b69-tfcrx       1/1     Running             1          47h
nginx-deploy-7d5c9644b-wrnd5        0/1     ContainerCreating   0          20s

#第一个pod升级完成,然后控制器将原来老的Pod进行终止后销毁 Terminating,接着升级第二个Pod ContainerCreating
kubectl get pods -n default | grep nginx-deploy
nginx-deploy-788b9c6b69-ncfvp       0/1     Terminating         1          45h
nginx-deploy-788b9c6b69-tfcrx       1/1     Running             1          47h
nginx-deploy-7d5c9644b-vsrbd        0/1     ContainerCreating   0          5s
nginx-deploy-7d5c9644b-wrnd5        1/1     Running             0          45s

#两个Pod都升级完成(pod的名称和IP地址都发生了改变)
kubectl get pods -n default | grep nginx-deploy
nginx-deploy-7d5c9644b-vsrbd        1/1     Running   0          82s
nginx-deploy-7d5c9644b-wrnd5        1/1     Running   0          2m2s

#升级成功后可以看下pod的升级状态
kubectl rollout status deployment/nginx-deploy

#访问Pod或者我们通过kubectl edit来去看pod的镜像(与上面一样,访问方式不变)
curl http://192.168.31.233:30390 -I
HTTP/1.1 200 OK
Server: nginx/1.17.10                       #可以看到,目前的容器版本是1.17.1
Date: Fri, 08 May 2020 07:45:39 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 14 Apr 2020 14:19:26 GMT
Connection: keep-alive
ETag: "5e95c66e-264"
Accept-Ranges: bytes

#在线编辑Pod或者deploy可以看到使用的镜像版本
kubectl edit pods/nginx-deploy-7d5c9644b-vsrbd

版本回滚

我们上线后也会偶尔也会出现问题,这个时候我们需要进行版本回滚,可以回滚到上个版本,或者指定版本

#查看发布的记录
kubectl rollout history deploy/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
1         <none>                    #第一次发布记录是1.14.2版本
2         <none>                    #第二次就是我们刚才升级后的版本1.17.1

#回滚到上个版本
k8sops@k8s-master01:~$ kubectl rollout undo deploy/nginx-deploy

#然后查看pod,发现已经回滚完成
kubectl get pods -n default | grep nginx-deploy
nginx-deploy-788b9c6b69-2mgn6       1/1     Running   0          11s
nginx-deploy-788b9c6b69-kkp5z       1/1     Running   0          8s

#访问测试回滚后的pod版本
curl http://192.168.31.233:30390 -I
HTTP/1.1 200 OK
Server: nginx/1.14.2                #版本已经变更到上个版本
Date: Fri, 08 May 2020 07:53:03 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 10 Apr 2019 01:08:42 GMT
Connection: keep-alive
ETag: "5cad421a-264"
Accept-Ranges: bytes

#然后再看下发布记录
kubectl rollout history deploy/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
2         <none>                    #1.17.1为第二版本
3         <none>                    #目前为第三版本

#回滚到指定版本(这里指定到2版本)
kubectl rollout undo deploy/nginx-deploy --to-revision=2

#然后访问测试,查看版本
curl http://192.168.31.233:30390 -I
HTTP/1.1 200 OK
Server: nginx/1.17.10               #可以看到变回了1.17.1版本
Date: Fri, 08 May 2020 07:56:33 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 14 Apr 2020 14:19:26 GMT
Connection: keep-alive
ETag: "5e95c66e-264"
Accept-Ranges: bytes

#再次查看发布记录(目前我们的1.17.1版本是4版本,1.14.2版本是3版本)
kubectl rollout history deploy/nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
3         <none>
4         <none>

#查看某个版本的详细记录(假如我们要查看3版本的更详细的一些记录,上面只显示了版本号,未显示一些其它属性信息)
#我们可以通过 history 然后指定资源/资源对象 指定版本号,然后输出为yaml格式进行详细查看
kubectl rollout history deploy/nginx-deploy --revision=3 -o yaml






「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论