Helmを使用してDigitalOceanKubernetesでNginxIngressを設定する方法
序章
Kubernetes Ingresses は、クラスターを超えて内部のKubernetesサービスにトラフィックをルーティングする柔軟な方法を提供します。 Ingress Resources は、HTTPおよびHTTPSトラフィックをサービスにルーティングするためのルールを定義するKubernetesのオブジェクトです。 これらが機能するには、Ingress Controllerが存在する必要があります。 その役割は、トラフィックを受け入れ(ほとんどの場合ロードバランサーを介して)、適切なサービスにルーティングすることでルールを実装することです。 ほとんどのIngressControllerは、すべてのIngressに対して1つのグローバルロードバランサーのみを使用します。これは、公開するサービスごとにロードバランサーを作成するよりも効率的です。
Helm は、Kubernetesを管理するためのパッケージマネージャーです。 KubernetesでHelmChartsを使用すると、Kubernetesアプリケーションを更新、ロールバック、削除するための構成可能性とライフサイクル管理が提供されます。
このガイドでは、Helmを使用してKubernetesで管理されている Nginx IngressControllerをセットアップします。 次に、入力リソースを作成して、ドメインからのトラフィックをHelloWorldバックエンドサービスの例にルーティングします。 Ingressを設定したら、 Certificate Manager をクラスターにインストールして、Let’sEncryptTLS証明書を自動的にプロビジョニングしてIngressを保護できるようにします。
前提条件
-
接続構成が次のように構成されたDigitalOceanKubernetes1.16+クラスター
kubectl
デフォルト。 設定方法の説明kubectl
は、クラスターの作成時に表示されるクラスターへの接続ステップの下に表示されます。 DigitalOceanでKubernetesクラスタを作成する方法については、 KubernetesQuickstartをご覧ください。 -
ローカルマシンにインストールされているHelm3パッケージマネージャー。 Helm 3 PackageManagerチュートリアルを使用してKubernetesクラスターにソフトウェアをインストールする方法のステップ1を完了します。
-
2つの利用可能なAレコードを持つ完全に登録されたドメイン名。 このチュートリアルでは、
hw1.your_domain
とhw2.your_domain
全体を通して。 Namecheap でドメイン名を購入するか、 Freenom で無料でドメイン名を取得するか、選択したドメイン登録事業者を使用できます。
ステップ1—HelloWorldデプロイメントのセットアップ
このセクションでは、Nginx Ingressをデプロイする前に、 hello-kubernetesというHelloWorldアプリをデプロイして、トラフィックをルーティングするサービスをいくつか用意します。 次の手順でNginxIngressが正しく機能することを確認するために、Nginx Ingressを2回デプロイします。そのたびに、ブラウザーからアクセスしたときに表示される異なるウェルカムメッセージが表示されます。
展開構成をローカルマシンに保存します。 最初の展開構成は、という名前のファイルになります hello-kubernetes-first.yaml
. テキストエディタを使用して作成します。
- nano hello-kubernetes-first.yaml
次の行を追加します。
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes-first
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes-first
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes-first
template:
metadata:
labels:
app: hello-kubernetes-first
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the first deployment!
この構成は、デプロイメントとサービスを定義します。 展開は、の3つのレプリカで構成されます paulbouwer/hello-kubernetes:1.7
image、およびという名前の環境変数 MESSAGE
-アプリにアクセスすると、その値が表示されます。 ここでのサービスは、ポートでクラスター内のデプロイメントを公開するように定義されています 80
.
ファイルを保存して閉じます。
次に、この最初のバリアントを作成します hello-kubernetes
次のコマンドを実行して、Kubernetesでアプリを実行します。
- kubectl create -f hello-kubernetes-first.yaml
次の出力が表示されます。
Outputservice/hello-kubernetes-first created
deployment.apps/hello-kubernetes-first created
サービスの作成を確認するには、次のコマンドを実行します。
- kubectl get service hello-kubernetes-first
出力は次のようになります。
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes-first ClusterIP 10.245.124.46 <none> 80/TCP 7s
新しく作成されたサービスにはClusterIPが割り当てられていることがわかります。これは、サービスが正しく機能していることを意味します。 そこに送信されたすべてのトラフィックは、ポート上の選択された展開に転送されます 8080
. これで、の最初のバリアントをデプロイしました hello-kubernetes
アプリ、あなたは2番目のものに取り組みます。
というファイルを開きます hello-kubernetes-second.yaml
編集用:
- nano hello-kubernetes-second.yaml
次の行を追加します。
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes-second
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes-second
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes-second
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes-second
template:
metadata:
labels:
app: hello-kubernetes-second
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the second deployment!
ファイルを保存して閉じます。
このバリアントは、前の構成と同じ構造を持っています。 唯一の違いは、衝突を回避するためのデプロイメント名とサービス名、およびメッセージです。
次のコマンドを使用して、Kubernetesで作成します。
- kubectl create -f hello-kubernetes-second.yaml
出力は次のようになります。
Outputservice/hello-kubernetes-second created
deployment.apps/hello-kubernetes-second created
すべてのサービスを一覧表示して、2番目のサービスが稼働していることを確認します。
- kubectl get service
出力は次のようになります。
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-kubernetes-first ClusterIP 10.245.124.46 <none> 80/TCP 49s
hello-kubernetes-second ClusterIP 10.245.254.124 <none> 80/TCP 10s
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 65m
両方 hello-kubernetes-first
と hello-kubernetes-second
リストされています。これは、Kubernetesがそれらを正常に作成したことを意味します。
の2つのデプロイメントを作成しました hello-kubernetes
付随するサービスを備えたアプリ。 それぞれにデプロイメント仕様に異なるメッセージセットがあり、テスト中にそれらを区別することができます。 次のステップでは、NginxIngressController自体をインストールします。
ステップ2— Kubernetes NginxIngressControllerをインストールする
次に、Helmを使用してKubernetesで管理されている Nginx IngressControllerをインストールします。 NginxIngressesがいくつかあることに注意してください。
Nginx Ingress Controllerは、ポッドとサービスで構成されています。 ポッドはコントローラーを実行します。コントローラーは常に /ingresses
使用可能な入力リソースの更新のためのクラスターのAPIサーバー上のエンドポイント。 サービスのタイプはLoadBalancerであり、DigitalOcean Kubernetesクラスターにデプロイしているため、クラスターは自動的に DigitalOcean Load Balancer を作成し、これを介してすべての外部トラフィックがコントローラーに流れます。 次に、コントローラは、入力リソースで定義されているように、トラフィックを適切なサービスにルーティングします。
LoadBalancerサービスのみが、自動的に作成されたロードバランサーのIPアドレスを認識します。 一部のアプリ( ExternalDNS など)はそのIPアドレスを知る必要がありますが、Ingressの構成のみを読み取ることができます。 コントローラは、設定することにより、各入力でIPアドレスを公開するように構成できます。 controller.publishService.enabled
パラメータから true
その間 helm install
. ロードバランサーのIPアドレスに依存する可能性のあるアプリケーションをサポートするには、この設定を有効にすることをお勧めします。
Nginx Ingress Controllerをクラスターにインストールするには、最初に次のコマンドを実行してリポジトリをHelmに追加する必要があります。
- helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
出力は次のようになります。
Output"ingress-nginx" has been added to your repositories
ヘルムに何が含まれているのかを知らせるために更新します。
- helm repo update
最後に、次のコマンドを実行してNginx入力をインストールします。
- helm install nginx-ingress ingress-nginx/ingress-nginx --set controller.publishService.enabled=true
このコマンドは、NginxIngressControllerをからインストールします stable
チャートリポジトリ、Helmリリースに名前を付けます nginx-ingress
、およびを設定します publishService
パラメータから true
.
出力は次のようになります。
OutputNAME: nginx-ingress
LAST DEPLOYED: Fri Apr 3 17:39:05 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
...
Helmは、チャートのインストールの一部として作成したKubernetesのリソースをログに記録しました。
次のコマンドを実行すると、ロードバランサーが使用可能になるのを確認できます。
- kubectl --namespace default get services -o wide -w nginx-ingress-ingress-nginx-controller
Kubernetesコミュニティによって管理されているNginxIngressをインストールしました。 ロードバランサーからのHTTPおよびHTTPSトラフィックを、IngressResourcesで構成された適切なバックエンドサービスにルーティングします。 次のステップでは、 hello-kubernetes
Ingressリソースを使用したアプリのデプロイ。
ステップ3—入力を使用してアプリを公開する
次に、入力リソースを作成し、それを使用して hello-kubernetes
目的のドメインでのアプリのデプロイ。 次に、ブラウザからアクセスしてテストします。
Ingressをという名前のファイルに保存します hello-kubernetes-ingress.yaml
. エディターを使用して作成します。
- nano hello-kubernetes-ingress.yaml
次の行をファイルに追加します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: "hw1.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-first
port:
number: 80
- host: "hw2.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-second
port:
number: 80
Ingressリソースを次の名前で定義します hello-kubernetes-ingress
. 次に、2つのホストルールを指定して、次のようにします。 hw1.your_domain
にルーティングされます hello-kubernetes-first
サービス、および hw2.your_domain
2番目の展開からサービスにルーティングされます(hello-kubernetes-second
).
次に、2つのドメインがAレコードを介してロードバランサーを指していることを確認する必要があります。 これは、DNSプロバイダーを介して行われます。 DigitalOceanでDNSレコードを構成するには、DNSレコードの管理方法を参照してください。
強調表示されたドメインを独自のドメインに置き換えてから、ファイルを保存して閉じることを忘れないでください。
次のコマンドを実行して、Kubernetesで作成します。
- kubectl apply -f hello-kubernetes-ingress.yaml
これで、に移動できます hw1.your_domain
ブラウザで。 次のように表示されます。
2番目のバリアント(hw2.your_domain
)別のメッセージが表示されます:
これにより、IngressControllerがリクエストを正しくルーティングすることを確認しました。 この場合、2つのドメインから2つの異なるサービスへ。
入力リソースを作成して構成し、 hello-kubernetes
ドメインでのアプリのデプロイ。 次のステップでは、Cert-Managerを設定して、Let’sEncryptからの無料のTLS証明書を使用してIngressリソースを保護できるようにします。
ステップ4—Cert-Managerを使用して入力を保護する
Ingressリソースを保護するには、Cert-Managerをインストールし、本番用のClusterIssuerを作成し、TLS証明書を利用するようにIngressの構成を変更します。 ClusterIssuersは、クラスター全体にTLS証明書をプロビジョニングするKubernetesのCert-Managerリソースです。 インストールして構成すると、アプリはHTTPSの背後で実行されます。
Helmを介してCert-Managerをクラスターにインストールする前に、次のコマンドを実行して、クラスターの名前空間を手動で作成します。
- kubectl create namespace cert-manager
Jetstack Helmリポジトリを、Cert-ManagerチャートをホストするHelmに追加する必要があります。 これを行うには、次のコマンドを実行します。
- helm repo add jetstack https://charts.jetstack.io
Helmは次の出力を表示します。
Output"jetstack" has been added to your repositories
次に、Helmのチャートキャッシュを更新します。
- helm repo update
最後に、Cert-Managerをにインストールします cert-manager
次のコマンドを実行して名前空間を作成します。
- helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.2.0 --set installCRDs=true
次の出力が表示されます。
OutputNAME: cert-manager
LAST DEPLOYED: Sun Dec 13 11:29:32 2020
NAMESPACE: cert-manager
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
cert-manager has been deployed successfully!
...
出力は、インストールが成功したことを示しています。 に記載されているように NOTES
出力では、TLS証明書を発行するために発行者を設定する必要があります。
次に、Let’s Encrypt証明書を発行する証明書を作成し、その構成を次の名前のファイルに保存します。 production_issuer.yaml
. それを作成し、編集のために開きます。
- nano production_issuer.yaml
次の行を追加します。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# Email address used for ACME registration
email: your_email_address
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Name of a secret used to store the ACME account private key
name: letsencrypt-prod-private-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
この構成は、証明書を発行するためにLet’sEncryptに接続するClusterIssuerを定義します。 交換する必要があります your_email_address
証明書のセキュリティと有効期限に関する緊急の通知を受け取るために、電子メールアドレスを使用してください。
ファイルを保存して閉じます。
でロールアウト kubectl
:
- kubectl apply -f production_issuer.yaml
次の出力が表示されます。
Outputclusterissuer.cert-manager.io/letsencrypt-prod created
Cert-Managerをインストールすると、前の手順で定義したIngressリソースに証明書を導入する準備が整います。 開ける hello-kubernetes-ingress.yaml
編集用:
- nano hello-kubernetes-ingress.yaml
強調表示された行を追加します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-kubernetes-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- hw1.your_domain
- hw2.your_domain
secretName: hello-kubernetes-tls
rules:
- host: "hw1.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-first
port:
number: 80
- host: "hw2.your_domain_name"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-kubernetes-second
port:
number: 80
The tls
下のブロック spec
サイトの証明書をどのシークレットに定義するか(以下にリストされています) hosts
)証明書を保存します。 letsencrypt-prod
ClusterIssuerの問題。 これは、作成するすべてのイングレスで異なる必要があります。
交換することを忘れないでください hw1.your_domain
と hw2.your_domain
あなた自身のドメインで。 編集が終了したら、ファイルを保存して閉じます。
次のコマンドを実行して、この構成をクラスターに再適用します。
- kubectl apply -f hello-kubernetes-ingress.yaml
次の出力が表示されます。
Outputingress.networking.k8s.io/hello-kubernetes-ingress configured
Let’sEncryptサーバーがドメインの証明書を発行するまで数分待つ必要があります。 それまでの間、次のコマンドの出力を調べることで、進行状況を追跡できます。
- kubectl describe certificate hello-kubernetes-tls
出力の終わりは次のようになります。
OutputEvents:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 26s cert-manager Issuing certificate as Secret does not exist
Normal Generated 26s cert-manager Stored new private key in temporary Secret resource "hello-kubernetes-tls2-nfsgp"
Normal Requested 26s cert-manager Created new CertificateRequest resource "hello-kubernetes-tls2-wzl8z"
Normal Issuing 24s cert-manager The certificate has been successfully issued
出力の最後の行が The certificate has been successfully issued
、を押して終了できます CTRL + C
. ブラウザでドメインの1つに移動して、テストします。 ブラウザのアドレスバーの左側に南京錠があり、接続が安全であることを示しています。
このステップでは、Helmを使用してCert-Managerをインストールし、Let’sEncryptClusterIssuerを作成しました。 その後、TLS証明書を生成するために発行者を利用するように入力リソースを更新しました。 最後に、ブラウザでドメインの1つに移動することにより、HTTPSが正しく機能することを確認しました。
結論
これで、Helmを使用してDigitalOceanKubernetesクラスターにNginxIngressControllerとCert-Managerを正常にセットアップできました。 これで、Let’s Encrypt TLS証明書を使用して保護された、ドメインでのアプリをインターネットに公開できるようになりました。
Helmパッケージマネージャーの詳細については、この紹介記事をお読みください。