Kubernetes(k3s)基础学习(二) -- 基于最小的pod单元来创建应用

我们先来看看Kubernetes最基础的知识吧。最初接触Kubernetes时候,一般初学者都会被一大堆单词所迷惑(例如:Deployment、Pod、ReplicationController、ReplicaSet、Service等)。笔者刚开始学习时也遭遇到这种困境。但是,任何复杂的系统都是发源于最基本的公式或定理,Kubernetes虽然庞大且复杂,不过只要抓住一些基本的脉络(一些最基本的组件的定义及使用),入门便也是毫不费劲。
重点:曾经的笔者,幻想着这产品在业界这么成熟了,是不是可以借助于某些成熟的工具(如cubeAdmin、之流)而不用掌握yml以及命令行语法就可以轻松入门?如果你也有这样的想法,建议你及早抛弃掉。

Kubernetes架构图

Kubernetes架构图

Kubernetes 最常用的组件介绍

\color{#FF0000}{Node} Node(节点)是 kubernetes 集群中的计算机,可以是虚拟机或物理机。每个 Node(节点)都由 master 管理。一个 Node(节点)可以有多个Pod(容器组),kubernetes master 会根据每个 Node(节点)上可用资源的情况,自动调度 Pod(容器组)到最佳的 Node(节点)上。

\color{#FF0000}{Pod} Pod 是一个Kubernetes中一个抽象的概念,用于存放一组 container(可包含一个或多个 container 容器),以及这些 container (容器)的一些共享资源,是Kubernetes 的最小单位。

\color{#FF0000}{Deployment} 译名为 部署。通过发布 Deployment,可以创建应用程序 (docker image) 的实例 (docker container),在旧版本的Kubernetes里,还有着ReplicationController,你可以认为Deployment属于ReplicationController的升级版。

\color{#FF0000}{Sercie} Kubernetes 中的 Service 提供了负载的抽象层,它选择具备某些特征的 Pod(容器组)并为它们定义一个访问方式。Service(服务)使 Pod(容器组)之间的相互依赖解耦(原本从一个 Pod 中访问另外一个 Pod,需要知道对方的 IP 地址)。一个 Service(服务)选定哪些 Pod(容器组) 通常由 LabelSelector(标签选择器) 来决定。

\color{#FF0000}{Ingress} 一种全局的、为了代理不同后端 Service 而设置的负载均衡服务。Ingress由两部分组成:Ingress controller和Ingress服务。

如果按照上述的架构图+ 一堆概念的文字来读,是很难搞明白这些组件会起到怎样的作用。 如果我拿个“公司”来做个比喻的话,假设我把Kubenetes 当作一家正在运作的企业,Node 代表这家企业会拥有多少个办公场地。某一天业务做大有钱了以及业务需要扩建了,企业就可以通过买更多办公场地(Node)来扩大业务。

某一天,企业接到了新项目,当然要组建团队来服务这个项目,这个所组建的团队名字就叫做Pod(容器组)了,团队成员就是容器了,它可以是Java、可以是PHP或者是NodeJS等。

有了Pod ,那得有场所空间给他们干活,也得有人指挥调度。假设项目太大,一个团队忙不过来怎么办,得多弄几个团队一起做大买卖。那谁来负责给Pod(容器组) 去向Node申请空间,以及动态扩容团队数量 这个调度呢?这就是Deployment 的工作(兼负着公司内政的角色)。

Service ,主要做分发的工作。从业务上可以理解成一名客服吧。就像某云、某信,用户不能直接触达内部的技术人员(Pod), 只能打客服热线或者是发起工单,把请求抛给Service ,再由Service 分配给Pod 来处理。像极了nginx 里面的upstream。

如果把Service 比作成客服, Ingress 就是用户要拨打过去的热线电话。 它主要管理着域名与service ip地址的映射关系,以及做高并发的限流、负载均衡工作。 顾名思义Ingress Nginx 。

注:Deployment 、Service、Ingress 均部署在Master节点,所有流量的入口都在Master机器上(k3s与k8s最大的区别,在于Master节点能否集群)。 而Pod 则由Deployment调配 到不同的Node节点。

使用Pod 创建一个内部可访问的容器

  • 测试准备工作
    理解好上面的概念后,让我们尝试在 Kubernetes 中跑我们的应用。在 Kubernetes 中,作为最小单元的pod其实是由容器组成的。所以我们需要有容器相关的开发环境,目前在本地开发环境方,比较常用是的 Docker 公司开发的 Docker Desktop和 Rancher 公司开始的 Rancher Desktop,这两个软件都包含了 docker 工具,并且都同时支持 Windows 和 macOS。目前我在Mac机上使用的是Docker Desktop。在Mac机的最上面会出现一个小船图标。
    Dockeer Destop的小船图标

    安装完成后,测试Docker 是启动成功,执行命令
docker version
  • 建立一个测试使用的NodeJS Demo
    使用阿里云的EggJS 框架 快速建立一个Hello Demo。
#k3s-test 是项目目录
$ mkdir k3s-test && cd k3s-test
$ npm init egg --type=simple
$ npm i

编写一段简单的代码(如果嫌麻烦,也可以直接下载写好的Demo

#1、添加app/controller/home.js

'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
    async index() {
        this.ctx.body="Hello K8s!";
    }
}
module.exports = HomeController;




#2、添加app/router.js
'use strict';
/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
    const { router, controller } = app;
    router.get('/', controller.home.index);
    router.get('/index', controller.home.index);
};



#3、添加config/config.default.js以及config/config.prod.js
#相同代码
/* eslint valid-jsdoc: "off" */

'use strict';

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = appInfo => {
    
    /**
     * built-in config
     * @type {Egg.EggAppConfig}
     **/
    const config = exports = {
        bodyParser: {
            jsonLimit: '10mb',
            formLimit: '10mb'
        }
    };
    // 添加自定义 中间件配置
    config.middleware = [
        'util', // 参数解析中间件
    ];

    config.multipart = {
        mode: 'file',
        whitelist: ['.png', '.csv', '.jpg', '.jpeg', '.xlsx','.xls']
    };
    config.proxy = true;
    // use for cookie sign key, should change to your own and keep security
    config.keys = appInfo.name + '_1620702942813_3365';

    //公共存储目录
    config.bashSavePath = './private/';


    // add your user config here
    const userConfig = {
        // myAppName: 'egg',
    };



    config.security = {
        csrf: {
            enable: false,
        }
    };

    config.cluster = {
        listen: {
            port: 7001,
            hostname: '0.0.0.0'
            //0.0.0.0 很关键,否则外网访问没法通进。
        }
    };
    return {
        ...config,
        ...userConfig,
    };
};

这个简单的Demo,会基于7001端口进行监听,首先要确保代码在本机运行的正确性

#编译
npm run dev

#测试
curl http://localhost:7001

#输出内容
Hello K8s!%

运行成功后,执行打包命令

npm install --production
  • 生成Dockfile容器

创建一个Dockerfile 文件,与k3s-test 目录同级,如下图:


1650437878928.jpg

录入以下内容

#建于Node最新的镜像
FROM node:latest
#先在根目录下k3s-test目录迁移过去
COPY k3s-test/ /k3s-test/
#对目录进行授权
RUN chmod -R 777 /k3s-test
#设置为工作目录
WORKDIR /k3s-test
#输出7001端口
EXPOSE 7001
#启动执行npm run start
ENTRYPOINT ["npm", "run"]
CMD ["start"]

然后然后命令生成镜像。

#例如
docker build -t k3s-test:latest .

#成功后,应该先试着运行容器,检查是否成功
docker run -d -p 8080:7001 --name k3s-test k3s-test:latest

#测试
curl http://localhost:8080

#输出内容
Hello K8s!%

为了方便从其它地方能拉取镜像,我们必须有一个镜像仓库,最著名的就是 Docker Hub,你可以注册账号,上传自己的镜像。当然国内也有很多类似的服务,比如:阿里云。如果你还没有自己账号的镜像仓库,建议使用阿里云的 容器镜像服务,目前个人账号有 300 个免费的镜像额度,足够使用。 (注:阿里云镜像怎么使用,这里不具体说明了)
如果嫌创建镜像麻烦,也可以使用我创建好的Demo镜像地址(复制即可):\color{#FF0000}{registry.cn-hangzhou.aliyuncs.com/dawson-project/hello-node}

  • 部署到 k3s
    与k8s的命令是一致的,部署到 k3s 使用 kubectl 命令完成。部署时支持使用纯命令的方式,也支持 yml 描述文件的方式。这里我们使用 yml 描述文件的方式。使用Multipass 进入server节点(请参照上一篇文章:Kubernetes(k3s)学习(一) -- 使用集群部署
#进入server节点容器的命令
multipass shell server

#进入容器后,先创建文件:k3s-test.yml
sudo vi k3s-test.yml

#k3s-test.yml 的内容:

apiVersion: v1       #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Pod #指定要创建的类型
metadata: #译名为元数据,即 Pod 的一些基本属性和信息
  name: k3s-test    #这个pod 的名称
  labels:  #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: k3s-test     #app 为key ,k3s-test 为value,还可以定义多个
spec:      #关于这个pod 的描述
  containers:             #要加载的docker 的容器
  - name: k3s-test     #容器名称
    #容器要挂载的镜像
    image: registry.cn-hangzhou.aliyuncs.com/dawson-project/hello-node:latest                

我们在server 节点的根目录下已经创建好k3s-test.yml 文件,接下来执行创建命令即可。

#create 命令也可以创建,但一般强烈推荐使用apply 命令
sudo kubectl apply -f k3s-test.yml

#输出内容
pod/k3s-test created


#通过命令检查是否创建成功
sudo kubectl get pods -o wide


#得到输出结果
NAME                                      READY   STATUS    RESTARTS        AGE     IP           NODE    NOMINATED NODE   READINESS GATES
k3s-test                                  1/1     Running   0               18s     10.42.1.41   node1   <none>           <none>

#其中关键的节点解析
STATUS : Running 表示Pod 已经成功执行
RESTARTS: 表示重启的次数
IP 为Kubernetes 给这个Pod 分配的可访问的ip地址(外网无法访问)
NODE: 表示这个Pod 被分配到哪个Node节点上。

现在我们分别在server节点、node1节点和node2节点,以及再新开一个“终端”,在正常的本机进行访问,结果如下

#在server 节点访问的结果
ubuntu@server:~$ curl http://10.42.1.41:7001
#输出
Hello K8s!

#在node1节点以及node2访问的结果
ubuntu@node1:~$ curl http://10.42.1.41:7001
#输出
Hello K8s!

#在本机正常环境的访问
#输出
curl http://10.42.1.41:7001

#输出
#没有结果

总结

当在Kubenetes 创建了Pod后,Kubenetes 都会自动分配出唯一IP地址,这个IP地址可以在Kubenetes内网任意节点内进行访问。但对于外界来说是一个被隔离的环境,至于怎么能够打通与外界的联系呢?以及怎么玩弹性伸缩呢? 这属于service 和deployment 的职能范围了, 我们下一篇再讲。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容