2. 说好不哭,HelloWorld

通过上一篇文章的摸爬滚打,一个“完整”的kubernetes集群已经出现在我们眼前。通过目光可以看出我们现在是又兴奋又焦虑…
k8s有是有了,它怎么用???
它怎么用???
它怎么用???
(我也是一脸懵逼,但我不敢说啊

(硬着头皮
那我们先来摸索一下,k8s界的helloworld:echoserver

Deployment

名如其人,这就是k8s的部署模块
首先我们先创建一个名为test的namespace来关联我们的测试行为

namespace是什么:Namespace(命名空间)是kubernetes系统中的另一个重要的概念,通过将系统内部的对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享使用整个集群的资源的同时还能被分别管理。

我们可以通过创建一个Kubernetes Deployment对象来运行一个应用, 可以在一个YAML文件中描述Deployment. 例如, 下面这个YAML文件描述了一个k8s界的helloworld

apiVersion: extensions/v1beta1
kind: Deployment // 定义对象类型
metadata:
  name: my-blog   // 定义服务名称
  namespace: test  // 定义namespace
spec:
  replicas: 1  // 定义该服务在集群中初始部署的个数,这也是未来能够支撑我们发布并发出轨文章的重要参数之一
  selector:
    matchLabels:
      app: my-blog
  template:
    metadata:
      labels:
        app: my-blog
    spec:
      containers:  // 定义POD中容器的具体信息
      - name: my-blog
        image: googlecontainer/echoserver:1.10
        ports:
        - containerPort: 8080 // 定义容器对外暴露的端口
        env:  // 设置容器的环境变量
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP

通过内容可以看出,这是一个被命名为my-blog的项目,监听容器的8080端口,容器镜像是一个docker hub上公共的echoserver镜像
我们将上述内容保存在一个echoserver.yaml文件中
通过执行命令 kubectl create -f echoserver.yaml 可以看到控制台输出 deployment.extensions/my-blog created 则表示我们的demo已经被部署在了k8s集群中

验证:

$ kubectl get deploy -n test
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
my-blog   1/1     1            1           3h22m

验证无误!
接下来我们就试着请求一下看看,是否可以真的工作

// 由于本专栏的重点是从0-1部署个人博客,所以k8s相关的操作就简单解释一下:P
// 首先我们先获取由上一步deploy出来的pod信息
$ kubectl get pod -n test -o wide
NAME                       READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
my-blog-7bcb7cdb76-jkcsh   1/1     Running   0          3h25m   172.16.0.5   10.0.0.9   <none>           <none>

什么是POD:在Kubernetes中,最小的管理元素不是一个个独立的容器,而是Pod,Pod是最小的,管理,创建,计划的最小单元。

一个Pod(就像一群鲸鱼,或者一个豌豆夹)相当于一个共享context的配置组,在同一个context下,应用可能还会有独立的cgroup隔离机制,一个Pod是一个容器环境下的“逻辑主机”,它可能包含一个或者多个紧密相连的应用,这些应用可能是在同一个物理主机或虚拟机上。

Pod 的context可以理解成多个linux命名空间的联合

PID 命名空间(同一个Pod中应用可以看到其它进程)

网络 命名空间(同一个Pod的中的应用对相同的IP地址和端口有权限)

IPC 命名空间(同一个Pod中的应用可以通过VPC或者POSIX进行通信)

UTS 命名空间(同一个Pod中的应用共享一个主机名称)

同一个Pod中的应用可以共享磁盘,磁盘是Pod级的,应用可以通过文件系统调用,额外的,一个Pod可能会定义顶级的cgroup隔离,这样的话绑定到任何一个应用(好吧,这句是在没怎么看懂,就是说Pod,应用,隔离)

找到POD IP后我们尝试对它发起一个GET请求,

$ curl 172.16.0.5:8080 // 上述配置文件显示,my-blog这个项目的容器对外监听的是8080端口

// 成功得到请求结果
Hostname: my-blog-7bcb7cdb76-jkcsh

Pod Information:
    node name:    10.0.0.9
    pod name:    my-blog-7bcb7cdb76-jkcsh
    pod namespace:    test
    pod IP:    172.16.0.5

Server values:
    server_version=nginx: 1.13.3 - lua: 10008

Request Information:
    client_address=172.16.0.1
    method=GET
    real path=/
    query=
    request_version=1.1
    request_scheme=http
    request_uri=http://172.16.0.5:8080/

Request Headers:
    accept=*/*
    host=172.16.0.5:8080
    user-agent=curl/7.47.0

Request Body:
    -no body in request-

感动,居然成功了。想想我们把它换成真正的博客页面,那是多么美好的一件事情!
不对…
这个POD的IP是怎么回事?172.16.0.5这个IP我好想没见过啊,我的机器不是这个IP啊!
前面有讲到,Kubernetes的最小部署单元是Pod。k8s利用Flannel(或其他网络插件)作为不同HOST之间容器互通技术时,由Flannel和etcd维护了一张节点间的路由表。Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

每个Pod启动时,会自动创建一个镜像为gcr.io/google_containers/pause:0.8.0的容器,容器内部与外部的通信经由此容器代理,该容器的IP也可以称为Pod IP。

原来啊,这些IP是Flannel创建出来的一个个内网IP地址,顾名思义,这个IP只有在集群网络内才可以通信。那作为博客站点,光能自己看有啥意思啊!唉,感觉忙活了半天坑了自己。

好在今天还是有点收获,实现了k8s的helloworld。但是只能内网通信的POD……..可咋整???

    原文作者:holdno
    原文地址: https://segmentfault.com/a/1190000020413762
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞