实战入门

本章介绍如何在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

Kubernetes(三)实战入门的更多相关文章

  1. 跟我一起学.NetCore之EF Core 实战入门,一看就会

    前言 还记得当初学习数据库操作时,用ADO.NET一步一步地进行数据操作及查询,对于查询到的数据还得对其进行解析,然后封装返回给应用层:遇到这种重复而繁琐的工作,总有一些大神或团队对其进行封装,从而出 ...

  2. scrapy 的三个入门应用场景

    说明: 本文参照了官网的 dmoz 爬虫例子. 不过这个例子有些年头了,而 dmoz.org 的网页结构已经不同以前.所以我对xpath也相应地进行了修改. 概要: 本文提出了scrapy 的三个入门 ...

  3. Selenium WebDriver + Grid2 + RSpec之旅(三) ----入门小例子

    Selenium WebDriver + Grid2 + RSpec之旅(三) ----入门小例子 第一个例子都是比较简单的博客园登录界面,就像学习编程语言时候都是从Hello,World!开始. 1 ...

  4. git和github新手安装使用教程(三步入门)

    git和github新手安装使用教程(三步入门) 对于新手来说,每次更换设备时,github的安装和配置都会耗费大量时间.主要原因是每次安装时都只关心了[怎么做],而忘记了记住[为什么].本文从操作的 ...

  5. [原]CentOS7安装Rancher2.1并部署kubernetes (三)---解决登录kubernets超时和部署测试Pod和Containter[nginx为例]

    ##################    Rancher v2.1.7  +    Kubernetes 1.13.4  ################ ##################### ...

  6. Laravel 教程 - Web 开发实战入门 ( Laravel 5.5 )购买链接

      Laravel 教程 - Web 开发实战入门 ( Laravel 5.5 )购买链接: 推荐给你高品质的实战课程 https://laravel-china.org/courses?rf=158 ...

  7. GitHub 运用实战入门,奶妈级教学

    ## 前言: 我不会用*官方*的语言告诉你Git 是什么,对此我表示深深得歉意--在我看来像CSDN.博客园.掘金等博客交流平台就是小的“GitHub”,只不过在这里更多的是一些零零散散的笔记或者文章 ...

  8. 《ASP.NET Core项目开发实战入门》带你走进ASP.NET Core开发

    <ASP.NET Core项目开发实战入门>从基础到实际项目开发部署带你走进ASP.NET Core开发. ASP.NET Core项目开发实战入门是基于ASP.NET Core 3.1 ...

  9. 学会Git玩转GitHub(第三篇) 入门详解 - 精简归纳

    学会Git玩转GitHub(第三篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 10 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第三篇) 入门详解 - 精简归纳 ...

  10. Python网络爬虫实战入门

    一.网络爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人),是一种按照一定的规则,自动地抓取万维网信息的程序. 爬虫的基本流程: 发起请求: 通过HTTP库向目标站点发起请求,也就是发送一个Request ...

随机推荐

  1. HttpClient配置SSL绕过https证书以及双向认证

    HttpClient简介 1.HTTP 协议是 Internet 上使用得最多.最重要的协议之一,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.虽然在 JDK 的 java ...

  2. .Net 8.0 下的新RPC,IceRPC之使用Dev Containers进行 .NET QUIC 精简开发

    作者引言 很高兴啊,我们来到了IceRPC之使用Dev Containers进行 .NET QUIC 精简开发,主要是一篇指引,如何使用开发容器做为开发环境,进行开发IceRPC,可适用于任务应用的开 ...

  3. JOISC2018 题解

    \(\text{By DaiRuiChen007}\) Contest Link A. Construction of Highway Problem Link 题目大意 给 \(n\) 个点,初始每 ...

  4. leaflet 河流颜色渐变效果

    1.Leaflet-polycolor github地址:https://github.com/Oliv/leaflet-polycolor 插件缺陷:需要把每个折点的颜色都指定才行,一般做不到 2. ...

  5. CMD文件内容统计程序简单版本

    WordCount命令行程序通过CMD接收参数,输出统计结果到指定文件. 项目码云地址:https://gitee.com/ggtc/WordCount.git 实现的功能有: 统计文件字符数 1 u ...

  6. 记一次DRF问题排障

    1 最近在搞django,在写一个接口的时候用到了APIview,之后再调用接口的时候一直显示405,不允许使用post方法 视图

  7. 分享一个Byte KB MB GB 单位转换方法 从《C#本质论第三版》

    static public string FormatBytes(long bytes) { string[] magnitudes = new string[] { "GB", ...

  8. HTML——select下拉选择标签

    select的基本语法: <select> <option></option> </select> 例子: <p>籍贯: <selec ...

  9. OpenQA.Selenium.WebDriverException The HTTP request to the remote WebDriver server for URL timed out

    OpenQA.Selenium.WebDriverException:"The HTTP request to the remote WebDriver server for URL htt ...

  10. 鸿蒙极速入门(一)-HarmonyOS简介

    1.华为官网介绍 2.OpenHarmony开源项目 3.技术架构 内核层 内核子系统:采用多内核(Linux内核或者LiteOS)设计,支持针对不同资源受限设备选用适合的OS内核 驱动子系统:驱动框 ...