kubernetesでwebサーバをたてて、kubernetesクラスタの外部からアクセスする方法。
webサーバとしてjenkinsをたててみた。
Replication Controllerのサンプル
apiVersion: v1
kind: ReplicationController
metadata:
name: jenkins
spec:
replicas: 1
selector:
app: web
template:
metadata:
labels:
app: web
spec:
volumes:
- name: jendata
hostPath:
path: /jenkins_home
containers:
- name: myjenkins
image: jenkins
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /var/jenkins_home
name: jendata
selectorでapp:webと名付ける。また、containerPortは8080に。この辺の設定が後で効いてくる。コンテナイメージはjenkinsでpullする。
また、Replication ControllerでPodがリカバリされた際に、基本VolumeはPodに紐づくので、せっかくPodが復活しても設定が全てクリアになっていたらあまり意味がない。
そこで、Volumeをローカルホストに規定し、Podのライフサイクルに依存せずデータを保持する。
コンテナ内の/var/jenkins_home配下を、ホストの/jenkins_homeにマウントする。
この時、ホスト側のディレクトリにchmod 777しておくことを忘れずに。適切な権限がない場合、Podが正しく起動できず(マウントできず)、kubectl get podコマンドのstatusでCrashLoopBackOffとなってしまう。
RCを起動してみる
kubectl create -f rc.yaml
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
jenkins-34f36 1/1 Running 0 45m
k8s-master-127.0.0.1 3/3 Running 0 3d
このままでは、起動したjenkinsはコンテナの外からはアクセスできない。コンテナと外部との接続を実現する方法がService。
Serviceのサンプル
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "my-service"
},
"spec": {
"selector": {
"app": "web"
},
"ports": [
{
"protocol": "TCP",
"port": 80,
"targetPort": 8080,
"nodePort": 30000
}
],
"type" : "NodePort"
}
}
selectorで先ほどのReplicationControlerと同じapp:webとする。selectorで両者の対応付けをしているらしい。
type:NodePortとすることで、ホストのIP(local/global)と、kubernetesのコンテナのIPとの紐付けがされる。
※Typeは他にLoadBalancerがあるが、利用可否はCloudサービスに依存するらしい。
ports内の各要素は次の通り
・port: ローカル(kubernetesの外)からPodへ接続用ポート
・targetPort: コンテナ(Pod)内の規定ポート
・NodePort: ホストを経由して外部からPodへの接続用ポート
例では、jenkinsのpodで8080を待ち受けポートにしていたので、targetPortを8080にする。
外部からホストIP(local/global)に30000ポートで接続すると、Pod内の8080ポートでjenkinsに接続される流れ。
80ポートは、kubectl get svcで取得できるIP宛にアクセスすると、80:8080に変換されてjenkinsに接続できる。
Serviceを起動する
※podやrcと同じ
kubectl create -f service.json
接続先を確認
$ kubectl get svc
NAME LABELS SELECTOR IP(S) PORT(S)
my-service <none> app=web 10.0.0.191 80/TCP
このIPが外部からの接続先。
kubernetesで付与される。
試しに接続
curl http://10.0.0.191:80
応答が返ってくる。
Global IPを持つ場合は、http://[global ip]:30000に接続すると、外部ホストからjenkinsにアクセスできる。
※Firewall(AWSならセキュリティポリシー)で該当ポートを許可する必要あり。
試しにkubectl stop pod [pod名]で起動中のjenkinsを停止させてみると、replication controllerですぐに新しいjenkinsが起動され、Volumeをホストに指定していると、設定情報も引き継がれることがわかる。