2-说好不哭HelloWorld

7次阅读

共计 3058 个字符,预计需要花费 8 分钟才能阅读完成。

通过上一篇文章的摸爬滚打,一个“完整”的 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…….. 可咋整???

正文完
 0