LoginSignup
3
3

More than 5 years have passed since last update.

Kubernetes 1.12にIngress Controllerをインストール

Last updated at Posted at 2018-09-29

昨日のKubernetes 1.12インストールに引き続き、今回はそのKubernetesにIngress Controllerを導入しよう。ワーカーノード2台あるので、そいつの上にDaemonSetで。
keepalivedでHA化もしよう。

NGINX Ingress Controllerを導入

どうもなかなかBetaが取れないIngress Controller。まあ、LoadBalancerのServiceですべてが賄えるならいらん訳だけど、Kubernetes成熟しないなあと思う一因でもある。それはとりあえず、Nginx Ingressのインストールの手順は以下。インストール手順探すのも現状ちょい手間。
https://kubernetes.github.io/ingress-nginx/deploy/

Mandatory commandでkubectl apply直接実行してもいいのだけど、今回はDaemonSetでデプロイしたいのでいったんダウンロードして加工。またhostPort 80, 443を割り当て。

curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml>mandatory.yaml
vi mandatory.yaml
■"name: nginx-ingress-controller"であるDeploymentをDaemonSetに書き換え
(変更前)
251 apiVersion: extensions/v1beta1
252 kind: Deployment
253 metadata:
254   name: nginx-ingress-controller
(変更後)
251 apiVersion: extensions/v1beta1
252 kind: DaemonSet
253 metadata:
254   name: nginx-ingress-controller
---
■ReplicaSetでなくなるのでreplica行を削除
(変更前)
259 spec:
260   replicas: 1
(変更後)
259 spec:
260 #  replicas: 1
---
■hostPortを追加
(変更前)
303           ports:
304             - name: http
305               containerPort: 80
306             - name: https
307               containerPort: 443
(変更後)
303           ports:
304             - name: http
305               containerPort: 80
306               hostPort: 80
307             - name: https
308               containerPort: 443
309               hostPort: 443
---
kubectl create -f mandatory.yaml

ingress-nginxネームスペースにIngress Controllerがデプロイされる。

# kubectl get pod -n ingress-nginx
NAME                                    READY   STATUS    RESTARTS   AGE
default-http-backend-6d6985d9d4-hv9dk   1/1     Running   0          81s
nginx-ingress-controller-j6fjn          1/1     Running   0          81s
nginx-ingress-controller-pjxkc          1/1     Running   0          81s
root@m16:~#

keepalivedを導入

せっかく2台のノードに1つずつIngress Controllerがいるので、keepalivedを使って2ノードのHAを構成したい。

まずは1台目のノードで以下を実行。

apt-get -y install ipvsadm keepalived

その1台目用の設定ファイルを作る。

/etc/keepalived/keepalived.conf
vrrp_instance INGRESS {
    state MASTER
    interface ens32
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.134/24
    }
}

※vipのサブネット指定(/24)必要だったっけと思ったが、指定しないと同じ筐体内のVMとVIPで通信できなくなる問題があったため、ここでは指定。

keepalivedを起動。

systemctl start keepalived

続いて2台目のノードで以下を実行。

apt-get -y install ipvsadm keepalived

その2台目用の設定ファイルを作る。

/etc/keepalived/keepalived.conf
vrrp_instance INGRESS {
    state MASTER
    interface ens32
    virtual_router_id 50
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.0.134/24
    }
}

keepalivedを起動。

systemctl start keepalived

動作確認

せっかくなので先日作ったNode.js->Mariadbのサンプルアプリをデプロイし、Ingressリソースを作って動作確認。

記事中にある「# REG=<レジストリ:ポート番号/namespace>」のところは、DockerHub上にレポジトリを作ったので「# REG=docker.io/rk05231977」で。

また、最後の「# PROXYIP=<kube-proxyが動作するサーバのIPアドレス>」は、今回の環境ではVIPの「# PROXYIP=192.168.0.134」。

そしてIngressリソースを作成。以下のファイルを作り、

my-node-ingress.yaml
kind: Ingress
metadata:
  name: my-node-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: my-node
          servicePort: 80
    host: my-node.com

以下のコマンドでデプロイ。

kubectl create -f my-node-ingress.yaml

Ingressリソースが出来ているか確認。

# kubectl get ingress
NAME              HOSTS         ADDRESS   PORTS   AGE
my-node-ingress   my-node.com             80      2m17s
# kubectl exec -n ingress-nginx nginx-ingress-controller-j6fjn -- grep -2 "my-node.com" /etc/nginx/nginx.conf
        ## end server _

        ## start server my-node.com
        server {
                server_name my-node.com ;

                listen 80;
--

        }
        ## end server my-node.com

        # default server, used for NGINX healthcheck and access to nginx stats

うん、良さそう。
以下のcurlコマンドで、VIP(今回の環境では192.168.0.134)に向けて「Host: my-node.com」ヘッダを付けて接続確認。

# curl -H "Host: my-node.com" 192.168.0.134
<html><body>
date: Sat Sep 29 2018 09:56:27 GMT+0000 (Coordinated Universal Time)<br/>
hostname: my-node-54d74b647-czsw5<br/>
remoteAddress: ::ffff:10.0.2.15<br/>
db:record: Success!<br/>
</html></body>

一応、1台ずつノードを停止して、まあ、Ingressは動作してVIPが引き継がれることも確認。

いくつか問題はあり、一つ目は、サンプル用アプリのDBがコンテナ再起動時にデータベースがなくなってしまうのでmariadb Podができるたびにcat > my-db.sql << 'EOF'~のコマンド実行してDB作り直さなければいけないということと、2つ目はVIPフェールオーバー時は問題ないのだけど、その後プライマリノードが起動してくるときにIngress Controllerより先にkeepalivedが起動してしまうので一時的にアプリに接続不可になる。
後者についてはkeepalivedを自動起動しないとか、起動まで30秒ぐらいdelayを掛けなければいけない。

/lib/systemd/system/keepalived.service
(変更前)
  8 [Service]
  9 Type=forking
(変更後)
  8 [Service]
  9 ExecStartPre=/bin/sleep 30
 10 Type=forking
systemctl daemon-reload
3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3