その他の設定-接続元IPアドレス取得,coredns,メール送信等-DigitalOceanのkubernetes環境にwordpressを構築する07

2024年1月14日

その他の変更点

接続元IPアドレスを正しいものにしたい

背景

/wp-login.phpへのアクセス制限をかけているので、デフォルトだとすべてのIPアドレスがDOKSのIPアドレスになってしまい、403で接続できません。

Serviceに直接アクセスされた場合の設定

ロードバランサー経由ではなく直接アクセスされた場合のREMOTE_ADDR取得の設定です。

https://kubernetes.io/ja/docs/tutorials/services/source-ip/

  • Type=NodePortを使用したServiceでの送信元IP
kubectl patch svc doks-wp-dev-web -n doks-wp -p '{"spec":{"externalTrafficPolicy":"Local"}}'

ingress-nginx-controller経由でのアクセスされた場合の設定

https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/configmap.md#use-proxy-protocol

  • loadbalancer及びingress-nginxのconfigmapへの設定変更が必要。
  • 両方同時に反映しないと(片方だけの設定だと)下記のSSLエラーになるのでご注意ください。

安全な接続ができませんでした

dev-memo.frzl.net への接続中にエラーが発生しました。PR_END_OF_FILE_ERROR

エラーコード: PR_END_OF_FILE_ERROR

受信したデータの真正性を検証できなかったため、このページは表示できませんでした。
この問題をウェブサイトの管理者に連絡してください。

アクセス元IPアドレス取得の設定を行うと、let's encryptの証明書の取得ができなくなることを確認しています。

05回 SSL設定でも説明しています。

  Reason:      Waiting for HTTP-01 challenge propagation: failed to perform self check GET request 'http://memo.frzl.net/.well-known/acme-challenge/oIpifCta1mHKwx5Ruoz4t2FUTu7Amgk95pt-2kl6JA4': Get "http://memo.frzl.net/.well-known/acme-challenge/oIpifCta1mHKwx5Ruoz4t2FUTu7Amgk95pt-2kl6JA4": EOF

対処方法は下の「Let'sEncrypt取得設定」に記載しています。

configmap/ingress-nginx-controller

backup

cd ~/work/doks-wp/dev/k8s
kubectl get configmap/ingress-nginx-controller -n ingress-nginx -o yaml > ingress-nginx-controller-configmap.yaml

edit

vi ingress-nginx-controller-configmap.yaml
data:配下に追記
  use-proxy-protocol: "true"

apply

kubectl apply -f ingress-nginx-controller-configmap.yaml

loadbalancer

digitaloceanコンソール > LoadBalancer > More > Edit settings

Proxy protocol : Enabled

2024.1/3現在仕様が変わってコマンドで変更するようになっています。

backup

kubectl get svc ingress-nginx-controller -n ingress-nginx -o yaml > Service.ingress-nginx-controller.yaml

vi

vi Service.ingress-nginx-controller.yaml

metadata.annotations[]へ追加

service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true"

apply

kubectl apply -f Service.ingress-nginx-controller.yaml

アクセス確認

wp-adminへの接続が403にならないことを確認

アクセスログ確認

kubectl get pods -n doks-wp
NAME                              READY   STATUS    RESTARTS   AGE
doks-wp-dev-web-66697c87f-qx95r   1/1     Running   0          11m

kubectl logs -f pods/doks-wp-dev-web-66697c87f-qx95r -n doks-wp

Let'sEncrypt取得設定

先に述べたとおり、proxy-protocol: "true"状態だとlet's encryptの更新、取得ができなくなる為、下記の方法のいずれかで対応する必要がありました。

方法1 hairpin-proxyの導入

hairpin-proxyを導入します

wget https://raw.githubusercontent.com/compumike/hairpin-proxy/v0.2.1/deploy.yml -O hairpin-proxy.yml
kubectl apply -f hairpin-proxy.yml 

namespace/hairpin-proxy created
deployment.apps/hairpin-proxy-haproxy created
service/hairpin-proxy created
serviceaccount/hairpin-proxy-controller-sa created
clusterrole.rbac.authorization.k8s.io/hairpin-proxy-controller-cr created
clusterrolebinding.rbac.authorization.k8s.io/hairpin-proxy-controller-crb created
role.rbac.authorization.k8s.io/hairpin-proxy-controller-r created
rolebinding.rbac.authorization.k8s.io/hairpin-proxy-controller-rb created
deployment.apps/hairpin-proxy-controller created

証明書が取得できていることを確認

ocarina@ab350-pro4:~/work/doks-wp/prod/k8s/ignore$ kubectl get cert -n doks-wp
NAME                               READY   SECRET                             AGE
quickstart-dev-memo.frzl.net-tls   True    quickstart-dev-memo.frzl.net-tls   7d15h
quickstart-memo.frzl.net-tls       True    quickstart-memo.frzl.net-tls       78m
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s/ignore$ 

方法2 ingress-nginx-controllerのserviceのannotationへ追記

こちらは公式の手順だしリソースも食わないのでオススメします。

ただしpodからpodへのcurlなどによる通信は出来ないのでそういったものが必要な場合はhairpin-proxyが良いと思います。

https://github.com/digitalocean/digitalocean-cloud-controller-manager/blob/master/docs/controllers/services/annotations.md#servicebetakubernetesiodo-loadbalancer-hostname

manifest取得

kubectl get svc ingress-nginx-controller -n ingress-nginx -o yaml > Service.ingress-nginx-controller.yaml

vi

vi Service.ingress-nginx-controller.yaml

metadata.annnotation[].へ下記を追加

    service.beta.kubernetes.io/do-loadbalancer-hostname: "true"

apply

kubectl apply -f Service.ingress-nginx-controller.yaml

service/ingress-nginx-controller configured

hairpin-proxy削除、hairpin-proxy有効時に取得した証明書削除

ocarina@ab350-pro4:~/work/doks-wp/prod/k8s/ignore$ kubectl delete -f hairpin-proxy.yml 
namespace "hairpin-proxy" deleted
deployment.apps "hairpin-proxy-haproxy" deleted
service "hairpin-proxy" deleted
serviceaccount "hairpin-proxy-controller-sa" deleted
clusterrole.rbac.authorization.k8s.io "hairpin-proxy-controller-cr" deleted
clusterrolebinding.rbac.authorization.k8s.io "hairpin-proxy-controller-crb" deleted
role.rbac.authorization.k8s.io "hairpin-proxy-controller-r" deleted
rolebinding.rbac.authorization.k8s.io "hairpin-proxy-controller-rb" deleted
deployment.apps "hairpin-proxy-controller" deleted

証明書の更新を確認

kubectl delete cert/quickstart-memo.frzl.net-tls -n doks-wp

certificate.cert-manager.io "quickstart-memo.frzl.net-tls" deleted

削除後すぐに取得されたことを確認

kubectl get cert -n doks-wp
NAME                               READY   SECRET                             AGE
quickstart-dev-memo.frzl.net-tls   True    quickstart-dev-memo.frzl.net-tls   7d15h
quickstart-memo.frzl.net-tls       True    quickstart-memo.frzl.net-tls       2s

corednsで名前解決

各podのhostsで名前解決をさせたい場合に利用

vi ignore/ConfigMap.coredns-custom.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns-custom # this is the name of the configmap you can overwrite with your changes
  namespace: kube-system
data:
  test.override: | # you may select any name here, but it must end with the .override file extension
        hosts {
          10.244.0.71 redis redis-master
          fallthrough
        }
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s$ kubectl apply -f ignore/ConfigMap.coredns-custom.yaml 
configmap/coredns-custom configured
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s$ kubectl -n kube-system rollout restart deployment coredns
deployment.apps/coredns restarted
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s$ kubectl get pods -n kube-system -l k8s-app=kube-dns
NAME                       READY   STATUS    RESTARTS   AGE
coredns-76fb544576-qsd8z   1/1     Running   0          10s
coredns-76fb544576-rktn9   1/1     Running   0          10s
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s$ 

configmap/corednsに直接設定してもしばらくするともとに戻ってしまっていましたので、configmap-customという名前で別に用意しています。

時間経過しても消えていないことを確認

ocarina@ab350-pro4:~/work/doks-wp/prod/k8s$ kubectl get configmap/coredns-custom -n kube-system
NAME             DATA   AGE
coredns-custom   1      23m
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s/ignore$ kubectl get configmap/coredns-custom -n kube-system -o yaml
apiVersion: v1
data:
  test.override: |
    hosts {
      10.244.0.71 redis redis-master
      fallthrough
    }
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"test.override":"hosts {\n  10.244.0.71 redis redis-master\n  fallthrough\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"coredns-custom","namespace":"kube-system"}}
  creationTimestamp: "2024-01-08T03:53:19Z"
  name: coredns-custom
  namespace: kube-system
  resourceVersion: "2825727"
  uid: b12ba780-af9e-4fe7-8bd7-eec38009b550
ocarina@ab350-pro4:~/work/doks-wp/prod/k8s/ignore$ 

メールの送信

docker wordpressのイメージではsendmailコマンドがなくてメールが送れませんでした。

メール送信コマンドをインストールして、外部SMTPサーバ経由でメールを遅れるようにします。

イメージを作り直します。

vi ../../../docker/Dockerfile 
FROM wordpress:latest

#ADD files/wproot.tgz /var/www/html/
ADD files/000-default.conf /etc/apache2/sites-enabled/

RUN apt-get -y update && apt-get -y install msmtp msmtp-mta

CMD /usr/local/bin/apache2-foreground

build,tag,push

docker build -t myimages/doks-wp:0.0.6 ./
docker tag myimages/doks-wp:0.0.6 registry.digitalocean.com/ocarina/doks-wp:0.0.6
docker push registry.digitalocean.com/ocarina/doks-wp:0.0.6

change image

ocarina@ab350-pro4:~/work/doks-wp/dev/k8s/ignore$ kubectl set image deployments/doks-wp-dev-web doks-wp=registry.digitalocean.com/ocarina/doks-wp:0.0.6 -n doks-wp
deployment.apps/doks-wp-dev-web image updated
ocarina@ab350-pro4:~/work/doks-wp/dev/k8s/ignore$ kubectl get pods -n doks-wp -w
NAME                               READY   STATUS              RESTARTS   AGE
doks-wp-dev-web-5f7dfd4d86-pzxb2   0/1     ContainerCreating   0          4s
doks-wp-dev-web-66697c87f-qx95r    1/1     Running             0          5h22m

msmtprcファイルの作成

SMTP認証情報を含んだ設定ファイルを作成

cd ~/work/doks-wp/dev/k8s/ && mkdir ignore
cd ignore/
vi msmtprc 
# Set default values for all following accounts.
defaults
auth off
tls off
#tls_trust_file /etc/ssl/certs/ca-certificates.crt
syslog on
aliases /etc/aliases

# smtp-auth
account CHANGE.YOUR.SERVICE
host CHANGE.YOUR.DOMAIN
port 587
from [email protected]
user [email protected]
password xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
tls on
tls_starttls on
tls_certcheck off
auth on

# Set a default account
account default : CHANGE.YOUR.SERVICE

msmtprcをsecretに保存

https://kubernetes.io/ja/docs/concepts/configuration/secret/

ocarina@ab350-pro4:~/work/doks-wp/dev/k8s/ignore$ kubectl create secret generic dev-msmtprc -n doks-wp --from-file=./msmtprc
secret/dev-msmtprc created

調整し直しで更新する場合

kubectl create secret generic dev-msmtprc -n doks-wp --from-file=./msmtprc --dry-run=client -o yaml  | kubectl apply -f -

secretをマウントします。

SecretをファイルとしてPodから利用する

  • PodのボリュームとしてSecretを使うには、Secretを作成するか既存のものを使用します。複数のPodが同一のSecretを参照することができます。
  • ボリュームを追加するため、Podの定義の.spec.volumes[]以下を書き換えます。ボリュームに命名し、.spec.volumes[].secret.secretNameフィールドはSecretオブジェクトの名称と同一にします。
  • Secretを必要とするそれぞれのコンテナに.spec.containers[].volumeMounts[]を追加します。.spec.containers[].volumeMounts[].readOnly = trueを指定して.spec.containers[].volumeMounts[].mountPathをSecretをマウントする未使用のディレクトリ名にします。
    イメージやコマンドラインを変更し、プログラムがそのディレクトリを参照するようにします。連想配列dataのキーはmountPath以下のファイル名になります。

backup

ocarina@ab350-pro4:~/work/doks-wp/dev/k8s$ kubectl get deployment/doks-wp-dev-web -n doks-wp -o yaml > Deployment-doks-wp-web.yaml
ocarina@ab350-pro4:~/work/doks-wp/dev/k8s$ vi Deployment-doks-wp-web.yaml
vi Deployment-doks-wp-dev-web.yaml
    spec:
      containers:
        volumeMounts:
        - mountPath: /etc/msmtprc
          name: dev-msmtprc
          readOnly: true
          subPath: msmtprc # /etc/msmtprc ファイルとしてマウントさせる。

      Volume:
      - name: dev-msmtprc
        secret:
          defaultMode: 420
          secretName: dev-msmtprc

反映

ocarina@ab350-pro4:~/work/doks-wp/dev/k8s$ kubectl apply -f Deployment-doks-wp-web.yaml
deployment.apps/doks-wp-dev-web configured

確認

ocarina@ab350-pro4:~/work/doks-wp/dev/k8s$ kubectl get pods -n doks-wp
NAME                               READY   STATUS    RESTARTS   AGE
doks-wp-dev-web-689c7c9d66-vs6c9   1/1     Running   0          2m46s
ocarina@ab350-pro4:~/work/doks-wp/dev/k8s$ kubectl exec -it pods/doks-wp-dev-web-689c7c9d66-vs6c9 -n doks-wp -- cat /etc/msmtprc
# Set default values for all following accounts.
defaults
auth off
tls off
#tls_trust_file /etc/ssl/certs/ca-certificates.crt
syslog on
...
...

Posted by ocarina