├── garden.yml ├── script ├── kubernetes │ ├── database │ │ ├── database.sh │ │ ├── database-service.yaml │ │ ├── database-volume.yaml │ │ └── database-deployment.yaml │ ├── chart │ │ ├── k8sdemo │ │ │ ├── charts │ │ │ │ ├── k8sdemo-backend-0.1.0.tgz │ │ │ │ └── k8sdemo-database-0.1.0.tgz │ │ │ ├── templates │ │ │ │ ├── serviceaccount.yaml │ │ │ │ ├── tests │ │ │ │ │ └── test-connection.yaml │ │ │ │ ├── service.yaml │ │ │ │ ├── ingress.yaml │ │ │ │ ├── NOTES.txt │ │ │ │ ├── deployment.yaml │ │ │ │ └── _helpers.tpl │ │ │ ├── Chart.lock │ │ │ ├── .helmignore │ │ │ ├── Chart.yaml │ │ │ ├── values.yaml │ │ │ └── values-dev.yaml │ │ ├── k8sdemo-backend │ │ │ ├── templates │ │ │ │ ├── serviceaccount.yaml │ │ │ │ ├── persistentvolumeclaim.yaml │ │ │ │ ├── tests │ │ │ │ │ └── test-connection.yaml │ │ │ │ ├── service.yaml │ │ │ │ ├── persistentvolume.yaml │ │ │ │ ├── ingress.yaml │ │ │ │ ├── NOTES.txt │ │ │ │ ├── _helpers.tpl │ │ │ │ └── deployment.yaml │ │ │ ├── .helmignore │ │ │ ├── Chart.yaml │ │ │ └── values.yaml │ │ └── k8sdemo-database │ │ │ ├── templates │ │ │ ├── serviceaccount.yaml │ │ │ ├── persistentvolumeclaim.yaml │ │ │ ├── tests │ │ │ │ └── test-connection.yaml │ │ │ ├── service.yaml │ │ │ ├── persistentvolume.yaml │ │ │ ├── ingress.yaml │ │ │ ├── NOTES.txt │ │ │ ├── _helpers.tpl │ │ │ └── deployment.yaml │ │ │ ├── .helmignore │ │ │ ├── Chart.yaml │ │ │ └── values.yaml │ ├── windowsEnv.bat │ ├── k8sdemo-secret.yaml │ ├── k8sdemo.sh │ ├── backend │ │ ├── backend-service.yaml │ │ ├── docker │ │ │ ├── docker-backend.sh │ │ │ ├── Dockerfile-k8sdemo-test │ │ │ ├── Dockerfile-k8sdemo-backend-full │ │ │ └── Dockerfile-k8sdemo-backend │ │ ├── backend.sh │ │ ├── backend-volume.yaml │ │ ├── backend-deployment.yaml │ │ └── backend-deployment1.yaml │ ├── k8sdemo-config.yaml │ └── jenkins │ │ ├── jenkins.sh │ │ ├── jenkins-service.yaml │ │ ├── docker │ │ ├── jenkins-docker.sh │ │ ├── Dockerfile-modified-jenkins │ │ └── Dockerfile-jenkins-docker │ │ ├── jenkins-volume.yaml │ │ ├── jenkins-deployment.yaml │ │ └── service-account.yaml ├── cd │ ├── jenkinsfile-test │ ├── jenkins-slave-test │ ├── jenkinsfile-declarative │ └── jenkins-k8sdemo └── database │ └── user.sql ├── model └── user.go ├── .idea ├── vcs.xml ├── misc.xml ├── modules.xml ├── k8sdemo.iml └── workspace.xml ├── go.mod ├── usecase ├── userCase.go └── registration │ └── registraton.go ├── README.md ├── skaffold.yaml ├── dataservice ├── dataservice.go └── userdata │ └── userDataService.go ├── Tiltfile ├── tool └── logger.go ├── README.zh.md ├── Dockerfile-k8sdemo-backend ├── LICENSE.txt ├── go.sum ├── config ├── appConfig.go └── logrus.go ├── cmd └── main.go └── logs └── demo.log /garden.yml: -------------------------------------------------------------------------------- 1 | kind: Project 2 | name: k8sdemo-project 3 | environments: 4 | - name: local 5 | providers: 6 | - name: local-kubernetes -------------------------------------------------------------------------------- /script/kubernetes/database/database.sh: -------------------------------------------------------------------------------- 1 | kubectl apply -f database-volume.yaml 2 | kubectl apply -f database-deployment.yaml 3 | kubectl apply -f database-service.yaml -------------------------------------------------------------------------------- /model/user.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type User struct { 4 | Id int 5 | Name string 6 | Department string 7 | Created string 8 | 9 | } 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/charts/k8sdemo-backend-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfeng45/k8sdemo/HEAD/script/kubernetes/chart/k8sdemo/charts/k8sdemo-backend-0.1.0.tgz -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/charts/k8sdemo-database-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jfeng45/k8sdemo/HEAD/script/kubernetes/chart/k8sdemo/charts/k8sdemo-database-0.1.0.tgz -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jfeng45/k8sdemo 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/go-sql-driver/mysql v1.4.1 7 | github.com/pkg/errors v0.8.1 8 | github.com/sirupsen/logrus v1.4.2 9 | ) 10 | -------------------------------------------------------------------------------- /script/cd/jenkinsfile-test: -------------------------------------------------------------------------------- 1 | def label = "master" 2 | podTemplate(label: label, cloud: 'kubernetes') { 3 | node(label) { 4 | stage('Run shell') { 5 | sh 'echo hello world.' 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /script/kubernetes/windowsEnv.bat: -------------------------------------------------------------------------------- 1 | setx MYSQL_ROOT_PASSWORD root 2 | setx MYSQL_USER_NAME dbuser 3 | setx MYSQL_USER_PASSWORD dbuser 4 | setx MYSQL_DATABASE service_config 5 | setx MYSQL_HOST 192.168.50.4 6 | setx MYSQL_PORT 30306 -------------------------------------------------------------------------------- /usecase/userCase.go: -------------------------------------------------------------------------------- 1 | package usecase 2 | 3 | import ( 4 | "github.com/jfeng45/k8sdemo/model" 5 | ) 6 | 7 | type RegistrationUseCaseInterface interface { 8 | Register(user *model.User) (bool, error) 9 | ListUser () ([]model.User, error) 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "k8sdemo.serviceAccountName" . }} 6 | labels: 7 | {{ include "k8sdemo.labels" . | nindent 4 }} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "k8sdemo-backend.serviceAccountName" . }} 6 | labels: 7 | {{ include "k8sdemo-backend.labels" . | nindent 4 }} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "k8sdemo-database.serviceAccountName" . }} 6 | labels: 7 | {{ include "k8sdemo-database.labels" . | nindent 4 }} 8 | {{- end -}} 9 | -------------------------------------------------------------------------------- /script/kubernetes/k8sdemo-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: k8sdemo-secret 5 | labels: 6 | app: k8sdemo 7 | data: 8 | MYSQL_ROOT_PASSWORD: cm9vdA== # database password for "root" 9 | MYSQL_USER_NAME: ZGJ1c2Vy # database user name for "dbuser" 10 | MYSQL_USER_PASSWORD: ZGJ1c2Vy # database password for "dbuser" -------------------------------------------------------------------------------- /script/kubernetes/k8sdemo.sh: -------------------------------------------------------------------------------- 1 | # sudo minikube start 2 | kubectl apply -f k8sdemo-config.yaml 3 | kubectl apply -f k8sdemo-secret.yaml 4 | 5 | # cd /home/vagrant/jfeng45/k8sdemo/script/kubernetes 6 | # kubectl get service 7 | # kubectl get deployment 8 | # kubectl describe configMap 9 | # kubectl describe secret 10 | # kubectl get pv 11 | # kubectl get pvc -------------------------------------------------------------------------------- /script/kubernetes/backend/backend-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: k8sdemo-backend-service 5 | labels: 6 | app: k8sdemo-backend 7 | spec: 8 | type: NodePort 9 | selector: 10 | app: k8sdemo-backend 11 | ports: 12 | - protocol : TCP 13 | nodePort: 32080 14 | port: 80 15 | targetPort: 8080 -------------------------------------------------------------------------------- /script/kubernetes/backend/docker/docker-backend.sh: -------------------------------------------------------------------------------- 1 | cd /home/vagrant/jfeng45/k8sdemo/ 2 | # docker build -f ./script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend -t k8sdemo-backend . 3 | # docker run -it --name k8sdemo-backend k8sdemo-backend /bin/sh 4 | docker build -f ./script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend-full -t k8sdemo-backend-full . -------------------------------------------------------------------------------- /script/kubernetes/database/database-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: k8sdemo-database-service 5 | labels: 6 | app: k8sdemo-database 7 | spec: 8 | type: NodePort 9 | selector: 10 | app: k8sdemo-database 11 | ports: 12 | - protocol : TCP 13 | nodePort: 30306 14 | port: 3306 15 | targetPort: 3306 -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: k8sdemo-backend 3 | repository: file://../k8sdemo-backend 4 | version: 0.1.0 5 | - name: k8sdemo-database 6 | repository: file://../k8sdemo-database 7 | version: 0.1.0 8 | digest: sha256:56623cf56ce2c7847ffbba4b91d1d9e2094c3d63ef1aef5179318b0400761335 9 | generated: "2019-11-25T05:56:07.224798283Z" 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes demo application for Go 2 | 3 | Other language: 4 | ### **[中文](README.zh.md)** 5 | 6 | This is an application to show how to deploy a Go application with Kubernetes. 7 | 8 | ## Getting Started 9 | 10 | #### Download Code 11 | 12 | ``` 13 | go get github.com/jfeng45/k8sdemo 14 | ``` 15 | 16 | ## License 17 | 18 | [MIT](LICENSE.txt) License 19 | 20 | 21 | -------------------------------------------------------------------------------- /script/kubernetes/k8sdemo-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: k8sdemo-config # name of ConfigMap, referenced in other files 5 | labels: 6 | app: k8sdemo 7 | data: 8 | MYSQL_HOST: k8sdemo-database-service # host address of mysql server, we are using DNS of Service 9 | MYSQL_PORT: "3306" 10 | MYSQL_DATABASE: service_config # name of the database -------------------------------------------------------------------------------- /script/kubernetes/jenkins/jenkins.sh: -------------------------------------------------------------------------------- 1 | cd /home/vagrant/jfeng45/k8sdemo/script/kubernetes/jenkins 2 | kubectl apply -f service-account.yaml 3 | kubectl create clusterrolebinding service-reader-pod --clusterrole=service-reader --serviceaccount=default:default 4 | kubectl apply -f jenkins-volume.yaml 5 | kubectl apply -f jenkins-deployment.yaml 6 | kubectl apply -f jenkins-service.yaml 7 | 8 | # kubectl delete clusterrolebinding service-reader-pod -------------------------------------------------------------------------------- /skaffold.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skaffold/v1 2 | kind: Config 3 | metadata: 4 | name: k-sdemo 5 | build: 6 | artifacts: 7 | - image: k8sdemo-backend 8 | context: . 9 | docker: 10 | dockerfile: script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend 11 | deploy: 12 | kubectl: 13 | manifests: 14 | - script/kubernetes/backend/backend-deployment.yaml 15 | - script/kubernetes/backend/backend-service.yaml 16 | 17 | -------------------------------------------------------------------------------- /dataservice/dataservice.go: -------------------------------------------------------------------------------- 1 | package dataservice 2 | 3 | import ( 4 | "github.com/jfeng45/k8sdemo/model" 5 | ) 6 | 7 | type UserDataInterface interface { 8 | Remove(err error, id int64, affect int64) 9 | Find(id int) error 10 | FindByName(name string) (bool, error) 11 | FindAll() ([]model.User, error) 12 | Update(user *model.User) (error, int64) 13 | Insert(user *model.User) int64 14 | Close() error 15 | } 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | .vscode/ 23 | -------------------------------------------------------------------------------- /script/kubernetes/jenkins/jenkins-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: k8sdemo-jenkins-service 5 | labels: 6 | app: k8sdemo-jenkins 7 | spec: 8 | type: NodePort 9 | selector: 10 | app: k8sdemo-jenkins 11 | ports: 12 | - port: 8080 13 | name: http 14 | protocol : TCP 15 | nodePort: 30080 16 | targetPort: 8080 17 | - port: 50000 18 | name: agent 19 | protocol: TCP 20 | targetPort: 50000 21 | 22 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/persistentvolumeclaim.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: {{ .Values.persistentvolumeclaim.name }} 5 | labels: 6 | {{- include "k8sdemo-backend.labels" . | nindent 4 }} 7 | spec: 8 | accessModes: {{ .Values.persistentvolumeclaim.accessModes}} 9 | # - ReadWriteOnce 10 | # storageClassName: local-storage 11 | resources: 12 | requests: 13 | storage: {{ .Values.persistentvolumeclaim.storage }} #1 GB -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/persistentvolumeclaim.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: {{ .Values.persistentvolumeclaim.name }} 5 | labels: 6 | {{- include "k8sdemo-database.labels" . | nindent 4 }} 7 | spec: 8 | accessModes: {{ .Values.persistentvolumeclaim.accessModes}} 9 | # - ReadWriteOnce 10 | # storageClassName: local-storage 11 | resources: 12 | requests: 13 | storage: {{ .Values.persistentvolumeclaim.storage }} #1 GB -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "k8sdemo.fullname" . }}-test-connection" 5 | labels: 6 | {{ include "k8sdemo.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test-success 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "k8sdemo.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "k8sdemo.fullname" . }} 5 | labels: 6 | {{- include "k8sdemo.labels" . | nindent 4 }} 7 | spec: 8 | type: {{.Values.service.type}} 9 | ports: 10 | - port: {{.Values.service.port}} 11 | nodePort: {{.Values.service.nodePort}} 12 | targetPort: http 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "k8sdemo.selectorLabels" . | nindent 4 }} 17 | -------------------------------------------------------------------------------- /.idea/k8sdemo.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "k8sdemo-backend.fullname" . }}-test-connection" 5 | labels: 6 | {{ include "k8sdemo-backend.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test-success 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "k8sdemo-backend.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "k8sdemo-database.fullname" . }}-test-connection" 5 | labels: 6 | {{ include "k8sdemo-database.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test-success 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "k8sdemo-database.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /script/kubernetes/backend/backend.sh: -------------------------------------------------------------------------------- 1 | cd /home/vagrant/jfeng45/k8sdemo/script/kubernetes/backend 2 | kubectl apply -f backend-volume.yaml 3 | kubectl apply -f backend-deployment.yaml 4 | kubectl apply -f backend-service.yaml 5 | 6 | # kubectl get pv 7 | # kubectl get pvc 8 | # kubectl get service 9 | # kubectl get deployment 10 | # kubectl describe configMap 11 | # kubectl describe secret 12 | # kubectl exec -ti k8sdemo-backend-deployment-6b99dc6b8c-tbl4v -- /bin/sh 13 | # kubectl exec -ti k8sdemo-backend-deployment-df5b977b5-skkc6 -- /bin/bash 14 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{.Values.global.k8sdemoBackendService}} 5 | labels: 6 | {{- include "k8sdemo-backend.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | nodePort: {{.Values.service.nodePort}} 12 | targetPort: http 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "k8sdemo-backend.selectorLabels" . | nindent 4 }} 17 | -------------------------------------------------------------------------------- /script/kubernetes/backend/docker/Dockerfile-k8sdemo-test: -------------------------------------------------------------------------------- 1 | ######## Start a new stage from scratch ####### 2 | FROM alpine:latest 3 | 4 | # RUN apk --no-cache add ca-certificates 5 | 6 | WORKDIR /root/ 7 | 8 | # RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 9 | 10 | # Copy the Pre-built binary file from the previous stage 11 | COPY . . 12 | 13 | # Command to run the executable 14 | # CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait" 15 | CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait" -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Values.global.k8sdemoDatabaseService}} 5 | labels: 6 | {{- include "k8sdemo-database.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: {{ .Values.service.targetPort }} 12 | protocol: TCP 13 | nodePort: {{.Values.service.nodePort}} 14 | selector: 15 | {{- include "k8sdemo-database.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /Tiltfile: -------------------------------------------------------------------------------- 1 | # Deploy: tell Tilt what YAML to deploy 2 | k8s_yaml(['script/kubernetes/backend/backend-deployment.yaml','script/kubernetes/backend/backend-service.yaml']) 3 | 4 | # Build: tell Tilt what images to build from which directories 5 | docker_build("k8sdemo-backend:2.0", "./", dockerfile="script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend") 6 | #docker_build('companyname/frontend', 'frontend') 7 | #docker_build('companyname/backend', 'backend') 8 | # ... 9 | 10 | # Watch: tell Tilt how to connect locally (optional) 11 | #k8s_resource('frontend', port_forwards=8080) -------------------------------------------------------------------------------- /script/kubernetes/jenkins/docker/jenkins-docker.sh: -------------------------------------------------------------------------------- 1 | cd /home/vagrant/jfeng45/k8sdemo/ 2 | # docker build -f ./script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend -t k8sdemo-backend . 3 | # docker run -it --name jenkins-docker jenkins-docker /bin/bash 4 | # docker run -it --name jenkins-test jenkinsci/jenkins:2.154-slim /bin/bash 5 | docker run --name jenkins-docker -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock jenkins-docker 6 | docker build -f ./script/kubernetes/jenkins/docker/Dockerfile-jenkins-docker -t jenkins-docker . 7 | 8 | # docker build -f ./script/kubernetes/jenkins/docker/Dockerfile-modified-jenkins -t jfeng45/modified-jenkins:1.0 . -------------------------------------------------------------------------------- /script/kubernetes/jenkins/docker/Dockerfile-modified-jenkins: -------------------------------------------------------------------------------- 1 | FROM jenkins/jenkins:lts 2 | 3 | USER root 4 | 5 | ENV DOCKERVERSION=19.03.4 6 | 7 | RUN curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKERVERSION}.tgz \ 8 | && tar xzvf docker-${DOCKERVERSION}.tgz --strip 1 \ 9 | -C /usr/local/bin docker/docker \ 10 | && rm docker-${DOCKERVERSION}.tgz 11 | 12 | RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl \ 13 | && chmod +x ./kubectl \ 14 | && mv ./kubectl /usr/local/bin/kubectl -------------------------------------------------------------------------------- /script/kubernetes/jenkins/docker/Dockerfile-jenkins-docker: -------------------------------------------------------------------------------- 1 | FROM jenkinsci/jenkins:2.154-slim 2 | USER root 3 | RUN apt-get update && \ 4 | apt-get -y install apt-transport-https \ 5 | ca-certificates \ 6 | curl \ 7 | gnupg2 \ 8 | software-properties-common && \ 9 | curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \ 10 | add-apt-repository \ 11 | "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \ 12 | $(lsb_release -cs) \ 13 | stable" && \ 14 | apt-get update && \ 15 | apt-get -y install docker-ce 16 | RUN apt-get install -y docker-ce 17 | RUN usermod -a -G docker jenkins 18 | USER jenkins -------------------------------------------------------------------------------- /script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend-full: -------------------------------------------------------------------------------- 1 | # vagrant@ubuntu-xenial:~/app/k8sdemo$ 2 | # cd dockerimages/kubernetes/k8sdemo/ 3 | # docker build -f ./script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend-full -t k8sdemo-backend-full . 4 | # docker run -td --name k8sdemo-backend-full k8sdemo-backend-full 5 | # docker exec -it a95c /bin/bash 6 | 7 | FROM golang:latest 8 | 9 | # Set the Current Working Directory inside the container 10 | WORKDIR /app 11 | 12 | COPY go.mod go.sum ./ 13 | 14 | RUN go mod download 15 | 16 | COPY . . 17 | 18 | WORKDIR /app/cmd 19 | 20 | # Build the Go app 21 | RUN GOOS=linux go build -o main.exe 22 | 23 | CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait" 24 | 25 | -------------------------------------------------------------------------------- /script/database/user.sql: -------------------------------------------------------------------------------- 1 | /* 2 | SQLyog Ultimate 3 | MySQL - 5.0.96-community-log : Database - fasp 4 | ********************************************************************* 5 | */ 6 | 7 | CREATE DATABASE `service_config` ; 8 | 9 | /*Table structure for table `userinfo` */ 10 | 11 | DROP TABLE IF EXISTS `userinfo`; 12 | 13 | CREATE TABLE `userinfo` ( 14 | `uid` int(10) NOT NULL auto_increment, 15 | `username` varchar(64) default NULL, 16 | `department` varchar(64) default NULL, 17 | `created` date default NULL, 18 | PRIMARY KEY (`uid`) 19 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 20 | 21 | CREATE TABLE `course` ( 22 | `id` INT(10) NOT NULL AUTO_INCREMENT, 23 | `name` VARCHAR(64) DEFAULT NULL, 24 | PRIMARY KEY (`id`) 25 | ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 26 | 27 | -------------------------------------------------------------------------------- /tool/logger.go: -------------------------------------------------------------------------------- 1 | // Package logger represents a generic logging interface 2 | 3 | package tool 4 | 5 | // Log is a package level variable, every program should access logging function through "Log" 6 | var Log Logger 7 | 8 | // Logger represent common interface for logging function 9 | type Logger interface { 10 | Errorf(format string, args ...interface{}) 11 | Fatalf(format string, args ...interface{}) 12 | Fatal(args ...interface{}) 13 | Infof(format string, args ...interface{}) 14 | Info(args ...interface{}) 15 | Warnf(format string, args ...interface{}) 16 | Debugf(format string, args ...interface{}) 17 | Debug(args ...interface{}) 18 | } 19 | 20 | // SetLogger is the setter for log variable, it should be the only way to assign value to log 21 | func SetLogger(newLogger Logger) { 22 | Log = newLogger 23 | } 24 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/persistentvolume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: {{ .Values.persistentvolume.name }} 5 | labels: 6 | {{- include "k8sdemo-database.labels" . | nindent 4 }} 7 | spec: 8 | capacity: 9 | storage: {{ .Values.persistentvolume.storage }} 10 | # volumeMode field requires BlockVolume Alpha feature gate to be enabled. 11 | volumeMode: Filesystem 12 | accessModes: {{ .Values.persistentvolume.accessModes }} 13 | storageClassName: standard 14 | local: 15 | path: /home/vagrant/database/k8sdemo/database 16 | nodeAffinity: 17 | required: 18 | nodeSelectorTerms: 19 | - matchExpressions: 20 | - key: kubernetes.io/hostname 21 | operator: In 22 | values: 23 | - minikube 24 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/persistentvolume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: {{ .Values.persistentvolume.name }} 5 | labels: 6 | {{- include "k8sdemo-backend.labels" . | nindent 4 }} 7 | spec: 8 | capacity: 9 | storage: {{ .Values.persistentvolume.storage }} 10 | # volumeMode field requires BlockVolume Alpha feature gate to be enabled. 11 | volumeMode: Filesystem 12 | accessModes: {{ .Values.persistentvolume.accessModes }} 13 | storageClassName: standard 14 | local: 15 | path: /home/vagrant/app/k8sdemo/logs #/home/vagrant/database/k8sdemo/database 16 | nodeAffinity: 17 | required: 18 | nodeSelectorTerms: 19 | - matchExpressions: 20 | - key: kubernetes.io/hostname 21 | operator: In 22 | values: 23 | - minikube 24 | -------------------------------------------------------------------------------- /script/cd/jenkins-slave-test: -------------------------------------------------------------------------------- 1 | def POD_LABEL = "testpod-${UUID.randomUUID().toString()}" 2 | podTemplate(label: POD_LABEL, cloud: 'kubernetes', containers: [ 3 | containerTemplate(name: 'build', image: 'jfeng45/k8sdemo-backend:1.0', ttyEnabled: true, command: 'cat'), 4 | containerTemplate(name: 'run', image: 'jfeng45/k8sdemo-backend:1.0', ttyEnabled: true, command: 'cat') 5 | ]) { 6 | 7 | node(POD_LABEL) { 8 | stage('build a go project') { 9 | container('build') { 10 | stage('Build a go project') { 11 | sh 'echo hello' 12 | } 13 | } 14 | } 15 | 16 | stage('Run a Golang project') { 17 | container('run') { 18 | stage('Run a Go project') { 19 | sh '/root/main.exe' 20 | } 21 | } 22 | } 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /README.zh.md: -------------------------------------------------------------------------------- 1 | ## K8s的Go演示程序 2 | 3 | 其他语言: 4 | 5 | ### **[English](README.md)** 6 | 7 | 这是一个K8s的Go演示程序。 8 | 9 | 请阅读下列文章以获取详细内容: 10 | 11 | + [从代码的视角深入浅出理解DevOps](https://blog.csdn.net/weixin_38748858/article/details/103068797) 12 | + [云原生开发环境初探](https://blog.csdn.net/weixin_38748858/article/details/103515050) 13 | + [用Helm3构建多层微服务](https://blog.csdn.net/weixin_38748858/article/details/103311973) 14 | + [把应用程序迁移到k8s需要修改什么?](https://blog.csdn.net/weixin_38748858/article/details/102758381) 15 | + [在容器上构建持续部署及最佳实践初探](https://blog.csdn.net/weixin_38748858/article/details/102967540) 16 | + [在k8s上安装Jenkins及常见问题](https://blog.csdn.net/weixin_38748858/article/details/102898043) 17 | + [创建优化的Go镜像文件以及踩过的坑](https://blog.csdn.net/weixin_38748858/article/details/102714799) 18 | 19 | ## 运行 20 | 21 | #### 下载程序 22 | 23 | ``` 24 | go get github.com/jfeng45/k8sdemo 25 | ``` 26 | 27 | 28 | 29 | ### 授权 30 | 31 | [MIT](LICENSE.txt) 授权 32 | 33 | 34 | -------------------------------------------------------------------------------- /script/kubernetes/backend/backend-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: k8sdemo-backend-pv 5 | labels: 6 | app: k8sdemo-backend 7 | spec: 8 | capacity: 9 | storage: 1Gi 10 | volumeMode: Filesystem 11 | accessModes: 12 | - ReadWriteOnce 13 | storageClassName: standard 14 | local: 15 | path: /home/vagrant/app/k8sdemo/logs 16 | nodeAffinity: 17 | required: 18 | nodeSelectorTerms: 19 | - matchExpressions: 20 | - key: kubernetes.io/hostname 21 | operator: In 22 | values: 23 | - minikube 24 | --- 25 | apiVersion: v1 26 | kind: PersistentVolumeClaim 27 | metadata: 28 | name: k8sdemo-backend-pvclaim 29 | labels: 30 | app: k8sdemo-backend 31 | spec: 32 | accessModes: 33 | - ReadWriteOnce 34 | # storageClassName: local-storage 35 | resources: 36 | requests: 37 | storage: 1Gi #1 GB -------------------------------------------------------------------------------- /script/kubernetes/jenkins/jenkins-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: k8sdemo-jenkins-pv 5 | labels: 6 | app: k8sdemo-jenkins 7 | spec: 8 | capacity: 9 | storage: 1Gi 10 | # volumeMode field requires BlockVolume Alpha feature gate to be enabled. 11 | volumeMode: Filesystem 12 | accessModes: 13 | - ReadWriteOnce 14 | storageClassName: standard 15 | local: 16 | path: /home/vagrant/app/jenkins 17 | nodeAffinity: 18 | required: 19 | nodeSelectorTerms: 20 | - matchExpressions: 21 | - key: kubernetes.io/hostname 22 | operator: In 23 | values: 24 | - minikube 25 | --- 26 | apiVersion: v1 27 | kind: PersistentVolumeClaim 28 | metadata: 29 | name: k8sdemo-jenkins-pvclaim 30 | labels: 31 | app: k8sdemo-jenkins 32 | spec: 33 | accessModes: 34 | - ReadWriteOnce 35 | # storageClassName: local-storage 36 | resources: 37 | requests: 38 | storage: 1Gi #1 GB -------------------------------------------------------------------------------- /script/kubernetes/jenkins/jenkins-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: k8sdemo-jenkins-deployment 5 | labels: 6 | app: k8sdemo-jenkins 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: k8sdemo-jenkins 11 | strategy: 12 | type: Recreate 13 | template: 14 | metadata: 15 | labels: 16 | app: k8sdemo-jenkins 17 | spec: 18 | serviceAccountName: default # 服务账户的名字是default 19 | containers: 20 | - image: jenkinsci/jenkins:2.154-slim 21 | name: k8sdemo-jenkins-container 22 | imagePullPolicy: Never 23 | ports: 24 | - containerPort: 8080 25 | - containerPort: 50000 26 | volumeMounts: 27 | - name: k8sdemo-jenkins-persistentstorage 28 | mountPath: /var/jenkins_home 29 | volumes: 30 | - name: k8sdemo-jenkins-persistentstorage 31 | persistentVolumeClaim: 32 | claimName: k8sdemo-jenkins-pvclaim 33 | 34 | 35 | -------------------------------------------------------------------------------- /script/kubernetes/database/database-volume.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: k8sdemo-database-pv 5 | labels: 6 | app: k8sdemo-database 7 | spec: 8 | capacity: 9 | storage: 1Gi 10 | # volumeMode field requires BlockVolume Alpha feature gate to be enabled. 11 | volumeMode: Filesystem 12 | accessModes: 13 | - ReadWriteOnce 14 | storageClassName: standard 15 | local: 16 | path: /home/vagrant/database/k8sdemo/database 17 | nodeAffinity: 18 | required: 19 | nodeSelectorTerms: 20 | - matchExpressions: 21 | - key: kubernetes.io/hostname 22 | operator: In 23 | values: 24 | - minikube 25 | --- 26 | apiVersion: v1 27 | kind: PersistentVolumeClaim 28 | metadata: 29 | name: k8sdemo-database-pvclaim 30 | labels: 31 | app: k8sdemo-database 32 | spec: 33 | accessModes: 34 | - ReadWriteOnce 35 | # storageClassName: local-storage 36 | resources: 37 | requests: 38 | storage: 1Gi #1 GB -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: k8sdemo-backend 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | version: 0.1.0 18 | 19 | # This is the version number of the application being deployed. This version number should be 20 | # incremented each time you make changes to the application. 21 | appVersion: 1.16.0 22 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: k8sdemo-database 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | version: 0.1.0 18 | 19 | # This is the version number of the application being deployed. This version number should be 20 | # incremented each time you make changes to the application. 21 | appVersion: 1.16.0 22 | -------------------------------------------------------------------------------- /usecase/registration/registraton.go: -------------------------------------------------------------------------------- 1 | package registration 2 | 3 | import ( 4 | "github.com/jfeng45/k8sdemo/dataservice" 5 | "github.com/jfeng45/k8sdemo/model" 6 | "github.com/pkg/errors" 7 | ) 8 | 9 | type UseCase struct { 10 | UserDataInterface dataservice.UserDataInterface 11 | } 12 | 13 | func (uuc *UseCase)Register(user *model.User) (bool, error) { 14 | isD, err := uuc.isDuplicate(user.Name) 15 | if err != nil { 16 | return false, err 17 | } 18 | if isD { 19 | return false, errors.New("duplicate user for "+ user.Name) 20 | } 21 | uuc.UserDataInterface.Insert(user) 22 | //if rowCount != 1 { 23 | // return false, errors.New("Register failed and the number f rows affected are "+ string(rowCount)) 24 | //} 25 | return true, nil 26 | } 27 | 28 | func (uuc *UseCase) ListUser () ([]model.User, error){ 29 | return uuc.UserDataInterface.FindAll() 30 | //return []model.User{}, nil 31 | } 32 | func (uuc *UseCase) isDuplicate(name string) (bool, error) { 33 | return uuc.UserDataInterface.FindByName(name) 34 | //return false 35 | } 36 | 37 | -------------------------------------------------------------------------------- /script/kubernetes/backend/docker/Dockerfile-k8sdemo-backend: -------------------------------------------------------------------------------- 1 | # vagrant@ubuntu-xenial:~/app/k8sdemo/script/kubernetes/backend$ 2 | # docker build -t k8sdemo-backend . 3 | 4 | FROM golang:latest as builder 5 | 6 | # Set the Current Working Directory inside the container 7 | WORKDIR /app 8 | 9 | COPY go.mod go.sum ./ 10 | 11 | RUN go mod download 12 | 13 | COPY . . 14 | 15 | WORKDIR /app/cmd 16 | 17 | # Build the Go app 18 | #RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main.exe 19 | 20 | RUN go build -o main.exe 21 | 22 | ######## Start a new stage from scratch ####### 23 | FROM alpine:latest 24 | 25 | RUN apk --no-cache add ca-certificates 26 | 27 | WORKDIR /root/ 28 | 29 | RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 30 | 31 | # Copy the Pre-built binary file from the previous stage 32 | COPY --from=builder /app/cmd/main.exe . 33 | 34 | # Command to run the executable 35 | # CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait" 36 | CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait" -------------------------------------------------------------------------------- /script/kubernetes/jenkins/service-account.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | namespace: default 5 | name: service-reader 6 | rules: 7 | - apiGroups: [""] # "" indicates the core API group 8 | resources: ["services"] 9 | verbs: ["create","delete","get","list","patch","update","watch"] 10 | - apiGroups: [""] # "" indicates the core API group 11 | resources: ["deployments"] 12 | verbs: ["create","delete","get","list","patch","update","watch"] 13 | - apiGroups: ["apps"] # "" indicates the core API group 14 | resources: ["deployments"] 15 | verbs: ["create","delete","get","list","patch","update","watch"] 16 | - apiGroups: [""] 17 | resources: ["pods"] 18 | verbs: ["create","delete","get","list","patch","update","watch"] 19 | - apiGroups: [""] 20 | resources: ["pods/exec"] 21 | verbs: ["create","delete","get","list","patch","update","watch"] 22 | - apiGroups: [""] 23 | resources: ["pods/log"] 24 | verbs: ["get","list","watch"] 25 | - apiGroups: [""] 26 | resources: ["secrets"] 27 | verbs: ["get"] -------------------------------------------------------------------------------- /Dockerfile-k8sdemo-backend: -------------------------------------------------------------------------------- 1 | # vagrant@ubuntu-xenial:~/app/k8sdemo/script/kubernetes/backend$ 2 | # docker build -t k8sdemo-backend . 3 | 4 | FROM golang:latest as builder 5 | 6 | # Set the Current Working Directory inside the container 7 | WORKDIR /app 8 | 9 | COPY go.mod go.sum ./ 10 | 11 | RUN export GO111MODULE=on 12 | RUN export GOPROXY=https://goproxy.io 13 | 14 | RUN go mod download 15 | 16 | COPY . . 17 | 18 | WORKDIR /app/cmd 19 | 20 | # Build the Go app 21 | #RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main.exe 22 | 23 | RUN go build -o main.exe 24 | 25 | ######## Start a new stage from scratch ####### 26 | FROM alpine:latest 27 | 28 | RUN apk --no-cache add ca-certificates 29 | 30 | WORKDIR /root/ 31 | 32 | RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 33 | 34 | # Copy the Pre-built binary file from the previous stage 35 | COPY --from=builder /app/cmd/main.exe . 36 | 37 | # Command to run the executable 38 | # CMD exec /bin/bash -c "trap : TERM INT; sleep infinity & wait" 39 | CMD exec /bin/sh -c "trap : TERM INT; (while true; do sleep 1000; done) & wait" -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Jin Feng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= 3 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 4 | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= 5 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 6 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 7 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= 10 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 11 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 12 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 13 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 14 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: k8sdemo 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | version: 0.1.0 18 | 19 | # This is the version number of the application being deployed. This version number should be 20 | # incremented each time you make changes to the application. 21 | appVersion: 1.16.0 22 | dependencies: 23 | - name: k8sdemo-backend 24 | repository: file://../k8sdemo-backend 25 | version: 0.1.0 26 | - name: k8sdemo-database 27 | repository: file://../k8sdemo-database 28 | version: 0.1.0 -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "k8sdemo.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- else -}} 7 | apiVersion: extensions/v1beta1 8 | {{- end }} 9 | kind: Ingress 10 | metadata: 11 | name: {{ $fullName }} 12 | labels: 13 | {{- include "k8sdemo.labels" . | nindent 4 }} 14 | {{- with .Values.ingress.annotations }} 15 | annotations: 16 | {{- toYaml . | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | {{- if .Values.ingress.tls }} 20 | tls: 21 | {{- range .Values.ingress.tls }} 22 | - hosts: 23 | {{- range .hosts }} 24 | - {{ . | quote }} 25 | {{- end }} 26 | secretName: {{ .secretName }} 27 | {{- end }} 28 | {{- end }} 29 | rules: 30 | {{- range .Values.ingress.hosts }} 31 | - host: {{ .host | quote }} 32 | http: 33 | paths: 34 | {{- range .paths }} 35 | - path: {{ . }} 36 | backend: 37 | serviceName: {{ $fullName }} 38 | servicePort: {{ $svcPort }} 39 | {{- end }} 40 | {{- end }} 41 | {{- end }} 42 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "k8sdemo-backend.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- else -}} 7 | apiVersion: extensions/v1beta1 8 | {{- end }} 9 | kind: Ingress 10 | metadata: 11 | name: {{ $fullName }} 12 | labels: 13 | {{- include "k8sdemo-backend.labels" . | nindent 4 }} 14 | {{- with .Values.ingress.annotations }} 15 | annotations: 16 | {{- toYaml . | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | {{- if .Values.ingress.tls }} 20 | tls: 21 | {{- range .Values.ingress.tls }} 22 | - hosts: 23 | {{- range .hosts }} 24 | - {{ . | quote }} 25 | {{- end }} 26 | secretName: {{ .secretName }} 27 | {{- end }} 28 | {{- end }} 29 | rules: 30 | {{- range .Values.ingress.hosts }} 31 | - host: {{ .host | quote }} 32 | http: 33 | paths: 34 | {{- range .paths }} 35 | - path: {{ . }} 36 | backend: 37 | serviceName: {{ $fullName }} 38 | servicePort: {{ $svcPort }} 39 | {{- end }} 40 | {{- end }} 41 | {{- end }} 42 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "k8sdemo-database.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 5 | apiVersion: networking.k8s.io/v1beta1 6 | {{- else -}} 7 | apiVersion: extensions/v1beta1 8 | {{- end }} 9 | kind: Ingress 10 | metadata: 11 | name: {{ $fullName }} 12 | labels: 13 | {{- include "k8sdemo-database.labels" . | nindent 4 }} 14 | {{- with .Values.ingress.annotations }} 15 | annotations: 16 | {{- toYaml . | nindent 4 }} 17 | {{- end }} 18 | spec: 19 | {{- if .Values.ingress.tls }} 20 | tls: 21 | {{- range .Values.ingress.tls }} 22 | - hosts: 23 | {{- range .hosts }} 24 | - {{ . | quote }} 25 | {{- end }} 26 | secretName: {{ .secretName }} 27 | {{- end }} 28 | {{- end }} 29 | rules: 30 | {{- range .Values.ingress.hosts }} 31 | - host: {{ .host | quote }} 32 | http: 33 | paths: 34 | {{- range .paths }} 35 | - path: {{ . }} 36 | backend: 37 | serviceName: {{ $fullName }} 38 | servicePort: {{ $svcPort }} 39 | {{- end }} 40 | {{- end }} 41 | {{- end }} 42 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "k8sdemo.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "k8sdemo.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "k8sdemo.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "k8sdemo.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /script/cd/jenkinsfile-declarative: -------------------------------------------------------------------------------- 1 | pipeline { 2 | environment { 3 | registry = "jfeng45/codedemo" 4 | registryCredential = 'dockerhub' 5 | } 6 | // Lets Jenkins use Docker for us later. 7 | agent any 8 | // If anything fails, the whole Pipeline stops. 9 | 10 | stages { 11 | stage('Initialize'){ 12 | def dockerHome = tool 'myDocker' 13 | env.PATH = "${dockerHome}/bin:${env.PATH}" 14 | } 15 | stage('Docker') { 16 | steps { 17 | 18 | // Use a scripted pipeline. 19 | script { 20 | node { 21 | def app 22 | 23 | stage('Clone repository') { 24 | git 'https://github.com/jfeng45/k8sdemo' 25 | } 26 | 27 | stage('Build image') { 28 | app = docker.build(registry+":$BUILD_NUMBER") 29 | } 30 | 31 | stage('Push image') { 32 | // Use the Credential ID of the Docker Hub Credentials we added to Jenkins. 33 | docker.withRegistry( '', registryCredential ) { 34 | // Push image and tag it with our build number for versioning purposes. 35 | app.push() 36 | 37 | } 38 | } 39 | } 40 | } 41 | } 42 | } 43 | } 44 | post { 45 | always { 46 | // Clean up our workspace. 47 | deleteDir() 48 | } 49 | } 50 | 51 | 52 | } -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "k8sdemo-backend.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "k8sdemo-backend.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "k8sdemo-backend.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "k8sdemo-backend.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "k8sdemo-database.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "k8sdemo-database.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "k8sdemo-database.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "k8sdemo-database.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | echo "Visit http://127.0.0.1:8080 to use your application" 20 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /script/kubernetes/database/database-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: k8sdemo-database-deployment 5 | labels: 6 | app: k8sdemo-database 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: k8sdemo-database 11 | strategy: 12 | type: Recreate 13 | template: 14 | metadata: 15 | labels: 16 | app: k8sdemo-database 17 | spec: 18 | containers: 19 | - image: mysql:5.7 20 | name: k8sdemo-database-container 21 | imagePullPolicy: Never 22 | env: 23 | - name: MYSQL_ROOT_PASSWORD 24 | valueFrom: 25 | secretKeyRef: 26 | name: k8sdemo-secret 27 | key: MYSQL_ROOT_PASSWORD 28 | - name: MYSQL_USER_NAME 29 | valueFrom: 30 | secretKeyRef: 31 | name: k8sdemo-secret 32 | key: MYSQL_USER_NAME 33 | - name: MYSQL_USER_PASSWORD 34 | valueFrom: 35 | secretKeyRef: 36 | name: k8sdemo-secret 37 | key: MYSQL_USER_PASSWORD 38 | - name: MYSQL_DATABASE 39 | valueFrom: 40 | configMapKeyRef: 41 | name: k8sdemo-config 42 | key: MYSQL_DATABASE 43 | args: ["--default-authentication-plugin=mysql_native_password"] 44 | ports: 45 | - containerPort: 3306 46 | name: portname 47 | volumeMounts: 48 | - name: k8sdemo-database-persistentstorage 49 | mountPath: /var/lib/mysql 50 | volumes: 51 | - name: k8sdemo-database-persistentstorage 52 | persistentVolumeClaim: 53 | claimName: k8sdemo-database-pvclaim 54 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "k8sdemo.fullname" . }} 5 | labels: 6 | {{- include "k8sdemo.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "k8sdemo.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | labels: 15 | {{- include "k8sdemo.selectorLabels" . | nindent 8 }} 16 | spec: 17 | {{- with .Values.imagePullSecrets }} 18 | imagePullSecrets: 19 | {{- toYaml . | nindent 8 }} 20 | {{- end }} 21 | serviceAccountName: {{ include "k8sdemo.serviceAccountName" . }} 22 | securityContext: 23 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 24 | containers: 25 | - name: {{ .Chart.Name }} 26 | securityContext: 27 | {{- toYaml .Values.securityContext | nindent 12 }} 28 | image: {{ .Values.image.repository }} 29 | imagePullPolicy: {{ .Values.image.pullPolicy }} 30 | ports: 31 | - name: http 32 | containerPort: 80 33 | protocol: TCP 34 | livenessProbe: 35 | httpGet: 36 | path: / 37 | port: http 38 | readinessProbe: 39 | httpGet: 40 | path: / 41 | port: http 42 | resources: 43 | {{- toYaml .Values.resources | nindent 12 }} 44 | {{- with .Values.nodeSelector }} 45 | nodeSelector: 46 | {{- toYaml . | nindent 8 }} 47 | {{- end }} 48 | {{- with .Values.affinity }} 49 | affinity: 50 | {{- toYaml . | nindent 8 }} 51 | {{- end }} 52 | {{- with .Values.tolerations }} 53 | tolerations: 54 | {{- toYaml . | nindent 8 }} 55 | {{- end }} 56 | -------------------------------------------------------------------------------- /script/cd/jenkins-k8sdemo: -------------------------------------------------------------------------------- 1 | def POD_LABEL = "k8sdemopod-${UUID.randomUUID().toString()}" 2 | podTemplate(label: POD_LABEL, cloud: 'kubernetes', containers: [ 3 | containerTemplate(name: 'modified-jenkins', image: 'jfeng45/modified-jenkins:1.0', ttyEnabled: true, command: 'cat') 4 | ], 5 | volumes: [ 6 | hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock') 7 | ]) { 8 | 9 | node(POD_LABEL) { 10 | def kubBackendDirectory = "/script/kubernetes/backend" 11 | stage('Checkout') { 12 | container('modified-jenkins') { 13 | sh 'echo get source from github' 14 | git 'https://github.com/jfeng45/k8sdemo' 15 | } 16 | } 17 | stage('Build image') { 18 | def imageName = "jfeng45/jenkins-k8sdemo:${env.BUILD_NUMBER}" 19 | def dockerDirectory = "${kubBackendDirectory}/docker/Dockerfile-k8sdemo-backend" 20 | container('modified-jenkins') { 21 | withCredentials([[$class: 'UsernamePasswordMultiBinding', 22 | credentialsId: 'dockerhub', 23 | usernameVariable: 'DOCKER_HUB_USER', 24 | passwordVariable: 'DOCKER_HUB_PASSWORD']]) { 25 | sh """ 26 | docker login -u ${DOCKER_HUB_USER} -p ${DOCKER_HUB_PASSWORD} 27 | docker build -f ${WORKSPACE}${dockerDirectory} -t ${imageName} . 28 | docker push ${imageName} 29 | """ 30 | } 31 | } 32 | } 33 | stage('Deploy') { 34 | container('modified-jenkins') { 35 | sh "kubectl apply -f ${WORKSPACE}${kubBackendDirectory}/backend-deployment.yaml" 36 | sh "kubectl apply -f ${WORKSPACE}${kubBackendDirectory}/backend-service.yaml" 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /script/kubernetes/backend/backend-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: k8sdemo-backend-deployment 5 | labels: 6 | app: k8sdemo-backend 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: k8sdemo-backend 11 | strategy: 12 | type: Recreate 13 | template: 14 | metadata: 15 | labels: 16 | app: k8sdemo-backend 17 | spec: 18 | containers: 19 | - image: k8sdemo-backend 20 | name: k8sdemo-backend-container 21 | imagePullPolicy: Never 22 | env: 23 | - name: MYSQL_USER_NAME 24 | valueFrom: 25 | secretKeyRef: 26 | name: k8sdemo-secret 27 | key: MYSQL_USER_NAME 28 | - name: MYSQL_USER_PASSWORD 29 | valueFrom: 30 | secretKeyRef: 31 | name: k8sdemo-secret 32 | key: MYSQL_USER_PASSWORD 33 | - name: MYSQL_HOST 34 | valueFrom: 35 | configMapKeyRef: 36 | name: k8sdemo-config 37 | key: MYSQL_HOST 38 | - name: MYSQL_PORT 39 | valueFrom: 40 | configMapKeyRef: 41 | name: k8sdemo-config 42 | key: MYSQL_PORT 43 | - name: MYSQL_DATABASE 44 | valueFrom: 45 | configMapKeyRef: 46 | name: k8sdemo-config 47 | key: MYSQL_DATABASE 48 | ports: 49 | - containerPort: 80 50 | name: portname 51 | volumeMounts: 52 | - name: k8sdemo-backend-persistentstorage 53 | mountPath: /app/logs 54 | volumes: 55 | - name: k8sdemo-backend-persistentstorage 56 | persistentVolumeClaim: 57 | claimName: k8sdemo-backend-pvclaim 58 | -------------------------------------------------------------------------------- /script/kubernetes/backend/backend-deployment1.yaml: -------------------------------------------------------------------------------- 1 | # Source: k8sdemo-backend/templates/deployment.yaml 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: k8sdemo-backend-deployment 6 | labels: 7 | helm.sh/chart: k8sdemo-backend-0.1.0 8 | app.kubernetes.io/name: k8sdemo-backend 9 | app.kubernetes.io/instance: k8sdemo-backend 10 | app.kubernetes.io/version: "1.16.0" 11 | app.kubernetes.io/managed-by: Helm 12 | spec: 13 | replicas: 1 14 | selector: 15 | matchLabels: 16 | app.kubernetes.io/name: k8sdemo-backend 17 | app.kubernetes.io/instance: k8sdemo-backend 18 | template: 19 | metadata: 20 | labels: 21 | app.kubernetes.io/name: k8sdemo-backend 22 | app.kubernetes.io/instance: k8sdemo-backend 23 | spec: 24 | serviceAccountName: default 25 | containers: 26 | - name: k8sdemo-backend-container 27 | image: k8sdemo-backend:05894ca-dirty 28 | imagePullPolicy: Never 29 | env: 30 | - name: MYSQL_USER_NAME 31 | value: dbuser 32 | - name: MYSQL_USER_PASSWORD 33 | value: dbuser 34 | - name: MYSQL_HOST 35 | value: k8sdemo-database-service 36 | - name: MYSQL_DATABASE 37 | value: service_config 38 | ports: 39 | - name: http 40 | containerPort: 80 41 | protocol: TCP 42 | volumeMounts: 43 | - name: k8sdemo-backend-persistentstorage 44 | mountPath: /app/logs 45 | livenessProbe: 46 | httpGet: 47 | path: / 48 | port: http 49 | readinessProbe: 50 | httpGet: 51 | path: / 52 | port: http 53 | volumes: 54 | - name: k8sdemo-backend-persistentstorage 55 | persistentVolumeClaim: 56 | claimName: k8sdemo-backend-pvclaim -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "k8sdemo.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "k8sdemo.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "k8sdemo.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "k8sdemo.labels" -}} 38 | helm.sh/chart: {{ include "k8sdemo.chart" . }} 39 | {{ include "k8sdemo.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end -}} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "k8sdemo.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "k8sdemo.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end -}} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "k8sdemo.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create -}} 59 | {{ default (include "k8sdemo.fullname" .) .Values.serviceAccount.name }} 60 | {{- else -}} 61 | {{ default "default" .Values.serviceAccount.name }} 62 | {{- end -}} 63 | {{- end -}} 64 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for k8sdemo. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: nginx:1.17.6 9 | pullPolicy: Never 10 | 11 | imagePullSecrets: [] 12 | nameOverride: "k8sdemo" 13 | fullnameOverride: "k8sdemo" 14 | 15 | global: 16 | k8sdemoBackendService: k8sdemo-backend-service 17 | k8sdemoDatabaseService: &k8sdemoDatabaseService k8sdemo-database-service 18 | mysqlUserName: dbuser 19 | mysqlUserPassword: dbuser 20 | mysqlRootPassword: root 21 | mysqlPort: 3306 22 | mysqlHost: *k8sdemoDatabaseService 23 | mysqlDatabase: service_config 24 | 25 | serviceAccount: 26 | # Specifies whether a service account should be created 27 | create: false 28 | # The name of the service account to use. 29 | # If not set and create is true, a name is generated using the fullname template 30 | name: 31 | 32 | podSecurityContext: {} 33 | # fsGroup: 2000 34 | 35 | securityContext: {} 36 | # capabilities: 37 | # drop: 38 | # - ALL 39 | # readOnlyRootFilesystem: true 40 | # runAsNonRoot: true 41 | # runAsUser: 1000 42 | 43 | service: 44 | type: NodePort 45 | port: 80 46 | nodePort: 31080 47 | 48 | ingress: 49 | enabled: false 50 | annotations: {} 51 | # kubernetes.io/ingress.class: nginx 52 | # kubernetes.io/tls-acme: "true" 53 | hosts: 54 | - host: chart-example.local 55 | paths: [] 56 | tls: [] 57 | # - secretName: chart-example-tls 58 | # hosts: 59 | # - chart-example.local 60 | 61 | resources: {} 62 | # We usually recommend not to specify default resources and to leave this as a conscious 63 | # choice for the user. This also increases chances charts run on environments with little 64 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 65 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 66 | # limits: 67 | # cpu: 100m 68 | # memory: 128Mi 69 | # requests: 70 | # cpu: 100m 71 | # memory: 128Mi 72 | 73 | nodeSelector: {} 74 | 75 | tolerations: [] 76 | 77 | affinity: {} 78 | -------------------------------------------------------------------------------- /config/appConfig.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | 4 | import ( 5 | "database/sql" 6 | "github.com/jfeng45/k8sdemo/dataservice" 7 | "github.com/jfeng45/k8sdemo/dataservice/userdata" 8 | "github.com/jfeng45/k8sdemo/usecase" 9 | "github.com/jfeng45/k8sdemo/usecase/registration" 10 | "github.com/jfeng45/k8sdemo/tool" 11 | "os" 12 | ) 13 | 14 | type dbConfig struct { 15 | dbHost string 16 | dbPort string 17 | dbDatabase string 18 | dbUser string 19 | dbPassword string 20 | } 21 | func BuildRegistrationInterface(dataServiceName string)(usecase.RegistrationUseCaseInterface, error) { 22 | //uds := user 23 | RegisterLogrusLog() 24 | //RegisterZapLog() 25 | uds, err := BuildUserDataInterface(dataServiceName) 26 | if err != nil { 27 | return nil, err 28 | } 29 | ucsi := registration.UseCase{uds} 30 | return &ucsi, nil 31 | } 32 | 33 | 34 | func BuildUserDataInterface(dataServiceName string) (dataservice.UserDataInterface, error) { 35 | //var ds dataStoreUserI 36 | //var err error 37 | switch dataServiceName { 38 | case "mysql": 39 | return buildMysql() 40 | default: 41 | return buildMysql() 42 | } 43 | //return ds, err 44 | } 45 | 46 | 47 | func buildMysql() (dataservice.UserDataInterface, error) { 48 | tool.Log.Debug("connect to database ") 49 | dc := buildDbConfig () 50 | dataSourceName := dc.dbUser + ":"+ dc.dbPassword + "@tcp(" +dc.dbHost +":" +dc.dbPort +")/" + dc.dbDatabase + "?charset=utf8"; 51 | tool.Log.Debug("dataSourceName:", dataSourceName) 52 | //db, err := sql.Open("mysql", "dbuser:dbuser@tcp(localhost:3306)/service_config?charset=utf8") 53 | db, err := sql.Open("mysql", dataSourceName) 54 | checkErr(err) 55 | dataService := userdata.UserDataMysql{DB: db} 56 | return &dataService, err 57 | } 58 | 59 | func buildDbConfig () dbConfig{ 60 | dc :=dbConfig{} 61 | dc.dbHost = os.Getenv("MYSQL_HOST") 62 | dc.dbPort = os.Getenv("MYSQL_PORT") 63 | dc.dbDatabase = os.Getenv("MYSQL_DATABASE") 64 | dc.dbUser = os.Getenv("MYSQL_USER_NAME") 65 | dc.dbPassword = os.Getenv("MYSQL_USER_PASSWORD") 66 | return dc 67 | } 68 | 69 | func checkErr(err error) { 70 | if err != nil { 71 | tool.Log.Debug("Error is ", err) 72 | os.Exit(-1) 73 | } 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "k8sdemo-backend.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "k8sdemo-backend.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "k8sdemo-backend.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "k8sdemo-backend.labels" -}} 38 | helm.sh/chart: {{ include "k8sdemo-backend.chart" . }} 39 | {{ include "k8sdemo-backend.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end -}} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "k8sdemo-backend.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "k8sdemo-backend.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end -}} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "k8sdemo-backend.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create -}} 59 | {{ default (include "k8sdemo-backend.fullname" .) .Values.serviceAccount.name }} 60 | {{- else -}} 61 | {{ default "default" .Values.serviceAccount.name }} 62 | {{- end -}} 63 | {{- end -}} 64 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "k8sdemo-database.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "k8sdemo-database.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "k8sdemo-database.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | {{/* 35 | Common labels 36 | */}} 37 | {{- define "k8sdemo-database.labels" -}} 38 | helm.sh/chart: {{ include "k8sdemo-database.chart" . }} 39 | {{ include "k8sdemo-database.selectorLabels" . }} 40 | {{- if .Chart.AppVersion }} 41 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 42 | {{- end }} 43 | app.kubernetes.io/managed-by: {{ .Release.Service }} 44 | {{- end -}} 45 | 46 | {{/* 47 | Selector labels 48 | */}} 49 | {{- define "k8sdemo-database.selectorLabels" -}} 50 | app.kubernetes.io/name: {{ include "k8sdemo-database.name" . }} 51 | app.kubernetes.io/instance: {{ .Release.Name }} 52 | {{- end -}} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "k8sdemo-database.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create -}} 59 | {{ default (include "k8sdemo-database.fullname" .) .Values.serviceAccount.name }} 60 | {{- else -}} 61 | {{ default "default" .Values.serviceAccount.name }} 62 | {{- end -}} 63 | {{- end -}} 64 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo/values-dev.yaml: -------------------------------------------------------------------------------- 1 | # Default values for k8sdemo. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: nginx:1.17.6 9 | pullPolicy: Never 10 | 11 | imagePullSecrets: [] 12 | nameOverride: "k8sdemo" 13 | fullnameOverride: "k8sdemo" 14 | 15 | global: 16 | k8sdemoBackendService: k8sdemo-backend-service 17 | k8sdemoDatabaseService: &k8sdemoDatabaseService k8sdemo-database-service 18 | mysqlUserName: dbuser 19 | mysqlUserPassword: dbuser 20 | mysqlRootPassword: root 21 | mysqlPort: 3306 22 | mysqlHost: *k8sdemoDatabaseService 23 | mysqlDatabase: service_config 24 | 25 | serviceAccount: 26 | # Specifies whether a service account should be created 27 | create: false 28 | # The name of the service account to use. 29 | # If not set and create is true, a name is generated using the fullname template 30 | name: 31 | 32 | podSecurityContext: {} 33 | # fsGroup: 2000 34 | 35 | securityContext: {} 36 | # capabilities: 37 | # drop: 38 | # - ALL 39 | # readOnlyRootFilesystem: true 40 | # runAsNonRoot: true 41 | # runAsUser: 1000 42 | 43 | service: 44 | type: NodePort 45 | port: 80 46 | nodePort: 31080 47 | 48 | ingress: 49 | enabled: false 50 | annotations: {} 51 | # kubernetes.io/ingress.class: nginx 52 | # kubernetes.io/tls-acme: "true" 53 | hosts: 54 | - host: chart-example.local 55 | paths: [] 56 | tls: [] 57 | # - secretName: chart-example-tls 58 | # hosts: 59 | # - chart-example.local 60 | 61 | resources: {} 62 | # We usually recommend not to specify default resources and to leave this as a conscious 63 | # choice for the user. This also increases chances charts run on environments with little 64 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 65 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 66 | # limits: 67 | # cpu: 100m 68 | # memory: 128Mi 69 | # requests: 70 | # cpu: 100m 71 | # memory: 128Mi 72 | 73 | nodeSelector: {} 74 | 75 | tolerations: [] 76 | 77 | affinity: {} 78 | 79 | k8sdemo-backend: 80 | replicaCount: 2 81 | k8sdemo-database: 82 | replicaCount: 2 83 | -------------------------------------------------------------------------------- /cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/jfeng45/k8sdemo/config" 5 | "github.com/jfeng45/k8sdemo/tool" 6 | ) 7 | 8 | func main(){ 9 | //testDataService() 10 | testRegistration() 11 | 12 | } 13 | 14 | func testRegistration() { 15 | dataServiceName :="mysql" 16 | 17 | ruci, err:= config.BuildRegistrationInterface(dataServiceName) 18 | if err != nil { 19 | tool.Log.Debug("registration interface build failed:", err) 20 | } 21 | //user :=model.User{Name:"jinefng", Department:"ddevelopment", Created:"2018-12-09"} 22 | //b, err :=ruci.Register(&user) 23 | //if b { 24 | // tool.Log.Debug("user registered:", user) 25 | //} else { 26 | // tool.Log.Debug("user registere failed:", err) 27 | //} 28 | users, err :=ruci.ListUser() 29 | if err != nil { 30 | 31 | tool.Log.Debug("user registere failed:", err) 32 | } else { 33 | tool.Log.Debug("user lst skaffold:", users) 34 | } 35 | 36 | } 37 | 38 | //func testDataService() { 39 | // id := 15 40 | // err := runSql(id) 41 | // checkErr(err) 42 | // err = runCouchdb(id) 43 | // checkErr(err) 44 | //} 45 | 46 | //func runCouchdb(id int) error { 47 | // dataServiceName :="couchdb" 48 | // userDataService, err := dataservice.BuildUserDataInterface(dataServiceName) 49 | // defer userDataService.Close() 50 | // if err != nil { 51 | // return err 52 | // } 53 | // 54 | // err = userDataService.Find(id) 55 | // checkErr(err) 56 | // return nil 57 | //} 58 | //func runSql(id int) error{ 59 | // dataServiceName :="mysql" 60 | // userDataService, err := dataservice.BuildUserDataInterface(dataServiceName) 61 | // if err != nil { 62 | // return err 63 | // } 64 | // //userDataService, err := buildDataStore() 65 | // defer userDataService.Close() 66 | // user :=model.User{Name:"jinefng", Department:"ddevelopment", Created:"2018-12-09"} 67 | // userDataService.Insert(&user) 68 | // user1 :=model.User{Id: user.Id, Name:"yeyang", Department:"sales", Created:"2019-1-21"} 69 | // err, affect := userDataService.Update(&user1) 70 | // 71 | // err = userDataService.Find(id) 72 | // _, err = userDataService.FindAll() 73 | // 74 | // userDataService.Remove(err, int64(id), affect) 75 | // return nil 76 | //} 77 | // 78 | //func checkErr(err error) { 79 | // if err != nil { 80 | // tool.Log.Debug("Error is ", err) 81 | // os.Exit(-1) 82 | // } 83 | //} -------------------------------------------------------------------------------- /config/logrus.go: -------------------------------------------------------------------------------- 1 | // package logrus handles creating logrus logger 2 | package config 3 | 4 | import ( 5 | "fmt" 6 | "github.com/jfeng45/k8sdemo/tool" 7 | "github.com/pkg/errors" 8 | "github.com/sirupsen/logrus" 9 | "io" 10 | "os" 11 | ) 12 | 13 | //type loggerWrapper struct { 14 | // lw *logrus.Logger 15 | //} 16 | // 17 | //func (logger *loggerWrapper) Errorf(format string, args ...interface{}) { 18 | // logger.lw.Errorf(format, args) 19 | //} 20 | //func (logger *loggerWrapper) Fatalf(format string, args ...interface{}) { 21 | // logger.lw.Fatalf(format, args) 22 | //} 23 | //func (logger *loggerWrapper) Fatal(args ...interface{}) { 24 | // logger.lw.Fatal(args) 25 | //} 26 | //func (logger *loggerWrapper) Infof(format string, args ...interface{}) { 27 | // logger.lw.Infof(format, args) 28 | //} 29 | //func (logger *loggerWrapper) Warnf(format string, args ...interface{}) { 30 | // logger.lw.Warnf(format, args) 31 | //} 32 | //func (logger *loggerWrapper) Debugf(format string, args ...interface{}) { 33 | // logger.lw.Debugf(format, args) 34 | //} 35 | //func (logger *loggerWrapper) Printf(format string, args ...interface{}) { 36 | // logger.lw.Printf(format, args) 37 | //} 38 | //func (logger *loggerWrapper) Println(args ...interface{}) { 39 | // logger.lw.Println(args) 40 | //} 41 | 42 | func RegisterLogrusLog() error { 43 | //standard configuration 44 | log := logrus.New() 45 | log.SetFormatter(&logrus.TextFormatter{}) 46 | log.SetReportCaller(true) 47 | file, err := os.OpenFile("../logs/demo.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) 48 | if err != nil { 49 | fmt.Println("Could Not Open Log File : ", err) 50 | return errors.Wrap(err, "") 51 | } 52 | mw := io.MultiWriter(os.Stdout,file) 53 | log.SetOutput(mw) 54 | //log.SetOutput(os.Stdout) 55 | //customize it from configuration file 56 | err = customizeLogrusFromConfig(log) 57 | if err != nil { 58 | return errors.Wrap(err, "") 59 | } 60 | //This is for loggerWrapper implementation 61 | //logger.Logger(&loggerWrapper{log}) 62 | tool.SetLogger(log) 63 | return nil 64 | } 65 | 66 | // customizeLogFromConfig customize log based on parameters from configuration file 67 | func customizeLogrusFromConfig(log *logrus.Logger) error { 68 | log.SetReportCaller(false) 69 | //log.SetOutput(os.Stdout) 70 | l := &log.Level 71 | err := l.UnmarshalText([]byte("debug")) 72 | if err != nil { 73 | return errors.Wrap(err, "") 74 | } 75 | log.SetLevel(*l) 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for k8sdemo-database. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: mysql:5.7 9 | pullPolicy: Never 10 | 11 | imagePullSecrets: [] 12 | nameOverride: k8sdemo-database 13 | fullnameOverride: k8sdemo-database 14 | 15 | global: 16 | k8sdemoDatabaseService: k8sdemo-database-service 17 | mysqlUserName: dbuser 18 | mysqlUserPassword: dbuser 19 | mysqlRootPassword: root 20 | mysqlDatabase: service_config 21 | 22 | serviceAccount: 23 | # Specifies whether a service account should be created 24 | create: false 25 | # The name of the service account to use. 26 | # If not set and create is true, a name is generated using the fullname template 27 | name: 28 | 29 | deployment: 30 | volumeName: k8sdemo-database-persistentstorage 31 | 32 | podSecurityContext: {} 33 | # fsGroup: 2000 34 | 35 | securityContext: {} 36 | # capabilities: 37 | # drop: 38 | # - ALL 39 | # readOnlyRootFilesystem: true 40 | # runAsNonRoot: true 41 | # runAsUser: 1000 42 | 43 | service: 44 | name: k8sdemo-database-service 45 | type: NodePort 46 | port: 3306 47 | nodePort: 30306 48 | protocol : TCP 49 | targetPort: 3306 50 | 51 | persistentvolume: 52 | name: k8sdemo-database-pv 53 | storage: &storage 1Gi 54 | accessModes: &accessModes 55 | - ReadWriteOnce 56 | 57 | persistentvolumeclaim: 58 | name: k8sdemo-database-pvclaim 59 | storage: *storage 60 | accessModes: *accessModes 61 | 62 | ingress: 63 | enabled: false 64 | annotations: {} 65 | # kubernetes.io/ingress.class: nginx 66 | # kubernetes.io/tls-acme: "true" 67 | hosts: 68 | - host: chart-example.local 69 | paths: [] 70 | tls: [] 71 | # - secretName: chart-example-tls 72 | # hosts: 73 | # - chart-example.local 74 | 75 | resources: {} 76 | # We usually recommend not to specify default resources and to leave this as a conscious 77 | # choice for the user. This also increases chances charts run on environments with little 78 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 79 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 80 | # limits: 81 | # cpu: 100m 82 | # memory: 128Mi 83 | # requests: 84 | # cpu: 100m 85 | # memory: 128Mi 86 | 87 | nodeSelector: {} 88 | 89 | tolerations: [] 90 | 91 | affinity: {} 92 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-database/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "k8sdemo-database.fullname" . }} 5 | labels: 6 | {{- include "k8sdemo-database.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "k8sdemo-database.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | labels: 15 | {{- include "k8sdemo-database.selectorLabels" . | nindent 8 }} 16 | spec: 17 | {{- with .Values.imagePullSecrets }} 18 | imagePullSecrets: 19 | {{- toYaml . | nindent 8 }} 20 | {{- end }} 21 | serviceAccountName: {{ include "k8sdemo-database.serviceAccountName" . }} 22 | securityContext: 23 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 24 | containers: 25 | - name: {{ .Chart.Name }} 26 | securityContext: 27 | {{- toYaml .Values.securityContext | nindent 12 }} 28 | image: {{ .Values.image.repository }} 29 | imagePullPolicy: {{ .Values.image.pullPolicy }} 30 | env: 31 | - name: MYSQL_ROOT_PASSWORD 32 | value: {{ .Values.global.mysqlRootPassword }} 33 | - name: MYSQL_USER_NAME 34 | value: {{ .Values.global.mysqlUserName }} 35 | - name: MYSQL_USER_PASSWORD 36 | value: {{ .Values.global.mysqlUserPassword }} 37 | - name: MYSQL_DATABASE 38 | value: {{ .Values.global.mysqlDatabase }} 39 | args: ["--default-authentication-plugin=mysql_native_password"] 40 | ports: 41 | - containerPort: 3306 42 | name: portname 43 | volumeMounts: 44 | - name: {{ .Values.deployment.volumeName }} #k8sdemo-database-persistentstorage 45 | mountPath: /var/lib/mysql 46 | resources: 47 | {{- toYaml .Values.resources | nindent 12 }} 48 | {{- with .Values.nodeSelector }} 49 | nodeSelector: 50 | {{- toYaml . | nindent 8 }} 51 | {{- end }} 52 | {{- with .Values.affinity }} 53 | affinity: 54 | {{- toYaml . | nindent 8 }} 55 | {{- end }} 56 | {{- with .Values.tolerations }} 57 | tolerations: 58 | {{- toYaml . | nindent 8 }} 59 | {{- end }} 60 | volumes: 61 | - name: {{ .Values.deployment.volumeName }} # k8sdemo-database-persistentstorage 62 | persistentVolumeClaim: 63 | claimName: {{ .Values.persistentvolumeclaim.name }} 64 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for k8sdemo-backend. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: k8sdemo-backend:2.0 9 | pullPolicy: Never 10 | 11 | imagePullSecrets: [] 12 | nameOverride: k8sdemo-backend 13 | fullnameOverride: k8sdemo-backend 14 | 15 | global: 16 | k8sdemoBackendService: k8sdemo-backend-service 17 | k8sdemoDatabaseService: &k8sdemoDatabaseService k8sdemo-database-service 18 | mysqlUserName: dbuser 19 | mysqlUserPassword: dbuser 20 | mysqlPort: 3306 21 | mysqlHost: *k8sdemoDatabaseService 22 | mysqlDatabase: service_config 23 | 24 | deployment: 25 | volumeName: k8sdemo-backend-persistentstorage 26 | 27 | serviceAccount: 28 | # Specifies whether a service account should be created 29 | create: false 30 | # The name of the service account to use. 31 | # If not set and create is true, a name is generated using the fullname template 32 | name: 33 | 34 | podSecurityContext: {} 35 | # fsGroup: 2000 36 | 37 | securityContext: {} 38 | # capabilities: 39 | # drop: 40 | # - ALL 41 | # readOnlyRootFilesystem: true 42 | # runAsNonRoot: true 43 | # runAsUser: 1000 44 | 45 | persistentvolume: 46 | name: k8sdemo-backend-pv 47 | storage: &storage 1Gi 48 | accessModes: &accessModes 49 | - ReadWriteOnce 50 | 51 | persistentvolumeclaim: 52 | name: k8sdemo-backend-pvclaim 53 | storage: *storage 54 | accessModes: *accessModes 55 | 56 | service: 57 | #type: ClusterIP 58 | #port: 80 59 | type: NodePort 60 | port: 80 61 | nodePort: 32080 62 | 63 | ingress: 64 | enabled: false 65 | annotations: {} 66 | # kubernetes.io/ingress.class: nginx 67 | # kubernetes.io/tls-acme: "true" 68 | hosts: 69 | - host: chart-example.local 70 | paths: [] 71 | tls: [] 72 | # - secretName: chart-example-tls 73 | # hosts: 74 | # - chart-example.local 75 | 76 | resources: {} 77 | # We usually recommend not to specify default resources and to leave this as a conscious 78 | # choice for the user. This also increases chances charts run on environments with little 79 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 80 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 81 | # limits: 82 | # cpu: 100m 83 | # memory: 128Mi 84 | # requests: 85 | # cpu: 100m 86 | # memory: 128Mi 87 | 88 | nodeSelector: {} 89 | 90 | tolerations: [] 91 | 92 | affinity: {} 93 | -------------------------------------------------------------------------------- /script/kubernetes/chart/k8sdemo-backend/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "k8sdemo-backend.fullname" . }} 5 | labels: 6 | {{- include "k8sdemo-backend.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "k8sdemo-backend.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | labels: 15 | {{- include "k8sdemo-backend.selectorLabels" . | nindent 8 }} 16 | spec: 17 | {{- with .Values.imagePullSecrets }} 18 | imagePullSecrets: 19 | {{- toYaml . | nindent 8 }} 20 | {{- end }} 21 | serviceAccountName: {{ include "k8sdemo-backend.serviceAccountName" . }} 22 | securityContext: 23 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 24 | containers: 25 | - name: {{ .Chart.Name }} 26 | securityContext: 27 | {{- toYaml .Values.securityContext | nindent 12 }} 28 | image: {{ .Values.image.repository }} 29 | imagePullPolicy: {{ .Values.image.pullPolicy }} 30 | env: 31 | - name: MYSQL_USER_NAME 32 | value: {{ .Values.global.mysqlUserName }} 33 | - name: MYSQL_USER_PASSWORD 34 | value: {{ .Values.global.mysqlUserPassword }} 35 | - name: MYSQL_HOST 36 | value: {{ .Values.global.mysqlHost }} 37 | - name: MYSQL_PORT 38 | value: "{{ .Values.global.mysqlPort }}" 39 | - name: MYSQL_DATABASE 40 | value: {{ .Values.global.mysqlDatabase }} 41 | ports: 42 | - name: http 43 | containerPort: 80 44 | protocol: TCP 45 | volumeMounts: 46 | - name: {{ .Values.deployment.volumeName }} #k8sdemo-backend-persistentstorage 47 | mountPath: /logs 48 | resources: 49 | {{- toYaml .Values.resources | nindent 12 }} 50 | {{- with .Values.nodeSelector }} 51 | nodeSelector: 52 | {{- toYaml . | nindent 8 }} 53 | {{- end }} 54 | {{- with .Values.affinity }} 55 | affinity: 56 | {{- toYaml . | nindent 8 }} 57 | {{- end }} 58 | {{- with .Values.tolerations }} 59 | tolerations: 60 | {{- toYaml . | nindent 8 }} 61 | {{- end }} 62 | volumes: 63 | - name: {{ .Values.deployment.volumeName }} # k8sdemo-backend-persistentstorage 64 | persistentVolumeClaim: 65 | claimName: {{ .Values.persistentvolumeclaim.name }} # k8sdemo-backend-pvclaim 66 | -------------------------------------------------------------------------------- /dataservice/userdata/userDataService.go: -------------------------------------------------------------------------------- 1 | package userdata 2 | 3 | import ( 4 | "database/sql" 5 | "github.com/jfeng45/k8sdemo/model" 6 | "github.com/jfeng45/k8sdemo/tool" 7 | _ "github.com/go-sql-driver/mysql" 8 | "os" 9 | ) 10 | 11 | type UserDataMysql struct { 12 | DB *sql.DB 13 | } 14 | 15 | func checkErr(err error) { 16 | if err != nil { 17 | tool.Log.Debug("Error is ", err) 18 | os.Exit(-1) 19 | } 20 | 21 | } 22 | 23 | func (userData *UserDataMysql ) Close() error{ 24 | return userData.DB.Close() 25 | } 26 | func (userData *UserDataMysql) Remove(err error, id int64, affect int64) { 27 | stmt, err := userData.DB.Prepare("delete from userinfo where uid=?") 28 | checkErr(err) 29 | res, err := stmt.Exec(id) 30 | checkErr(err) 31 | affect, err = res.RowsAffected() 32 | checkErr(err) 33 | tool.Log.Debug("remove:row affected", affect) 34 | } 35 | 36 | func (userData *UserDataMysql) Find(id int) error { 37 | rows, err := userData.DB.Query("SELECT * FROM userinfo where uid =?", id) 38 | checkErr(err) 39 | for rows.Next() { 40 | var uid int 41 | var username string 42 | var department string 43 | var created string 44 | err = rows.Scan(&uid, &username, &department, &created) 45 | checkErr(err) 46 | user := model.User{uid, username, department, created} 47 | 48 | tool.Log.Debug("find user:", user) 49 | //fmt.Print("find: uid=",uid) 50 | //fmt.Print("username=",username) 51 | //fmt.Print("department=", department) 52 | //tool.Log.Debug("created=", created) 53 | } 54 | return err 55 | } 56 | func (userData *UserDataMysql) FindByName(name string) (bool, error) { 57 | rows, err := userData.DB.Query("SELECT * FROM userinfo where username =?", name) 58 | if err != nil { 59 | return false, err 60 | } 61 | if rows.Next() { 62 | return true, nil 63 | //var uid int 64 | //var username string 65 | //var department string 66 | //var created string 67 | //err = rows.Scan(&uid, &username, &department, &created) 68 | //user := model.User{uid, username, department, created} 69 | //checkErr(err) 70 | //tool.Log.Debug("find user:", user) 71 | //fmt.Print("find: uid=",uid) 72 | //fmt.Print("username=",username) 73 | //fmt.Print("department=", department) 74 | //tool.Log.Debug("created=", created) 75 | } 76 | 77 | return false, nil 78 | } 79 | 80 | func (userData *UserDataMysql) FindAll() ([]model.User, error) { 81 | tool.Log.Debug("FindAll()") 82 | 83 | rows, err := userData.DB.Query("SELECT * FROM userinfo ") 84 | if err != nil { 85 | return nil, err 86 | } 87 | var users = []model.User{} 88 | for rows.Next() { 89 | var uid int 90 | var username string 91 | var department string 92 | var created string 93 | err = rows.Scan(&uid, &username, &department, &created) 94 | checkErr(err) 95 | tool.Log.Debug("created=", created) 96 | user := model.User{uid, username, department, created} 97 | tool.Log.Debug("find user:", user) 98 | 99 | users = append(users, user) 100 | 101 | 102 | //fmt.Print("find: uid=",uid) 103 | //fmt.Print("username=",username) 104 | //fmt.Print("department=", department) 105 | 106 | } 107 | tool.Log.Debug("find user list:", users) 108 | return users, nil 109 | } 110 | 111 | func (userData *UserDataMysql) Update(user *model.User) (error, int64) { 112 | stmt, err := userData.DB.Prepare("update userinfo set username=?, department=?, created=? where uid=?") 113 | defer stmt.Close() 114 | checkErr(err) 115 | res, err := stmt.Exec(user.Name, user.Department, user.Created, user.Id) 116 | checkErr(err) 117 | affect, err := res.RowsAffected() 118 | checkErr(err) 119 | tool.Log.Debug("update: rows affected: ", affect) 120 | return err, affect 121 | } 122 | 123 | func (userData *UserDataMysql) Insert(user *model.User) int64 { 124 | stmt, err := userData.DB.Prepare("INSERT userinfo SET username=?,department=?,created=?") 125 | defer stmt.Close() 126 | checkErr(err) 127 | res, err := stmt.Exec(user.Name, user.Department, user.Created) 128 | checkErr(err) 129 | id, err := res.LastInsertId() 130 | user.Id = int(id) 131 | checkErr(err) 132 | tool.Log.Debug("user inserted:", user) 133 | return id 134 | } 135 | 136 | -------------------------------------------------------------------------------- /logs/demo.log: -------------------------------------------------------------------------------- 1 | time="2019-10-24T23:49:48-07:00" level=debug msg="connect to database " 2 | time="2019-10-24T23:49:48-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 3 | time="2019-10-24T23:49:48-07:00" level=debug msg="FindAll()" 4 | time="2019-10-24T23:50:09-07:00" level=debug msg="user registere failed:dial tcp 192.168.50.4:30306: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond." 5 | time="2019-10-30T03:53:39-07:00" level=debug msg="connect to database " 6 | time="2019-10-30T03:53:39-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 7 | time="2019-10-30T03:53:39-07:00" level=debug msg="FindAll()" 8 | time="2019-10-30T03:53:40-07:00" level=debug msg="created=2019-10-21" 9 | time="2019-10-30T03:53:40-07:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 10 | time="2019-10-30T03:53:40-07:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 11 | time="2019-10-30T03:53:40-07:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 12 | time="2019-10-30T03:55:03-07:00" level=debug msg="connect to database " 13 | time="2019-10-30T03:55:03-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 14 | time="2019-10-30T03:55:03-07:00" level=debug msg="FindAll()" 15 | time="2019-10-30T03:55:03-07:00" level=debug msg="created=2019-10-21" 16 | time="2019-10-30T03:55:03-07:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 17 | time="2019-10-30T03:55:03-07:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 18 | time="2019-10-30T03:55:03-07:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 19 | time="2019-10-30T03:56:10-07:00" level=debug msg="connect to database " 20 | time="2019-10-30T03:56:10-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 21 | time="2019-10-30T03:56:10-07:00" level=debug msg="FindAll()" 22 | time="2019-10-30T03:56:10-07:00" level=debug msg="created=2019-10-21" 23 | time="2019-10-30T03:56:10-07:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 24 | time="2019-10-30T03:56:10-07:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 25 | time="2019-10-30T03:56:10-07:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 26 | time="2019-10-30T03:56:45-07:00" level=debug msg="connect to database " 27 | time="2019-10-30T03:56:45-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 28 | time="2019-10-30T03:56:45-07:00" level=debug msg="FindAll()" 29 | time="2019-10-30T03:56:45-07:00" level=debug msg="created=2019-10-21" 30 | time="2019-10-30T03:56:45-07:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 31 | time="2019-10-30T03:56:45-07:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 32 | time="2019-10-30T03:56:45-07:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 33 | time="2019-10-30T03:57:42-07:00" level=debug msg="connect to database " 34 | time="2019-10-30T03:57:42-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 35 | time="2019-10-30T03:57:42-07:00" level=debug msg="FindAll()" 36 | time="2019-10-30T03:57:42-07:00" level=debug msg="created=2019-10-21" 37 | time="2019-10-30T03:57:42-07:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 38 | time="2019-10-30T03:57:42-07:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 39 | time="2019-10-30T03:57:42-07:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 40 | time="2019-10-30T03:58:11-07:00" level=debug msg="connect to database " 41 | time="2019-10-30T03:58:11-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 42 | time="2019-10-30T03:58:11-07:00" level=debug msg="FindAll()" 43 | time="2019-10-30T03:58:11-07:00" level=debug msg="created=2019-10-21" 44 | time="2019-10-30T03:58:11-07:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 45 | time="2019-10-30T03:58:11-07:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 46 | time="2019-10-30T03:58:11-07:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 47 | time="2019-10-30T04:01:53-07:00" level=debug msg="connect to database " 48 | time="2019-10-30T04:01:53-07:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 49 | time="2019-10-30T04:01:53-07:00" level=debug msg="FindAll()" 50 | time="2019-10-30T04:01:53-07:00" level=debug msg="created=2019-10-21" 51 | time="2019-10-30T04:01:53-07:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 52 | time="2019-10-30T04:01:53-07:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 53 | time="2019-10-30T04:01:53-07:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 54 | time="2019-11-25T03:58:08-08:00" level=debug msg="connect to database " 55 | time="2019-11-25T03:58:08-08:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 56 | time="2019-11-25T03:58:08-08:00" level=debug msg="FindAll()" 57 | time="2019-11-25T03:58:08-08:00" level=debug msg="created=2019-10-21" 58 | time="2019-11-25T03:58:08-08:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 59 | time="2019-11-25T03:58:08-08:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 60 | time="2019-11-25T03:58:08-08:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 61 | time="2019-12-06T22:42:05-08:00" level=debug msg="connect to database " 62 | time="2019-12-06T22:42:05-08:00" level=debug msg="dataSourceName:dbuser:dbuser@tcp(192.168.50.4:30306)/service_config?charset=utf8" 63 | time="2019-12-06T22:42:05-08:00" level=debug msg="FindAll()" 64 | time="2019-12-06T22:42:06-08:00" level=debug msg="created=2019-10-21" 65 | time="2019-12-06T22:42:06-08:00" level=debug msg="find user:{1 Tony IT 2019-10-21}" 66 | time="2019-12-06T22:42:06-08:00" level=debug msg="find user list:[{1 Tony IT 2019-10-21}]" 67 | time="2019-12-06T22:42:06-08:00" level=debug msg="user lst:[{1 Tony IT 2019-10-21}]" 68 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 121 | 122 | 123 | 124 | databaseApp 125 | fmt.Println 126 | "fmt" 127 | mysql 128 | k8sdemo-secret 129 | k8sdemo-config 130 | db-host 131 | k8sdemo.database.config 132 | k8sdemo.database.secret 133 | k8sdemo.database 134 | MYSQL_HOST 135 | net 136 | database 137 | k8sdemo-jenkins 138 | k8sdemo-database 139 | codedemo 140 | serviceAccount 141 | fullname 142 | selectorLabels 143 | serviceAccountName 144 | k8sdemo.name 145 | .mysql. 146 | userName 147 | userPassword 148 | rootPassword 149 | 150 | 151 | github.com/jfeng45/k8sdemo 152 | tool.Log.Debug 153 | "github.com/jfeng45/k8sdemo/tool" 154 | k8sdemo 155 | k8sdemo.database.secret 156 | k8sdemo.database.config 157 | k8sdemo.config 158 | k8sdemo.secret 159 | k8sdemo.backend 160 | k8sdemo-backend 161 | jenkins 162 | k8sdemo-jenkins 163 | 164 | .global. 165 | mysqlUserName 166 | mysqlUserPassword 167 | mysqlRootPassword 168 | 169 | 170 | C:\code\src\github.com\jfeng45\k8sdemo\script\kubernetes\database 171 | C:\code\src\github.com\jfeng45\k8sdemo\script 172 | C:\code\src\github.com\jfeng45\k8sdemo\script\kubernetes\backend 173 | C:\code\src\github.com\jfeng45\k8sdemo\script\kubernetes\chart 174 | 175 | 176 | 177 | 178 | 180 | 181 | 236 | 237 | 238 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 |