{"id":3122,"date":"2022-09-25T20:17:36","date_gmt":"2022-09-26T00:17:36","guid":{"rendered":"https:\/\/dft.wiki\/?p=3122"},"modified":"2026-06-08T17:22:32","modified_gmt":"2026-06-08T21:22:32","slug":"kubernetes-demo-namespace-secret-deployment-service-ingress","status":"publish","type":"post","link":"https:\/\/dft.wiki\/?p=3122","title":{"rendered":"Kubernetes Demo: Namespace + Secret + Deployment + Service + Ingress"},"content":{"rendered":"<p>In this post I will walk through all the steps of deploying a containerized web application and all the required resources to make it externally accessible.<\/p>\n<ul>\n<li><strong>Create a Namespace<\/strong>\n<ul>\n<li>Namespaces isolate resources from other namespaces.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Create a Secret<\/strong>\n<ul>\n<li>Secrets act as a key vault for the Namespace. They store variables such as passwords that should not be hardcoded in the deployment script.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Create a Deployment<\/strong>\n<ul>\n<li>Deployments create Pods, which are the running instance(s) of the container application(s).<\/li>\n<\/ul>\n<\/li>\n<li><strong>Create a Service<\/strong>\n<ul>\n<li>Services route traffic to Deployments (similar to an internal load balancer).<\/li>\n<\/ul>\n<\/li>\n<li><strong>Create an Ingress<\/strong>\n<ul>\n<li>Ingresses expose the service port externally (similar to opening a port on a firewall).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>The files for this post can also be found in the public repository [<a href=\"https:\/\/github.com\/davift\/k8s-manifests-template\">Link<\/a>].<\/p>\n<hr \/>\n<p><strong>NAMESPACES<\/strong><\/p>\n<pre>nano namespace.yaml<\/pre>\n<pre>kind: Namespace\r\napiVersion: v1\r\nmetadata:\r\n  name: demo-namespace\r\n  labels:\r\n    name: demo-namespace<\/pre>\n<pre>kubectl apply -f namespace.yaml\r\nkubectl get ns<\/pre>\n<hr \/>\n<p><strong>SECRETS<\/strong><\/p>\n<pre>nano secret.yaml<\/pre>\n<pre>apiVersion: v1\r\nkind: Secret\r\nmetadata:\r\n  name: demo-secret\r\n  namespace: demo-namespace\r\nstringData:\r\n  SECRET_PASS: \"stringPassword\"<\/pre>\n<pre>kubectl apply -f secret.yaml\r\nkubectl get secret -n demo-namespace\r\nkubectl describe secret demo-secret -n demo-namespace<\/pre>\n<hr \/>\n<p><strong>DEPLOYMENTS<\/strong><\/p>\n<pre>nano deployment.yaml<\/pre>\n<pre>apiVersion: apps\/v1\r\nkind: Deployment\r\nmetadata:\r\n  name: demo-deployment\r\n  namespace: demo-namespace\r\nspec:\r\n  replicas: 1\r\n  selector:\r\n    matchLabels:\r\n      app: demo-deployment\r\n  template:\r\n    metadata:\r\n      labels:\r\n        app: demo-deployment\r\n    spec:\r\n      containers:\r\n      - name: demo-deployment\r\n        image: nginx:alpine\r\n        ports:\r\n        - containerPort: 80\r\n        startupProbe:\r\n          httpGet:\r\n            path: \/\r\n            port: 80\r\n          periodSeconds: 5\r\n          failureThreshold: 20\r\n        env:\r\n        - name: USERNAME\r\n          value: \"stringUsername\"\r\n        - name: PASSWORD\r\n          valueFrom:\r\n            secretKeyRef:\r\n              name: demo-secret\r\n              key: SECRET_PASS<\/pre>\n<pre>kubectl apply -f deployment.yaml\r\nkubectl get pods -n demo-namespace\r\nkubectl get pods -n demo-namespace -o wide\r\nkubectl logs -n demo-namespace demo-deployment-<strong>*********<\/strong>\r\nkubectl exec -it demo-deployment-<strong>*********-*****<\/strong> -n demo-namespace -- \/bin\/sh\r\nkubectl get replicaset -n demo-namespace<\/pre>\n<hr \/>\n<p><strong>SERVICE<\/strong><\/p>\n<pre>nano service.yaml<\/pre>\n<pre>apiVersion: v1\r\nkind: Service\r\nmetadata:\r\n  name: demo-service\r\n  namespace: demo-namespace\r\nspec:\r\n  type: ClusterIP\r\n  ports:\r\n  - port: 80\r\n  selector:\r\n    app: demo-deployment<\/pre>\n<pre>kubectl apply -f service.yaml\r\nkubectl get svc -n demo-namespace\r\nkubectl describe svc demo-service -n demo-namespace<\/pre>\n<p>Now you can test if the service is reachable from inside the server:<\/p>\n<pre>curl http:\/\/<strong>10.1.1.1<\/strong>:80\/<\/pre>\n<p><strong>Note:<\/strong> Replace <strong>10.1.1.1<\/strong> with the IP address assigned to the service.<\/p>\n<p>If it works, run the following command to access it from a browser outside the server:<\/p>\n<pre>kubectl port-forward service\/demo-service 80:80 --address='0.0.0.0' -n demo-namespace<\/pre>\n<hr \/>\n<p><strong>INGRESSES<\/strong><\/p>\n<p>The Ingress requires an Ingress Controller to be installed on the server. It comes out of the box with Minikube.<\/p>\n<pre>minikube addons enable ingress<\/pre>\n<p>If needed, see the following list of options and installation instructions at [<a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/ingress-controllers\/\">Link<\/a>].<\/p>\n<pre>nano ingress.yaml<\/pre>\n<pre>apiVersion: networking.k8s.io\/v1\r\nkind: Ingress\r\nmetadata:\r\n  name: demo-ingress\r\n  namespace: demo-namespace\r\n  annotations:\r\n    nginx.ingress.kubernetes.io\/rewrite-target: \"\/\"\r\nspec:\r\n  ingressClassName: nginx\r\n  rules:\r\n  - host: nginx.local\r\n    http:\r\n      paths:\r\n      - path: \/\r\n        pathType: Prefix\r\n        backend:\r\n          service:\r\n            name: demo-service\r\n            port:\r\n              number: 80<\/pre>\n<pre>kubectl apply -f ingress.yaml\r\nkubectl get ing -n demo-namespace\r\nkubectl get ing -n demo-namespace --watch\r\nkubectl describe ing demo-ingress -n demo-namespace<\/pre>\n<p><strong>Note:<\/strong> The ingress resource will take a few seconds to acquire an external IP.<\/p>\n<hr \/>\n<p><strong>CHECK THE ENVIRONMENT VARIABLES<\/strong><\/p>\n<pre>kubectl get pods -n demo-namespace<\/pre>\n<pre>kubectl exec -it demo-deployment-**********-***** -n demo-namespace -- bash<\/pre>\n<p>OR<\/p>\n<pre>kubectl exec --stdin --tty demo-deployment-**********-***** -n demo-namespace -- bash<\/pre>\n<pre>root@demo-deployment-**********-*****:\/# <strong>echo $PASSWORD<\/strong>\r\n<span style=\"text-decoration: underline;\">stringPassword<\/span>\r\nroot@demo-deployment-**********-*****:\/# <strong>echo $USERNAME<\/strong>\r\n<span style=\"text-decoration: underline;\">stringUsername<\/span><\/pre>\n<p>Or update the web page to display the variables:<\/p>\n<pre>kubectl exec --stdin --tty demo-deployment-**********-***** -n demo-namespace -- bash -c \"echo \\$USERNAME : \\$PASSWORD &gt; \/usr\/share\/nginx\/html\/index.html\"<\/pre>\n<hr \/>\n<p><strong>SEE ALSO<\/strong><\/p>\n<p><strong>K3s<\/strong> on Ubuntu 20.04 [<a href=\"https:\/\/dft.wiki\/?p=3105\">Link<\/a>].<\/p>\n<p><strong>Minikube<\/strong> on Ubuntu 22.04 [<a href=\"https:\/\/dft.wiki\/?p=3087\">Link<\/a>].<\/p>\n<p><strong>MicroK8s<\/strong> on Ubuntu 22.04 [<a href=\"https:\/\/dft.wiki\/?p=3151\">Link<\/a>].<\/p>\n<p><strong>Kubernetes<\/strong> Cheat Sheet [<a href=\"https:\/\/dft.wiki\/?p=1372\">Link<\/a>].<\/p>\n<p><strong>Kubernetes<\/strong> Persistent Volumes [<a href=\"https:\/\/dft.wiki\/?p=1435\">Link<\/a>].<\/p>\n<p><strong>Kubernetes<\/strong> Dashboard [<a href=\"https:\/\/dft.wiki\/?p=4114\">Link<\/a>].<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post I will walk through all the steps of deploying a containerized web [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,7],"tags":[],"class_list":["post-3122","post","type-post","status-publish","format-standard","hentry","category-linux","category-web"],"_links":{"self":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/3122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3122"}],"version-history":[{"count":18,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/3122\/revisions"}],"predecessor-version":[{"id":5664,"href":"https:\/\/dft.wiki\/index.php?rest_route=\/wp\/v2\/posts\/3122\/revisions\/5664"}],"wp:attachment":[{"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dft.wiki\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}