Kubernetes实战入门

通过本篇文章记录如何在Kubernetes集群中部署一个nginx服务,并且能够对其进行访问

1、Namespace

Namespace是Kubernetes系统中的一种非常重要的资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离

默认情况下,Kubernetes集群中的所有Pod都是可以相互访问的,但是我们再实际过程中很可能不想让两个Pod之间进行相互的访问,那么此时就可以将两个Pod划分到不同的namespace下。Kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的“组”,以方便不同的组的资源进行隔离使用和管理。(多套环境资源隔离)

可以通过Kubernetes的授权机制,将不同的Namespace交给不同的租户进行管理,这样就实现了多租户的资源隔离。此时还能结合Kubernetes的资源配额机制,限定不同租户所能占用的资源,例如CPU的使用量,内存的使用量等等,以实现租户可用资源的管理。(多租户的资源隔离)

Kubernetes实战入门_第1张图片

在Kubernetes集群启动之后,是会默认创建几个Namespace的

[root@master ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   2d19h     #所有未指定Namespace的对象都会被分配在default空间
kube-node-lease   Active   2d19h     #集群节点之间的心跳维护,从v1.13开始引入
kube-public       Active   2d19h     #此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system       Active   2d19h     #所有由Kubernetes系统创建的资源都处于这个命名空间

下面可以来看看Namespace资源的具体操作:

# 1、查看所有Namespace
[root@master ~]# kubectl get ns
NAME              STATUS   AGE
default           Active   2d19h
dev               Active   19h
kube-node-lease   Active   2d19h
kube-public       Active   2d19h
kube-system       Active   2d19h

# 2、查看指定的Namespace 命令:kubectl get ns 
[root@master ~]# kubectl get ns dev
NAME   STATUS   AGE
dev    Active   19h

# 3、指定输出格式 命令:kubectl get ns  -o <格式参数>
# Kubernetes支持的格式有很多,比较常见的是wide、JSON、yaml
[root@master ~]# kubectl get ns dev -o yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Namespace","metadata":{"annotations":{},"name":"dev"}}
  creationTimestamp: "2022-04-06T10:44:40Z"
  labels:
    kubernetes.io/metadata.name: dev
  name: dev
  resourceVersion: "91162"
  uid: c8973639-a1ed-4a50-a83e-93ea9f5c53a3
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

# 4、查看ns详情 命令:kubectl describe ns 
[root@master ~]# kubectl describe ns dev 
Name:         dev
Labels:       kubernetes.io/metadata.name=dev
Annotations:  
Status:       Active         # Active是命名空间正在使用中 Terminating:正在删除命名空间

# ResourceQuota 针对namespace做的资源限制
# LimitRange针对namespace中的每个组件做的资源限制

No resource quota.

No LimitRange resource.

创建

创建namespace

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

删除namespace

[root@master ~]# kubectl delete ns dev
namespace "dev" deleted

2、Pod 

      Pod是Kubernetes集群进行管理的最小单元,程序要运行必须部署在容器中,而且容器必须存在于Pod中。Pod可以认为是容器的封装,一个Pod中可以存在一个或者多个容器。

Kubernetes实战入门_第2张图片

    Kubernetes在集群启动之后,集群中的各个组件也是以Pod方式运行的可以通过下面的命令进行查看:

[root@master ~]# kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS         AGE
calico-kube-controllers-68845d5dc9-8t42r   1/1     Running   1 (5h21m ago)    27h
calico-node-f64nf                          1/1     Running   1 (5h21m ago)    27h
calico-node-gx9rm                          1/1     Running   1 (5h21m ago)    27h
calico-node-mh2s9                          1/1     Running   1 (5h21m ago)    27h
coredns-6d8c4cb4d-ndjfj                    1/1     Running   1 (5h21m ago)    2d22h
coredns-6d8c4cb4d-sfkhv                    1/1     Running   1 (5h21m ago)    2d22h
etcd-master                                1/1     Running   7 (5h21m ago)    2d22h
kube-apiserver-master                      1/1     Running   12 (5h21m ago)   2d22h
kube-controller-manager-master             1/1     Running   6 (5h21m ago)    2d22h
kube-flannel-ds-66plh                      1/1     Running   2 (5h19m ago)    27h
kube-flannel-ds-76qlm                      1/1     Running   2 (5h19m ago)    27h
kube-flannel-ds-xcwdf                      1/1     Running   1 (5h21m ago)    27h
kube-proxy-gtfkb                           1/1     Running   4 (5h21m ago)    2d22h
kube-proxy-nzrf5                           1/1     Running   4 (5h21m ago)    2d22h
kube-proxy-trd4z                           1/1     Running   4 (5h21m ago)    2d22h
kube-scheduler-master                      1/1     Running   7 (5h21m ago)    2d22h
[root@master ~]# 

创建并运行

        Kubernetes没有提供单独运行Pod的命令,都是通过Pod控制器来进行实现的

# 命令格式:kubectl run  <参数>
# --image         指定Pod的镜像
# --port          指定端口
# --namespace     指定namespace
[root@master ~]# kubectl run nginx --image=nginx:1.17.3 --port=80 -n dev
pod/nginx created

#查看pod的详细信息 -o wide
[root@master ~]# kubectl get pod -n dev -o wide
NAME    READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          4m59s   10.244.169.135   k8s-node2              

# 查看更加详细的关于Pod的描述
[root@master ~]# kubectl describe pods nginx -n dev
Name:         nginx
Namespace:    dev
Priority:     0
Node:         k8s-node2/192.168.88.102
Start Time:   Thu, 07 Apr 2022 18:12:27 +0800
Labels:       run=nginx
Annotations:  cni.projectcalico.org/containerID: 468f473e2f618ebfdefde078143e5585c406ae553c6ef72e9bb832dddb2cb465
              cni.projectcalico.org/podIP: 10.244.169.136/32
              cni.projectcalico.org/podIPs: 10.244.169.136/32
Status:       Running
IP:           10.244.169.136
IPs:
  IP:  10.244.169.136
Containers:
  nginx:
    Container ID:   docker://582fc46f31c50a0c154a81af05f6f1e762a12a4d2fc80e5df2a14a499580a0d6
    Image:          nginx:1.17.3
    Image ID:       docker-pullable://nginx@sha256:9688d0dae8812dd2437947b756393eb0779487e361aa2ffbc3a529dca61f102c
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sat, 09 Apr 2022 10:10:02 +0800
    Last State:     Terminated
      Reason:       Error
      Exit Code:    255
      Started:      Thu, 07 Apr 2022 18:12:31 +0800
      Finished:     Sat, 09 Apr 2022 10:09:07 +0800
    Ready:          True
    Restart Count:  1
    Environment:    
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-xwb7n (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-xwb7n:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              
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       40h                   default-scheduler  Successfully assigned dev/nginx to k8s-node2
  Normal  Pulled          40h                   kubelet            Container image "nginx:1.17.3" already present on machine
  Normal  Created         40h                   kubelet            Created container nginx
  Normal  Started         40h                   kubelet            Started container nginx
  Normal  SandboxChanged  4m6s (x3 over 4m34s)  kubelet            Pod sandbox changed, it will be killed and re-created.
  Normal  Pulled          4m5s                  kubelet            Container image "nginx:1.17.3" already present on machine
  Normal  Created         4m4s                  kubelet            Created container nginx
  Normal  Started         4m4s                  kubelet            Started container nginx

访问Pod

# 首先可以查询一下Pod的IP地址
[root@master ~]# kubectl get pods -n dev -o wide
NAME    READY   STATUS    RESTARTS      AGE   IP               NODE        NOMINATED NODE   READINESS GATES
nginx   1/1     Running   1 (43m ago)   40h   10.244.169.136   k8s-node2              

#然后使用curl命令进行访问
[root@k8s-node2 ~]# curl 10.244.169.137:80



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

删除Pod

# 先使用get命令看看空间里面运行的Pod
[root@master ~]# kubectl get pod -n dev
NAME    READY   STATUS    RESTARTS        AGE
nginx   1/1     Running   2 (6h58m ago)   2d2h
# delete命令删除想要删除的命令?试试先
[root@master ~]# kubectl delete pod nginx -n dev
pod "nginx" deleted
# 去看看有没有删除成功
[root@master ~]# kubectl get pod -n dev
No resources found in dev namespace.

kubectl delete这个命令在新版的里面是可以直接删除Pod的 因为新版本不会自动创建Deployment了 但是在老版的里面只会重启Pod,所以在老版本里面需要这个后台(deployment)给直接干掉,所以我现在再重新创建一个Pod,再使用删除deployment的方法删除Pod。

在这个过程中我发现了一个问题,就是我在自己创建的namespace中新建pod之后,是看不到ns中有deployment的,然后在我去掉了-n dev之后,发现在default空间中有一个deployment,是我之前运行在default中的nginx,然后我使用delete命令删除这个pod,就出现了我之前提过的在老版的k8s中的情况:

[root@master ~]# kubectl get pod
NAME                     READY   STATUS    RESTARTS       AGE
nginx-85b98978db-n2rfw   1/1     Running   4 (102m ago)   5d1h
[root@master ~]# ^C
[root@master ~]# kubectl delete pod nginx-85b98978db-n2rfw 
pod "nginx-85b98978db-n2rfw" deleted
[root@master ~]# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
nginx-85b98978db-qhz7j   0/1     ContainerCreating   0          5s

然后试试用删除deployment的方法:

[root@master ~]# kubectl delete deployment nginx
deployment.apps "nginx" deleted
[root@master ~]# kubectl get pod
No resources found in default namespace.
[root@master ~]# 

只要deployment没了,Pod也就消失了这就是怎么样删除一个带有Pod控制器的pod。新版本的run会直接通过Controller创建一个pod,不会创建deployment对象

3、Label

          Label是Kubernetes系统中的一个重要概念,它的作用就是在资源上添加标识,用来对他们进行区分和选择。Label的特点:

● 一个Label会以key/value的键值对的形式附加到各种对象上,如Node、Pod、Service

● 一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源上去

● Label通常在资源对象定义时确定,当然也可以在对象创建后动态添加或者删除

           可以通过Label实现资源的多维度分组,以便灵活、方便的进行资源分配、调度、配置、部署等管理工作。

一些常用的Label示例如下:

        ● 版本标签:“version”:“release”,“version”:“stable”...

        ● 环境标签:“environment”:“dev”,“environment”:“test”,“environment”:“pro”

        ● 架构标签:“tier”:“fronted”,“tier”:“backend”

标签定义完毕之后还要考虑到标签的选择,这就要用到Label Selector,即:

   Label用于给某个资源对象定义标识

   Label Selector用于查询和筛选拥有某些标签的资源对象

当前有两种Label Selector:

     ● 基于等式的Label Selector

name = salve :选择所有包含Label中key=“name”且value="salve"的对象

env !=production:选择所有包括Label中的key=“env”且value不等于production的对象

     ● 基于集合的Label Selector

name in (master,salve) : 选择所有包含Label中的key=“name”且value=“master”或“salve”的对象

name not in (fronted) :选择所有包含Label中的key="name"且value不等于fronted的对象

        标签的选择条件可以使用多个,此时将多个Label Selector进行组合,使用逗号进行分隔即可。例如:

                    name=slave,env!=production

                    name not in (fronted),env!=production

命令方式

# 为Pod资源打标签
[root@master ~]# kubectl label pod nginx version=1.0 -n dev
pod/nginx labeled

# 为Pod资源更新标签
[root@master ~]# kubectl label pod nginx version=2.0 -n dev --overwrite
pod/nginx labeled

# 查看标签
[root@master ~]# kubectl get pod nginx  -n dev --show-labels
NAME    READY   STATUS    RESTARTS      AGE   LABELS
nginx   1/1     Running   1 (11h ago)   13h   run=nginx,version=2.0

# 筛选标签
[root@master ~]# kubectl get pod  -n dev -l version=2.0 --show-labels
NAME    READY   STATUS    RESTARTS      AGE   LABELS
nginx   1/1     Running   1 (11h ago)   13h   run=nginx,version=2.0
[root@master ~]# kubectl get pod  -n dev -l version!=2.0 --show-labels
No resources found in dev namespace.

# 删除标签(使用的是打标签的方式,在想要删除的标签后面打上减号)
[root@master ~]# kubectl label pod nginx -n dev version-
pod/nginx unlabeled
[root@master ~]# kubectl get pod  -n dev -l version!=2.0 --show-labels
NAME    READY   STATUS    RESTARTS      AGE   LABELS
nginx   1/1     Running   1 (11h ago)   13h   run=nginx

配置方式

# 首先创建一个YAML文件
apiVersion: v1
kind: Pod
metadata:
  name: nginx1
  namespace: dev
  #这里打两个标签
  labels:
    version: "3.0"
    env: "test"
spec:
  containers:
  - image: nginx:1.71.1
    name: pod
    ports:
    -  name: nginx1-port
       containerPort: 80
       protocol: TCP
[root@master ~]# kubectl apply -f nginx1.yaml
pod/nginx1 created
[root@master ~]# kubectl get pod -n dev --show-labels
NAME     READY   STATUS    RESTARTS      AGE    LABELS
nginx    1/1     Running   1 (13h ago)   15h    run=nginx
nginx1   1/1     Running   0             114s   env=test,version=3.0

4、Deployment

       在Kubernetes,Pod是最小的控制单元,但是Kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成的。Pod控制器用于Pod的管理,确保Pod资源符合预期的状态,当Pod资源出现故障时,会尝试进行重启或重建Pod。

       在Kubernetes中Pod控制器的种类有很多,这里先介绍一种:Deployment

Kubernetes实战入门_第3张图片

 命令操作

# 命令格式 :kubectl create deploy  '
# --image 指定pod的镜像
# --port  指定端口
# --replicas 指定创建pod的数量
# --namespace 指定namespace
[root@master ~]# kubectl create deploy nginx --image=nginx --port=80 --replicas=3 -n dev
deployment.apps/nginx created
[root@master ~]# kubectl get pod -n dev
NAME                     READY   STATUS    RESTARTS      AGE
nginx                    1/1     Running   1 (15h ago)   17h
nginx-74d589986c-bsv2h   1/1     Running   0             47s
nginx-74d589986c-nxv5d   1/1     Running   0             47s
nginx-74d589986c-tbpv2   1/1     Running   0             47s

可以看到dev中已经新建了三个新的nginx的pod,查看一下这个deployment

[root@master ~]# kubectl describe deployment nginx -n dev
Name:                   nginx
Namespace:              dev
CreationTimestamp:      Sun, 10 Apr 2022 14:15:09 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=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:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  
NewReplicaSet:   nginx-74d589986c (3/3 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  6m8s  deployment-controller  Scaled up replica set nginx-74d589986c to 3
# 删除这个deployment
[root@master ~]# kubectl delete deploy nginx -n dev
deployment.apps "nginx" deleted
[root@master ~]# kubectl get pod -n dev
NAME     READY   STATUS    RESTARTS      AGE
nginx    1/1     Running   1 (16h ago)   18h

配置操作

        创建一个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
         name: nginx
         ports:
         -  containerPort: 80
            protocol: TCP
[root@master ~]# kubectl create -f deploy-nginx.yaml 
deployment.apps/nginx created
[root@master ~]# vi deploy-nginx.yaml
[root@master ~]# kubectl get pod -n dev
NAME                    READY   STATUS    RESTARTS      AGE
nginx                   1/1     Running   1 (17h ago)   19h
nginx-69ccc6c65-4tw7n   1/1     Running   0             3m18s
nginx-69ccc6c65-7sw85   1/1     Running   0             3m18s
nginx-69ccc6c65-hv5bq   1/1     Running   0             3m18s
nginx1                  1/1     Running   0             3h40m
[root@master ~]# kubectl get deploy -n dev
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   3/3     3            3           3m28s
                      

 5、Service

       虽然每个Pod都会被分配一个单独的Pod IP,然而却存在着如下的两个问题:

              ● Pod IP会随着Pod的重建产生变化

              ● Pod IP仅仅只是集群内可见的虚拟IP,外部无法访问

       这样对于访问这个服务就带来了困难,也正因如此,Kubernetes设计了Service来解决这个问题。Service可以看做是一组同类Pod对外的访问接口。借助Service,应用可以方便的实现服务发现和负载均衡

Kubernetes实战入门_第4张图片

        Service作为对外访问的接口,收到一个请求后,直接到达Service上,Service再根据标签选择器去寻找对应的Pod。

操作一:创建集群内部可访问的Service

# 暴露Service 指定名称、类型、端口号、目标端口号(从Service的80端口转发的pod的80端口)
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed

现在就可以直接通过Service的IP:端口来对里面的Pod进行访问了

[root@master ~]# kubectl get svc -n dev
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
svc-nginx1   ClusterIP   10.110.30.14           80/TCP    5m45s
[root@master ~]# curl 10.110.30.14:80



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

操作二:创建集群外部也可访问的Service 

       上面创建的Service的type类型为ClusterIP,这个IP地址只有集群内部可以进行访问,如果需要创建集群外部也可以进行访问的Service,需要修改type为NodePort

[root@master ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
[root@master ~]# kubectl get svc -n dev
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
svc-nginx1   ClusterIP   10.110.30.14             80/TCP         33m
svc-nginx2   NodePort    10.110.131.245           80:31431/TCP   25s

这里,访问主机的相应端口号:192.168.88.100:31431

Kubernetes实战入门_第5张图片

删除Service 

[root@master ~]# kubectl delete svc svc-nginx2 -n dev
service "svc-nginx2" deleted

你可能感兴趣的:(Kubernetes,kubernetes,容器)