---
title: PCF Dev(v0.20+)でCloud FoundryのTCP Routingを試す
tags: ["Cloud Foundry", "PCF Dev", "Pivotal Cloud Foundry"]
categories: ["Service", "PaaS", "CloudFoundry"]
date: 2016-10-14T19:23:09Z
updated: 2016-10-15T03:44:56Z
---

PCF 1.8から[TCP Routing](http://docs.pivotal.io/pivotalcf/1-8/devguide/deploy-apps/routes-domains.html)がサポートされて、ようやくCloud FoundryでHTTP以外も扱えるようになりました。
[PCF Dev](https://network.pivotal.io/products/pcfdev)はv0.20から使用可能です。

> 現時点では
> **複数ポートは未対応**です。
> **永続ストレージは未対応**です

### PCF Devを起動

このブログには何回も書いていますが、簡単にもう一度。

まずはじめに、 [Pivotal Network](https://network.pivotal.io/products/pcfdev)からpcfdevプラグインをダウンロードします（要Pivotal Networkアカウント）。OSごとに次の方法でpcfdevプラグインをインストールします。

* [OSX](https://docs.pivotal.io/pcf-dev/install-osx.html#install-pcf-dev)
* [Linux](https://docs.pivotal.io/pcf-dev/install-linux.html#install-pcf-dev)
* [Windows](https://docs.pivotal.io/pcf-dev/install-windows.html#install-pcf-dev)

プラグインをインストールしたら起動します。

```
cf dev start
```

初回はVMが降ってくるので10分くらい時間がかかります。

起動したら次のコマンドでログインします。

```
cf login -a https://api.local.pcfdev.io --skip-ssl-validation -u admin -p admin -o pcfdev-org
```

### Echo Serverをデプロイ

TCPサーバーのHello WorldであるEcho Serverを書いてデプロイします。

#### Echo Serverの作成

```
mkdir echo-server
cd echo-server
glide init
```

`main.go`に以下の内容を記述

``` go
package main

import (
	"bufio"
	"log"
	"net"
	"os"
)

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Println("Launching echo server on port " + port)
	ln, err := net.Listen("tcp", ":"+port)
	if err != nil {
		log.Fatal("Error(Listen)! ", err)
	}
	defer ln.Close()

	for {
		c, err := ln.Accept()
		if err != nil {
			log.Fatal("Error(Accept)! ", err)
		}
		go handleConnection(c)
	}
}

func handleConnection(c net.Conn) {
	bufr := bufio.NewReader(c)
	buf := make([]byte, 1024)

	for {
		readBytes, err := bufr.Read(buf)
		if err != nil {
			c.Close()
			return
		}
		message := string(buf[:readBytes])
		log.Print("Received " + message)
		c.Write([]byte(message))
	}
}
```

ローカルで確認

```
go run main.go
```
動作確認

```
$ echo Hello | nc localhost 8080
Hello
```

#### Echo ServerをPCF Devにデプロイ

TCP Routeのマッピングは

* `cf create-route` && `cf map-route`で手動マッピングする方法
* `manifest.yml`に`routes`を定義する方法

の2種類があります。

##### `cf create-route` && `cf map-route`で手動マッピングする方法


`create-route`の使い方は

```
cf create-route <space> <domain> --port <port>
```

利用可能なポート番号はCloud Foundryのインストール時に設定します。
PCF Devの場合は[61001-61100](https://github.com/pivotal-cf/pcfdev/blob/v0.21.0/manifest.yml#L207)です。
`--random-port`で空いているポートを自動で選択させることもできます。

```
cf create-route <space> <domain> --random-port
```

```
cf push echo-server -b go_buildpack -m 8m --no-start
cf create-route pcfdev-space tcp.local.pcfdev.io --port 61001
cf map-route echo-server tcp.local.pcfdev.io --port 61001
cf start echo-server
```

`cf apps`の結果は次のようになります。

```
$ cf apps
Getting apps in org pcfdev-org / space pcfdev-space as admin...
OK

name              requested state   instances   memory   disk   urls
echo-server       started           1/1         8M       512M   tcp.local.pcfdev.io:61001
```

動作確認

```
$ echo Hello | nc tcp.local.pcfdev.io 61001
Hello
```

🙌


##### `manifest.yml`に`routes`を定義する方法

次の`manifest.yml`を使えばワンコマンドでデプロイできます。

``` yaml
applications:
- name: echo-server
  routes:
  - route: tcp.local.pcfdev.io:61001
  buildpack: go_buildpack
  memory: 8m
```

あとは

```
cf push
```

でデプロイできます。こっちがオススメです。

#### Dockerイメージをデプロイ

PCF DevはDockerイメージのpushもサポートしています。Echo Serverを[`making/echo-server`](https://hub.docker.com/r/making/echo-server/)にデプロイ済みなのでこれを使えばソースコードなしでEcho ServerをPCF Devデプロイですます。

`manifest.yml`から`buildpack`を除きます。すでにbuildpackでデプロイしていたら`cf d -r -f echo-server`で削除します。

``` yaml
applications:
- name: echo-server
  routes:
  - route: tcp.local.pcfdev.io:61001
  memory: 8m
```

この`manifest.yml`を使って`making/echo-server`をpushします。

```
cf push --docker-image making/echo-server
```

その他いろいろなDockerイメージをCloud Fondryにデプロイしてみます(ただし、HTTPのものは除く)。

### Redisのデプロイ

[`redis`](https://hub.docker.com/_/redis/)のデプロイ。

`manifest.yml`

``` yaml
applications:
- name: redis
  memory: 256M
  routes:
  - route: tcp.local.pcfdev.io:61002
```

`cf push`

```
cf push --docker-image redis
```

動作確認

```
$ redis-cli -h tcp.local.pcfdev.io -p 61002
tcp.local.pcfdev.io:61002> set "foo" 100
OK
tcp.local.pcfdev.io:61002> get "foo"
"100"
```

### MySQLのデプロイ

[`mysql`](https://hub.docker.com/_/mysql/)のデプロイ。

`manifest.yml`

``` yaml
applications:
- name: mysql
  memory: 256M
  routes:
  - route: tcp.local.pcfdev.io:61003
  env:
    MYSQL_ROOT_PASSWORD: my-secret
```

`cf push`

```
cf push --docker-image mysql
```

動作確認

```
$ mysql -h tcp.local.pcfdev.io -u root -P 61003 -p
Enter password: my-secret
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2016-10-14 18:25:48 |
+---------------------+
1 row in set (0.01 sec)
```

### PostgreSQLのデプロイ

[`postgres`](https://hub.docker.com/_/postgres/)のデプロイ。

`manifest.yml`

``` yaml
applications:
- name: postgres
  memory: 256M
  routes:
  - route: tcp.local.pcfdev.io:61004
  env:
    POSTGRES_USER: vcap
    POSTGRES_PASSWORD: my-secret
    PGDATA: /home/vcap/postgresql/data
```

`cf push`

```
cf push --docker-image mysql
```

動作確認


```
$ psql -U vcap -h tcp.local.pcfdev.io -p 61004
Password for user vcap: my-secret
psql (9.5.0, server 9.6.0)
WARNING: psql major version 9.5, server major version 9.6.
         Some psql features might not work.
Type "help" for help.

vcap=# select now();
              now              
-------------------------------
 2016-10-14 18:34:29.844692+00
(1 row)
```

### MongoDBのデプロイ

[`mongo`](https://hub.docker.com/_/mongo/)のデプロイ。

`manifest.yml`

``` yaml
applications:
- name: mongo
  memory: 256M
  routes:
  - route: tcp.local.pcfdev.io:61005
```

`cf push`

```
cf push --docker-image mongo
```

動作確認


```
$ mongo --host tcp.local.pcfdev.io --port 61005
MongoDB shell version: 3.2.6
connecting to: tcp.local.pcfdev.io:61005/test
Server has startup warnings: 
2016-10-14T18:39:09.654+0000 I CONTROL  [initandlisten] 
2016-10-14T18:39:09.654+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2016-10-14T18:39:09.654+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2016-10-14T18:39:09.654+0000 I CONTROL  [initandlisten] 
2016-10-14T18:39:09.654+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2016-10-14T18:39:09.654+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2016-10-14T18:39:09.654+0000 I CONTROL  [initandlisten] 
> 
```

### Mosquitto(MQTT Broker)のデプロイ

[`toke/mosquitto`](https://hub.docker.com/toke/mosquitto/)のデプロイ。

`manifest.yml`

``` yaml
applications:
- name: mosquitto
  memory: 256M
  routes:
  - route: tcp.local.pcfdev.io:61006
```

`cf push`

```
cf push --docker-image toke/mosquitto
```

動作確認


受信側

```
mosquitto_sub -h tcp.local.pcfdev.io -p 61006 -d -t test
```

送信側

```
mosquitto_pub -h tcp.local.pcfdev.io -p 61006 -d -t test -m 'Hello World!'
```

### rsyslogのデプロイ

[`helder/rsyslog`](https://hub.docker.com/helder/rsyslog/)のデプロイ。

`manifest.yml`

``` yaml
applications:
- name: rsyslog
  memory: 256M
  routes:
  - route: tcp.local.pcfdev.io:61007
```

`cf push`

```
cf push --docker-image helder/rsyslog
```

動作確認


受信側

```
$ cf ssh rsyslog
tail -f /var/log/messages 
```

送信側

```
echo '<14>localhost Hello World' | nc tcp.local.pcfdev.io 61007
```
