Kubernetes的包管理工具Helm的安装和使用
1.源码安装
[root@master ~]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.0-linux-amd64.tar.gz
[root@master ~]# tar -zxvf helm-v2.14.0-linux-amd64.tar.gz
linux-amd64/
linux-amd64/tiller
linux-amd64/README.md
linux-amd64/LICENSE
linux-amd64/helm
[root@master ~]# ls
anaconda-ks.cfg helm-v2.14.0-linux-amd64.tar.gz linux-amd64 token.txt
[root@master ~]# ls linux-amd64/
helm LICENSE README.md tiller
[root@master ~]# mv linux-amd64/helm /usr/bin
[root@master ~]# helm --help
2.脚本安装
[root@master ~]# curl -LO https://git.io/get_helm.sh
[root@master ~]# chmod get_helm.sh
[root@master ~]# ./get_helm.sh
//[root@master ~]# curl -L https://git.io/get_helm.sh | bash
2.1初始化
[root@master istio-1.1.]# helm init
[root@master istio-1.1.]# helm version
Client: &version.Version{SemVer:"v2.14.0", GitCommit:"05811b84a3f93603dd6c2fcfe57944dfa7ab7fd0", GitTreeState:"clean"}
Error: could not find a ready tiller pod
//gcr.io/kubernetes-helm/tiller:v2.11.0镜像被墙,无法下载
[root@master ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-fb8b8dccf-7dt66 / Running 14d
coredns-fb8b8dccf-7rt9b / Running 14d
etcd-master / Running 14d
kube-apiserver-master / Running 14d
kube-controller-manager-master / Running 14d
kube-flannel-ds-amd64-dpdws / Running 14d
kube-flannel-ds-amd64-k8xnf / Running 14d
kube-flannel-ds-amd64-kmc5h / Running 13d
kube-proxy-qjtsd / Running 14d
kube-proxy-t6lpf / Running 14d
kube-proxy-t77xh / Running 13d
kube-scheduler-master / Running 14d
tiller-deploy-765dcb8745-2vswr / ImagePullBackOff 18m
2.2解决办法1.helm reset
[root@master ~]# kubectl delete pod tiller-deploy-765dcb8745-2vswr -n kube-system
pod "tiller-deploy-765dcb8745-2vswr" deleted
[root@master istio-1.1.]# docker search tiller:v2.14.0
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
hekai/gcr.io_kubernetes-helm_tiller_v2.14.0 FROM gcr.io/kubernetes-helm/tiller:v2.14.0
//[root@master ~]# helm init --service-account tiller --tiller-image hekai/gcr.io_kubernetes-helm_tiller_v2.14.0 --skip-refresh
//[root@master ~]# helm init -i hekai/gcr.io_kubernetes-helm_tiller_v2.14.0
//更新tiller,使用docker上镜像
[root@master ~]# helm init --upgrade -i hekai/gcr.io_kubernetes-helm_tiller_v2.14.0
[root@master istio-1.1.]# helm version
Client: &version.Version{SemVer:"v2.14.0", GitCommit:"05811b84a3f93603dd6c2fcfe57944dfa7ab7fd0", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.0", GitCommit:"05811b84a3f93603dd6c2fcfe57944dfa7ab7fd0", GitTreeState:"clean"}
tiller默认被部署在k8s集群中的kube-system这个namespace下
[root@master istio-1.1.]# kubectl get pod -n kube-system -l app=helm
NAME READY STATUS RESTARTS AGE
tiller-deploy-58f5d95b9c-vrbbg / Running 24h
3.给予helm的rbac管理权限
帮助:https://github.com/helm/helm/blob/master/docs/rbac.md
[root@master helm]# vim rbac-config.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system
[root@master helm]]# kubectl create -f rbac-config.yaml
serviceaccount "tiller" created
clusterrolebinding "tiller" created
[root@master helm]]# helm init --service-account tiller --history-max
[root@master ~]# helm init --upgrade -i hekai/gcr.io_kubernetes-helm_tiller_v2.14.0
[root@master helm]]# kubectl get sa -n kube-system
4.使用helm
//更新镜像仓库
[root@master helm]# helm repo update
//查看帮助
[root@master helm]# helm --help
//官方仓库,stable是稳定版,incubator预发版
https://hub.helm.sh/
https://hub.kubeapps.com
//查看使用哪些仓库
[root@master helm]# helm repo list
NAME URL
stable https://kubernetes-charts.storage.googleapis.com
local http://127.0.0.1:8879/charts 常用命令,release管理:
//搜索镜像
[root@master helm]# helm search redis
[root@master helm]# helm install --name redis stable/redis
//安装时要事先准备好pv,下载安装的都在$HOME/.helm/cache/archive/目录下,把.tgz的文件解压然后tree redis查看
[root@master ~]# cd .helm/cache/archive/
[root@master archive]# ls
redis-8.0.5.tgz
[root@master archive]# tar -xzvf redis-8.0.5.tgz
[root@master archive]# ls
redis redis-8.0.5.tgz
[root@master archive]# cd redis/
[root@master redis]# ls
Chart.yaml ci README.md templates values-production.yaml values.yaml
//修改values.yaml,再根据values.yaml安装
[root@master helm]# helm install --name redis -f values.yaml stable/redis
[root@master helm]# helm status redis //此命令有用,用于安装完后需要做哪些操作都有步骤
[root@master helm]# helm history redis //可以用于回滚
[root@master helm]# helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
redis 1 Sat Jun 1 10:09:52 2019 DEPLOYED redis-8.0.5 5.0.5 default
[root@master helm]# helm delete --help
[root@master helm]# helm delete --dry-run
[root@master helm]# helm delete jenkins
[root@master helm]# helm upgrade/rollback //结合history用于回滚
[root@master helm]# helm upgrade nginx-ingress stable/nginx-ingress --namespace ingress-nginx --install -f values.yaml 常用命令,chart管理:
[root@master helm]# helm create
//下载镜像
[root@master helm]# helm fetch
[root@master helm]# helm get
[root@master helm]# helm inspect stable/redis
//打包本地
[root@master helm]# helm package ./
[root@master archive]# tree redis
redis
├── Chart.yaml
├── ci
│ ├── default-values.yaml
│ ├── dev-values.yaml
│ ├── production-sentinel-values.yaml
│ ├── production-values.yaml
│ ├── redisgraph-module-values.yaml
│ └── redis-lib-values.yaml
├── README.md
├── templates
│ ├── configmap.yaml
│ ├── headless-svc.yaml
│ ├── health-configmap.yaml
│ ├── _helpers.tpl
│ ├── metrics-deployment.yaml
│ ├── metrics-prometheus.yaml
│ ├── metrics-svc.yaml
│ ├── networkpolicy.yaml
│ ├── NOTES.txt
│ ├── redis-master-statefulset.yaml
│ ├── redis-master-svc.yaml
│ ├── redis-rolebinding.yaml
│ ├── redis-role.yaml
│ ├── redis-serviceaccount.yaml
│ ├── redis-slave-statefulset.yaml
│ ├── redis-slave-svc.yaml
│ ├── redis-with-sentinel-svc.yaml
│ └── secret.yaml
├── values-production.yaml
└── values.yaml
directories, files
//模板语法
[root@master archive]# cat redis/templates/redis-master-statefulset.yaml
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
name: {{ template "redis.fullname" . }}-master
labels:
app: {{ template "redis.name" . }}
chart: {{ template "redis.chart" . }}
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
spec:
selector:
matchLabels:
release: "{{ .Release.Name }}"
role: master
app: {{ template "redis.name" . }}
serviceName: {{ template "redis.fullname" . }}-headless
template:
metadata:
labels:
release: "{{ .Release.Name }}"
chart: {{ template "redis.chart" . }}
role: master
app: {{ template "redis.name" . }}
{{- if .Values.master.podLabels }}
{{ toYaml .Values.master.podLabels | indent }}
{{- end }}
annotations:
checksum/health: {{ include (print $.Template.BasePath "/health-configmap.yaml") . | sha256sum }}
checksum/configmap: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- if .Values.master.podAnnotations }}
{{ toYaml .Values.master.podAnnotations | indent }}
{{- end }}
spec:
{{- include "redis.imagePullSecrets" . | indent }}
{{- if .Values.securityContext.enabled }}
securityContext:
fsGroup: {{ .Values.securityContext.fsGroup }}
{{- end }}
serviceAccountName: "{{ template "redis.serviceAccountName" . }}"
{{- if .Values.master.priorityClassName }}
priorityClassName: "{{ .Values.master.priorityClassName }}"
{{- end }}
{{- with .Values.master.affinity }}
affinity:
{{ tpl (toYaml .) $ | indent }}
{{- end }}
{{- if .Values.master.nodeSelector }}
nodeSelector:
{{ toYaml .Values.master.nodeSelector | indent }}
{{- end }}
{{- if .Values.master.tolerations }}
tolerations:
{{ toYaml .Values.master.tolerations | indent }}
{{- end }}
{{- if .Values.master.schedulerName }}
schedulerName: "{{ .Values.master.schedulerName }}"
{{- end }}
containers:
- name: {{ template "redis.fullname" . }}
image: "{{ template "redis.image" . }}"
imagePullPolicy: {{ .Values.image.pullPolicy | quote }}
{{- if .Values.securityContext.enabled }}
securityContext:
runAsUser: {{ .Values.securityContext.runAsUser }}
{{- end }}
command:
- /bin/bash
- -c
- |
if [[ -n $REDIS_PASSWORD_FILE ]]; then
password_aux=`cat ${REDIS_PASSWORD_FILE}`
export REDIS_PASSWORD=$password_aux
fi
if [[ ! -f /opt/bitnami/redis/etc/master.conf ]];then
cp /opt/bitnami/redis/mounted-etc/master.conf /opt/bitnami/redis/etc/master.conf
fi
if [[ ! -f /opt/bitnami/redis/etc/redis.conf ]];then
cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf
fi
ARGS=("--port" "${REDIS_PORT}")
{{- if .Values.usePassword }}
ARGS+=("--requirepass" "${REDIS_PASSWORD}")
{{- else }}
ARGS+=("--protected-mode" "no")
{{- end }}
ARGS+=("--include" "/opt/bitnami/redis/etc/redis.conf")
ARGS+=("--include" "/opt/bitnami/redis/etc/master.conf")
{{- if .Values.master.command }}
{{ .Values.master.command }} ${ARGS[@]}
{{- else }}
redis-server "${ARGS[@]}"
{{- end }}
env:
- name: REDIS_REPLICATION_MODE
value: master
{{- if .Values.usePassword }}
{{- if .Values.usePasswordFile }}
- name: REDIS_PASSWORD_FILE
value: "/opt/bitnami/redis/secrets/redis-password"
{{- else }}
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "redis.secretName" . }}
key: redis-password
{{- end }}
{{- else }}
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
{{- end }}
- name: REDIS_PORT
value: {{ .Values.redisPort | quote }}
ports:
- name: redis
containerPort: {{ .Values.redisPort }}
{{- if .Values.master.livenessProbe.enabled }}
livenessProbe:
initialDelaySeconds: {{ .Values.master.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.master.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.master.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.master.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.master.livenessProbe.failureThreshold }}
exec:
command:
- sh
- -c
- /health/ping_local.sh {{ .Values.master.livenessProbe.timeoutSeconds }}
{{- end }}
{{- if .Values.master.readinessProbe.enabled}}
readinessProbe:
initialDelaySeconds: {{ .Values.master.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.master.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.master.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.master.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.master.readinessProbe.failureThreshold }}
exec:
command:
- sh
- -c
- /health/ping_local.sh {{ .Values.master.livenessProbe.timeoutSeconds }}
{{- end }}
resources:
{{ toYaml .Values.master.resources | indent }}
volumeMounts:
- name: health
mountPath: /health
{{- if .Values.usePasswordFile }}
- name: redis-password
mountPath: /opt/bitnami/redis/secrets/
{{- end }}
- name: redis-data
mountPath: {{ .Values.master.persistence.path }}
subPath: {{ .Values.master.persistence.subPath }}
- name: config
mountPath: /opt/bitnami/redis/mounted-etc
- name: redis-tmp-conf
mountPath: /opt/bitnami/redis/etc/
{{- if and .Values.cluster.enabled .Values.sentinel.enabled }}
- name: sentinel
image: "{{ template "sentinel.image" . }}"
imagePullPolicy: {{ .Values.sentinel.image.pullPolicy | quote }}
{{- if .Values.securityContext.enabled }}
securityContext:
runAsUser: {{ .Values.securityContext.runAsUser }}
{{- end }}
command:
- /bin/bash
- -c
- |
if [[ -n $REDIS_PASSWORD_FILE ]]; then
password_aux=`cat ${REDIS_PASSWORD_FILE}`
export REDIS_PASSWORD=$password_aux
fi
if [[ ! -f /opt/bitnami/redis-sentinel/etc/sentinel.conf ]];then
cp /opt/bitnami/redis-sentinel/mounted-etc/sentinel.conf /opt/bitnami/redis-sentinel/etc/sentinel.conf
{{- if .Values.usePassword }}
printf "\nsentinel auth-pass {{ .Values.sentinel.masterSet }} $REDIS_PASSWORD" >> /opt/bitnami/redis-sentinel/etc/sentinel.conf
{{- end }}
fi
echo "Getting information about current running sentinels"
# Get information from existing sentinels
existing_sentinels=$(timeout -s {{ .Values.sentinel.initialCheckTimeout }} redis-cli --raw -h {{ template "redis.fullname" . }} -a $REDIS_PASSWORD -p {{ .Values.sentinel.service.sentinelPort }} SENTINEL sentinels {{ .Values.sentinel.masterSet }})
echo "$existing_sentinels" | awk -f /health/parse_sentinels.awk | tee -a /opt/bitnami/redis-sentinel/etc/sentinel.conf redis-server /opt/bitnami/redis-sentinel/etc/sentinel.conf --sentinel
env:
{{- if .Values.usePassword }}
{{- if .Values.usePasswordFile }}
- name: REDIS_PASSWORD_FILE
value: "/opt/bitnami/redis/secrets/redis-password"
{{- else }}
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ template "redis.secretName" . }}
key: redis-password
{{- end }}
{{- else }}
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
{{- end }}
- name: REDIS_SENTINEL_PORT
value: {{ .Values.sentinel.port | quote }}
ports:
- name: redis-sentinel
containerPort: {{ .Values.sentinel.port }}
{{- if .Values.sentinel.livenessProbe.enabled }}
livenessProbe:
initialDelaySeconds: {{ .Values.sentinel.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.sentinel.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.sentinel.livenessProbe.timeoutSeconds }}
successThreshold: {{ .Values.sentinel.livenessProbe.successThreshold }}
failureThreshold: {{ .Values.sentinel.livenessProbe.failureThreshold }}
exec:
command:
- sh
- -c
- /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }}
{{- end }}
{{- if .Values.sentinel.readinessProbe.enabled}}
readinessProbe:
initialDelaySeconds: {{ .Values.sentinel.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.sentinel.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.sentinel.readinessProbe.timeoutSeconds }}
successThreshold: {{ .Values.sentinel.readinessProbe.successThreshold }}
failureThreshold: {{ .Values.sentinel.readinessProbe.failureThreshold }}
exec:
command:
- sh
- -c
- /health/ping_sentinel.sh {{ .Values.sentinel.livenessProbe.timeoutSeconds }}
{{- end }}
resources:
{{ toYaml .Values.sentinel.resources | indent }}
volumeMounts:
- name: health
mountPath: /health
{{- if .Values.usePasswordFile }}
- name: redis-password
mountPath: /opt/bitnami/redis/secrets/
{{- end }}
- name: redis-data
mountPath: {{ .Values.master.persistence.path }}
subPath: {{ .Values.master.persistence.subPath }}
- name: config
mountPath: /opt/bitnami/redis-sentinel/mounted-etc
- name: sentinel-tmp-conf
mountPath: /opt/bitnami/redis-sentinel/etc/
{{- end }}
{{- $needsVolumePermissions := and .Values.volumePermissions.enabled (and ( and .Values.master.persistence.enabled (not .Values.persistence.existingClaim) ) .Values.securityContext.enabled) }}
{{- if or $needsVolumePermissions .Values.sysctlImage.enabled }}
initContainers:
{{- if $needsVolumePermissions }}
- name: volume-permissions
image: "{{ template "redis.volumePermissions.image" . }}"
imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }}
command: ["/bin/chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }}", "{{ .Values.master.persistence.path }}"]
securityContext:
runAsUser:
resources:
{{ toYaml .Values.volumePermissions.resources | indent }}
volumeMounts:
- name: redis-data
mountPath: {{ .Values.master.persistence.path }}
subPath: {{ .Values.master.persistence.subPath }}
{{- end }}
{{- if .Values.sysctlImage.enabled }}
- name: init-sysctl
image: {{ template "redis.sysctl.image" . }}
imagePullPolicy: {{ default "" .Values.sysctlImage.pullPolicy | quote }}
resources:
{{ toYaml .Values.sysctlImage.resources | indent }}
{{- if .Values.sysctlImage.mountHostSys }}
volumeMounts:
- name: host-sys
mountPath: /host-sys
{{- end }}
command:
{{ toYaml .Values.sysctlImage.command | indent }}
securityContext:
privileged: true
runAsUser:
{{- end }}
{{- end }}
volumes:
- name: health
configMap:
name: {{ template "redis.fullname" . }}-health
defaultMode:
{{- if .Values.usePasswordFile }}
- name: redis-password
secret:
secretName: {{ template "redis.secretName" . }}
{{- end }}
- name: config
configMap:
name: {{ template "redis.fullname" . }}
{{- if not .Values.master.persistence.enabled }}
- name: "redis-data"
emptyDir: {}
{{- else }}
{{- if .Values.persistence.existingClaim }}
- name: "redis-data"
persistentVolumeClaim:
claimName: {{ .Values.persistence.existingClaim }}
{{- end }}
{{- end }}
{{- if .Values.sysctlImage.mountHostSys }}
- name: host-sys
hostPath:
path: /sys
{{- end }}
- name: redis-tmp-conf
emptyDir: {}
{{- if and .Values.cluster.enabled .Values.sentinel.enabled }}
- name: sentinel-tmp-conf
emptyDir: {}
{{- end }}
{{- if and .Values.master.persistence.enabled (not .Values.persistence.existingClaim) }}
volumeClaimTemplates:
- metadata:
name: redis-data
labels:
app: "{{ template "redis.name" . }}"
component: "master"
release: {{ .Release.Name | quote }}
heritage: {{ .Release.Service | quote }}
spec:
accessModes:
{{- range .Values.master.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.master.persistence.size | quote }}
{{- if .Values.master.persistence.storageClass }}
{{- if (eq "-" .Values.master.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: {{ .Values.master.persistence.storageClass | quote }}
{{- end }}
{{- end }}
{{- end }}
updateStrategy:
type: {{ .Values.master.statefulset.updateStrategy }}
{{- if .Values.master.statefulset.rollingUpdatePartition }}
{{- if (eq "Recreate" .Values.master.statefulset.updateStrategy) }}
rollingUpdate: null
{{- else }}
rollingUpdate:
partition: {{ .Values.master.statefulset.rollingUpdatePartition }}
{{- end }}
{{- end }}
用法:
https://helm.sh/docs/
https://www.kubernetes.org.cn/3435.html
Kubernetes的包管理工具Helm的安装和使用的更多相关文章
- 云原生之旅 - 5)Kubernetes时代的包管理工具 Helm
前言 上一篇文章 [基础设施即代码 使用 Terraform 创建 Kubernetes] 教会了你如何在Cloud上面建Kubernetes资源,那么本篇来讲一下如何在Kubernetes上面部署应 ...
- Helm:kubernetes应用包管理工具
概要 Helm:kubernetes应用包管理工具 K8s部署应用的时候,应用会通过yaml描述信息调用K8s-api:Helm即是管理这些Yaml的应用包管理工具 组成 Helm包含5个部分 Hel ...
- Kubernetes-17:Kubernets包管理工具—>Helm介绍与使用
Kubernets包管理工具->Helm 什么是Helm? 我们都知道,Linux系统各发行版都有自己的包管理工具,比如Centos的YUM,再如Ubuntu的APT. Kubernetes也有 ...
- iOS包管理工具Cocoapods的安装与使用
转自:http://www.sxt.cn/u/10014/blog/6448 在我们开发移动应用的时候,一般都会使用到第三方工具,而由于第三方类库的种类繁多,我们在项目中进行管理也会相对麻烦,所以此时 ...
- Helm包管理工具(简介、安装、方法)
认识Helm 每次我们要部署一个应用都需要写一个配置清单(维护一套yaml文件),但是每个环境又不一样.部署一套新的环境成本是真的很高.如果我们能够使用类似于yum的工具来安装我们的应用的话那就太好了 ...
- k8s包管理工具helm - 介绍和安装
目录 1.Kubernetes 应用部署的挑战 2.Helm 是什么 3.Helm 组件及相关术语 4.Helm 工作原理 5.Helm 安装 5.1 客户端安装 5.2 安装服务端 Tiller 5 ...
- k8s的应用包管理工具helm的部署和使用
1.概述 我们一般是在k8s里面部署一些简单的应用,比如用deployment,daemonset,statefuleset的方式来部署应用,但是如果要部署一些复杂的应用,那么整个配置的编写.部署的过 ...
- $python包管理工具pip的安装和使用
pip是python的一个非常好用的包管理工具,可以用来很方便地安装和管理各种三方库,本文对其基本用法进行介绍. 安装pip Windows系统上安装 python 2.7.9及以上版本的window ...
- windows包管理工具和 ssh安装
Chocolatey windows下的包管理工具 https://chocolatey.org/ cmd里执行 @"%SystemRoot%\System32\WindowsPowerSh ...
随机推荐
- could not load the tomcat server configuration ...
参考文档: https://blog.csdn.net/u013381651/article/details/51567758 问题解决. 原因是你把项目里的tomcat的server项目也关闭了, ...
- javascript 跨域问题 jsonp
转载:http://www.cnblogs.com/choon/p/5393682.html demo 用动态创建<script></script>节点的方式实现了跨域HTTP ...
- Homestead 安装其它的PHP版本
运行环境: 系统: win10 软件: virtualbox 6.2 vagrant 2.2.4 homestead 7.1.0 sudo apt-get update sudo apt-get -y ...
- 解决小程序sessionid不一致
由于小程序端两次请求的 sessionid 不一致, 导致后端无法取得 session,解决办法:在登录时获取sessionid //第一次请求登录接口时保存到sessionid中 success: ...
- JAVA SE Download
{ //https://www.oracle.com/technetwork/java/javase/downloads/index.html }
- 【NOI2019模拟2019.6.27】B (生成函数+整数划分dp|多项式exp)
Description: \(1<=n,k<=1e5,mod~1e9+7\) 题解: 考虑最经典的排列dp,每次插入第\(i\)大的数,那么可以增加的逆序对个数是\(0-i-1\). 不难 ...
- 同构图+思维构造——牛客多校第六场E
考的其实是同构图的性质: 1.同构图的顶点数,边数相等 2.同构图通过点的映射后邻接矩阵相同 这篇博客讲的很好https://www.jianshu.com/p/c33b5d1b4cd9 本题还需要一 ...
- PAT_A1086#Tree Traversals Again
Source: PAT A1086 Tree Traversals Again (25 分) Description: An inorder binary tree traversal can be ...
- HTTPS客户端的java实现
目录 https客户端 指定ssl算法套 浏览器可以作为客户端向服务器发送Http请求,当需要访问后台或第三方Restful接口时,也可以用java实现客户端直接发get/post请求,获取数据. h ...
- varnish(转http://www.ttlsa.com/nginx/varnish-4-configure-file/)
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ...