cert-managerでさくらのクラウドDNSを使ってワイルドカード証明書を発行する

cert-managerのさくらのクラウド対応版

Kubernetes上で証明書の発行/更新の自動化を行えるcert-managerをフォークしてさくらのクラウド対応版をリリースしました。

github.com

これを利用することでさくらのクラウドDNSを利用して証明書の発行/更新が行えるようになります。

今回はこのさくらのクラウド対応版cert-managerを利用して証明書を発行する方法をご紹介します。

なお今回は現時点(2019/10/3)の最新版のv0.11.0-alpha.0を利用します。
v0.11系はまだalpha版となっており、今後細かな仕様変更などがあるかもしれない点には留意ください。

発行までの手順

以下のような流れとなります。

準備しておくもの

最後のさくらのクラウドDNSヘのゾーン登録ですが、証明書を発行したいドメインさくらのクラウドDNSへあらかじめ登録しておくということです。
(レコードは登録しておかなくても構いません)

ゾーン登録後に表示されるDNSサーバに対して権限移譲を行うところまでは済ませておいてください。

manual.sakura.ad.jp

さくらのクラウド対応版cert-managerのインストール

Helm Chartを用意していますのでこちらを利用してインストールします。

helm init

まずはhelm initしておきます。
(以下はRBACが有効なクラスタhelm initする場合の例です。)

kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller

helm lsなどを実行してエラーが出ないことを確認しておきます。

もしError: could not find a ready tiller podが表示されたら少し待ちましょう。

cert-managerのインストール

まずCRDの作成とNameSpaceの作成を行い、その後helm installを実行します。

# CRDの登録
kubectl apply -f https://raw.githubusercontent.com/sacloud/cert-manager/sacloud/v0.11.0-alpha.0/deploy/manifests/00-crds.yaml

# NameSpaceの作成
kubectl apply -f https://raw.githubusercontent.com/sacloud/cert-manager/sacloud/v0.11.0-alpha.0/deploy/manifests/01-namespace.yaml

# sacloudリポジトリの追加
helm repo add sacloud https://sacloud.github.io/helm-charts/

# cert-managerのインストール
helm install --name cert-manager --namespace cert-manager --version v0.11.0-alpha.0 sacloud/cert-manager

これでcert-managerのインストールができました。

さくらのクラウドAPIキーをSecretに格納

次にcert-managerからさくらのクラウドDNSAPIを通じて操作する際に利用するAPIキーをSecretとして作成します。

まず以下のようなyamlファイルを作成します。 (ここではsecret.yamlというファイル名にしました)

apiVersion: v1
kind: Secret
metadata:
  name: sakuracloud-dns
  namespace: cert-manager
type: Opaque
data:
  access-token: <BASE64エンコードしたAPIトークン>
  access-secret: <BASE64エンコードしたAPIシークレット>

APIキーのトークン/シークレットはBASE64エンコードした値に置き換えてください。
(BASE64エンコードecho '<APIトークン>' | base64などのコマンドでOK)

その後kubectlで登録します。

kubectl apply -f secret.yaml

今回は後ほどClusterIssuerを利用するつもりですのでSecretのNameSpaceをcert-managerにしています。
ClusterIssuerではなくIssuerを利用する場合は適宜修正してください。

参考: https://docs.cert-manager.io/en/release-0.11/reference/clusterissuers.html

Issuer or ClusterIssuerの作成

次にIssuer、またはClusterIssuerを作成します。

参考: - https://docs.cert-manager.io/en/release-0.11/reference/issuers.html - https://docs.cert-manager.io/en/release-0.11/reference/clusterissuers.html

今回はClusterIssuerを作成します。

まず以下のようなyamlファイルを作成します。 (今回はissuer.yamlというファイル名にしました)

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: example-issuer
spec:
  acme:
    email: <メールアドレス>
    # ステージング
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    # 本番
    #server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: example-issuer-account-key
    solvers:
      - dns01:
          sakuracloud:
            accessTokenSecretRef:
              name: sakuracloud-dns
              key: access-token
            accessSecretSecretRef:
              name: sakuracloud-dns
              key: access-secret

メールアドレスの部分は適宜修正してください。

その後kubectlで登録します。

kubectl apply -f issuer.yaml

これで証明書の発行を行う準備が整いました。続いて早速証明書の発行を行います。

Certificateリソースを作成して証明書を発行

以下のようなyamlファイルを作成します。
(今回はcert.yamlというファイル名にしました)

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
 name: example-tls
 namespace: default
spec:
  secretName: example-tls
  commonName: '*.<ゾーン名>'
  dnsNames:
    - '*.<ゾーン名>'
  issuerRef:
    name: example-issuer
    kind: ClusterIssuer    

ゾーン名の部分は各自で適切に置き換えてください。
例えばexample.comというゾーン名に対し*.hoge.example.comというワイルドカード証明書を発行する場合、spec.commonNamespec.dnsNames[*]には*.hoge.example.comを指定します。

あとはkubectlで登録するだけです。

kubectl apply -f cert.yaml

確認

取得できているか確認してみます。

$ kubectl describe cert example-tls

Name:         example-tls
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"cert-manager.io/v1alpha2","kind":"Certificate","metadata":{"annotations":{},"name":"example-tls","namespace":"default"},"sp...
API Version:  cert-manager.io/v1alpha2
Kind:         Certificate
Metadata:
  Creation Timestamp:  2019-10-03T06:26:57Z
  Generation:          5
  Resource Version:    2951
  Self Link:           /apis/cert-manager.io/v1alpha2/namespaces/default/certificates/example-tls
  UID:                 ccde4ca9-e5a6-11e9-a60d-9ca3ba2833af
Spec:
  Common Name:  *.example.com
  Dns Names:
    *.example.com
  Issuer Ref:
    Kind:       ClusterIssuer
    Name:       example-issuer
  Secret Name:  example-tls
Status:
  Conditions:
    Last Transition Time:  2019-10-03T06:29:12Z
    Message:               Certificate is up to date and has not expired
    Reason:                Ready
    Status:                True
    Type:                  Ready
  Not After:               2020-01-01T05:29:11Z
Events:
  Type    Reason        Age    From          Message
  ----    ------        ----   ----          -------
  Normal  GeneratedKey  2m44s  cert-manager  Generated a new private key
  Normal  Requested     2m43s  cert-manager  Created new CertificateRequest resource "example-tls-2800673269"
  Normal  Issued        29s    cert-manager  Certificate issued successfully

Eventsの部分にIssuedが表示されたら発行完了してます。

発行された証明書を確認してみます。

$ kubectl get secret 

apiVersion: v1
data:
  ca.crt: null
  tls.crt: ...
  tls.key: ...
kind: Secret
metadata:
  annotations:
    cert-manager.io/alt-names: '*.example.com'
    cert-manager.io/certificate-name: example-tls
    cert-manager.io/common-name: '*.example.com'
    cert-manager.io/ip-sans: ""
    cert-manager.io/issuer-kind: ClusterIssuer
    cert-manager.io/issuer-name: example-issuer
  creationTimestamp: "2019-10-03T06:26:57Z"
  name: example-tls
  namespace: default
  resourceVersion: "2949"
  selfLink: /api/v1/namespaces/default/secrets/example-tls
  uid: cd15196e-e5a6-11e9-a60d-9ca3ba2833af
type: kubernetes.io/tls

data.tls配下にBASE64エンコードされた証明書データが格納されているはずです。

これでワイルドカード証明書を発行することができました。

さくらのクラウド対応版cert-managerの利用上の注意

さくらのクラウド対応版のcert-managerはオリジナルのcert-manager v0.11系以降のみに対応予定です。
それ以前のバージョンには対応しませんのでご注意ください。

終わりに

さくらのクラウド対応版cert-managerを利用することで、さくらのクラウドDNSを用いてワイルドカード証明書の発行が行えます。
さくらのクラウド上でKubernetesを利用する場合などに便利だと思います。 ぜひご利用ください。

以上です。