• Kubernetes(三)实战入门


    实战入门

    本章介绍如何在kubernetes集群中部署一个nginx服务,并能够对其进行访问。

    1. Namespace

    Namespace主要作用是实现多套环境的资源隔离或者多租户的资源隔离。

    默认情况下,kubernetes 集群中的所有Pod都是可以相互访问的。但是在实际中,可能不希望让2个Pod之间进行相互访问,此时即可将两个Pod划分到不同的namespace下。Kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的“组”,以方便不同的组的资源进行隔离使用和管理。

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

    例如可以给namespace-dev 的 ns 分配5GB的内存资源,而namespace-test 只分配3GB的资源。

    Kubernetes集群在创建后,会默认创建几个namespaces:

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

    下面是 namespaces 的资源操作示例:

    # 查看
    $ kubectl get ns kube-system
    NAME          STATUS   AGE
    kube-system   Active   23h
    
    => Active 表示命名空间正在使用;另一种状态是Terminating :表示正在删除命名空间
    
    # 描述
    $ kubectl describe ns default
    Name:         default
    Labels:       <none>
    Annotations:  <none>
    Status:       Active
    
    No resource quota.   => ResourceQuota 针对namespace做的资源限制
    
    No LimitRange resource.   => LimitRange 针对namespace中的每个组件做的资源限制
    
    
    # 创建
    $ kubectl create ns dev
    namespace/dev created
    
    # 删除
    $ kubectl delete ns dev
    namespace "dev" deleted
    
    #配置方式
    首先准备一个 yaml 文件:ds-dev.yaml
    $ cat yamls/ns-dev.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: dev
    
    $ kubectl apply -f yamls/ns-dev.yaml
    namespace/dev created
    
    $ kubectl delete -f yamls/ns-dev.yaml
    namespace "dev" deleted

    2. Pod

    Pod 是kubernetes集群进行管理的最小单元,程序要运行必须部署在container中,而container必须存在于Pod中。

    Pod可以认为是container的封装,一个Pod中可以存在一个或多个container。如下图所示,默认会有一个根容器(也就是这里的Pause),此容器不会在 get pods 时显示给用户。

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

    $ kubectl get pods -n kube-system
    NAME                                        READY     STATUS        RESTARTS      AGE
    aws-node-jtzb7                              1/1     Running           0            22h
    coredns-74c8b6b7dd-7nhz8                    1/1     Running           0            23h
    coredns-74c8b6b7dd-v6ztk               1/1     Running           0            23h
    kube-proxy-lhd84                           1/1     Running           0            22h

    此结果为 aws eks 集群的结果。在自建的eks集群中,一般还会有 etcd-master、kube-apiserver-master、kube-controller-manager-master、kube-scheduler-master 等 Pods。但是在 aws eks 中,客户端并无法显示这些pods。

    另外的aws-node-jtzb7 与kube-proxy-lhd84均对应当前集群中的1个节点(当前集群仅有1个节点)。

    Pod 操作

    在创建并运行一个pod时,kubernetes没有提供单独运行Pod的命令,都是通过Pod控制器来实现的:

    # 命令格式:kubectl run (pod控制器名称) [参数]
    # --image             指定Pod 镜像
    # --port                指定服务暴露的端口
    # --namespace   指定namespace
    
    $ kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace dev
    pod/nginx created
    
    $ kubectl get pods -o wide -n dev
    NAME    READY   STATUS    RESTARTS   AGE     IP          NODE                                        NOMINATED NODE   READINESS GATES
    nginx   1/1     Running   0          2m51s   10.0.1.84   ip-10-0-1-217.cn-north-1.compute.internal   <none>           <none>
    
    => 这个 ip 是Pod 的ip,并非节点 ip
    
    # 查看更详细内容
    kubectl describe pod nginx -n dev

    如何访问到此nginx 服务?

    首先在 kubectl get pods -o wide -n dev 的结果中,可以看到 pod 的ip 为 10.0.1.84。结合我们指定暴露的端口为 80,在访问时通过curl 10.0.1.84:80 访问即可。

    创建pod与创建deployment的不同:

    1. kubectl run 一个pod后,一般会显示 pod/nginx created。此时创建的是单个pod,可以直接通过delete pod xxx 进行删除
    2. kubectl create deploy nginx --image=nginx:1.17.1 -n dev 会创建一个deployment,一般会显示deployment.apps/nginx created。此时创建的是一个deployment,直接删除一个pod 的话,会立即自动再创建一个pod。需要通过 $ kubectl delete deployment nginx -n dev 删除一个deployment,返回的结果是:deployment.apps "nginx" deleted

    基于配置文件进行操作

    创建一个pod-nginx.yaml,内容为:

    apiVersion: v1
    kind: Pod
    metadata:
       name: nginx
       namespace: dev
    spec:
       containers:
       - image: nginx:1.17.1
         imagePullPolicy: IfNotPresent
         name: pod
         ports:
         - name: nginx-port
           containerPort: 80
           protocol: TCP

    创建:

    $ kubectl create -f yamls/pod-nginx.yaml

    pod/nginx created

    删除:

    $ kubectl delete -f yamls/pod-nginx.yaml

    pod "nginx" deleted

    3. Label

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

    Label的特点:

    1. 一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等
    2. 一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去
    3. Label 通常在资源对象定义时确定,当然也可以在对象创建后动态添加或删除

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

    •    版本标签:"version":"release", "version":"stable"
    •    环境标签:"environment":"dev", "environment":"test", "environment":"pro"
    •    架构标签:"tier":"frontend", "tier":"backend"

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

    • Label 用于给某个资源对象定义标识
    • 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

    Label操作

    命令方式:

    # 为pod资源打标签
    $ kubectl label pod nginx version=1.0 -n dev
    pod/nginx labeled
    
    $ kubectl label pod nginx -n dev tier=back
    pod/nginx labeled
    
    # 查看标签
    $ kubectl get pod -n dev --show-labels
    NAME    READY     STATUS       RESTARTS      AGE                LABELS
    nginx         1/1       Running              0             6m2s      tier=back,version=1.0
    
    # 为pod 资源更新标签
    $ kubectl label pod nginx1 version=2.0 -n dev --overwrite
    pod/nginx1 labeled
    
    $ kubectl get pods -n dev --show-labels
    NAME     READY   STATUS    RESTARTS   AGE   LABELS
    nginx    1/1     Running   0          15m   tier=back,version=1.0
    nginx1   1/1     Running   0          89s   run=nginx1,version=2.0
    
    # 标签选择
    $ kubectl get pods -l "version=2.0" -n dev --show-labels
    NAME     READY   STATUS    RESTARTS   AGE   LABELS
    nginx1   1/1     Running   0          2m    run=nginx1,version=2.0
    
    # 删除标签
    $ kubectl label pod nginx -n dev tier-
    pod/nginx labeled
    
    $ kubectl get pods -n dev --show-labels
    NAME     READY   STATUS    RESTARTS   AGE     LABELS
    nginx    1/1     Running   0          18m     version=1.0
    nginx1   1/1     Running   0          4m10s   run=nginx1,version=2.0

    以配置方式:

    在yaml文件中加上label字段:

    $ cat yamls/pod-nginx.yaml
    apiVersion: v1
    kind: Pod
    metadata:
       name: nginx
       namespace: dev
       labels:
         version: "3.0"
         tier: "production"
    spec:
       containers:
       - image: nginx:1.17.1
         imagePullPolicy: IfNotPresent
         name: pod
         ports:
         - name: nginx-port
           containerPort: 80
           protocol: TCP

    4. Deployment

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

    在kubernetes中Pod控制器的种类有很多,下面主要介绍其中一种:Deployment。

    Deployment操作

    命令方式:

    # 创建
    $ kubectl create deploy nginx-dep --image=nginx:1.17.1 -n dev
    deployment.apps/nginx-dep created
    
    # 查看
    $ kubectl get deploy -n dev -o wide
    NAME        READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
    nginx-dep   1/1                           1            1           37s        nginx            nginx:1.17.1   app=nginx-dep
    
    $ kubectl get pods -n dev --show-labels
    NAME                         READY   STATUS    RESTARTS   AGE   LABELS
    nginx-dep-74c95fbff9-lsngl   1/1     Running   0          19s   app=nginx-dep,pod-template-hash=74c95fbff9
    
    => 可以看到 deployment 有个SELECTOR 的标签选择器,选择的标签即为启动的pod自动打上的名称标签
    
    # 删除
    $ kubectl delete deploy nginx-dep -n dev
    deployment.apps "nginx-dep" deleted

    配置文件方式:

    $ cat yamls/deploy-nginx.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
       name: nginx-dep
       namespace: dev
    spec:
       replicas: 3
       selector:
          matchLabels:
             run: nginx
       template:
          metadata:
            labels:
              run: nginx
          spec:
            containers:
            - image: nginx:1.17.1
              name: nginx
              ports:
              - containerPort: 80
                protocol: TCP
    
    
    selector 就是label选择器,pod哪里的label给予的是run:nginx
    $ kubectl apply -f yamls/deploy-nginx.yaml
    deployment.apps/nginx-dep created
    
    $ kubectl get deploy -n dev
    NAME        READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-dep   3/3     3            3           103s
    
    $ kubectl get pods -n dev
    NAME                         READY   STATUS    RESTARTS   AGE
    nginx-dep-755c49cf64-462g5   1/1     Running   0          2m21s
    nginx-dep-755c49cf64-s74rx   1/1     Running   0          2m21s
    nginx-dep-755c49cf64-sgc88   1/1     Running   0          2m21s
    
    $ kubectl delete -f yamls/deploy-nginx.yaml

    5. Service

    现在我们可以通过deployment创建一组Pods,用于提供高可用服务。

    但是,虽然每个Pod都会被分配一个单独的Pod IP,仍会存在以下2个问题:

    1. Pod IP会随着Pod的重建产生变化
    2. Pod IP仅是集群内可见的虚拟IP,外部无法访问

    这样对于访问服务带来了难度。因此,kubernetes设计了Service来解决此问题。

    Service可以看作是一组同类Pod对外的访问接口。借助Service,应用可以很方便地实现服务发现和负载均衡。

    如下图所示:

    一个请求在访问Service时,Service会通过标签选择器选择需要访问的Pod,然后将请求转发到对应的Pod中,其中也涉及负载均衡算法。Service在其整个生命周期中,IP地址都是不变的。

    Service操作

    创建集群内部可访问的Service

    # 暴露Service
    $ kubectl expose deploy nginx-dep --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
    service/svc-nginx1 exposed
    
    此时暴露的是deployment,而不是直接1个pod。--port 指定的是 service 80 端口,转发到pod上的 80 端口(--terget-port=80)
    
    # 查看Service
    $ kubectl get svc -n dev
    NAME         TYPE                CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE
    svc-nginx1   ClusterIP    172.20.246.209         <none>        80/TCP    65s
    
    # 由于指定的是ClusterIP,所以仅有集群内的节点能访问到此服务
    # 通过 eks node 访问此地址:
    $ curl 172.20.246.209<p><em>Thank you for using nginx.</em></p>
    …
    
    # 删除svc
    $ kubectl delete svc svc-nginx2 -n dev
    service "svc-nginx2" deleted

    创建集群外部也能访问Service

    # 若是需要外部也能访问,则需要修改type为NodePort
    $ kubectl expose deploy nginx-dep --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
    service/svc-nginx2 exposed
    
    $ kubectl get svc -n dev -o wide
    NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE     SELECTOR
    svc-nginx1   ClusterIP   172.20.246.209   <none>        80/TCP         8m13s   run=nginx
    svc-nginx2   NodePort    172.20.140.200   <none>        80:31890/TCP   18s     run=nginx
    $ kubectl apply -f yamls/svc-nginx.yaml
    service/svc-nginx created
    
    $ kubectl delete -f yamls/svc-nginx.yaml
    service "svc-nginx" deleted
  • 相关阅读:
    Windows 运行 中的命令
    Base64 实现。名家手笔
    熊猫烧香病毒专杀及手动修复方案
    pdf病毒的源代码(VBS)
    Base64 实现。名家手笔
    pdf病毒的源代码(VBS)
    Code:关于加密解密 Base64 and URL and Hex Encoding and Decoding
    wmDrawer:实用的步骤启动器
    gnormalize:音频转换对象
    Avidemux:视频编纂软件
  • 原文地址:https://www.cnblogs.com/zackstang/p/14510364.html
Copyright © 2020-2023  润新知