Kubernetesのクラスタ内のPodからクラスタ外にあるMySQLなどのサーバに接続するときには、Envoyを使うと良さそうという話です。
まだ運用はしていませんが、設定方法を載せるので迷っている方の参考になったら幸いです。
Envoyを選択する理由
要件にもよりますが、次のような理由からです。
- productionやstagingなどの環境によりMySQLの接続先を自由に切り替えたかったので、ELBやEC2上でプロキシを立てるのではなく、サイドカーコンテナを立てる方向で考えていた
- 今回は、マイクロサービスを構築するわけではなかったため、Istioはtoo muchと判断した
- HAProxyやnginxはこちらの比較記事を読んだ結果、除外した
- KubernetesのNon-selector Serviceを使うという手もあるが、手元で検証したところヘルスチェックが動作しなかった。(もしかしたらやりようはあるのかもしれません)
構成図
設定内容
envoyの設定はconfigmapにまとめています。
envoy-configmap.yml
kind: ConfigMap
apiVersion: v1
metadata:
name: envoy-conf
data:
envoy.yaml: |
static_resources:
listeners:
- name: mysql_listener
address:
socket_address:
address: 0.0.0.0
port_value: 3306
filter_chains:
- filters:
- name: envoy.filters.network.mysql_proxy
typed_config:
"@type": type.googleapis.com/envoy.config.filter.network.mysql_proxy.v1alpha1.MySQLProxy
stat_prefix: egress_mysql
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy
stat_prefix: mysql_tcp
cluster: mysql_cluster
clusters:
- name: mysql_cluster
connect_timeout: 1s
health_checks:
- healthy_threshold: 3
interval: 5s
tcp_health_check: {}
timeout: 1s
unhealthy_threshold: 3
type: strict_dns
load_assignment:
cluster_name: mysql_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: **.**.**.** # ここにそれぞれのMySQLのIPアドレスを設定する
port_value: 3306
- endpoint:
address:
socket_address:
address: **.**.**.** # ここにそれぞれのMySQLのIPアドレスを設定する
port_value: 3306
admin:
access_log_path: "/dev/null"
address:
socket_address:
address: 0.0.0.0
port_value: 8001
Podの設定は、nginx+php-fpmのサイドカーとしてEnvoyを追加しています。
api.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
hostname: myhostname
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
- name: php-fpm
image: phpfpm:latest
ports:
- containerPort: 9000
- name: envoy-proxy
image: envoyproxy/envoy-dev:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
name: proxy-mysql
protocol: TCP
resources:
limits:
cpu: 0.5
memory: 1Gi
volumeMounts:
- name: envoy-conf
mountPath: /etc/envoy/envoy.yaml
subPath: envoy.yaml
volumes:
- name: envoy-conf
configMap:
name: envoy-conf
items:
- key: envoy.yaml
path: envoy.yaml
mode: 0644
---
apiVersion: v1
kind: Service
metadata:
name: web-service
labels:
app: nginx
spec:
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 80
type: LoadBalancer
selector:
app: nginx
この設定により、php-fpmのコンテナから0.0.0.0:3306に接続するとMySqlに繋がります。
まとめ
Kubernetesのクラスタに外部から接続する方法は、ネットで探すと色々出てくるのですが、クラスタから外部サーバに接続する方法についての情報はあまりない印象だったので書くことにしました。