我试过在OSX上使用Vagrant和CoreOS来尝试Kubernetes

我在OSX + Vagrant + CoreOS上尝试了Kubernetes,并做了一些整理,下面是我的备忘录。请注意,由于整理了一些步骤,可能不能直接运行。

借鉴

    • GoogleCloudPlatform/kubernetes

 

    • Running Kubernetes Example on CoreOS, Part 1

 

    • Running CoreOS on Vagrant

 

    kelseyhightower/kubernetes-coreos

步骤

使用Vagrant启动CoreOS,并进行SSH登录。

参照Running CoreOS on Vagrant的Vagrantfile进行获取并启动。在CoreOS上运行Kubernetes示例,第一部分。

这个教程只需要一个节点的集群即可。

在config.rb文件中,由于某个原因,$num_instances可以保持为1。因此,我直接使用了所有注释行的config.rb.sample文件。

git clone https://github.com/coreos/coreos-vagrant.git
cd coreos-vagrant
cp config.rb.sample
vagrant up

一旦启动后,使用SSH进行登录。

vagrant ssh

在CoreOS上设置和启动Kubernetes服务

根据kelseyhightower/kubernetes-coreos的步骤来运行CoreOS上的Kubernetes示例,因为《在CoreOS上运行Kubernetes示例,第1部分》的说明已经过时。

创建一个 Kubernetes 安装目录。

在这里,我参考了kelseyhightower/kubernetes-coreos的”Running Kubernetes Example on CoreOS, Part 1″,得出以下结果。

sudo mkdir -p /opt/kubernetes 
sudo chown -R core: /opt/kubernetes
cd /opt/kubernetes

安装Kubernetes的二进制文件

sudo mkdir -p /opt/bin
sudo wget http://storage.googleapis.com/kubernetes/binaries.tar.gz
sudo tar -xvf binaries.tar.gz -C /opt/bin

我会检查kubecfg是否在路径中。

core@core-01 /opt/kubernetes/kubernetes $ which kubecfg
/opt/bin/kubecfg

添加Kubernetes的systemd单位文件

git clone https://github.com/kelseyhightower/kubernetes-coreos.git
sudo cp kubernetes-coreos/units/* /etc/systemd/system/

启动Kubernetes服务

sudo systemctl start apiserver
sudo systemctl start controller-manager
sudo systemctl start kubelet
sudo systemctl start proxy

显示pod列表

因为我还没有创建任何东西,所以是空的。

core@core-01 /opt/kubernetes $ kubecfg list /pods
Name                Image(s)            Host                Labels
----------          ----------          ----------          ----------

Redis的示例成功运行。

我尝试运行了《在CoreOS上运行Kubernetes示例,第一部分》中的《创建一个Kubernetes容器》一节的例子。

在上述文章中,提到的是 /opt/kubernetes/bin/kubecfg,但是该文章中将其路径添加到了PATH中,所以在下面的内容中,只需使用 kubecfg 进行启动。另外,由于省略了 -h http://127.0.0.1:8080 的选项,程序也能正常运行。

我在CoreOS的/opt/kubernetes目录下运行了以下命令。

mkdir kubernetes-coreos/pods

cat <<EOF > kubernetes-coreos/pods/redis.json
{
  "id": "redis",
  "desiredState": {
    "manifest": {
      "version": "v1beta1",
      "id": "redis",
      "containers": [{
        "name": "redis",
        "image": "dockerfile/redis",
        "ports": [{
          "containerPort": 6379,
          "hostPort": 6379
        }]
      }]
    }
  },
  "labels": {
    "name": "redis"
  }
}
EOF

kubecfg -c kubernetes-coreos/pods/redis.json create /pods

我放置了一段时间(大约10分钟?),然后任务顺利完成了。我将显示Pod列表。

core@core-01 /opt/kubernetes $ kubecfg list /pods
Name                Image(s)            Host                Labels
----------          ----------          ----------          ----------
redis               dockerfile/redis    127.0.0.1/          name=redis

确认 docker0 接口的 IP 地址。

core@core-01 /opt/kubernetes $ ip a show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 10.1.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever

使用Docker启动Redis客户端进行操作验证。

core@core-01 /opt/kubernetes $ docker run -t -i dockerfile/redis /usr/local/bin/redis-cli -h 10.1.42.1
10.1.42.1:6379> keys *
(empty list or set)
10.1.42.1:6379> set foo bar
OK
10.1.42.1:6379> get foo
"bar"
10.1.42.1:6379> exit

让我们删除pod。

core@core-01 /opt/kubernetes $ kubecfg delete /pods/redis
I0721 03:23:40.857563 03173 request.go:220] Waiting for completion of /operations/3
Status
----------
success

我确认了Pod清单已经消失了。

core@core-01 /opt/kubernetes $ kubecfg list /pods
Name                Image(s)            Host                Labels
----------          ----------          ----------          ----------

Kubernetes源码中包含的guestbook示例在中途出现了问题。

我参考了GuestBook example的README并尝试了一下。

git clone https://github.com/GoogleCloudPlatform/kubernetes
cd kubernetes

提前准备

在GuestBook示例的”第零步:前提条件”中,”hack/dev-build-and-up.sh”似乎是在Google Cloud Engine上尝试时所需的脚本,所以我们不在这里执行它。

我试着运行了 hack/build-go.sh,但出现了一个错误,提示我尚未安装Go语言。

我后来发现,按照以下步骤进行的时候,我发现在hack/build-go.sh中构建的命令文件名与我之前提到的“安装Kubernetes二进制文件”一节中提到的http://storage.googleapis.com/kubernetes/binaries.tar.gz中下载的文件名是相同的。虽然命令文件的大小不同,但是似乎不需要执行以下的“安装go”和hack/build-go.sh的步骤。

进行go的安装

core@core-01 ~ $ uname -m
x86_64

当确认是x86_64架构后,您可以从 “Downloads – The Go Programming Language” 下载 go1.3.linux-amd64.tar.gz 文件并进行安装。

希望將GOPATH設置為~/go,因此我原本打算將安裝目錄設置為/usr/local/go,但嘗試了sudo mkdir /usr/local/go等命令後,卻出現了Read-only file system錯誤,因此我改為在/opt/go安裝。

cd
wget http://golang.org/dl/go1.3.linux-amd64.tar.gz
sudo tar xf go1.3.linux-amd64.tar.gz -C /opt

接下来,我们需要创建GOPATH目录。

mkdir ~/go

/.bash_profile 是一个符号链接。

core@core-01 ~ $ ls -l ~/.bash_profile
lrwxrwxrwx 1 core core 34 Jul 16 02:52 /home/core/.bash_profile -> ../../usr/share/skel/.bash_profile

刪除並複製

core@core-01 ~ $ rm .bash_profile
core@core-01 ~ $ cp /usr/share/skel/.bash_profile .bash_profile

我已经添加了以下设置(但不确定是否符合CoreOS的规范)。

cat <<'EOF' >> ~/.bash_profile

export GOROOT=/opt/go
export GOPATH=~/go
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
EOF
exec $SHELL -l
core@core-01 ~ $ which go
/opt/go/bin/go
core@core-01 ~ $ go version
go version go1.3 linux/amd64

执行 hack/build-go.sh

core@core-01 ~ $ cd /opt/kubernetes/kubernetes
core@core-01 /opt/kubernetes/kubernetes $ hack/build-go.sh
+++ Building proxy
+++ Building integration
+++ Building apiserver
+++ Building controller-manager
+++ Building kubelet
+++ Building kubecfg

源代码位于cmd目录中。

core@core-01 /opt/kubernetes/kubernetes $ find cmd -type f -ls
  8974    4 -rw-r--r--   1 core     core         3114 Jul 21 03:29 cmd/apiserver/apiserver.go
  8976    4 -rw-r--r--   1 core     core         1905 Jul 21 03:29 cmd/controller-manager/controller-manager.go
  8978   12 -rw-r--r--   1 core     core         9421 Jul 21 03:29 cmd/integration/integration.go
  8980    8 -rw-r--r--   1 core     core         7687 Jul 21 03:29 cmd/kubecfg/kubecfg.go
  8982    4 -rw-r--r--   1 core     core         3836 Jul 21 03:29 cmd/kubelet/kubelet.go
  8984    4 -rw-r--r--   1 core     core         2187 Jul 21 03:29 cmd/proxy/proxy.go

已经在output/go目录中创建了编译好的二进制文件。

core@core-01 /opt/kubernetes/kubernetes $ ls -l output/go
total 50852
-rwxr-xr-x 1 core core 10412840 Jul 21 14:23 apiserver
-rwxr-xr-x 1 core core  7893672 Jul 21 14:23 controller-manager
-rwxr-xr-x 1 core core  9233288 Jul 21 14:23 integration
-rwxr-xr-x 1 core core  8522640 Jul 21 14:23 kubecfg
-rwxr-xr-x 1 core core  8523160 Jul 21 14:23 kubelet
-rwxr-xr-x 1 core core  7471752 Jul 21 14:23 proxy
drwxr-xr-x 1 core core       20 Jul 21 14:23 src

我安装在/opt/bin目录下的二进制文件有以下五个。

    • apiserver

 

    • controll-manager

 

    • kubecfg

 

    • kubelet

 

    proxy

输出/在这个项目中,除了上述的integration二进制文件之外,还有一个名为go的输出。如果我们搜索源码,可能会找到相关信息。

${KUBE_TARGET}/linux/amd64/integration

似乎是被调用并用于集成测试的命令。

我已经停止了服务,并将除了integration之外的所有文件复制到/opt/bin/目录下。

core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl stop apiserver
core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl stop controller-manager
core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl stop kubelet
core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl stop proxy
core@core-01 /opt/kubernetes/kubernetes $ sudo cp output/go/{apiserver,controller-manager,kubecfg,kubelet,proxy} /opt/bin

随后,我们启动了服务。

core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl start apiserver
core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl start controller-manager
core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl start kubelet
core@core-01 /opt/kubernetes/kubernetes $ sudo systemctl start proxy

因此,我尝试继续执行,但最终发现redis-slave的启动仍未完成,情况没有改变。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg -c examples/guestbook/redis-slave-controller.json create /replicationControllers
I0721 14:55:39.058324 01343 request.go:220] Waiting for completion of /operations/9
I0721 14:55:59.062134 01343 request.go:220] Waiting for completion of /operations/9
^C

启动 Redis 主服务器

检查存储库中包含的配置文件。

core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/redis-master.json
{
  "id": "redis-master-2",
  "desiredState": {
    "manifest": {
      "version": "v1beta1",
      "id": "redis-master-2",
      "containers": [{
        "name": "master",
        "image": "dockerfile/redis",
        "ports": [{
          "containerPort": 6379,
          "hostPort": 6379
        }]
      }]
    }
  },
  "labels": {
    "name": "redis-master"
  }
}

请使用以下命令启动。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg -c examples/guestbook/redis-master.json create /pods
I0721 03:47:11.215798 03349 request.go:220] Waiting for completion of /operations/8
I0721 03:47:31.218575 03349 request.go:220] Waiting for completion of /operations/8
Name                Image(s)            Host                Labels
----------          ----------          ----------          ----------
redis-master-2      dockerfile/redis    /                   name=redis-master

我会检查一下pod的列表。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /pods
Name                Image(s)            Host                Labels
----------          ----------          ----------          ----------
redis-master-2      dockerfile/redis    127.0.0.1/          name=redis-master

我尝试使用 docker ps 命令查看了 Docker 的状态。

core@core-01 /opt/kubernetes/kubernetes $ docker ps
CONTAINER ID        IMAGE                       COMMAND                CREATED              STATUS              PORTS                    NAMES
e45fe7b25100        dockerfile/redis:latest     redis-server /etc/re   About a minute ago   Up About a minute                            k8s--master--redis_-_master_-_2--4befd1d1
787bb5ddf655        busybox:buildroot-2014.02   sh -c 'rm -f nap &&    About a minute ago   Up About a minute   0.0.0.0:6379->6379/tcp   k8s--net--redis_-_master_-_2--f8803f12

在 GuestBook 的示例 README 文件中,只显示了一行关于 redis-server 的配置 “/etc/re”,但是在这里显示了两行。

在GuestBook的示例的README中,它是在Google Computing Engine上运行的,但是在这里,它是在CoreOS上运行,所以似乎有一些差异。

启动主服务

根据GuestBook示例的README文件所述

Kubernetes中的“service”是一个命名的负载均衡器,用于代理流量到一个或多个容器。Kubernetes集群中的服务可以通过环境变量在其他容器中进行发现。服务根据pod标签来找到需要进行负载均衡的容器。

听说如此。

检查存储库中包含的配置文件。

core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/redis-master-service.json
{
  "id": "redismaster",
  "port": 10000,
  "selector": {
    "name": "redis-master"
  }
}

请使用以下指令启动。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg -c examples/guestbook/redis-master-service.json create /services
I0721 03:56:40.888615 03412 request.go:220] Waiting for completion of /operations/9
Name                Labels              Selector            Port
----------          ----------          ----------          ----------
redismaster                             name=redis-master   10000

显示服务列表时内容相同。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /services
Name                Labels              Selector            Port
----------          ----------          ----------          ----------
redismaster                             name=redis-master   10000

启动Slave的pod。

查看存储库中包含的配置文件。

core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/redis-slave-controller.json
  {
    "id": "redisSlaveController",
    "desiredState": {
      "replicas": 2,
      "replicaSelector": {"name": "redisslave"},
      "podTemplate": {
        "desiredState": {
           "manifest": {
             "version": "v1beta1",
             "id": "redisSlaveController",
             "containers": [{
               "image": "brendanburns/redis-slave",
               "ports": [{"containerPort": 6379, "hostPort": 6380}]
             }]
           }
         },
         "labels": {"name": "redisslave"}
        }},
    "labels": {"name": "redisslave"}
  }

我试着启动了一下,但是因为一直重复显示“等待完成”,而且没有停止,所以我用Ctrl+C停止了它。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg -c examples/guestbook/redis-slave-controller.json create /replicationControllers
I0721 04:24:00.818199 03499 request.go:220] Waiting for completion of /operations/67
I0721 04:24:20.823015 03499 request.go:220] Waiting for completion of /operations/67
I0721 04:24:40.826668 03499 request.go:220] Waiting for completion of /operations/67
…(略)…
^C

由于 redis-slave 的 Dockerfile 也包含在存储库中,我尝试查看了其内容,并发现如下所示。

core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/redis-slave/Dockerfile
FROM dockerfile/redis

ADD run.sh /run.sh

RUN chmod a+x /run.sh

CMD /run.sh
core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/redis-slave/run.sh
#!/bin/bash

redis-server --slaveof $SERVICE_HOST $REDISMASTER_SERVICE_PORT

只是启动redis-server而已,不可能花这么长时间,似乎有什么问题。

当尝试显示/replicationControllers清单时,似乎已成功创建。

core@core-01 /opt/kubernetes/kubernetes/examples/guestbook $ kubecfg list /replicationControllers
Name                   Image(s)                   Selector            Replicas
----------             ----------                 ----------          ----------
redisSlaveController   brendanburns/redis-slave   name=redisslave     2

我尝试显示/pods的列表。步骤三:启动复制的从pod。但是,在我的环境中只显示了一个brendanburns/redis-slave的pod,而不是两个。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /pods
Name                                   Image(s)                   Host                Labels
----------                             ----------                 ----------          ----------
redis-master-2                         dockerfile/redis           127.0.0.1/          name=redis-master
169d845e-108c-11e4-b2af-0800273da0c1   brendanburns/redis-slave   127.0.0.1/          name=redisslave,replicationController=redisSlaveController

因为不太清楚正在发生什么以及原因,所以我先尝试着往前走了一步。

启动Redis从服务。

我们将检查存储库中包含的配置文件。

core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/redis-slave-service.json
{
  "id": "redisslave",
  "port": 10001,
  "labels": {
    "name": "redisslave"
  },
  "selector": {
    "name": "redisslave"
  }
}

启动服务。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg -c examples/guestbook/redis-slave-service.json create /services
I0721 04:44:42.565445 03593 request.go:220] Waiting for completion of /operations/128
Name                Labels              Selector            Port
----------          ----------          ----------          ----------
redisslave          name=redisslave     name=redisslave     10001

这个事情已经顺利结束了。

我来看一下/services和/pods的列表。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /services
Name                Labels              Selector            Port
----------          ----------          ----------          ----------
redismaster                             name=redis-master   10000
redisslave          name=redisslave     name=redisslave     10001

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /pods
Name                                   Image(s)                   Host                Labels
----------                             ----------                 ----------          ----------
redis-master-2                         dockerfile/redis           127.0.0.1/          name=redis-master
169d845e-108c-11e4-b2af-0800273da0c1   brendanburns/redis-slave   127.0.0.1/          name=redisslave,replicationController=redisSlaveController

创建前端的 pod

我们将参考GoogleCloudPlatform/kubernetes的示例中的guestbook/README.md进行操作。

查看存储库中的配置文件。

core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/frontend-controller.json
  {
    "id": "frontendController",
    "desiredState": {
      "replicas": 3,
      "replicaSelector": {"name": "frontend"},
      "podTemplate": {
        "desiredState": {
           "manifest": {
             "version": "v1beta1",
             "id": "frontendController",
             "containers": [{
               "image": "brendanburns/php-redis",
               "ports": [{"containerPort": 80, "hostPort": 8000}]
             }]
           }
         },
         "labels": {"name": "frontend"}
        }},
    "labels": {"name": "frontend"}
  }

由于examples/guestbook/php-redis/中似乎有一个Dockerfile,我也会检查它以确认。

core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/php-redis/Dockerfile
FROM brendanburns/php

ADD index.php /var/www/index.php
ADD controllers.js /var/www/controllers.js
ADD index.html /var/www/index.html

CMD /run.sh
core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/php-redis/index.php
<?

set_include_path('.:/usr/share/php:/usr/share/pear:/vendor/predis');

error_reporting(E_ALL);
ini_set('display_errors', 1);

require 'predis/autoload.php';

if (isset($_GET['cmd']) === true) {
  header('Content-Type: application/json');
  if ($_GET['cmd'] == 'set') {
    $client = new Predis\Client([
      'scheme' => 'tcp',
      'host'   => getenv('SERVICE_HOST'),
      'port'   => getenv('REDISMASTER_SERVICE_PORT'),
    ]);
    $client->set($_GET['key'], $_GET['value']);
    print('{"message": "Updated"}');
  } else {
    $read_port = getenv('REDISMASTER_SERVICE_PORT');

    if (isset($_ENV['REDISSLAVE_SERVICE_PORT'])) {
      $read_port = getenv('REDISSLAVE_SERVICE_PORT');
    }
    $client = new Predis\Client([
      'scheme' => 'tcp',
      'host'   => getenv('SERVICE_HOST'),
      'port'   => $read_port,
    ]);

    $value = $client->get($_GET['key']);
    print('{"data": "' . $value . '"}');
  }
} else {
  phpinfo();
} ?>
core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/php-redis/index.html
<html ng-app="redis">
  <head>
    <title>Guestbook</title>
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
    <script src="/controllers.js"></script>
    <script src="ui-bootstrap-tpls-0.10.0.min.js"></script>
  </head>
  <body ng-controller="RedisCtrl">
    <div style="width: 50%; margin-left: 20px">
      <h2>Guestbook</h2>
    <form>
    <fieldset>
    <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br>
    <button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button>
    </fieldset>
    </form>
    <div>
      <div ng-repeat="msg in messages">
        {{msg}}
      </div>
    </div>
    </div>
  </body>
</html>
core@core-01 /opt/kubernetes/kubernetes $ cat examples/guestbook/php-redis/controllers.js
var redisApp = angular.module('redis', ['ui.bootstrap']);

/**
 * Constructor
 */
function RedisController() {}

RedisController.prototype.onRedis = function() {
    this.scope_.messages.push(this.scope_.msg);
    this.scope_.msg = "";
    var value = this.scope_.messages.join();
    this.http_.get("/index.php?cmd=set&key=messages&value=" + value)
            .success(angular.bind(this, function(data) {
                this.scope_.redisResponse = "Updated.";
            }));
};

redisApp.controller('RedisCtrl', function ($scope, $http, $location) {
        $scope.controller = new RedisController();
        $scope.controller.scope_ = $scope;
        $scope.controller.location_ = $location;
        $scope.controller.http_ = $http;

        $scope.controller.http_.get("/index.php?cmd=get&key=messages")
            .success(function(data) {
                console.log(data);
                $scope.messages = data.data.split(",");
            });
});

使用以下命令启动服务。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg -c examples/guestbook/frontend-controller.json create /replicationControllers
I0721 04:47:55.237466 03614 request.go:220] Waiting for completion of /operations/138
I0721 04:48:15.242877 03614 request.go:220] Waiting for completion of /operations/138
I0721 04:48:35.246837 03614 request.go:220] Waiting for completion of /operations/138
…(略)…
^C

因为他一直没有回来,所以我按下了Ctrl-C来停止并检查了状态。

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /pods
Name                                   Image(s)                   Host                Labels
----------                             ----------                 ----------          ----------
redis-master-2                         dockerfile/redis           127.0.0.1/          name=redis-master
169d845e-108c-11e4-b2af-0800273da0c1   brendanburns/redis-slave   127.0.0.1/          name=redisslave,replicationController=redisSlaveController
45ff7456-1092-11e4-b2af-0800273da0c1   brendanburns/php-redis     127.0.0.1/          name=frontend,replicationController=frontendController

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /replicationControllers
Name                   Image(s)                   Selector            Replicas
----------             ----------                 ----------          ----------
redisSlaveController   brendanburns/redis-slave   name=redisslave     2
frontendController     brendanburns/php-redis     name=frontend       3

core@core-01 /opt/kubernetes/kubernetes $ kubecfg list /services
Name                Labels              Selector            Port
----------          ----------          ----------          ----------
redismaster                             name=redis-master   10000
redisslave          name=redisslave     name=redisslave     10001

尝试使用curl访问http://localhost:8000时,返回了guestbook页面。

core@core-01 /opt/kubernetes/kubernetes $ curl http://localhost:8000
<html ng-app="redis">
  <head>
    <title>Guestbook</title>
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
    <script src="/controllers.js"></script>
    <script src="ui-bootstrap-tpls-0.10.0.min.js"></script>
  </head>
  <body ng-controller="RedisCtrl">
    <div style="width: 50%; margin-left: 20px">
      <h2>Guestbook</h2>
    <form>
    <fieldset>
    <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br>
    <button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button>
    </fieldset>
    </form>
    <div>
      <div ng-repeat="msg in messages">
        {{msg}}
      </div>
    </div>
    </div>
  </body>
</html>

当用OSX系统中的Chrome浏览器打开http://172.17.8.101:8000/时,可以看到以下的显示内容。

guestbook.png

然而,无论输入什么然后点击提交按钮,都没有任何反应。

当您重新加载http://172.17.8.101:8000/并查看Chrome的开发工具控制台时,发现了JavaScript错误。

guestbook_js_error.png
br />
<b>Fatal error</b>:  Uncaught exception 'Predis\Connection\ConnectionException' with message 'Connection refused [tcp://127.0.0.1:10000]' in /vendor/predis/predis/lib/Predis/Connection/AbstractConnection.php:141
Stack trace:
#0 /vendor/predis/predis/lib/Predis/Connection/StreamConnection.php(96): Predis\Connection\AbstractConnection-&gt;onConnectionError('Connection refu...', 111)
#1 /vendor/predis/predis/lib/Predis/Connection/StreamConnection.php(70): Predis\Connection\StreamConnection-&gt;tcpStreamInitializer(Object(Predis\Connection\ConnectionParameters))
#2 /vendor/predis/predis/lib/Predis/Connection/AbstractConnection.php(96): Predis\Connection\StreamConnection-&gt;createResource()
#3 /vendor/predis/predis/lib/Predis/Connection/StreamConnection.php(144): Predis\Connection\AbstractConnection-&gt;connect()
#4 /vendor/predis/predis/lib/Predis/Connection/AbstractConnection.php(181): Predis\Connection\StreamConnection-&gt;connect()
#5 /vendor/predis/predis/lib/Predis/Connection/StreamConnection.php(183): Predis\Connection\AbstractConnection-&gt;ge in <b>/vendor/predis/predis/lib/Predis/Connection/AbstractConnection.php</b> on line <b>141</b><br />
 controllers.js:26


TypeError: Cannot read property 'split' of undefined
    at http://172.17.8.101:8000/controllers.js:27:37
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:66:373
    at A (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:93:5)
    at A (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:93:5)
    at https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:94:173
    at h.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:102:456)
    at h.$digest (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:100:218)
    at h.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:103:264)
    at f (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:67:120)
    at H (https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js:71:191) angular.js:9435

看起来predis无法连接到tcp://127.0.0.1:10000。为什么端口是10000仍然是个谜。根据上述的index.php文件,如果设置了REDISSLAVE_SERVICE_PORT环境变量,则使用该值,如果没有设置,则使用REDISMASTER_SERVICE_PORT环境变量的值。

在这个时间点上,docker ps的情况如下所示。

core@core-01 /opt/kubernetes/kubernetes $ docker ps --no-trunc
CONTAINER ID                                                       IMAGE                             COMMAND                                           CREATED             STATUS              PORTS                    NAMES
150252488eb48d673ea27cc624f67d19894b0e6f7131b000d7f257b0fddff450   brendanburns/php-redis:latest     /bin/sh -c /run.sh                                46 minutes ago      Up 46 minutes                                k8s----45ff7456_-_1092_-_11e4_-_b2af_-_0800273da0c1--8fafe560
d0c0d44598a1fc7e18bf3e37d4332dad2af23a61644092d3f7fb24344d6e0a1d   busybox:buildroot-2014.02         sh -c 'rm -f nap && mkfifo nap && exec cat nap'   50 minutes ago      Up 50 minutes       0.0.0.0:8000->80/tcp     k8s--net--45ff7456_-_1092_-_11e4_-_b2af_-_0800273da0c1--94270597
0f4f8e809955377da2c176e0114795fa23d38f7d18e6237e27332a8a861ec101   brendanburns/redis-slave:latest   /bin/sh -c /run.sh                                About an hour ago   Up About an hour                             k8s----169d845e_-_108c_-_11e4_-_b2af_-_0800273da0c1--c8c817c2
56c29b155bab49ac10f76e963c7c431555accb4881a9d9dcf12952ed85265738   busybox:buildroot-2014.02         sh -c 'rm -f nap && mkfifo nap && exec cat nap'   About an hour ago   Up About an hour    0.0.0.0:6380->6379/tcp   k8s--net--169d845e_-_108c_-_11e4_-_b2af_-_0800273da0c1--196db470
e45fe7b2510009127e2700cb628a2ac2fc3cfafff2278040d2d0d26fc21a6935   dockerfile/redis:latest           redis-server /etc/redis/redis.conf                About an hour ago   Up About an hour                             k8s--master--redis_-_master_-_2--4befd1d1
787bb5ddf655ef576b1425f64772291296ce5cc983836153787a56587ad41c85   busybox:buildroot-2014.02         sh -c 'rm -f nap && mkfifo nap && exec cat nap'   About an hour ago   Up About an hour    0.0.0.0:6379->6379/tcp   k8s--net--redis_-_master_-_2--f8803f12

Redis的从服务器端口是6380,主服务器端口是6379,所以端口变成10000是不正常的。也许,brendanburns/php-redis镜像在Docker Hub注册的Dockerfile和index.php与上述确认的可能不同。

因为我累了,所以暂时就到这里吧。如果心血来潮的话,我会在本地使用docker build再次尝试,而不是从Docker Hub下载。

广告
将在 10 秒后关闭
bannerAds