[{"data":1,"prerenderedAt":1715},["ShallowReactive",2],{"blog-en-cert-manager-automatic-tls":3,"blog-related-en-cert-manager-automatic-tls":1668,"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__":1667},"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 .s0U2E, html code.shiki .s0U2E{--shiki-default:#F7768E}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sPY7s, html code.shiki .sPY7s{--shiki-default:#9ECE6A}html pre.shiki code .sgJMe, html code.shiki .sgJMe{--shiki-default:#9ABDF5}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 .sOJ5S, html code.shiki .sOJ5S{--shiki-default:#FF9E64}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 .sT800, html code.shiki .sT800{--shiki-default:#E0AF68}",{"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,1662,1663,1664,1665,1666],"kubernetes","tls","lets-encrypt","acme","cncf","security","certificates","7YG-KufbJ6kICiZVcu8e1n14VsMW3SHwqS1MxXkF_p0",[1669,1676,1682,1692,1700,1708],{"path":1670,"title":1671,"description":1672,"date":1673,"tags":1674},"\u002Fblog\u002Fen\u002Fk3s-cert-manager-acme-renewal-pitfalls","A Saturday Morning K3s Outage from an Expired TLS Certificate: Designing ACME Automation That Actually Escapes Manual Renewal","Even with cert-manager installed, K3s production certificates can silently expire due to Issuer misconfiguration, failed DNS validation, Let's Encrypt rate limits, or Secrets that never get reloaded. This post covers the monitoring and design choices that turn ACME auto-renewal from 'installed' into 'actually working.'","2026-08-27",[1675,1660,20,1661,1662,1663],"k3s",{"path":1677,"title":1678,"description":1679,"date":1680,"tags":1681},"\u002Fblog\u002Fen\u002Fkubernetes-certificate-management-cert-manager-process-debt","The Cert Renewal Took One Line of Code and Two Months of Meetings: Why Kubernetes Certificate Management Is a Process Problem, Not a Technical One","Kubernetes certificate management is technically a matter of days. What actually takes time is the organizational process of getting sign-off. Here's how cert-manager automates the technical side, and how to design away the operational debt that remains.","2026-08-09",[1675,1660,20,1661,1665],{"path":1683,"title":1684,"description":1685,"date":1651,"tags":1686},"\u002Fblog\u002Fen\u002Fcilium-ebpf-kubernetes-networking","Revolutionizing Kubernetes Networking with Cilium and eBPF","Discover how Cilium uses eBPF to transform Kubernetes networking. Compare with traditional CNIs, explore L7 policies, and leverage Hubble for observability.",[1687,1688,1660,1689,1690,1664,1665,1691],"cilium","ebpf","networking","cni","hubble",{"path":1693,"title":1694,"description":1695,"date":1696,"tags":1697},"\u002Fblog\u002Fen\u002Fk3s-zero-trust-kubectl-management-access","Stop Trusting Your Corporate VPN: 3 Steps to Make K3s Management Access Boundary-Free","Are you still designing K3s cluster management access around a corporate VPN? Learn 3 practical steps to secure kubectl and Rancher dashboard access with identity instead of network perimeter, plus the pitfall most teams hit when they implement zero trust.","2026-09-05",[1675,1660,1698,1665,1699],"zero-trust","rancher",{"path":1701,"title":1702,"description":1703,"date":1704,"tags":1705},"\u002Fblog\u002Fen\u002Fcncf-project-maturity-graduation-criteria-production","10,000 GitHub Stars Isn't a Diploma. Why the Real Criterion for Choosing a CNCF Project Isn't Commit Count but Maturity Stage","When adopting CNCF projects for your Kubernetes stack, are you judging them by GitHub stars and name recognition alone? Learn the Sandbox\u002FIncubating\u002FGraduated maturity framework and the Harbor case study to know what to check before production.","2026-08-19",[1675,1660,1664,1706,1707],"oss-governance","container-registry",{"path":1709,"title":1710,"description":1711,"date":1712,"tags":1713},"\u002Fblog\u002Fen\u002Fkubernetes-ebpf-inspektor-gadget-observability","No strace. No Sidecars. Still Debuggable: Inspektor Gadget's Answer for Seeing Inside Kubernetes with eBPF","When you can't add a privileged container or inject a sidecar into a production Kubernetes cluster, how do you diagnose Pod traffic and syscalls? We explain how the eBPF tool Inspektor Gadget works, and what happened to it in 2026.","2026-08-15",[1675,1660,1688,1714,1664],"observability",1792488895825]