步步驚心:從頭部署服務到 Kubernetes(五)

Duan Li
Brobridge - 寬橋微服務
6 min readMay 26, 2020

如何管理多個應用程式之間的連線機制

Photo by Christopher Burns on Unsplash

傳統上,當 app 部署在不同台機器上時,最常見的就是透過指定的 ip:port 的方式來溝通,例如 216.58.200.228:80 ,或者用 FQDN,例如 www.google.com:80。

在 Kubernetes 內部的運作方式其實也是一樣,只是 Kubernetes 內部有自己的 DNS 以及運作機制,一般稱之為服務發現( Service Discovery)。我們這邊不對此運作原理多做介紹,直接以實際來說明運作方式。

建立一個 App 提供對外可呼叫的介面

我們先建立另一個 app ,換個口味用 PHP 吧。開始建立程式前,先準備框架的環境:

$ mkdir php-app && cd php-app
$ composer require google/cloud-functions-framework

建立主程式 index.php ,內容如下:

$ cat index.php
<?php
use Symfony\Component\HttpFoundation\Request;
function initShowtime(Request $request)
{
$now = date("Y/m/d H:i");
return $now;
}

做的事情很簡單,就是顯示目前時間。接下來要打包成 image 了,所以撰寫 Dockerfile 內容如下:

FROM gcr.io/gae-runtimes/php73:php73_20191020_7_3_10_RC00WORKDIR /srv/RUN mkdir .googleconfig && \
echo '{"entrypointContents": "serve vendor/bin/router.php"}' > .googleconfig/app_start.json
COPY composer.* ./
COPY --from=composer:1 /usr/bin/composer /usr/local/bin
RUN composer install --no-dev
COPY . .
ENV FUNCTION_TARGET=initShowtime
ENV FUNCTION_SIGNATURE_TYPE=http
ENV GAE_RUNTIME php73

然後開始打包 image 以及推送上 dockerhub 最後部署到 minikube 裡:

$ docker build -t duanli/showtime-php:0.0.1 .
$ docker push duanli/showtime-php:0.0.1
$ kubectl create deployment showtime --image=duanli/showtime-php:0.0.1
$ kubectl expose deployment showtime --port=80 --target-port=8080

先測試一下,方法和之前一樣:

$ SVC=$(kubectl get svc showtime -o jsonpath='{.spec.clusterIP}')
$ minikube ssh curl $svc
2020/03/06 23:17

看起來運作良好,php 的部分先在這告一段落。

修改舊的程式以呼叫前一支 PHP 程式

修改 nodejs 程式,讓它提供一個路徑可以打 php 程式提供的 API。對於 hello-node 這隻 app 來說,showtime-php 這隻 app 的 url ,就相當於替 showtime-php 建立的 service name,也就是 http://showtime/,因此修改 index.js 如下:

const express = require('express');
const app = express();
const unirest = require('unirest')
app.get('/', (req, res) => {
res.send('Hello World!')
});
app.get('/time', (req, res) => {
unirest.get('http://showtime')
.end(function(response) {
if (response.error) {
console.log('get time fail')
res.send('Call API fail')
} else {
res.send(response.body)
}
})
});
app.listen(3000, () => {
console.log('Example app listening on port 3000!');
});

然後同樣的步驟來部署以及測試:

$ docker build -t duanli/hello-node:0.0.3 .
$ docker push duanli/hello-node:0.0.3
$ kubectl set image deployment/hellonode hello-node=duanli/hello-node:0.0.3 --record
$ curl --resolve hello.node.minikube:80:192.168.64.2 http://hello.node.minikube/time
2020/03/07 00:22

測試成功!

這篇介紹後端程式打內部 API 的方式,雖然寫的有點長,不過其實只要了解 Kubernetes 內部 DNS 運作的方式,就會知道這和傳統打 API 的方式都是一樣的。現階段就 DNS 的部分隱藏了一些細節,是有關於 namespace 的部分,目前暫時先用比較簡單的方式去理解 app 之間,或者是說 service 之間的關係。

下一篇我們加上前端的部分,其實方法上差異不太大,一來是可以更熟悉這樣的流程,再者是透過不同語言的部署方式,可以更容易看出需要注意的地方。

<<上一篇 | 下一篇>>

--

--

Duan Li
Brobridge - 寬橋微服務

All we do crumbles to the ground, though we refuse to see, dust in the wind, all we are is dust in the wind