[{"data":1,"prerenderedAt":1667},["ShallowReactive",2],{"blog-en-cert-manager-automatic-tls":3,"blog-en-cert-manager-automatic-tls-alt":197},{"id":4,"title":5,"author":6,"body":7,"date":1651,"description":1652,"extension":1653,"image":149,"locale":1654,"meta":1655,"navigation":197,"path":1656,"seo":1657,"stem":1658,"tags":1659,"__hash__":1666},"blog\u002Fblog\u002Fen\u002Fcert-manager-automatic-tls.md","Automating TLS Certificate Management in Kubernetes with cert-manager","Kubo Team",{"type":8,"value":9,"toc":1625},"minimark",[10,28,33,46,51,54,83,87,95,127,135,139,143,266,270,321,325,334,471,474,582,589,593,606,610,647,668,672,735,750,759,762,795,799,808,812,1017,1024,1028,1031,1164,1168,1181,1304,1311,1315,1319,1333,1453,1457,1535,1539,1562,1566,1569,1600,1609,1621],[11,12,13,14,21,22,27],"p",{},"When exposing services on Kubernetes, TLS certificate management is an unavoidable challenge. Manual certificate issuance and renewal increase operational burden and create outage risks from expiration. ",[15,16,20],"a",{"href":17,"rel":18},"https:\u002F\u002Fcert-manager.io\u002F",[19],"nofollow","cert-manager",", a CNCF Graduated project, fully automates the TLS certificate lifecycle and solves this problem at its root. On K3s-based Kubernetes platforms like ",[15,23,26],{"href":24,"rel":25},"https:\u002F\u002Fkubo.hexabase.io\u002F",[19],"Kubo",", cert-manager enables zero-touch certificate management.",[29,30,32],"h2",{"id":31},"cert-manager-fundamentals-and-architecture","cert-manager Fundamentals and Architecture",[11,34,35,39,40,45],{},[15,36,20],{"href":37,"rel":38},"https:\u002F\u002Fcert-manager.io\u002Fdocs\u002F",[19]," is an add-on that automates TLS certificate issuance and renewal on Kubernetes and OpenShift clusters. Actively developed on ",[15,41,44],{"href":42,"rel":43},"https:\u002F\u002Fgithub.com\u002Fcert-manager\u002Fcert-manager",[19],"GitHub",", it has become the de facto standard for certificate management in cloud-native environments.",[47,48,50],"h3",{"id":49},"core-components","Core Components",[11,52,53],{},"cert-manager consists of:",[55,56,57,65,71,77],"ul",{},[58,59,60,64],"li",{},[61,62,63],"strong",{},"Controller",": Monitors Certificate resource state and executes issuance and renewal",[58,66,67,70],{},[61,68,69],{},"Webhook",": Handles CRD validation and Admission Control",[58,72,73,76],{},[61,74,75],{},"CA Injector",": Automatically injects CA bundles into webhooks and custom resources",[58,78,79,82],{},[61,80,81],{},"ACME Solver",": Manages challenge processing with ACME providers like Let's Encrypt",[47,84,86],{"id":85},"supported-issuers","Supported Issuers",[11,88,89,90,94],{},"According to the ",[15,91,93],{"href":37,"rel":92},[19],"cert-manager documentation",", the following certificate authorities are supported:",[55,96,97,103,109,115,121],{},[58,98,99,102],{},[61,100,101],{},"Let's Encrypt"," (ACME protocol): Free, automated TLS certificates",[58,104,105,108],{},[61,106,107],{},"HashiCorp Vault",": Enterprise PKI integration",[58,110,111,114],{},[61,112,113],{},"CyberArk Certificate Manager",": Enterprise certificate management",[58,116,117,120],{},[61,118,119],{},"Private PKI",": Certificates from your own CA",[58,122,123,126],{},[61,124,125],{},"Self-signed",": For test environments",[11,128,129,134],{},[15,130,133],{"href":131,"rel":132},"https:\u002F\u002Fwww.hexabase.com\u002Fproduct\u002Fcaptain-ai\u002F",[19],"Captain.AI"," monitors the security posture of your entire Kubernetes environment with AI, proactively detecting certificate expiration risks.",[29,136,138],{"id":137},"installation-and-initial-configuration","Installation and Initial Configuration",[47,140,142],{"id":141},"installing-with-helm","Installing with Helm",[144,145,150],"pre",{"className":146,"code":147,"language":148,"meta":149,"style":149},"language-bash shiki shiki-themes tokyo-night","# Add the cert-manager Helm repository\nhelm repo add jetstack https:\u002F\u002Fcharts.jetstack.io\nhelm repo update\n\n# Install with CRDs included\nhelm install cert-manager jetstack\u002Fcert-manager \\\n  --namespace cert-manager \\\n  --create-namespace \\\n  --version v1.18.1 \\\n  --set crds.enabled=true\n","bash","",[151,152,153,162,182,192,199,205,223,234,242,253],"code",{"__ignoreMap":149},[154,155,158],"span",{"class":156,"line":157},"line",1,[154,159,161],{"class":160},"sbD-w","# Add the cert-manager Helm repository\n",[154,163,165,169,173,176,179],{"class":156,"line":164},2,[154,166,168],{"class":167},"sE3pS","helm",[154,170,172],{"class":171},"sPY7s"," repo",[154,174,175],{"class":171}," add",[154,177,178],{"class":171}," jetstack",[154,180,181],{"class":171}," https:\u002F\u002Fcharts.jetstack.io\n",[154,183,185,187,189],{"class":156,"line":184},3,[154,186,168],{"class":167},[154,188,172],{"class":171},[154,190,191],{"class":171}," update\n",[154,193,195],{"class":156,"line":194},4,[154,196,198],{"emptyLinePlaceholder":197},true,"\n",[154,200,202],{"class":156,"line":201},5,[154,203,204],{"class":160},"# Install with CRDs included\n",[154,206,208,210,213,216,219],{"class":156,"line":207},6,[154,209,168],{"class":167},[154,211,212],{"class":171}," install",[154,214,215],{"class":171}," cert-manager",[154,217,218],{"class":171}," jetstack\u002Fcert-manager",[154,220,222],{"class":221},"sAklC"," \\\n",[154,224,226,230,232],{"class":156,"line":225},7,[154,227,229],{"class":228},"sT800","  --namespace",[154,231,215],{"class":171},[154,233,222],{"class":221},[154,235,237,240],{"class":156,"line":236},8,[154,238,239],{"class":228},"  --create-namespace",[154,241,222],{"class":221},[154,243,245,248,251],{"class":156,"line":244},9,[154,246,247],{"class":228},"  --version",[154,249,250],{"class":171}," v1.18.1",[154,252,222],{"class":221},[154,254,256,259,262],{"class":156,"line":255},10,[154,257,258],{"class":228},"  --set",[154,260,261],{"class":171}," crds.enabled=",[154,263,265],{"class":264},"sOJ5S","true\n",[47,267,269],{"id":268},"verifying-installation","Verifying Installation",[144,271,273],{"className":146,"code":272,"language":148,"meta":149,"style":149},"# Check pod status\nkubectl get pods -n cert-manager\n\n# Expected output:\n# cert-manager-5c6866597-zw7kh          1\u002F1     Running   0\n# cert-manager-cainjector-577f6d9fd7-b   1\u002F1     Running   0\n# cert-manager-webhook-56f8b4f8d-hsqvg   1\u002F1     Running   0\n",[151,274,275,280,297,301,306,311,316],{"__ignoreMap":149},[154,276,277],{"class":156,"line":157},[154,278,279],{"class":160},"# Check pod status\n",[154,281,282,285,288,291,294],{"class":156,"line":164},[154,283,284],{"class":167},"kubectl",[154,286,287],{"class":171}," get",[154,289,290],{"class":171}," pods",[154,292,293],{"class":228}," -n",[154,295,296],{"class":171}," cert-manager\n",[154,298,299],{"class":156,"line":184},[154,300,198],{"emptyLinePlaceholder":197},[154,302,303],{"class":156,"line":194},[154,304,305],{"class":160},"# Expected output:\n",[154,307,308],{"class":156,"line":201},[154,309,310],{"class":160},"# cert-manager-5c6866597-zw7kh          1\u002F1     Running   0\n",[154,312,313],{"class":156,"line":207},[154,314,315],{"class":160},"# cert-manager-cainjector-577f6d9fd7-b   1\u002F1     Running   0\n",[154,317,318],{"class":156,"line":225},[154,319,320],{"class":160},"# cert-manager-webhook-56f8b4f8d-hsqvg   1\u002F1     Running   0\n",[47,322,324],{"id":323},"creating-a-clusterissuer","Creating a ClusterIssuer",[11,326,327,328,333],{},"Following the ",[15,329,332],{"href":330,"rel":331},"https:\u002F\u002Fwww.funkysi1701.com\u002Fposts\u002F2025\u002Fkubernetes-and-letsencrypt\u002F",[19],"practical guide from Funky Si's Blog",", configure a ClusterIssuer for Let's Encrypt:",[144,335,339],{"className":336,"code":337,"language":338,"meta":149,"style":149},"language-yaml shiki shiki-themes tokyo-night","apiVersion: cert-manager.io\u002Fv1\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-prod\nspec:\n  acme:\n    server: https:\u002F\u002Facme-v02.api.letsencrypt.org\u002Fdirectory\n    email: admin@example.com\n    privateKeySecretRef:\n      name: letsencrypt-prod-key\n    solvers:\n    - http01:\n        ingress:\n          class: nginx\n","yaml",[151,340,341,353,363,371,381,388,395,405,415,422,432,440,452,460],{"__ignoreMap":149},[154,342,343,347,350],{"class":156,"line":157},[154,344,346],{"class":345},"s0U2E","apiVersion",[154,348,349],{"class":221},":",[154,351,352],{"class":171}," cert-manager.io\u002Fv1\n",[154,354,355,358,360],{"class":156,"line":164},[154,356,357],{"class":345},"kind",[154,359,349],{"class":221},[154,361,362],{"class":171}," ClusterIssuer\n",[154,364,365,368],{"class":156,"line":184},[154,366,367],{"class":345},"metadata",[154,369,370],{"class":221},":\n",[154,372,373,376,378],{"class":156,"line":194},[154,374,375],{"class":345},"  name",[154,377,349],{"class":221},[154,379,380],{"class":171}," letsencrypt-prod\n",[154,382,383,386],{"class":156,"line":201},[154,384,385],{"class":345},"spec",[154,387,370],{"class":221},[154,389,390,393],{"class":156,"line":207},[154,391,392],{"class":345},"  acme",[154,394,370],{"class":221},[154,396,397,400,402],{"class":156,"line":225},[154,398,399],{"class":345},"    server",[154,401,349],{"class":221},[154,403,404],{"class":171}," https:\u002F\u002Facme-v02.api.letsencrypt.org\u002Fdirectory\n",[154,406,407,410,412],{"class":156,"line":236},[154,408,409],{"class":345},"    email",[154,411,349],{"class":221},[154,413,414],{"class":171}," admin@example.com\n",[154,416,417,420],{"class":156,"line":244},[154,418,419],{"class":345},"    privateKeySecretRef",[154,421,370],{"class":221},[154,423,424,427,429],{"class":156,"line":255},[154,425,426],{"class":345},"      name",[154,428,349],{"class":221},[154,430,431],{"class":171}," letsencrypt-prod-key\n",[154,433,435,438],{"class":156,"line":434},11,[154,436,437],{"class":345},"    solvers",[154,439,370],{"class":221},[154,441,443,447,450],{"class":156,"line":442},12,[154,444,446],{"class":445},"sgJMe","    -",[154,448,449],{"class":345}," http01",[154,451,370],{"class":221},[154,453,455,458],{"class":156,"line":454},13,[154,456,457],{"class":345},"        ingress",[154,459,370],{"class":221},[154,461,463,466,468],{"class":156,"line":462},14,[154,464,465],{"class":345},"          class",[154,467,349],{"class":221},[154,469,470],{"class":171}," nginx\n",[11,472,473],{},"It is recommended to also prepare a staging issuer for testing:",[144,475,477],{"className":336,"code":476,"language":338,"meta":149,"style":149},"apiVersion: cert-manager.io\u002Fv1\nkind: ClusterIssuer\nmetadata:\n  name: letsencrypt-staging\nspec:\n  acme:\n    server: https:\u002F\u002Facme-staging-v02.api.letsencrypt.org\u002Fdirectory\n    email: admin@example.com\n    privateKeySecretRef:\n      name: letsencrypt-staging-key\n    solvers:\n    - http01:\n        ingress:\n          class: nginx\n",[151,478,479,487,495,501,510,516,522,531,539,545,554,560,568,574],{"__ignoreMap":149},[154,480,481,483,485],{"class":156,"line":157},[154,482,346],{"class":345},[154,484,349],{"class":221},[154,486,352],{"class":171},[154,488,489,491,493],{"class":156,"line":164},[154,490,357],{"class":345},[154,492,349],{"class":221},[154,494,362],{"class":171},[154,496,497,499],{"class":156,"line":184},[154,498,367],{"class":345},[154,500,370],{"class":221},[154,502,503,505,507],{"class":156,"line":194},[154,504,375],{"class":345},[154,506,349],{"class":221},[154,508,509],{"class":171}," letsencrypt-staging\n",[154,511,512,514],{"class":156,"line":201},[154,513,385],{"class":345},[154,515,370],{"class":221},[154,517,518,520],{"class":156,"line":207},[154,519,392],{"class":345},[154,521,370],{"class":221},[154,523,524,526,528],{"class":156,"line":225},[154,525,399],{"class":345},[154,527,349],{"class":221},[154,529,530],{"class":171}," https:\u002F\u002Facme-staging-v02.api.letsencrypt.org\u002Fdirectory\n",[154,532,533,535,537],{"class":156,"line":236},[154,534,409],{"class":345},[154,536,349],{"class":221},[154,538,414],{"class":171},[154,540,541,543],{"class":156,"line":244},[154,542,419],{"class":345},[154,544,370],{"class":221},[154,546,547,549,551],{"class":156,"line":255},[154,548,426],{"class":345},[154,550,349],{"class":221},[154,552,553],{"class":171}," letsencrypt-staging-key\n",[154,555,556,558],{"class":156,"line":434},[154,557,437],{"class":345},[154,559,370],{"class":221},[154,561,562,564,566],{"class":156,"line":442},[154,563,446],{"class":445},[154,565,449],{"class":345},[154,567,370],{"class":221},[154,569,570,572],{"class":156,"line":454},[154,571,457],{"class":345},[154,573,370],{"class":221},[154,575,576,578,580],{"class":156,"line":462},[154,577,465],{"class":345},[154,579,349],{"class":221},[154,581,470],{"class":171},[11,583,584,585,588],{},"On ",[15,586,26],{"href":24,"rel":587},[19],", you can also integrate with the Traefik Ingress Controller that ships with K3s.",[29,590,592],{"id":591},"how-acme-challenges-work","How ACME Challenges Work",[11,594,595,599,600,605],{},[15,596,101],{"href":597,"rel":598},"https:\u002F\u002Fletsencrypt.org\u002F",[19]," uses the ACME (Automatic Certificate Management Environment) protocol to verify domain ownership. As explained by ",[15,601,604],{"href":602,"rel":603},"https:\u002F\u002Fnotes.kodekloud.com\u002Fdocs\u002FKubernetes-Networking-Deep-Dive\u002FNetwork-Security\u002FCert-Manager-and-Lets-Encrypt-Overview\u002Fpage",[19],"KodeKloud",", cert-manager supports two primary challenge types.",[47,607,609],{"id":608},"http-01-challenge","HTTP-01 Challenge",[144,611,613],{"className":336,"code":612,"language":338,"meta":149,"style":149},"solvers:\n- http01:\n    ingress:\n      class: nginx\n",[151,614,615,622,631,638],{"__ignoreMap":149},[154,616,617,620],{"class":156,"line":157},[154,618,619],{"class":345},"solvers",[154,621,370],{"class":221},[154,623,624,627,629],{"class":156,"line":164},[154,625,626],{"class":445},"-",[154,628,449],{"class":345},[154,630,370],{"class":221},[154,632,633,636],{"class":156,"line":184},[154,634,635],{"class":345},"    ingress",[154,637,370],{"class":221},[154,639,640,643,645],{"class":156,"line":194},[154,641,642],{"class":345},"      class",[154,644,349],{"class":221},[154,646,470],{"class":171},[55,648,649,656,662],{},[58,650,651,652,655],{},"let's encrypt accesses the ",[151,653,654],{},"-.well-known-acme-challenge-"," endpoint to validate",[58,657,658,661],{},[61,659,660],{},"Pros",": Simple configuration, no additional DNS permissions needed",[58,663,664,667],{},[61,665,666],{},"Cons",": Port 80 must be externally accessible, wildcard certificates not supported",[47,669,671],{"id":670},"dns-01-challenge","DNS-01 Challenge",[144,673,675],{"className":336,"code":674,"language":338,"meta":149,"style":149},"solvers:\n- dns01:\n    cloudflare:\n      email: admin@example.com\n      apiTokenSecretRef:\n        name: cloudflare-api-token\n        key: api-token\n",[151,676,677,683,692,699,708,715,725],{"__ignoreMap":149},[154,678,679,681],{"class":156,"line":157},[154,680,619],{"class":345},[154,682,370],{"class":221},[154,684,685,687,690],{"class":156,"line":164},[154,686,626],{"class":445},[154,688,689],{"class":345}," dns01",[154,691,370],{"class":221},[154,693,694,697],{"class":156,"line":184},[154,695,696],{"class":345},"    cloudflare",[154,698,370],{"class":221},[154,700,701,704,706],{"class":156,"line":194},[154,702,703],{"class":345},"      email",[154,705,349],{"class":221},[154,707,414],{"class":171},[154,709,710,713],{"class":156,"line":201},[154,711,712],{"class":345},"      apiTokenSecretRef",[154,714,370],{"class":221},[154,716,717,720,722],{"class":156,"line":207},[154,718,719],{"class":345},"        name",[154,721,349],{"class":221},[154,723,724],{"class":171}," cloudflare-api-token\n",[154,726,727,730,732],{"class":156,"line":225},[154,728,729],{"class":345},"        key",[154,731,349],{"class":221},[154,733,734],{"class":171}," api-token\n",[55,736,737,740,745],{},[58,738,739],{},"Validation via DNS TXT records",[58,741,742,744],{},[61,743,660],{},": Supports wildcard certificates, port 80 not required",[58,746,747,749],{},[61,748,666],{},": Requires DNS provider API credentials",[11,751,752,753,758],{},"As ",[15,754,757],{"href":755,"rel":756},"https:\u002F\u002Fwww.thedougie.com\u002F2025\u002F11\u002F01\u002Fkubernetes-cert-manager-cloudflare-lets-encrypt\u002F",[19],"The Dougie Chronicles"," details, the Cloudflare DNS-01 challenge is the most common choice when wildcard certificates are needed.",[11,760,761],{},"Supported DNS providers include:",[55,763,764,771,778,785,792],{},[58,765,766],{},[15,767,770],{"href":768,"rel":769},"https:\u002F\u002Fwww.cloudflare.com\u002F",[19],"Cloudflare",[58,772,773],{},[15,774,777],{"href":775,"rel":776},"https:\u002F\u002Faws.amazon.com\u002Froute53\u002F",[19],"AWS Route 53",[58,779,780],{},[15,781,784],{"href":782,"rel":783},"https:\u002F\u002Fcloud.google.com\u002Fdns",[19],"Google Cloud DNS",[58,786,787],{},[15,788,791],{"href":789,"rel":790},"https:\u002F\u002Fazure.microsoft.com\u002Fservices\u002Fdns\u002F",[19],"Azure DNS",[58,793,794],{},"And many more",[29,796,798],{"id":797},"ingress-integration-and-automatic-certificate-issuance","Ingress Integration and Automatic Certificate Issuance",[11,800,801,802,807],{},"One of cert-manager's most powerful features is its ",[15,803,806],{"href":804,"rel":805},"https:\u002F\u002Fcert-manager.io\u002Fdocs\u002Fusage\u002Fingress\u002F",[19],"automatic integration with Ingress resources",".",[47,809,811],{"id":810},"annotation-based-auto-issuance","Annotation-Based Auto-Issuance",[144,813,815],{"className":336,"code":814,"language":338,"meta":149,"style":149},"apiVersion: networking.k8s.io\u002Fv1\nkind: Ingress\nmetadata:\n  name: my-app-ingress\n  annotations:\n    cert-manager.io\u002Fcluster-issuer: \"letsencrypt-prod\"\nspec:\n  tls:\n  - hosts:\n    - app.example.com\n    secretName: app-tls-secret\n  rules:\n  - host: app.example.com\n    http:\n      paths:\n      - path: \u002F\n        pathType: Prefix\n        backend:\n          service:\n            name: my-app\n            port:\n              number: 80\n",[151,816,817,826,835,841,850,857,873,879,886,896,903,913,920,931,938,946,960,971,979,987,998,1006],{"__ignoreMap":149},[154,818,819,821,823],{"class":156,"line":157},[154,820,346],{"class":345},[154,822,349],{"class":221},[154,824,825],{"class":171}," networking.k8s.io\u002Fv1\n",[154,827,828,830,832],{"class":156,"line":164},[154,829,357],{"class":345},[154,831,349],{"class":221},[154,833,834],{"class":171}," Ingress\n",[154,836,837,839],{"class":156,"line":184},[154,838,367],{"class":345},[154,840,370],{"class":221},[154,842,843,845,847],{"class":156,"line":194},[154,844,375],{"class":345},[154,846,349],{"class":221},[154,848,849],{"class":171}," my-app-ingress\n",[154,851,852,855],{"class":156,"line":201},[154,853,854],{"class":345},"  annotations",[154,856,370],{"class":221},[154,858,859,862,864,867,870],{"class":156,"line":207},[154,860,861],{"class":345},"    cert-manager.io\u002Fcluster-issuer",[154,863,349],{"class":221},[154,865,866],{"class":221}," \"",[154,868,869],{"class":171},"letsencrypt-prod",[154,871,872],{"class":221},"\"\n",[154,874,875,877],{"class":156,"line":225},[154,876,385],{"class":345},[154,878,370],{"class":221},[154,880,881,884],{"class":156,"line":236},[154,882,883],{"class":345},"  tls",[154,885,370],{"class":221},[154,887,888,891,894],{"class":156,"line":244},[154,889,890],{"class":445},"  -",[154,892,893],{"class":345}," hosts",[154,895,370],{"class":221},[154,897,898,900],{"class":156,"line":255},[154,899,446],{"class":445},[154,901,902],{"class":171}," app.example.com\n",[154,904,905,908,910],{"class":156,"line":434},[154,906,907],{"class":345},"    secretName",[154,909,349],{"class":221},[154,911,912],{"class":171}," app-tls-secret\n",[154,914,915,918],{"class":156,"line":442},[154,916,917],{"class":345},"  rules",[154,919,370],{"class":221},[154,921,922,924,927,929],{"class":156,"line":454},[154,923,890],{"class":445},[154,925,926],{"class":345}," host",[154,928,349],{"class":221},[154,930,902],{"class":171},[154,932,933,936],{"class":156,"line":462},[154,934,935],{"class":345},"    http",[154,937,370],{"class":221},[154,939,941,944],{"class":156,"line":940},15,[154,942,943],{"class":345},"      paths",[154,945,370],{"class":221},[154,947,949,952,955,957],{"class":156,"line":948},16,[154,950,951],{"class":445},"      -",[154,953,954],{"class":345}," path",[154,956,349],{"class":221},[154,958,959],{"class":171}," \u002F\n",[154,961,963,966,968],{"class":156,"line":962},17,[154,964,965],{"class":345},"        pathType",[154,967,349],{"class":221},[154,969,970],{"class":171}," Prefix\n",[154,972,974,977],{"class":156,"line":973},18,[154,975,976],{"class":345},"        backend",[154,978,370],{"class":221},[154,980,982,985],{"class":156,"line":981},19,[154,983,984],{"class":345},"          service",[154,986,370],{"class":221},[154,988,990,993,995],{"class":156,"line":989},20,[154,991,992],{"class":345},"            name",[154,994,349],{"class":221},[154,996,997],{"class":171}," my-app\n",[154,999,1001,1004],{"class":156,"line":1000},21,[154,1002,1003],{"class":345},"            port",[154,1005,370],{"class":221},[154,1007,1009,1012,1014],{"class":156,"line":1008},22,[154,1010,1011],{"class":345},"              number",[154,1013,349],{"class":221},[154,1015,1016],{"class":264}," 80\n",[11,1018,1019,1020,1023],{},"Simply adding the ",[151,1021,1022],{},"cert-manager.io\u002Fcluster-issuer"," annotation causes cert-manager to automatically create a Certificate resource, obtain a certificate from Let's Encrypt, and store it in a Kubernetes Secret.",[47,1025,1027],{"id":1026},"gateway-api-integration","Gateway API Integration",[11,1029,1030],{},"cert-manager also works with the Kubernetes Gateway API:",[144,1032,1034],{"className":336,"code":1033,"language":338,"meta":149,"style":149},"apiVersion: gateway.networking.k8s.io\u002Fv1\nkind: HTTPRoute\nmetadata:\n  name: my-app-route\n  annotations:\n    cert-manager.io\u002Fcluster-issuer: \"letsencrypt-prod\"\nspec:\n  parentRefs:\n  - name: my-gateway\n  hostnames:\n  - \"app.example.com\"\n  rules:\n  - backendRefs:\n    - name: my-app\n      port: 80\n",[151,1035,1036,1045,1054,1060,1069,1075,1087,1093,1100,1112,1119,1130,1136,1145,1155],{"__ignoreMap":149},[154,1037,1038,1040,1042],{"class":156,"line":157},[154,1039,346],{"class":345},[154,1041,349],{"class":221},[154,1043,1044],{"class":171}," gateway.networking.k8s.io\u002Fv1\n",[154,1046,1047,1049,1051],{"class":156,"line":164},[154,1048,357],{"class":345},[154,1050,349],{"class":221},[154,1052,1053],{"class":171}," HTTPRoute\n",[154,1055,1056,1058],{"class":156,"line":184},[154,1057,367],{"class":345},[154,1059,370],{"class":221},[154,1061,1062,1064,1066],{"class":156,"line":194},[154,1063,375],{"class":345},[154,1065,349],{"class":221},[154,1067,1068],{"class":171}," my-app-route\n",[154,1070,1071,1073],{"class":156,"line":201},[154,1072,854],{"class":345},[154,1074,370],{"class":221},[154,1076,1077,1079,1081,1083,1085],{"class":156,"line":207},[154,1078,861],{"class":345},[154,1080,349],{"class":221},[154,1082,866],{"class":221},[154,1084,869],{"class":171},[154,1086,872],{"class":221},[154,1088,1089,1091],{"class":156,"line":225},[154,1090,385],{"class":345},[154,1092,370],{"class":221},[154,1094,1095,1098],{"class":156,"line":236},[154,1096,1097],{"class":345},"  parentRefs",[154,1099,370],{"class":221},[154,1101,1102,1104,1107,1109],{"class":156,"line":244},[154,1103,890],{"class":445},[154,1105,1106],{"class":345}," name",[154,1108,349],{"class":221},[154,1110,1111],{"class":171}," my-gateway\n",[154,1113,1114,1117],{"class":156,"line":255},[154,1115,1116],{"class":345},"  hostnames",[154,1118,370],{"class":221},[154,1120,1121,1123,1125,1128],{"class":156,"line":434},[154,1122,890],{"class":445},[154,1124,866],{"class":221},[154,1126,1127],{"class":171},"app.example.com",[154,1129,872],{"class":221},[154,1131,1132,1134],{"class":156,"line":442},[154,1133,917],{"class":345},[154,1135,370],{"class":221},[154,1137,1138,1140,1143],{"class":156,"line":454},[154,1139,890],{"class":445},[154,1141,1142],{"class":345}," backendRefs",[154,1144,370],{"class":221},[154,1146,1147,1149,1151,1153],{"class":156,"line":462},[154,1148,446],{"class":445},[154,1150,1106],{"class":345},[154,1152,349],{"class":221},[154,1154,997],{"class":171},[154,1156,1157,1160,1162],{"class":156,"line":940},[154,1158,1159],{"class":345},"      port",[154,1161,349],{"class":221},[154,1163,1016],{"class":264},[47,1165,1167],{"id":1166},"automatic-renewal","Automatic Renewal",[11,1169,1170,1171,1176,1177,1180],{},"As explained in this ",[15,1172,1175],{"href":1173,"rel":1174},"https:\u002F\u002Fmedium.com\u002F@tashikmoinsheikh\u002Fthe-ultimate-deep-dive-automating-ssl-tls-with-cert-manager-in-kubernetes-83c91ae11df4",[19],"detailed Medium article",", cert-manager continuously monitors certificate expiration and automatically triggers renewal before the ",[151,1178,1179],{},"renewBefore"," period. Let's Encrypt certificates are valid for 90 days, and by default renewal starts 30 days before expiration.",[144,1182,1184],{"className":336,"code":1183,"language":338,"meta":149,"style":149},"apiVersion: cert-manager.io\u002Fv1\nkind: Certificate\nmetadata:\n  name: app-tls\nspec:\n  secretName: app-tls-secret\n  duration: 2160h    # 90 days\n  renewBefore: 720h  # Renew 30 days before expiry\n  issuerRef:\n    name: letsencrypt-prod\n    kind: ClusterIssuer\n  dnsNames:\n  - app.example.com\n  - www.app.example.com\n",[151,1185,1186,1194,1203,1209,1218,1224,1233,1246,1259,1266,1275,1284,1291,1297],{"__ignoreMap":149},[154,1187,1188,1190,1192],{"class":156,"line":157},[154,1189,346],{"class":345},[154,1191,349],{"class":221},[154,1193,352],{"class":171},[154,1195,1196,1198,1200],{"class":156,"line":164},[154,1197,357],{"class":345},[154,1199,349],{"class":221},[154,1201,1202],{"class":171}," Certificate\n",[154,1204,1205,1207],{"class":156,"line":184},[154,1206,367],{"class":345},[154,1208,370],{"class":221},[154,1210,1211,1213,1215],{"class":156,"line":194},[154,1212,375],{"class":345},[154,1214,349],{"class":221},[154,1216,1217],{"class":171}," app-tls\n",[154,1219,1220,1222],{"class":156,"line":201},[154,1221,385],{"class":345},[154,1223,370],{"class":221},[154,1225,1226,1229,1231],{"class":156,"line":207},[154,1227,1228],{"class":345},"  secretName",[154,1230,349],{"class":221},[154,1232,912],{"class":171},[154,1234,1235,1238,1240,1243],{"class":156,"line":225},[154,1236,1237],{"class":345},"  duration",[154,1239,349],{"class":221},[154,1241,1242],{"class":171}," 2160h",[154,1244,1245],{"class":160},"    # 90 days\n",[154,1247,1248,1251,1253,1256],{"class":156,"line":236},[154,1249,1250],{"class":345},"  renewBefore",[154,1252,349],{"class":221},[154,1254,1255],{"class":171}," 720h",[154,1257,1258],{"class":160},"  # Renew 30 days before expiry\n",[154,1260,1261,1264],{"class":156,"line":244},[154,1262,1263],{"class":345},"  issuerRef",[154,1265,370],{"class":221},[154,1267,1268,1271,1273],{"class":156,"line":255},[154,1269,1270],{"class":345},"    name",[154,1272,349],{"class":221},[154,1274,380],{"class":171},[154,1276,1277,1280,1282],{"class":156,"line":434},[154,1278,1279],{"class":345},"    kind",[154,1281,349],{"class":221},[154,1283,362],{"class":171},[154,1285,1286,1289],{"class":156,"line":442},[154,1287,1288],{"class":345},"  dnsNames",[154,1290,370],{"class":221},[154,1292,1293,1295],{"class":156,"line":454},[154,1294,890],{"class":445},[154,1296,902],{"class":171},[154,1298,1299,1301],{"class":156,"line":462},[154,1300,890],{"class":445},[154,1302,1303],{"class":171}," www.app.example.com\n",[11,1305,1306,1307,1310],{},"By integrating with ",[15,1308,133],{"href":131,"rel":1309},[19],", you can build workflows where AI detects certificate renewal failures and automatically suggests remediation.",[29,1312,1314],{"id":1313},"troubleshooting-and-best-practices","Troubleshooting and Best Practices",[47,1316,1318],{"id":1317},"common-issues-and-solutions","Common Issues and Solutions",[11,1320,1321,1322,1327,1328,349],{},"Drawing from the ",[15,1323,1326],{"href":1324,"rel":1325},"https:\u002F\u002Foneuptime.com\u002Fblog\u002Fpost\u002F2026-02-09-cert-manager-letsencrypt-acme\u002Fview",[19],"oneuptime guide"," and ",[15,1329,1332],{"href":1330,"rel":1331},"https:\u002F\u002Fwww.f5.com\u002Fcompany\u002Fblog\u002Fnginx\u002Fautomating-certificate-management-in-a-kubernetes-environment",[19],"F5 best practices",[144,1334,1336],{"className":146,"code":1335,"language":148,"meta":149,"style":149},"# Check Certificate status\nkubectl describe certificate app-tls -n default\n\n# Check CertificateRequest\nkubectl get certificaterequest -n default\n\n# Check Order (for ACME)\nkubectl get order -n default\n\n# Check Challenge\nkubectl get challenge -n default\n\n# View cert-manager logs\nkubectl logs -n cert-manager -l app=cert-manager\n",[151,1337,1338,1343,1361,1365,1370,1383,1387,1392,1405,1409,1414,1427,1431,1436],{"__ignoreMap":149},[154,1339,1340],{"class":156,"line":157},[154,1341,1342],{"class":160},"# Check Certificate status\n",[154,1344,1345,1347,1350,1353,1356,1358],{"class":156,"line":164},[154,1346,284],{"class":167},[154,1348,1349],{"class":171}," describe",[154,1351,1352],{"class":171}," certificate",[154,1354,1355],{"class":171}," app-tls",[154,1357,293],{"class":228},[154,1359,1360],{"class":171}," default\n",[154,1362,1363],{"class":156,"line":184},[154,1364,198],{"emptyLinePlaceholder":197},[154,1366,1367],{"class":156,"line":194},[154,1368,1369],{"class":160},"# Check CertificateRequest\n",[154,1371,1372,1374,1376,1379,1381],{"class":156,"line":201},[154,1373,284],{"class":167},[154,1375,287],{"class":171},[154,1377,1378],{"class":171}," certificaterequest",[154,1380,293],{"class":228},[154,1382,1360],{"class":171},[154,1384,1385],{"class":156,"line":207},[154,1386,198],{"emptyLinePlaceholder":197},[154,1388,1389],{"class":156,"line":225},[154,1390,1391],{"class":160},"# Check Order (for ACME)\n",[154,1393,1394,1396,1398,1401,1403],{"class":156,"line":236},[154,1395,284],{"class":167},[154,1397,287],{"class":171},[154,1399,1400],{"class":171}," order",[154,1402,293],{"class":228},[154,1404,1360],{"class":171},[154,1406,1407],{"class":156,"line":244},[154,1408,198],{"emptyLinePlaceholder":197},[154,1410,1411],{"class":156,"line":255},[154,1412,1413],{"class":160},"# Check Challenge\n",[154,1415,1416,1418,1420,1423,1425],{"class":156,"line":434},[154,1417,284],{"class":167},[154,1419,287],{"class":171},[154,1421,1422],{"class":171}," challenge",[154,1424,293],{"class":228},[154,1426,1360],{"class":171},[154,1428,1429],{"class":156,"line":442},[154,1430,198],{"emptyLinePlaceholder":197},[154,1432,1433],{"class":156,"line":454},[154,1434,1435],{"class":160},"# View cert-manager logs\n",[154,1437,1438,1440,1443,1445,1447,1450],{"class":156,"line":462},[154,1439,284],{"class":167},[154,1441,1442],{"class":171}," logs",[154,1444,293],{"class":228},[154,1446,215],{"class":171},[154,1448,1449],{"class":228}," -l",[154,1451,1452],{"class":171}," app=cert-manager\n",[47,1454,1456],{"id":1455},"common-errors-and-fixes","Common Errors and Fixes",[1458,1459,1460,1476],"table",{},[1461,1462,1463],"thead",{},[1464,1465,1466,1470,1473],"tr",{},[1467,1468,1469],"th",{},"Error",[1467,1471,1472],{},"Cause",[1467,1474,1475],{},"Fix",[1477,1478,1479,1493,1509,1522],"tbody",{},[1464,1480,1481,1487,1490],{},[1482,1483,1484],"td",{},[151,1485,1486],{},"Waiting for HTTP-01 challenge",[1482,1488,1489],{},"Port 80 blocked",[1482,1491,1492],{},"Check firewall settings",[1464,1494,1495,1500,1503],{},[1482,1496,1497],{},[151,1498,1499],{},"DNS record not yet propagated",[1482,1501,1502],{},"DNS propagation delay",[1482,1504,1505,1506],{},"Set ",[151,1507,1508],{},"--dns01-recursive-nameservers",[1464,1510,1511,1516,1519],{},[1482,1512,1513],{},[151,1514,1515],{},"rate limited",[1482,1517,1518],{},"Let's Encrypt rate limits",[1482,1520,1521],{},"Test with staging environment first",[1464,1523,1524,1529,1532],{},[1482,1525,1526],{},[151,1527,1528],{},"account is not registered",[1482,1530,1531],{},"ACME registration failure",[1482,1533,1534],{},"Verify the email field",[47,1536,1538],{"id":1537},"security-best-practices","Security Best Practices",[55,1540,1541,1544,1547,1555],{},[58,1542,1543],{},"Test with staging Issuer before switching to production",[58,1545,1546],{},"Restrict access to Certificate resources with RBAC",[58,1548,752,1549,1554],{},[15,1550,1553],{"href":1551,"rel":1552},"https:\u002F\u002Fapurv.me\u002Fposts\u002Fkubernetes-setup-cert-manager-automated-tls-management\u002F",[19],"Apurv's tech notes"," recommend, manage API tokens securely in Kubernetes Secrets",[58,1556,1557,1558,1561],{},"Set up monitoring alerts for certificates (Prometheus metric ",[151,1559,1560],{},"certmanager_certificate_expiration_timestamp_seconds",")",[29,1563,1565],{"id":1564},"conclusion","Conclusion",[11,1567,1568],{},"cert-manager dramatically reduces the effort of TLS certificate management in Kubernetes. The key takeaways are:",[1570,1571,1572,1577,1582,1588,1594],"ol",{},[58,1573,1574,1576],{},[61,1575,20],{}," fully automates certificate issuance, renewal, and management",[58,1578,1579,1581],{},[61,1580,101],{}," integration provides free TLS certificates automatically",[58,1583,1584,1587],{},[61,1585,1586],{},"HTTP-01 \u002F DNS-01"," challenges adapt to various environment requirements",[58,1589,1590,1593],{},[61,1591,1592],{},"Ingress annotations"," enable adoption with minimal changes to existing workloads",[58,1595,1596,1599],{},[61,1597,1598],{},"Automatic renewal"," eliminates the risk of certificate expiration",[11,1601,1602,1605,1606,807],{},[15,1603,26],{"href":24,"rel":1604},[19]," is built on K3s with strong affinity for the CNCF ecosystem, and cert-manager deployment enables secure service exposure with ease. If you are looking to strengthen Kubernetes security, explore ",[15,1607,26],{"href":24,"rel":1608},[19],[11,1610,1611,1612,1615,1616,807],{},"For AI-powered Kubernetes operations automation, see ",[15,1613,133],{"href":131,"rel":1614},[19]," for details. For consultations, reach out through our ",[15,1617,1620],{"href":1618,"rel":1619},"https:\u002F\u002Fwww.hexabase.com\u002Fcontact-us\u002F",[19],"contact page",[1622,1623,1624],"style",{},"html pre.shiki code .sbD-w, html code.shiki .sbD-w{--shiki-default:#51597D;--shiki-default-font-style:italic}html pre.shiki code .sE3pS, html code.shiki .sE3pS{--shiki-default:#C0CAF5}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sT800, html code.shiki .sT800{--shiki-default:#E0AF68}html pre.shiki code .sOJ5S, html code.shiki .sOJ5S{--shiki-default:#FF9E64}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s0U2E, html code.shiki .s0U2E{--shiki-default:#F7768E}html pre.shiki code .sgJMe, html code.shiki .sgJMe{--shiki-default:#9ABDF5}",{"title":149,"searchDepth":164,"depth":164,"links":1626},[1627,1631,1636,1640,1645,1650],{"id":31,"depth":164,"text":32,"children":1628},[1629,1630],{"id":49,"depth":184,"text":50},{"id":85,"depth":184,"text":86},{"id":137,"depth":164,"text":138,"children":1632},[1633,1634,1635],{"id":141,"depth":184,"text":142},{"id":268,"depth":184,"text":269},{"id":323,"depth":184,"text":324},{"id":591,"depth":164,"text":592,"children":1637},[1638,1639],{"id":608,"depth":184,"text":609},{"id":670,"depth":184,"text":671},{"id":797,"depth":164,"text":798,"children":1641},[1642,1643,1644],{"id":810,"depth":184,"text":811},{"id":1026,"depth":184,"text":1027},{"id":1166,"depth":184,"text":1167},{"id":1313,"depth":164,"text":1314,"children":1646},[1647,1648,1649],{"id":1317,"depth":184,"text":1318},{"id":1455,"depth":184,"text":1456},{"id":1537,"depth":184,"text":1538},{"id":1564,"depth":164,"text":1565},"2026-05-27","Automate TLS certificate issuance and renewal in Kubernetes using cert-manager. Covers Let's Encrypt, ACME challenges, Ingress integration, and best practices.","md","en",{},"\u002Fblog\u002Fen\u002Fcert-manager-automatic-tls",{"title":5,"description":1652},"blog\u002Fen\u002Fcert-manager-automatic-tls",[20,1660,1661,101,1662,1663,1664,1665],"Kubernetes","TLS","ACME","CNCF","Security","Certificates","6wLjlTQm5BYMwChkzZlOUlCJmt_qjqOzrP3SCCNQCq0",1780391431673]