diff --git a/.infrastructure/helm-chart/todoapp/.helmignore b/.infrastructure/helm-chart/todoapp/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/.infrastructure/helm-chart/todoapp/Chart.yaml b/.infrastructure/helm-chart/todoapp/Chart.yaml new file mode 100644 index 0000000..573365e --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: todoapp +description: A Helm chart for Kubernetes +type: application +version: 0.1.0 +appVersion: "1.16.0" +dependencies: +- name: mysql + version: "8.0.0" diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/.helmignore b/.infrastructure/helm-chart/todoapp/charts/mysql/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/Chart.yaml b/.infrastructure/helm-chart/todoapp/charts/mysql/Chart.yaml new file mode 100644 index 0000000..e65c7a0 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: mysql +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/templates/configMap.yml b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/configMap.yml new file mode 100644 index 0000000..f20dbd9 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/configMap.yml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Chart.Name }} + namespace: {{ .Values.mysql.namespace }} + labels: + app: {{ .Chart.Name }} +data: + init.sql: | + GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%'; + USE app_db; + CREATE TABLE counter ( + id INT AUTO_INCREMENT PRIMARY KEY, + value INT + ); diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/templates/ns.yml b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/ns.yml new file mode 100644 index 0000000..035e9aa --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/ns.yml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Chart.Name }} diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/templates/secret.yml b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/secret.yml new file mode 100644 index 0000000..71451c7 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/secret.yml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Chart.Name }}-secrets + namespace: {{ .Values.mysql.namespace }} +type: Opaque +data: + {{- range $k, $v := .Values.mysql.secret }} + {{ $k }}: {{ $v }} + {{ end }} diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/templates/service.yml b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/service.yml new file mode 100644 index 0000000..07a7f88 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/service.yml @@ -0,0 +1,17 @@ +# Headless service for stable DNS entries of StatefulSet members. +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }} + namespace: {{ .Values.mysql.namespace }} +spec: + selector: + app: {{ .Chart.Name }} + ports: + - name: {{ .Chart.Name }} + port: 3306 + clusterIP: None + +# pod-name.service-name.namespace.svc.cluster.local +# pod-name.service-name +# mysql-0.mysql.mysql.svc.cluster.local diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/templates/statefulSet.yml b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/statefulSet.yml new file mode 100644 index 0000000..3b4fba6 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/templates/statefulSet.yml @@ -0,0 +1,89 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ .Chart.Name }} + namespace: {{ .Values.mysql.namespace}} +spec: + selector: + matchLabels: + app: {{ .Chart.Name }} + replicas: {{ .Values.mysql.replicas }} + serviceName: {{ .Chart.Name }} + template: + metadata: + labels: + app: {{ .Chart.Name }} + spec: + containers: + - name: {{ .Chart.Name }} + image: {{ .Values.mysql.image.repository }}:{{ .Values.mysql.image.tag }} + env: + {{- range $k, $v := .Values.mysql.secret }} + - name: {{ $k }} + valueFrom: + secretKeyRef: + name: mysql-secrets + key: {{ $k }} + {{- end }} + - name: MYSQL_DATABASE + value: app_db + ports: + - name: {{ .Chart.Name }} + containerPort: 3306 + volumeMounts: + - name: data + mountPath: /var/lib/mysql + subPath: {{ .Chart.Name }} + - name: config-map + mountPath: /docker-entrypoint-initdb.d + resources: + requests: + cpu: {{ .Values.mysql.resources.requests.cpu }} + memory: {{ .Values.mysql.resources.requests.memory }} + livenessProbe: + exec: + command: ["mysqladmin", "ping"] + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + readinessProbe: + exec: + command: ["mysqladmin", "ping"] + initialDelaySeconds: 5 + periodSeconds: 2 + timeoutSeconds: 1 + volumes: + - name: config-map + configMap: + name: {{ .Chart.Name }} + tolerations: + - key: {{ .Values.mysql.tolerations.key }} + operator: {{ .Values.mysql.tolerations.operator }} + value: {{ .Values.mysql.tolerations.value }} + effect: {{ .Values.mysql.tolerations.effect }} + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: {{ .Values.mysql.affinities.podAntiAffinity.key}} + operator: {{ .Values.mysql.affinities.podAntiAffinity.operator}} + values: + - {{ .Values.mysql.affinities.podAntiAffinity.values}} + topologyKey: "kubernetes.io/hostname" + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .Values.mysql.affinities.nodeAffinity.key }} + operator: {{ .Values.mysql.affinities.nodeAffinity.operator }} + values: + - {{ .Values.mysql.affinities.nodeAffinity.values }} + volumeClaimTemplates: + - metadata: + name: data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: {{ .Values.mysql.pvcStorageRequest }} diff --git a/.infrastructure/helm-chart/todoapp/charts/mysql/values.yaml b/.infrastructure/helm-chart/todoapp/charts/mysql/values.yaml new file mode 100644 index 0000000..ef9cfa5 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/charts/mysql/values.yaml @@ -0,0 +1,36 @@ +mysql: + namespace: mysql + + secret: + MYSQL_ROOT_PASSWORD: "MTIzNA==" # Base64 encoding for "1234" + MYSQL_USER: "YXBwX3VzZXI=" # Base64 encoding for "app_user" + MYSQL_PASSWORD: "MTIzNA==" # Base64 encoding for "1234" + + replicas: 2 + + image: + repository: mysql + tag: 8.0 + + resources: + requests: + cpu: 500m + memory: 1Gi + + pvcStorageRequest: 2Gi + + tolerations: + key: "app" + operator: "Equal" + value: "mysql" + effect: "NoSchedule" + + affinities: + podAntiAffinity: + key: "app" + operator: In + values: "mysql" + nodeAffinity: + key: "app" + operator: In + values: "mysql" diff --git a/.infrastructure/helm-chart/todoapp/templates/clusterIp.yml b/.infrastructure/helm-chart/todoapp/templates/clusterIp.yml new file mode 100644 index 0000000..f900b2b --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/clusterIp.yml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }}-service + namespace: {{ .Values.todoapp.namespace }} +spec: + type: ClusterIP + selector: + app: todoapp + ports: + - protocol: TCP + port: 80 + targetPort: 8080 diff --git a/.infrastructure/helm-chart/todoapp/templates/configMap.yml b/.infrastructure/helm-chart/todoapp/templates/configMap.yml new file mode 100644 index 0000000..8bf9081 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/configMap.yml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Chart.Name }}-config + namespace: {{ .Values.todoapp.namespace }} +data: + PYTHONUNBUFFERED: "1" diff --git a/.infrastructure/helm-chart/todoapp/templates/deployment.yml b/.infrastructure/helm-chart/todoapp/templates/deployment.yml new file mode 100644 index 0000000..5d39605 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/deployment.yml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Chart.Name }} + namespace: {{ .Values.todoapp.namespace }} +spec: + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: {{ .Values.todoapp.rollingUpdate.maxSurge }} + maxUnavailable: {{ .Values.todoapp.rollingUpdate.maxUnavailable }} + selector: + matchLabels: + app: {{ .Chart.Name }} + template: + metadata: + labels: + app: {{ .Chart.Name }} + spec: + serviceAccountName: {{ .Values.todoapp.RBAC.name }} + containers: + - name: {{ .Chart.Name }} + image: {{ .Values.todoapp.image.repository}}:{{ .Values.todoapp.image.tag }} + volumeMounts: + - name: data + mountPath: /app/data + - name: app-secrets-volume + mountPath: "/app/secrets" + readOnly: true + - name: app-config-volume + mountPath: "/app/configs" + readOnly: true + resources: + requests: + memory: {{ .Values.todoapp.resources.requests.memory }} + cpu: {{ .Values.todoapp.resources.requests.cpu }} + limits: + memory: {{ .Values.todoapp.resources.limits.memory }} + cpu: {{ .Values.todoapp.resources.limits.cpu }} + env: + - name: PYTHONUNBUFFERED + valueFrom: + configMapKeyRef: + name: {{ .Chart.Name }}-config + key: PYTHONUNBUFFERED + {{- range $k, $v := .Values.todoapp.secrets }} + - name: {{ $k }} + valueFrom: + secretKeyRef: + name: todoapp-secret + key: {{ $k }} + {{- end }} + ports: + - containerPort: 8080 + livenessProbe: + httpGet: + path: api/health + port: 8080 + initialDelaySeconds: 60 + periodSeconds: 5 + readinessProbe: + httpGet: + path: api/ready + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ .Chart.Name }}-pvc + - name: app-secrets-volume + secret: + secretName: {{ .Chart.Name }}-secret + - name: app-config-volume + configMap: + name: {{ .Chart.Name }}-config + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: app + operator: In + values: + - kube2py diff --git a/.infrastructure/helm-chart/todoapp/templates/hpa.yml b/.infrastructure/helm-chart/todoapp/templates/hpa.yml new file mode 100644 index 0000000..a409979 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/hpa.yml @@ -0,0 +1,25 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ .Chart.Name }}-hpa + namespace: {{ .Values.todoapp.namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: todoapp + minReplicas: {{ .Values.todoapp.hpa.minReplicas }} + maxReplicas: {{ .Values.todoapp.hpa.maxReplicas }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.todoapp.hpa.resourceAvgUtilization.cpu }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.todoapp.hpa.resourceAvgUtilization.memory }} diff --git a/.infrastructure/helm-chart/todoapp/templates/ingress.yml b/.infrastructure/helm-chart/todoapp/templates/ingress.yml new file mode 100644 index 0000000..95f2e6a --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/ingress.yml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Chart.Name }}-ingress + namespace: {{ .Values.todoapp.namespace }} + annotations: + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + rules: + - http: + paths: + - pathType: Prefix + path: /(|$)(.*) + backend: + service: + name: {{ .Chart.Name }}-service + port: + number: 80 diff --git a/.infrastructure/helm-chart/todoapp/templates/nodeport.yml b/.infrastructure/helm-chart/todoapp/templates/nodeport.yml new file mode 100644 index 0000000..f038370 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/nodeport.yml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Chart.Name }}-nodeport + namespace: {{ .Values.todoapp.namespace }} +spec: + type: NodePort + selector: + app: {{ .Chart.Name }} + ports: + - protocol: TCP + port: 80 + targetPort: 8080 + nodePort: 30007 diff --git a/.infrastructure/helm-chart/todoapp/templates/ns.yml b/.infrastructure/helm-chart/todoapp/templates/ns.yml new file mode 100644 index 0000000..5b90b3f --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/ns.yml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Values.todoapp.namespace }} diff --git a/.infrastructure/helm-chart/todoapp/templates/pv.yml b/.infrastructure/helm-chart/todoapp/templates/pv.yml new file mode 100644 index 0000000..d6721ae --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/pv.yml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ .Chart.Name }}-pv +spec: + storageClassName: standard + persistentVolumeReclaimPolicy: Delete + accessModes: + - ReadWriteMany + capacity: + storage: {{ .Values.todoapp.pvcStorageRequest }} + hostPath: + path: /data/ diff --git a/.infrastructure/helm-chart/todoapp/templates/pvc.yml b/.infrastructure/helm-chart/todoapp/templates/pvc.yml new file mode 100644 index 0000000..29bbcdf --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/pvc.yml @@ -0,0 +1,13 @@ + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .Chart.Name }}-pvc + namespace: {{ .Values.todoapp.namespace }} +spec: + volumeName: {{ .Chart.Name }}-pv + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.todoapp.pvcStorageRequest}} diff --git a/.infrastructure/helm-chart/todoapp/templates/rbac.yml b/.infrastructure/helm-chart/todoapp/templates/rbac.yml new file mode 100644 index 0000000..e85985a --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/rbac.yml @@ -0,0 +1,30 @@ +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ .Values.todoapp.RBAC.name }} + namespace: {{ .Values.todoapp.namespace }} + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: {{ .Values.todoapp.namespace }} + name: {{ .Values.todoapp.RBAC.name }} +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Values.todoapp.RBAC.name }} + namespace: {{ .Values.todoapp.namespace }} +subjects: +- kind: ServiceAccount + name: {{ .Values.todoapp.RBAC.name }} +roleRef: + kind: Role + name: {{ .Values.todoapp.RBAC.name }} + apiGroup: rbac.authorization.k8s.io diff --git a/.infrastructure/helm-chart/todoapp/templates/secret.yml b/.infrastructure/helm-chart/todoapp/templates/secret.yml new file mode 100644 index 0000000..156dc95 --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/templates/secret.yml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Chart.Name }}-secret + namespace: {{ .Values.todoapp.namespace }} +type: Opaque +data: + {{- range $k, $v := .Values.todoapp.secrets}} + {{ $k }}: {{ $v }} + {{- end }} diff --git a/.infrastructure/helm-chart/todoapp/values.yaml b/.infrastructure/helm-chart/todoapp/values.yaml new file mode 100644 index 0000000..cffe74e --- /dev/null +++ b/.infrastructure/helm-chart/todoapp/values.yaml @@ -0,0 +1,45 @@ +todoapp: + namespace: todoapp + + secrets: + SECRET_KEY: QGUyKHl4KXYmdGdoM19zPTB5amEtaSFkcGVieHN6XmRnNDd4KS1rJmtxXzN6Zio5ZSoK + DB_NAME: "YXBwX2RiCg==" + DB_USER: "YXBwX3VzZXI=" + DB_PASSWORD: "MTIzNA==" + DB_HOST: "bXlzcWwtMC5teXNxbC5teXNxbC5zdmMuY2x1c3Rlci5sb2NhbAo=" + + resources: + requests: + cpu: "150m" + memory: "256Mi" + limits: + cpu: "150m" + memory: "256Mi" + + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + + image: + repository: ikulyk404/todoapp + tag: 4.0.1 + + nodeAffinity: + weight: 1 + key: app + operator: In + values: kube2py + + hpa: + minReplicas: 2 + maxReplicas: 5 + resourceAvgUtilization: + cpu: 70 + memory: 70 + + pvStorageCap: 1Gi + + pvcStorageRequest: 1Gi + + RBAC: + name: secrets-reader diff --git a/INSTRUCTION.md b/INSTRUCTION.md new file mode 100644 index 0000000..f19bc13 --- /dev/null +++ b/INSTRUCTION.md @@ -0,0 +1,26 @@ +# TodoApp deployment through Helm + +## 1. Create a kind cluster: +```bash +kind create cluster --config cluster.yml +``` + +## 2. Apply taints to MySQL nodes: +```bash +kubectl taint nodes -l app=mysql app=mysql:NoSchedule +``` + +## 3. Deploy the app: +```bash +./bootstrap.sh +``` +Or +```bash +helm install todoapp .infrastructure/helm-chart/todoapp +``` + +## 4. Wait 2-3 minutes for pods and services to start, then validate the app: +```bash +kubectl get all,cm,secret,ing -A +``` +All pods and services should be ready and running. The app should available in your browser at http://localhost:30007/ diff --git a/bootstrap.sh b/bootstrap.sh index 2d534d7..3e68159 100644 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,20 +1,2 @@ #!/bin/bash -kubectl apply -f .infrastructure/mysql/ns.yml -kubectl apply -f .infrastructure/mysql/configMap.yml -kubectl apply -f .infrastructure/mysql/secret.yml -kubectl apply -f .infrastructure/mysql/service.yml -kubectl apply -f .infrastructure/mysql/statefulSet.yml - -kubectl apply -f .infrastructure/app/ns.yml -kubectl apply -f .infrastructure/app/pv.yml -kubectl apply -f .infrastructure/app/pvc.yml -kubectl apply -f .infrastructure/app/secret.yml -kubectl apply -f .infrastructure/app/configMap.yml -kubectl apply -f .infrastructure/app/clusterIp.yml -kubectl apply -f .infrastructure/app/nodeport.yml -kubectl apply -f .infrastructure/app/hpa.yml -kubectl apply -f .infrastructure/app/deployment.yml - -# Install Ingress Controller -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml -# kubectl apply -f .infrastructure/ingress/ingress.yml +helm install todoapp .infrastructure/helm-chart/todoapp diff --git a/output.log b/output.log new file mode 100644 index 0000000..a25501f --- /dev/null +++ b/output.log @@ -0,0 +1,81 @@ +NAMESPACE NAME READY STATUS RESTARTS AGE +kube-system pod/coredns-7c65d6cfc9-f7dst 1/1 Running 0 2m22s +kube-system pod/coredns-7c65d6cfc9-pnznf 1/1 Running 0 2m22s +kube-system pod/etcd-kind-control-plane 1/1 Running 0 2m29s +kube-system pod/kindnet-2msh2 1/1 Running 0 2m19s +kube-system pod/kindnet-7ldc7 1/1 Running 0 2m19s +kube-system pod/kindnet-8vfgs 1/1 Running 0 2m19s +kube-system pod/kindnet-gb7j6 1/1 Running 0 2m19s +kube-system pod/kindnet-gfk4j 1/1 Running 0 2m19s +kube-system pod/kindnet-jtmsr 1/1 Running 0 2m19s +kube-system pod/kindnet-nflkx 1/1 Running 0 2m23s +kube-system pod/kube-apiserver-kind-control-plane 1/1 Running 0 2m30s +kube-system pod/kube-controller-manager-kind-control-plane 1/1 Running 0 2m29s +kube-system pod/kube-proxy-4d969 1/1 Running 0 2m19s +kube-system pod/kube-proxy-8ql62 1/1 Running 0 2m19s +kube-system pod/kube-proxy-b48tn 1/1 Running 0 2m19s +kube-system pod/kube-proxy-bhmlg 1/1 Running 0 2m23s +kube-system pod/kube-proxy-nzl7z 1/1 Running 0 2m19s +kube-system pod/kube-proxy-xjnkf 1/1 Running 0 2m19s +kube-system pod/kube-proxy-z59g7 1/1 Running 0 2m19s +kube-system pod/kube-scheduler-kind-control-plane 1/1 Running 0 2m29s +local-path-storage pod/local-path-provisioner-57c5987fd4-qtslx 1/1 Running 0 2m22s +mysql pod/mysql-0 1/1 Running 0 2m15s +mysql pod/mysql-1 1/1 Running 0 95s +todoapp pod/todoapp-f9f76ccb5-p7bnp 1/1 Running 0 2m16s +todoapp pod/todoapp-f9f76ccb5-wlfkm 1/1 Running 0 2m1s + +NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +default service/kubernetes ClusterIP 10.96.0.1 443/TCP 2m30s +kube-system service/kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 2m29s +mysql service/mysql ClusterIP None 3306/TCP 2m16s +todoapp service/todoapp-nodeport NodePort 10.96.5.150 80:30007/TCP 2m16s +todoapp service/todoapp-service ClusterIP 10.96.243.129 80/TCP 2m16s + +NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE +kube-system daemonset.apps/kindnet 7 7 7 7 7 kubernetes.io/os=linux 2m26s +kube-system daemonset.apps/kube-proxy 7 7 7 7 7 kubernetes.io/os=linux 2m29s + +NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE +kube-system deployment.apps/coredns 2/2 2 2 2m29s +local-path-storage deployment.apps/local-path-provisioner 1/1 1 1 2m26s +todoapp deployment.apps/todoapp 2/2 2 2 2m16s + +NAMESPACE NAME DESIRED CURRENT READY AGE +kube-system replicaset.apps/coredns-7c65d6cfc9 2 2 2 2m23s +local-path-storage replicaset.apps/local-path-provisioner-57c5987fd4 1 1 1 2m23s +todoapp replicaset.apps/todoapp-f9f76ccb5 2 2 2 2m16s + +NAMESPACE NAME READY AGE +mysql statefulset.apps/mysql 2/2 2m16s + +NAMESPACE NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE +todoapp horizontalpodautoscaler.autoscaling/todoapp-hpa Deployment/todoapp cpu: /70%, memory: /70% 2 5 2 2m16s + +NAMESPACE NAME DATA AGE +default configmap/kube-root-ca.crt 1 2m23s +kube-node-lease configmap/kube-root-ca.crt 1 2m23s +kube-public configmap/cluster-info 2 2m29s +kube-public configmap/kube-root-ca.crt 1 2m23s +kube-system configmap/coredns 1 2m29s +kube-system configmap/extension-apiserver-authentication 6 2m31s +kube-system configmap/kube-apiserver-legacy-service-account-token-tracking 1 2m31s +kube-system configmap/kube-proxy 2 2m29s +kube-system configmap/kube-root-ca.crt 1 2m23s +kube-system configmap/kubeadm-config 1 2m30s +kube-system configmap/kubelet-config 1 2m30s +local-path-storage configmap/kube-root-ca.crt 1 2m23s +local-path-storage configmap/local-path-config 4 2m26s +mysql configmap/kube-root-ca.crt 1 2m16s +mysql configmap/mysql 1 2m16s +todoapp configmap/kube-root-ca.crt 1 2m16s +todoapp configmap/todoapp-config 1 2m16s + +NAMESPACE NAME TYPE DATA AGE +default secret/sh.helm.release.v1.todoapp.v1 helm.sh/release.v1 1 2m16s +kube-system secret/bootstrap-token-abcdef bootstrap.kubernetes.io/token 6 2m29s +mysql secret/mysql-secrets Opaque 3 2m16s +todoapp secret/todoapp-secret Opaque 5 2m16s + +NAMESPACE NAME CLASS HOSTS ADDRESS PORTS AGE +todoapp ingress.networking.k8s.io/todoapp-ingress * 80 2m16s