主頁 > 軟體設計 > helm入門

helm入門

2021-10-27 09:35:08 軟體設計

helm入門

簡介

Helm是一個由CNCF范訓和管理的專案,用于對需要在Kubernetes 上部署的復雜應用進行定義、安裝和更新,Helm以Chart的方式對應用軟體進行描述,可以方便地創建、版本化、共享和發布復雜的應用軟體,

helm3架構

在這里插入圖片描述

helm3安裝

#github地址
#https://github.com/helm/helm
#本文示例使用的是v3.7.0版本
wget https://get.helm.sh/helm-v3.7.0-linux-amd64.tar.gz
#解壓->helm放入PATH一個路徑下

helm中三大概念

  • Chart:一個Helm包,其中包含運行一個應用所需要的工具和資源定義,還可能包含Kubernetes集群中的服務定義,類似于Homebrew 中的formula、APT中的dpkg或者Yum中的RPM檔案,
  • Release:在Kubernetes集群上運行的一個Chart實體,在同一個 集群上,一個Chart可以被安裝多次,例如有一個MySQL Chart,如果想在服務器上運行兩個MySQL資料庫,就可以基于這個Chart安裝兩次, 每次安裝都會生成新的Release,會有獨立的Release名稱,
  • Repository:用于存放和共享Chart倉庫, 簡單來說,Helm整個系統的主要任務就是,在倉庫中查找需要的 Chart,然后將Chart以Release的形式安裝到Kubernetes集群中,

Helm Chart的使用

下面將使用一個例子展示helm chart的使用,

創建

$ helm create nginx

該命令會創建一個nginx檔案目錄,tree查看目錄結構

$ tree
.
├── charts  #包含chart依賴的其他chart
├── Chart.yaml #包含了chart資訊的YAML檔案
├── templates #模板目錄, 當和values 結合時,可生成有效的Kubernetes manifest檔案
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests #測驗
│       └── test-connection.yaml
└── values.yaml #chart 默認的配置值

Chart.yaml

$ cat Chart.yaml 
apiVersion: v2 #在heml3中apiVersion必須是v2
name: nginx #chart名字
description: A Helm chart for Kubernetes #chart描述
type: application #chart型別 application(默認)、library
version: 0.1.0 #chart的版本
appVersion: "1.16.0" #應用的版本

values.yaml

$ cat values.yaml 
# Default values for nginx.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
  repository: nginx
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: ""

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

serviceAccount:
  # Specifies whether a service account should be created
  create: true
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

podAnnotations: {}

podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  className: ""
  annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

resources: {}
  # We usually recommend not to specify default resources and to leave this as a conscious
  # choice for the user. This also increases chances charts run on environments with little
  # resources, such as Minikube. If you do want to specify resources, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

templates目錄下存放了應用編排檔案,

  • (_)開頭的檔案用來存盤區域和輔助物件,供其他chart模板使用,模板命令都是嵌入在{{}}之間的,

    cat _helpers.tpl 
    {{/*
    Expand the name of the chart.
    */}}
    {{- define "nginx.name" -}}
    {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
    {{- end }}
    
    {{/*
    Create a default fully qualified app name.
    We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
    If release name contains chart name it will be used as a full name.
    */}}
    {{- define "nginx.fullname" -}}
    {{- if .Values.fullnameOverride }}
    {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
    {{- else }}
    {{- $name := default .Chart.Name .Values.nameOverride }}
    {{- if contains $name .Release.Name }}
    {{- .Release.Name | trunc 63 | trimSuffix "-" }}
    {{- else }}
    {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
    {{- end }}
    {{- end }}
    {{- end }}
    
    {{/*
    Create chart name and version as used by the chart label.
    */}}
    {{- define "nginx.chart" -}}
    {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
    {{- end }}
    
    {{/*
    Common labels
    */}}
    {{- define "nginx.labels" -}}
    helm.sh/chart: {{ include "nginx.chart" . }}
    {{ include "nginx.selectorLabels" . }}
    {{- if .Chart.AppVersion }}
    app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
    {{- end }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
    {{- end }}
    
    {{/*
    Selector labels
    */}}
    {{- define "nginx.selectorLabels" -}}
    app.kubernetes.io/name: {{ include "nginx.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    {{- end }}
    
    {{/*
    Create the name of the service account to use
    */}}
    {{- define "nginx.serviceAccountName" -}}
    {{- if .Values.serviceAccount.create }}
    {{- default (include "nginx.fullname" .) .Values.serviceAccount.name }}
    {{- else }}
    {{- default "default" .Values.serviceAccount.name }}
    {{- end }}
    {{- end }}
    
  • yaml格式的編排檔案中將某些欄位設定為“模板命令”,這些“模板命令”會在Helm部署應用時進行引數注入和模板的動態渲染,

    $ cat deployment.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{ include "nginx.fullname" . }}
      labels:
        {{- include "nginx.labels" . | nindent 4 }}
    spec:
      {{- if not .Values.autoscaling.enabled }}
      replicas: {{ .Values.replicaCount }}
      {{- end }}
      selector:
        matchLabels:
          {{- include "nginx.selectorLabels" . | nindent 6 }}
      template:
        metadata:
          {{- with .Values.podAnnotations }}
          annotations:
            {{- toYaml . | nindent 8 }}
          {{- end }}
          labels:
            {{- include "nginx.selectorLabels" . | nindent 8 }}
        spec:
          {{- with .Values.imagePullSecrets }}
          imagePullSecrets:
            {{- toYaml . | nindent 8 }}
          {{- end }}
          serviceAccountName: {{ include "nginx.serviceAccountName" . }}
          securityContext:
            {{- toYaml .Values.podSecurityContext | nindent 8 }}
          containers:
            - name: {{ .Chart.Name }}
              securityContext:
                {{- toYaml .Values.securityContext | nindent 12 }}
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
              imagePullPolicy: {{ .Values.image.pullPolicy }}
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
              livenessProbe:
                httpGet:
                  path: /
                  port: http
              readinessProbe:
                httpGet:
                  path: /
                  port: http
              resources:
                {{- toYaml .Values.resources | nindent 12 }}
          {{- with .Values.nodeSelector }}
          nodeSelector:
            {{- toYaml . | nindent 8 }}
          {{- end }}
          {{- with .Values.affinity }}
          affinity:
            {{- toYaml . | nindent 8 }}
          {{- end }}
          {{- with .Values.tolerations }}
          tolerations:
            {{- toYaml . | nindent 8 }}
          {{- end }}
    

    可是使用helm template [NAME] [CHART] [flags]命令在本地渲染Helm Chart并列印最終的應用模板內容,values.yaml和(_)開頭的檔案中的值會被注入到yaml中,引數--set則會覆寫value.yaml檔案中的值,

    $ helm template nginx  ./nginx --set image.repository=docker.io/library/nginx,service.type=NodePort
    ...
    ...
    ---
    # Source: nginx/templates/deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
      labels:
        helm.sh/chart: nginx-0.1.0
        app.kubernetes.io/name: nginx
        app.kubernetes.io/instance: nginx
        app.kubernetes.io/version: "1.16.0"
        app.kubernetes.io/managed-by: Helm
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: nginx
          app.kubernetes.io/instance: nginx
      template:
        metadata:
          labels:
            app.kubernetes.io/name: nginx
            app.kubernetes.io/instance: nginx
        spec:
          serviceAccountName: nginx
          securityContext:
            {}
          containers:
            - name: nginx
              securityContext:
                {}
              image: "docker.io/library/nginx:1.16.0"
              imagePullPolicy: IfNotPresent
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
              livenessProbe:
                httpGet:
                  path: /
                  port: http
              readinessProbe:
                httpGet:
                  path: /
                  port: http
              resources:
                {}
    ---
    ...
    ...
    
  • NOTES.txt在helm installhelm upgrade命令的最后,Helm會列印出對用戶有用的資訊,該檔案是純文本,但會像模板一樣處理, 所有正常的模板函式和物件都是可用的,

    $ cat NOTES.txt 
    1. Get the application URL by running these commands:
    {{- if .Values.ingress.enabled }}
    {{- range $host := .Values.ingress.hosts }}
      {{- range .paths }}
      http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
      {{- end }}
    {{- end }}
    {{- else if contains "NodePort" .Values.service.type }}
      export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nginx.fullname" . }})
      export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
      echo http://$NODE_IP:$NODE_PORT
    {{- else if contains "LoadBalancer" .Values.service.type }}
         NOTE: It may take a few minutes for the LoadBalancer IP to be available.
               You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "nginx.fullname" . }}'
      export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nginx.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
      echo http://$SERVICE_IP:{{ .Values.service.port }}
    {{- else if contains "ClusterIP" .Values.service.type }}
      export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nginx.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
      export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
      echo "Visit http://127.0.0.1:8080 to use your application"
      kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
    {{- end }}
    

部署

helm install [NAME] [CHART] [flags]命令安裝部署,同樣values.yaml和(_)開頭的檔案中的值會被注入到yaml中,引數--set則會覆寫value.yaml檔案中的值,

$ helm -n default install nginx ./nginx --set image.repository=docker.io/library/nginx,service.type=NodePort
NAME: nginx
LAST DEPLOYED: Sat Oct  9 16:26:50 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services nginx)
  export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT
  • 查看部署的release

    $ helm -n default ls
    NAME 	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART      	APP VERSION
    nginx	default  	1       	2021-10-09 16:26:50.820014356 +0800 CST	deployed	nginx-0.1.0	1.16.0 
    
  • release版本資訊存盤

    默認存盤在release相應namespace下的secret(可配置configmap、sql),每一個REVISION都會生成一個secret,

    $ kubectl -n default get secret -l "owner=helm"
    NAME                          TYPE                 DATA   AGE
    sh.helm.release.v1.nginx.v1   helm.sh/release.v1   1      1m
    

    查看存盤內容

    kubectl -n default get secret sh.helm.release.v1.nginx.v1 -ojsonpath={.data.release} |base64 -d |base64 -d |gzip -d
    
  • 測驗release是否符合預期(需等待所有部署的資源物件創建成功),原理:通過在集群中部署templates/tests/下的yaml,根據容器退出狀態判斷(exit 0:通過)是否測驗通過,測驗的yaml必須含有注解:helm.sh/hook: test,

    $ helm test nginx
    NAME: nginx
    LAST DEPLOYED: Sat Oct  9 16:26:50 2021
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE:     nginx-test-connection
    Last Started:   Sat Oct  9 16:47:02 2021
    Last Completed: Sat Oct  9 16:47:20 2021
    Phase:          Succeeded
    NOTES:
    1. Get the application URL by running these commands:
      export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services nginx)
      export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
      echo http://$NODE_IP:$NODE_PORT
    

升級、回滾、卸載

  • helm upgrade [RELEASE] [CHART] [flags]命令進行升級,

    升級之前查看nginx release當前版本:REVISION=1

    helm -n default ls
    NAME 	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART      	APP VERSION
    nginx	default  	1       	2021-10-09 16:26:50.820014356 +0800 CST	deployed	nginx-0.1.0	1.16.0     
    

    使用升級命令,將deployment中的鏡像tag升級到1.17.0,可使用--dry-run試運行測驗是否可以升級成功,并列印升級清單,

    $ helm -n default upgrade nginx ./nginx/ --set image.repository=docker.io/library/nginx,service.type=NodePort,image.tag=1.17.0
    Release "nginx" has been upgraded. Happy Helming!
    NAME: nginx
    LAST DEPLOYED: Sun Oct 10 13:41:17 2021
    NAMESPACE: default
    STATUS: deployed
    REVISION: 2
    NOTES:
    1. Get the application URL by running these commands:
      export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services nginx)
      export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
      echo http://$NODE_IP:$NODE_PORT
    

    再次查看nginx release當前版本:REVISION=2

    $ helm -n default ls
    NAME 	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART      	APP VERSION
    nginx	default  	2       	2021-10-10 13:41:17.486033411 +0800 CST	deployed	nginx-0.1.0	1.16.0     
    
  • helm rollback <RELEASE> [REVISION] [flags]命令進行回滾,

    回滾之前可使用helm history RELEASE_NAME [flags]查看nginx release歷史版本,

    $ helm -n default history nginx
    REVISION	UPDATED                 	STATUS    	CHART      	APP VERSION	DESCRIPTION     
    1       	Sat Oct  9 16:26:50 2021	superseded	nginx-0.1.0	1.16.0     	Install complete
    2       	Sun Oct 10 13:41:17 2021	deployed  	nginx-0.1.0	1.16.0     	Upgrade complete
    

    將nginx release回滾到REVISION=1,回滾完成后可查看deployment image tag:1.16.0,

    $ helm -n default rollback nginx 1
    Rollback was a success! Happy Helming!
    
  • helm uninstall RELEASE_NAME [...] [flags]命令卸載release,卸載完成后release、release secret、k8s manifest都被洗掉,

    $ helm -n default uninstall nginx
    release "nginx" uninstalled
    

倉庫使用

Harbor

  • 使用helm安裝harbor

    $ helm repo add harbor https://helm.goharbor.io
    "harbor" has been added to your repositories
    #查看本地repo串列
    $ helm repo ls
    NAME  	URL                     
    harbor	https://helm.goharbor.io
    #查看harbor倉庫helm chart版本
    $ helm search repo harbor
    NAME         	CHART VERSION	APP VERSION	DESCRIPTION                                       
    harbor/harbor	1.7.3        	2.3.3      	An open source trusted cloud native registry th...
    #部署harbor release
    #persistence.enabled=false 關閉持久化存盤
    #expose.type=nodePort service型別設定為nodeport方便暴露服務
    #expose.tls.enabled=false 關閉tls
    #--create-namespace 沒有harbor命名空間,則會創建
    #externalURL中的ip為本機網卡ip
    $ helm -n harbor install harbor harbor/harbor --set persistence.enabled=false,expose.type=nodePort,expose.tls.enabled=false,externalURL=http://10.23.18.211:30002 --create-namespace
    NAME: harbor
    LAST DEPLOYED: Mon Oct 11 18:38:47 2021
    NAMESPACE: harbor
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    Please wait for several minutes for Harbor deployment to complete.
    Then you should be able to visit the Harbor portal at http://10.23.18.211:30002
    For more details, please visit https://github.com/goharbor/harbor
    #等待所有pod running
    $ kubectl -n harbor get pod
    NAME                                    READY   STATUS    RESTARTS   AGE
    harbor-chartmuseum-6c9f9c84f8-ztpgp     1/1     Running   0          3m20s
    harbor-core-c6dc8c895-vn5kx             1/1     Running   0          3m19s
    harbor-database-0                       1/1     Running   0          3m20s
    harbor-jobservice-6c4d647bcb-nd64t      1/1     Running   0          3m20s
    harbor-nginx-7bc597c58b-67x6x           1/1     Running   0          3m19s
    harbor-notary-server-5f598b9555-4qjpm   1/1     Running   0          3m20s
    harbor-notary-signer-65b84d688d-g92tv   1/1     Running   0          3m19s
    harbor-portal-945d945f-ks6tx            1/1     Running   0          3m20s
    harbor-redis-0                          1/1     Running   0          3m20s
    harbor-registry-6d976587dc-dbrnt        2/2     Running   0          3m20s
    harbor-trivy-0                          1/1     Running   0          3m20s
    

    瀏覽器訪問http://10.23.18.211:30002即可訪問harbor頁面,admin/Harbor12345為默認用戶密碼,

  • 推送nginx chart到倉庫

    登錄harbor頁面,專案–>新建專案,創建一個名為helm的helm chart倉庫,

    添加helm倉庫,

    $ helm repo add my-harbor http://10.23.18.211:30002/chartrepo/helm --username=admin --password=Harbor12345
    "my-harbor" has been added to your repositories
    #查看當前repo
    $ helm repo ls
    NAME     	URL                                     
    harbor   	https://helm.goharbor.io                
    my-harbor	http://10.23.18.211:30002/chartrepo/helm
    

    由于原生helm沒有推送命令,所以需要安裝一個推送插件,

    $ helm plugin install https://github.com/chartmuseum/helm-push.git
    Downloading and installing helm-push v0.10.0 ...
    https://github.com/chartmuseum/helm-push/releases/download/v0.10.0/helm-push_0.10.0_linux_amd64.tar.gz
    Installed plugin: cm-push
    #查看已安裝的插件
    $ helm plugin ls
    NAME   	VERSION	DESCRIPTION                      
    cm-push	0.10.0 	Push chart package to ChartMuseum
    

    (備選方案)如果服務器不能訪問外網,可以從能夠訪問外網的機器clone插件代碼和插件壓縮包,然后放到此服務器上,

    #在能夠訪問外網的機器上
    $ git clone https://github.com/chartmuseum/helm-push.git
    $curl https://github.com/chartmuseum/helm-push/releases/download/v0.10.0/helm-push_0.10.0_linux_amd64.tar.gz
    #將插件代碼上傳到服務器/root/.cache/helm/plugins目錄下,創建release目錄
    $ mkdiir /root/.cache/helm/plugins/helm-push/release
    #將插件壓縮包上傳到服務器/root/.cache/helm/plugins/helm-push/releases下
    $ cd /root/.cache/helm/plugins
    #vim 編輯helm-push/scripts/install_plugin.sh,根據需要注釋掉 `# Download with curl if possible.`下邊代碼,以注釋掉curl為例:
    $ vim helm-push/scripts/install_plugin.sh
    $ cat helm-push/scripts/install_plugin.sh
    ...
    ...
    # Download with curl if possible.
    if [ -x "$(which curl 2>/dev/null)" ]; then
      #  curl -sSL "${url}" -o "releases/v${version}.tar.gz"
         echo "jump curl"
    else
        wget -q "${url}" -O "releases/v${version}.tar.gz"
    fi
    ...
    ...
    #安裝推送插件
    $ helm plugin install ./helm-push/
    Downloading and installing helm-push v0.10.0 ...
    https://github.com/chartmuseum/helm-push/releases/download/v0.10.0/helm-push_0.10.0_linux_amd64.tar.gz
    jump curl
    Installed plugin: cm-push
    [root@master01 plugins]# helm plugin ls
    NAME   	VERSION	DESCRIPTION                      
    cm-push	0.10.0 	Push chart package to ChartMuseum
    

    推送nginx chart,

    #cd到nginx目錄,推送
    $ helm cm-push ./nginx my-harbor
    Pushing nginx-0.1.0.tgz to my-harbor...
    Done.
    #更新本地快取的my-harbor倉庫資訊,可以確認nginx chart上傳到harbor上,也可以在harbor頁面上確認
    $ helm repo  update my-harbor 
    Hang tight while we grab the latest from your chart repositories...
    ...Successfully got an update from the "my-harbor" chart repository
    Update Complete. ?Happy Helming!?
    $ helm search repo my-harbor
    NAME           	CHART VERSION	APP VERSION	DESCRIPTION                
    my-harbor/nginx	0.1.0        	1.16.0     	A Helm chart for Kubernetes
    
  • 拉取、部署倉庫中的chart

    helm pull [chart URL | repo/chartname] [...] [flags]拉取倉庫中chart,pull只會拉取到本地當前目錄下的.tgz壓縮包,可使用tar xzvf xxx.tgz解壓,

    #更新本地helm repo 快取
    $ helm repo update
    #pull拉取nginx chart
    $ helm pull my-harbor/nginx
    

    helm install [NAME] [CHART] [flags]部署倉庫中的chart,和上邊部署篇幅類似,把使用本地檔案改成使用倉庫中的chart即可,

    $ helm -n test install nginx my-harbor/nginx --set image.repository=docker.io/library/nginx,service.type=NodePort --create-namespace
    NAME: nginx
    LAST DEPLOYED: Mon Oct 11 19:47:36 2021
    NAMESPACE: test
    STATUS: deployed
    REVISION: 1
    NOTES:
    1. Get the application URL by running these commands:
      export NODE_PORT=$(kubectl get --namespace test -o jsonpath="{.spec.ports[0].nodePort}" services nginx)
      export NODE_IP=$(kubectl get nodes --namespace test -o jsonpath="{.items[0].status.addresses[0].address}")
      echo http://$NODE_IP:$NODE_PORT
    

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/337662.html

標籤:其他

上一篇:關于微信小程式使用WebSokect

下一篇:典型傳統專案部署實戰(jdk,tomcat,mysql,nginx實戰)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more