环境说明:

主机名

操作系统版本

ip

docker version

kubelet version

备注

master

Centos 7.6.1810

172.27.9.131

Docker 18.09.6

V1.14.2

master主机

node01

Centos 7.6.1810

172.27.9.135

Docker 18.09.6

V1.14.2

node节点

node02

Centos 7.6.1810

172.27.9.136

Docker 18.09.6

V1.14.2

node节点

一、 pod简介

1. pod概览

Pod是kubernetes中你可以创建和部署的最小也是最简单位。一个Pod代表着集群中运行的一个进程。
Pod中封装着应用的容器(有的情况下是好几个容器),存储、独立的网络IP,管理容器如何运行的策略选项。Pod代表着部署的一个单位:kubernetes中应用的一个实例,可能由一个或者多个容器组合在一起共享资源

 

在Kubrenetes集群中Pod有如下两种使用方式:

  • 一个Pod中运行一个容器。“每个Pod中一个容器”的模式是最常见的用法:在这种使用方式中,你可以把Pod想象成是单个容器的封装,kuberentes管理的是Pod而不是直接管理容器。
  • 在一个Pod中同时运行多个容器。一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位——一个容器共享文件,另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。

2. pod网络

由于一个pod中的容器运行于相同的Network命名空间中,因此它们共享相同的IP地址和端口空间。当两个pod彼此之间发送网络数据包时,它们都会将对方的实际IP地址看作数据包中的源IP。

k8s pod容器启动命令 k8s进入pod中容器_运维

pod 是逻辑主机,其行为与非容器世界中的物理主机或虚拟机非常相似。此外,运行在同一个pod中的进程与运行在同一物理机或虚拟机上的进程相似,只是每个进程都封装在一个容器之中。

二、创建pod的两种方式

1. 命令方式

[root@master ~]# kubectl run kubia --image=luksa/kubia --replicas=3 
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/kubia created

kubia指定deployment名字(本文pod的创建不论命令还是文件方式都使用Controller deployment),--image=luksa/kubia显示的是指定要运行的镜像,--replicas=3指定副本数为3

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_02

先创建deployment:nginx-deployment,再创建replicasets:kubia-66c8b6d4fc,最后创建三个pod:kubia-66c8b6d4fc-cdzzg、kubia-66c8b6d4fc-ff9f8和kubia-66c8b6d4fc-xtcmm,3个pod分别位于3个node节点上。

2. 文件方式

[root@master ~]# more nginx-master.yaml
apiVersion: extensions/v1beta1  #描述文件遵循extensions/v1beta1版本的Kubernetes API
kind: Deployment                #创建资源类型为Deployment
metadata:                       #该资源元数据
  name: nginx-master            #Deployment名称
spec:                           #Deployment的规格说明
  replicas: 3                   #指定副本数为3
  template:                     #定义Pod的模板
    metadata:                   #定义Pod的元数据
      labels:                   #定义label(标签)
        app: nginx              #label的key和value分别为app和nginx
    spec:                       #Pod的规格说明
      containers:               
      - name: nginx             #容器的名称
        image: nginx:latest     #创建容器所使用的镜像

执行创建命令

[root@master ~]# kubectl create -f nginx-master.yaml 
deployment.extensions/nginx-master created

查看创建的资源

k8s pod容器启动命令 k8s进入pod中容器_5g_03

3. 进入pod

进入pod kubia-66c8b6d4fc-cdzzg

[root@master ~]# kubectl exec -it kubia-66c8b6d4fc-cdzzg bash

类似docker,使用kubectl exec命令进入容器

k8s pod容器启动命令 k8s进入pod中容器_nginx_04

容器的ip和主机名同pod

三、标签

标签其实就一对 key/value,可以附加到资源的任意键值对,标签可以用来划分特定组的对象,用以选择具有该确切标签的资源。

1. pod使用标签

pod指定标签

[root@master ~]# kubectl run http-label --image=httpd --labels="app=web,env=prod"
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/http-label created

指定pod的标签为'app=web和env=prod'

查看pod的标签

[root@master ~]# kubectl get pod --show-labels

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_05

通过--show-labels参数可查看pod的标签

通过标签筛选pod

[root@master ~]# kubectl get pod -l app --show-labels 
NAME                           READY   STATUS    RESTARTS   AGE    LABELS
http-label-7cf498876f-rhqxf    1/1     Running   0          107s   app=web,env=prod,pod-template-hash=7cf498876f
nginx-master-9d4cf4f77-cg47g   1/1     Running   1          46h    app=nginx,pod-template-hash=9d4cf4f77
nginx-master-9d4cf4f77-lflck   1/1     Running   1          46h    app=nginx,pod-template-hash=9d4cf4f77
nginx-master-9d4cf4f77-w4xgb   1/1     Running   1          46h    app=nginx,pod-template-hash=9d4cf4f77

通过-l app参数可筛选所有标签为app的pod

 

修改现有标签

[root@master ~]# kubectl label pod http-label-7cf498876f-rhqxf env=debug  --overwrite 
pod/http-label-7cf498876f-rhqxf labeled

k8s pod容器启动命令 k8s进入pod中容器_运维_06

将pod http-label-7cf498876f-rhqxf的标签env由prod更改为debug

 

删除标签

[root@master ~]#  kubectl label pod http-label-7cf498876f-rhqxf env-
pod/http-label-7cf498876f-rhqxf labeled

k8s pod容器启动命令 k8s进入pod中容器_网络_07

将pod http-label-7cf498876f-rhqxf的标签env删除

2. 通过标签指定pod创建的节点

给node节点打标签

k8s pod容器启动命令 k8s进入pod中容器_nginx_08

分别给节点打上标签node=master、node=node01、node=node02

 

指定node创建pod

[root@master ~]# more httpd-node.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: httpd-node
spec:
  template:
    metadata:
      labels:
        env: prod
    spec:
      containers:
      - name: httpd-node
        image: httpd:latest
      nodeSelector:
        node: master
[root@master ~]# kubectl apply -f httpd-node.yaml

指定pod的label为env:prod,node节点为master

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_09

四、命名空间

Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default)

1. 查看命名空间

[root@master ~]# kubectl  get ns
NAME              STATUS   AGE
default           Active   37d
kube-node-lease   Active   46h
kube-public       Active   37d
kube-system       Active   37d

其中命名空间kube-node-lease发布于1.14的beta版本,被kubelet用作确定节点运行状况。

2. 查看指定命名空间的pod

[root@master ~]# kubectl get po -n kube-system 
NAME                                    READY   STATUS    RESTARTS   AGE
busybox03-5b4cb76f96-jg8f8              1/1     Running   4          5d22h
coredns-fb8b8dccf-bxvrz                 1/1     Running   24         37d
coredns-fb8b8dccf-mqvd8                 1/1     Running   24         37d
etcd-master                             1/1     Running   26         37d
fluentd-elasticsearch-928nt             1/1     Running   21         29d
fluentd-elasticsearch-gw5tx             1/1     Running   30         29d
fluentd-elasticsearch-n4mc6             1/1     Running   26         29d
kube-apiserver-master                   1/1     Running   26         37d
kube-controller-manager-master          1/1     Running   31         37d
kube-flannel-ds-amd64-lkh5n             1/1     Running   30         35d
kube-flannel-ds-amd64-pv5ll             1/1     Running   24         36d
kube-flannel-ds-amd64-wnn5g             1/1     Running   36         36d
kube-proxy-42vb5                        1/1     Running   26         37d
kube-proxy-7nrfk                        1/1     Running   30         35d
kube-proxy-x7dmk                        1/1     Running   35         36d
kube-scheduler-master                   1/1     Running   32         37d
kubernetes-dashboard-7b87f5bdd6-7d5s8   1/1     Running   4          5d18h

该命令也可写作为:'kubectl get pod --namespace=kube-system'

3. 创建命名空间

文件方式
创建test01-namespace

[root@master ~]# more test01-namespace.yaml 
apiVersion: v1
kind: Namespace
metadata: 
  name: test01-namespace
[root@master ~]# kubectl apply -f test01-namespace.yaml 
namespace/test01-namespace created

kubectl apply和kubectl create命令类似,都可以根据文件创建相关资源。

 

命令方式
创建test02-namespace

[root@master ~]# kubectl create ns test02-namespace
namespace/test02-namespace created

k8s pod容器启动命令 k8s进入pod中容器_网络_10

4. pod指定命名空间

[root@master ~]# kubectl run httpd --image=httpd -n test01-namespace 
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
deployment.apps/httpd created
[root@master ~]# kubectl get pod -o wide -n test01-namespace 
NAME                    READY   STATUS              RESTARTS   AGE   IP       NODE     NOMINATED NODE   READINESS GATES
httpd-6b77d6648-zqnv4   0/1     ContainerCreating   0          27s   <none>   node01   <none>           <none>

指定创建pod的命名空间为test01-namespace,查询pod是需带上命名空间。

命名空间切换

[root@master ~]# alias kcd='kubectl config set-context $(kubectl config current-context) --namespace'
[root@master ~]# kcd test01-namespace
Context "kubernetes-admin@kubernetes" modified.
[root@master ~]# kubectl get pod
NAME                    READY   STATUS    RESTARTS   AGE
httpd-6b77d6648-zqnv4   1/1     Running   0          5m6s

配置kcd,通过kcd namespace可切换命名空间。

五、扩容/缩容

创建文件nginx-scale.yaml并新建资源

k8s pod容器启动命令 k8s进入pod中容器_运维_11

新建deployment nginx-scale,pod副本数为3

 

文件方式

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_12

通过修改文件中参数replicas的值并重新执行kubectl apply命令即可实现pod的扩缩容

 

命令方式

[root@master ~]# kubectl scale deployment nginx-scale --replicas=1
deployment.extensions/nginx-scale scaled

k8s pod容器启动命令 k8s进入pod中容器_5g_13

通过命令将pod副本数缩容为1

六、failover

1. pod节点分布查看

k8s pod容器启动命令 k8s进入pod中容器_网络_14

2. failover测试

节点node02关机

[root@node02 ~]# init 0

查看node状态和pod分布

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_15

node02状态为NotReady且之前在该节点的pod被迁移至master或者node01

当node02恢复后,运行在该节点的Pod会被删除,且迁移至master和node01的Pod不会重新调度回到node02

七、升级及回滚

1. 创建deployment

[root@master ~]# more nginx-roll.yaml                                             
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-roll
  namespace: test02-namespace
spec:
  selector:
    matchLabels:
      env: prod
  replicas: 3
  template:
    metadata:
      labels:
        env: prod
    spec:
      containers:
      - name: nginx-roll
        image: nginx:1.16
[root@master ~]# kubectl apply -f nginx-roll.yaml --record                        
deployment.apps/nginx-roll created

创建deployment nginx-roll,副本数为3,namespace为test02-namespace,nginx版本为1.16,--record参数会记录历史版本号

 

Deployment apiVersion版本说明:

  • 1.6版本之前 apiVsersion:extensions/v1beta1
  • 1.6版本到1.9版本之间:apps/v1beta1
  • 1.9版本之后:apps/v1

 

查看部署状态

[root@master ~]# kubectl rollout status deployment -n test02-namespace nginx-roll
Waiting for deployment "nginx-roll" rollout to finish: 0 of 3 updated replicas are available...
Waiting for deployment "nginx-roll" rollout to finish: 1 of 3 updated replicas are available...
Waiting for deployment "nginx-roll" rollout to finish: 2 of 3 updated replicas are available...
deployment "nginx-roll" successfully rolled out

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_16

 

查看pod

k8s pod容器启动命令 k8s进入pod中容器_运维_17

分别查看deployment、replicaset、pod

2. 升级

升级方式有多种,比如'kubectl edit deployments -n test02-namespace nginx-roll'方式、直接修改nginx-roll.yaml文件方式、kubectl set image方式等

 

修改文件方式

[root@master ~]# sed -i 's/image: nginx:1.16/image: nginx:1.17/g' nginx-roll.yaml
[root@master ~]# kubectl apply -f nginx-roll.yaml --record  
deployment.apps/nginx-roll configured

将nginx-roll.yaml中nginx镜像版本修改为1.17并重新执行kubectl apply命令

k8s pod容器启动命令 k8s进入pod中容器_运维_18

nginx升级为1.17

 

kubectl set image方式

[root@master ~]# kubectl set image deployment -n test02-namespace nginx-roll nginx-roll=nginx:1.17.1
deployment.extensions/nginx-roll image updated

将nginx升级至1.17.1

k8s pod容器启动命令 k8s进入pod中容器_5g_19

3. 回滚

查看deployments版本

[root@master ~]# kubectl rollout history deployments -n test02-namespace nginx-roll
deployment.extensions/nginx-roll 
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=nginx-roll.yaml --record=true
2         kubectl apply --filename=nginx-roll.yaml --record=true
3         kubectl apply --filename=nginx-roll.yaml --record=true

 

查看deployment具体版本信息

k8s pod容器启动命令 k8s进入pod中容器_运维_20

 

回滚至上一个版本

[root@master ~]# kubectl rollout undo deployment -n test02-namespace nginx-roll 
deployment.extensions/nginx-roll rolled back

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_21

 

回滚至指定版本

[root@master ~]# kubectl rollout undo deployment -n test02-namespace nginx-roll --to-revision=1
deployment.extensions/nginx-roll rolled back

k8s pod容器启动命令 k8s进入pod中容器_运维_22

--to-revision=1指定回滚至1.16版本的nginx

 

查看ReplicasSet

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_23

可以看到在升级过程中replicaset保留了修改的历史版本信息

八、内外网访问

1. 创建pod

[root@master ~]# more web-svc.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-svc
  namespace: test02-namespace
spec:
  selector:
    matchLabels:
      app: web-svc
  replicas: 3
  template:
    metadata:
      labels:
        app: web-svc
    spec:
      containers:
      - name: web-svc
        image: httpd:latest
[root@master ~]# kubectl apply -f web-svc.yaml
deployment.apps/web-svc created

创建pod,namespace为test02,副本数为3

k8s pod容器启动命令 k8s进入pod中容器_网络_24

2. 内网访问

创建servcie

内网通过pod ip访问没什么太大意义,因为pod会随时重建,每次ip会随机分配

[root@master ~]#  cat >> web-svc.yaml  << EOF
---
apiVersion: v1
kind: Service
metadata:
  name: web-svc
  namespace: test02-namespace
spec:
  selector:
    app: web-svc
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80
> EOF
[root@master ~]# kubectl apply -f web-svc.yaml
deployment.apps/web-svc unchanged
service/web-svc created

 

查看创建的service

[root@master ~]# kubectl get service -n test02-namespace
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
web-svc   ClusterIP   10.106.53.114   <none>        8080/TCP   5m12s

 

修改index.html

[root@master ~]# kubectl get po -o wide -n test02-namespace
NAME                        READY   STATUS    RESTARTS   AGE     IP             NODE     NOMINATED NODE   READINESS GATES
nginx-roll-8fd7f679-9h9ng   1/1     Running   2          2d17h   10.244.1.52    node01   <none>           <none>
nginx-roll-8fd7f679-b5clj   1/1     Running   2          2d17h   10.244.0.180   master   <none>           <none>
nginx-roll-8fd7f679-pwkbw   1/1     Running   2          2d17h   10.244.2.6     node02   <none>           <none>
web-svc-58956c55fc-7vnw5    1/1     Running   0          3m35s   10.244.1.59    node01   <none>           <none>
web-svc-58956c55fc-8wbst    1/1     Running   0          3m35s   10.244.2.14    node02   <none>           <none>
web-svc-58956c55fc-nxt4r    1/1     Running   0          3m35s   10.244.2.13    node02   <none>           <none>
[root@master ~]# kubectl exec -it web-svc-58956c55fc-7vnw5 -n test02-namespace bash 
root@web-svc-58956c55fc-7vnw5:/usr/local/apache2# cat > /usr/local/apache2/htdocs/index.html << EOF
> web-svc-58956c55fc-7vnw5
> EOF
root@web-svc-58956c55fc-7vnw5:/usr/local/apache2# exit
exit
[root@master ~]# kubectl exec -it web-svc-58956c55fc-8wbst -n test02-namespace bash     
root@web-svc-58956c55fc-8wbst:/usr/local/apache2# cat > /usr/local/apache2/htdocs/index.html << EOF
> web-svc-58956c55fc-8wbst
> EOF
root@web-svc-58956c55fc-8wbst:/usr/local/apache2# exit
exit
[root@master ~]# kubectl exec -it web-svc-58956c55fc-nxt4r -n test02-namespace bash 
root@web-svc-58956c55fc-nxt4r:/usr/local/apache2# cat > /usr/local/apache2/htdocs/index.html << EOF
>  web-svc-58956c55fc-nxt4r
> EOF
root@web-svc-58956c55fc-nxt4r:/usr/local/apache2# exit

分别进入pod,将访问的主页修改为pod名

 

内网访问pod

[root@master ~]# for i in {1..10};do sleep 1;curl 10.98.103.41:8080;done
web-svc-58956c55fc-8wbst
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-7vnw5
 web-svc-58956c55fc-nxt4r
 web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-7vnw5
 web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-8wbst
web-svc-58956c55fc-8wbst

通过service内容访问pod

k8s pod容器启动命令 k8s进入pod中容器_运维_25

3. 外网访问

修改servcie

apiVersion: v1
kind: Service
metadata:
  name: web-svc
  namespace: test02-namespace
spec:
  type: NodePort
  selector:
    app: web-svc
  ports:
  - protocol: TCP
    nodePort: 30002
    port: 8080
    targetPort: 80

新增'type: NodePort'和'nodePort: 30002',通过NodePort方式外网访问pod,映射端口为30002,重新kubectl apply

 

外网访问pod

[root@master ~]# for i in {1..10};do sleep 1;curl 172.27.9.131:30002;done
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-8wbst
 web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-7vnw5
 web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-8wbst
web-svc-58956c55fc-7vnw5
 web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-7vnw5

通过node ip + nodePort方式外网访问pod

k8s pod容器启动命令 k8s进入pod中容器_5g_26

九、日志查看

使用kubectl logs命令可获取pod日志

 

1. 查看最近的日志

[root@master ~]# kubectl logs kubernetes-dashboard-7b87f5bdd6-m62r6 -n kube-system --tail=20

'--tail=20':查看命名空间kube-system下kubernetes-dashboard-7b87f5bdd6-m62r6最近20行的日志,

k8s pod容器启动命令 k8s进入pod中容器_k8s pod容器启动命令_27

 

2. 查看前一个容器的日志

[root@master ~]# kubectl logs kubernetes-dashboard-7b87f5bdd6-m62r6 -n kube-system  --previous

'--previous':当容器重启时,该参数可以查看前一个容器的日志。

k8s pod容器启动命令 k8s进入pod中容器_nginx_28

3. 通过标签查看日志

[root@master ~]# kubectl logs -lapp=web

查看标签为'app=web'的日志

k8s pod容器启动命令 k8s进入pod中容器_nginx_29

'-lapp=web'该日志是标签为'app=web'的合集

十、删除pod

1. 通过删除deployment删除pod

通过deployment创建的pod可以直接删除deployment

[root@master ~]# kubectl delete deployments kubia 
deployment.extensions "kubia" deleted

k8s pod容器启动命令 k8s进入pod中容器_5g_30

2. 通过删除namespace删除pod

删除namespace中所有资源

[root@master ~]# kubectl delete all --all -n test02-namespace

k8s pod容器启动命令 k8s进入pod中容器_nginx_31

直接删除namespace

[root@master ~]# kubectl delete ns test01-namespace

k8s pod容器启动命令 k8s进入pod中容器_运维_32

 
总结:

  • 直接删除pod会重建一个新的不同名的pod;
  • 直接删除replicasets会重建同名replicasets,其下所有pod则会删除重建且名字不同;
  • 直接删除deployments则其下的replicasets和pod将一起被删除;