在 WSL2 中为本地开发环境生成证书

Generating certificate for local dev environment in WSL2

难以在与 WSL2 隔离的本地开发环境中安装证书。我在 macOS 和 Linux 中完成了完全相同的步骤,并且没有出现任何问题。

步骤如下:

# Download and install mkcert
if [[ `uname` = "Darwin" ]] then
    brew install mkcert
    brew install nss
else
    curl -Lo mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64 && \
        sudo install mkcert /usr/local/bin/
fi

# Installing tls certificate
mkcert -install

# Installing tls certificate
mkcert localhost 127.0.0.1 ::1

# Installing cert-manager locally
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.2.0/cert-manager.yaml

# Add the certificates to secrets
kubectl create secret tls tls-localhost-dev --key=localhost+2-key.pem --cert=localhost+2.pem -n dev

# Create the tls service that will attach to ingress-nginx
kubectl apply -f k8s/dev/tls.yaml
# k8s/dev/tls.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-dev-issuer
  namespace: cert-manager
spec:
  ca:
    secretName: tls-localhost-dev
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: letsencrypt-dev-certificate
  namespace: cert-manager
spec:
  secretName: tls-localhost-dev
  dnsNames:
    - localhost
  issuerRef:
    name: letsencrypt-dev-issuer
    kind: Issuer
# k8s/dev/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-dev"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  name: ingress-dev
  namespace: dev
spec:
  tls:
    - hosts:
        - localhost
      secretName: tls-localhost-dev
  rules:
    - host: localhost
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: client-cluster-ip-service-dev
                port:
                  number: 3000

完成所有这些之后,您可以导航到 localhost 并查看它有一个证书...在 Linux 和 macOS 上。

在 WSL2 中,即使没有错误,我也无法使证书正常工作,除非我 describe 一些资源:

$ kubectl describe issuer letsencrypt-dev-issuer -n cert-manager
Name:         letsencrypt-dev-issuer
Namespace:    cert-manager
Labels:       <none>
Annotations:  <none>
API Version:  cert-manager.io/v1
Kind:         Issuer
Metadata:
  Creation Timestamp:  2021-03-04T01:33:06Z
  Generation:          1
  Managed Fields:
    API Version:  cert-manager.io/v1
    Fields Type:  FieldsV1
    fieldsV1:
      f:status:
        .:
        f:conditions:
    Manager:      controller
    Operation:    Update
    Time:         2021-03-04T01:33:06Z
    API Version:  cert-manager.io/v1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .:
          f:kubectl.kubernetes.io/last-applied-configuration:
      f:spec:
        .:
        f:ca:
          .:
          f:secretName:
    Manager:         kubectl-client-side-apply
    Operation:       Update
    Time:            2021-03-04T01:33:06Z
  Resource Version:  800
  Self Link:         /apis/cert-manager.io/v1/namespaces/cert-manager/issuers/letsencrypt-dev-issuer
  UID:               ebad4607-afe7-480a-8107-1c27fa8c2e8d
Spec:
  Ca:
    Secret Name:  tls-localhost-dev
Status:
  Conditions:
    Last Transition Time:  2021-03-04T01:33:06Z
    Message:               Error getting keypair for CA issuer: secret "tls-localhost-dev" not found
    Reason:                ErrGetKeyPair
    Status:                False
    Type:                  Ready
Events:
  Type     Reason         Age                  From          Message
  ----     ------         ----                 ----          -------
  Warning  ErrGetKeyPair  4m30s (x9 over 19m)  cert-manager  Error getting keypair for CA issuer: secret "tls-localhost-dev" not found
  Warning  ErrInitIssuer  4m30s (x9 over 19m)  cert-manager  Error initializing issuer: secret "tls-localhost-dev" not found
$ kubectl describe certificate tls-localhost-dev -n dev
Name:         tls-localhost-dev
Namespace:    dev
Labels:       app.kubernetes.io/managed-by=skaffold
              skaffold.dev/run-id=a853f8d6-f192-465c-a43f-4369d5c5a636
Annotations:  <none>
API Version:  cert-manager.io/v1
Kind:         Certificate
Metadata:
  Creation Timestamp:  2021-03-04T01:38:18Z
  Generation:          1
  Managed Fields:
    API Version:  cert-manager.io/v1
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:labels:
          .:
          f:app.kubernetes.io/managed-by:
          f:skaffold.dev/run-id:
        f:ownerReferences:
          .:
          k:{"uid":"d596b83b-95eb-46f6-941f-0f6cef0a76d8"}:
            .:
            f:apiVersion:
            f:blockOwnerDeletion:
            f:controller:
            f:kind:
            f:name:
            f:uid:
      f:spec:
        .:
        f:dnsNames:
        f:issuerRef:
          .:
          f:group:
          f:kind:
          f:name:
        f:secretName:
        f:usages:
      f:status:
        .:
        f:conditions:
        f:nextPrivateKeySecretName:
        f:notAfter:
        f:notBefore:
        f:renewalTime:
    Manager:    controller
    Operation:  Update
    Time:       2021-03-04T01:38:18Z
  Owner References:
    API Version:           networking.k8s.io/v1beta1
    Block Owner Deletion:  true
    Controller:            true
    Kind:                  Ingress
    Name:                  ingress-dev
    UID:                   d596b83b-95eb-46f6-941f-0f6cef0a76d8
  Resource Version:        1312
  Self Link:               /apis/cert-manager.io/v1/namespaces/dev/certificates/tls-localhost-dev
  UID:                     12d0f503-928b-4aaf-b691-3e6ed6e76e39
Spec:
  Dns Names:
    localhost
  Issuer Ref:
    Group:      cert-manager.io
    Kind:       ClusterIssuer
    Name:       letsencrypt-dev
  Secret Name:  tls-localhost-dev
  Usages:
    digital signature
    key encipherment
Status:
  Conditions:
    Last Transition Time:        2021-03-04T01:38:18Z
    Message:                     Issuing certificate as Secret was previously issued by Issuer.cert-manager.io/
    Reason:                      IncorrectIssuer
    Status:                      True
    Type:                        Issuing
    Last Transition Time:        2021-03-04T01:38:18Z
    Message:                     Existing issued Secret is not up to date for spec: [spec.ipAddresses]
    Reason:                      SecretMismatch
    Status:                      False
    Type:                        Ready
  Next Private Key Secret Name:  tls-localhost-dev-zqwpw
  Not After:                     2023-06-04T00:32:33Z
  Not Before:                    2021-03-04T01:32:33Z
  Renewal Time:                  2023-05-05T00:32:33Z
Events:
  Type    Reason     Age   From          Message
  ----    ------     ----  ----          -------
  Normal  Issuing    15m   cert-manager  Issuing certificate as Secret was previously issued by Issuer.cert-manager.io/
  Normal  Reused     15m   cert-manager  Reusing private key stored in existing Secret resource "tls-localhost-dev"
  Normal  Requested  15m   cert-manager  Created new CertificateRequest resource "tls-localhost-dev-4xrv9"
$ kubectl describe secret tls-localhost-dev -n dev
Name:         tls-localhost-dev
Namespace:    dev
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.crt:  1521 bytes
tls.key:  1708 bytes

基本上是说明显存在但不存在的东西。

关于如何解决这个问题有什么建议吗?

好的,在一些帮助下解决了这个问题:

这对我的用例有效。当然,我没有在没有将 mkcert 安装到 WSL 中的情况下对其进行测试,因此可能不需要该步骤:

  1. 使用choco安装mkcertchoco install -y mkcert
  2. 在Windows、mkcert -install
  3. WSL 安装mkcert(同样,不能 100% 确定这是必要的):
    curl -Lo mkcert https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64 &&
       sudo install mkcert /usr/local/bin/
    
  4. 在 WSL 中,mkcert -install(同样,不能 100% 确定这是必要的)
  5. 在Windows中:
    mkcert localhost 127.0.0.1 ::1
    
  6. 默认情况下,这会在您的 C:\Users\<user>\ 目录中生成它们
  7. 将它们复制到 WSL 中,对于我的用例来说,它是我项目的根目录
  8. 然后对于我的用例,我 运行:
    kubectl create secret tls tls-localhost-dev --key=localhost+2-key.pem --cert=localhost+2.pem -n dev 
    
  9. 对于我的用例,我然后 运行 kubectl apply -f k8s/dev/tls.yaml 其中包含:
     apiVersion: cert-manager.io/v1
     kind: Issuer
     metadata:
       name: letsencrypt-dev-issuer
       namespace: cert-manager
     spec:
       ca:
         secretName: tls-localhost-dev
     ---
     apiVersion: cert-manager.io/v1
     kind: Certificate
     metadata:
       name: letsencrypt-dev-certificate
       namespace: cert-manager
     spec:
       secretName: tls-localhost-dev
       dnsNames:
         - localhost
       issuerRef:
         name: letsencrypt-dev-issuer
         kind: Issuer
    

这一次在 运行 宁 skaffold devminikube tunnel 之后,我的应用程序 运行 应该是 TLS 证书。