目录
Deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.19
ports:
- containerPort: 80
Service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: web
name: web
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: web
Ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
spec:
rules:
- host: web.linux.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
| completion | 命令补全,source <(helm completion bash) |
| create | 创建一个chart并指定名字 |
| history | 获取release历史 |
| install | 安装一个chart |
| list | 列出release |
|
|
|
|
|
|
|
|
|
|
|
|
| package | 将chart目录打包到chart存档文件中 |
| pull | 从远程仓库中下载chart并解压到本地 # helm pull stable/mysql --untar |
| repo | 添加,列出,移除,更新和索引chart仓库。可用子命令:add、index、list、remove、update |
|
|
|
|
|
|
|
|
|
|
|
|
| help | 命令的帮助文档 |
| dependency | 管理chart依赖 |
| get | 下载一个release。可用子命令:all、hooks、manifest、notes、values |
下面我们来直接使用它:
使用helm前这里插个故障我之前遇到的,因为集群是二进制搭建的 k8s的config文件并不在~/.kube目录下,所以使用时报错:
charts:目录里存放这个chart依赖的所有子chart。 #这个我没有使用
Chart.yaml:用于描述这个 Chart的基本信息,包括名字、描述信息以及版本等。#只用于描述。
values.yaml :用于存储 templates 目录中模板文件中用到变量的值。
templates: 目录里面存放所有yaml模板文件。

NOTES.txt :用于介绍Chart帮助信息, helm install 部署后展示给用户。例如:如何使用这个 Chart、列出缺省的设置等。
_helpers.tpl:放置模板的地方,可以在整个chart中重复使用。
helm install web mychart #部署一个示例chart,示例这里是一个nginx。


这是一个官方的chart,演示示例。
我这边不用它的示例,我们自己动手写一个chart。
mkdir test-chart
cd test-chart
touch values.yaml #先创建后面添加变量
mkdir templates
cat > Chart.yaml <<EOF #这里我只是删除了示例里的注释信息。
apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: test-chart
type: application
version: 0.1.0
EOF
cd templates
touch _helpers.tpl
touch NOTES.txt
#创建一个deployment
kubectl create deployment web --image=nginx --dry-run=client -o yaml > deployment.yaml
#创建一个service用NodePort方式暴露方便测试,因为我是用的iptables转发没用使用ipvs模式,不能直接访问。
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort --dry-run=client -o yaml > service.yaml
echo hello! > NOTES.txt
#这就已经完成了一个基础的chart,部署之后可以查看版本。
helm install web /root/test-chart/ -n test #指定在test名称空间部署
helm ls -n test #查看chart列表
kubectl get pod,svc,ep -n test -o wide #查看资源部署情况
#更新与回滚测试
sed -i "s/1.16.0/1.17.0/" /root/test-chart/Chart.yaml
helm upgrade web /root/test-chart/ -n test
sed -i "s/1.17.0/1.18.0/" /root/test-chart/Chart.yaml
helm upgrade web /root/test-chart/ -n test
#这里做2个版本升级用于测试回滚
helm history web -n test

helm rollback web 1 -n test#默认不指定版本是回滚到上一个版本,我这里指定了版本号“1”。
#到这里已经学会了helm的基本使用,但是这个不是我们使用helm的最终目的,helm的强大之处在于它的模板渲染功能,下面我们学习模板使用。
--------------------------------------------------------------------------------------------------------------------------------
在做模板之前,我们要知道每个yaml文件的差异化信息,这里大致整理了一下以下几点:
1.应用名称
2.标签
3.镜像和tag
4.端口
5.命名空间
6.数据卷
7.副本数量
8.资源限制
|
| 作用 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#helm 动态传参演示。
#/root/test-chart/values.yaml
#存储yaml文件渲染时的默认值,以后部署只修改这个文件的参数。
#参考刚刚我们使用helm create mychart 的目录里的values.yaml
#默认副本数
replicaCount: 1
#默认使用的镜像
image:
repository: nginx
tag: "latest"
---
#/root/test-chart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Release.Name }}
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
strategy: {}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: nginx
resources: {}
---
#/root/test-chart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: {{ .Release.Name }}
type: NodePort


#这里默认values文件里使用的nginx镜像,使用set命令将它更改成httpd。

如果执行helm upgrade web3 /root/test-chart/ --set image.tag=1.19 -n test
我这里web3是一个httpd,在执行完指定版本更新后,是否会变更release的镜像?

做到这里时会发现,如果用命令行执行了set变更了values的值,我又没有写入到文件,我该怎么查询我做的更改?
这里可以使用get命令获取:
helm get values web3 -n test
helm get manifest web3 -n test 则可以获取这个release部署的所有yaml文件内容:
然后会发现我获取的是我当前版本的yaml,那我需要获取的是某个部署失败或者部署错误的yaml文件来拍错,例如我之前部署的httpd版本yaml文件我该怎么查询?
这里可以是用参数 --revesion ,通history查询到报错的版本,我这里是版本号1.
helm history -n test web3 #查询到版本号
helm get manifest --revision=1 web3 -n test #指定版本号查询release所渲染的yaml文件。

我们会发现在使用set命令,只指定了values.yaml里的的tag参数时,默认也会读取image的信息,当我不想让它读取默认values.yaml里的其他参数时,我们也可以指定一个自定义需要变更的values文件来更新,不要对原有values.yaml来操作。
cat >/tmp/test.yaml <<EOF
image:
repository: nginx
tag: "1.20"
EOF
helm upgrade web3 /root/test-chart/ -f /tmp/test.yaml -n test

| yaml | set |
| name: value | --set name=value |
| a:b c:d | --set a=b,c=d |
| outer: inner: value | --set outer.inner=value |
| name: - a - b - c | --set name={a,b,c} |
| servers: - port: 80 | --set servers[0].port=80 |
| servers: - port: 80 host: example | --set servers[0].port=80,servers[0].host=example |
| name: "value1,value2" | --set name=value1\,value2 |
| nodeSelector: kubernetes.io/role: master | --set nodeSelector."kubernetes\.io/role"=master |
Chart模板:调试
我们在创建完chart时往往不确定渲染出来的yaml是否是自己所需要的,这是可以使用调试命令查看所渲染的yaml文件。
helm template /root/test-chart/ #直接本地渲染,使用了Releaes.Name处使用占位符显示,因为我们没有提供release的名称。
helm install web4 /root/test-chart/ -n test --dry-run #使用--dry-run 则会直接完整显示release所渲染的结果。

Chart模板:函数与管道
在deployment.yaml增加函数quote 解决

渲染结果:
indent和nindent:都是缩进字符串,主要区别在于nindent会在缩进前多添加一个换行符。
渲染结果:
渲染结果:
cat > /root/test-chart/templates/configmap.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-test
data:
config.yaml: |
{{ .Files.Get "redis.properties" | indent 4 }} #引用chart根目录下的redis.properties文件内容
EOF
cat > /root/test-chart/redis.properties << EOF
redis.host=127.0.0.1
redis.port=6379
redis.passwd=123456
EOF
helm install web4 /root/test-chart/ -n test --dry-run #渲染测试
Files.Glob方法返回所有匹配的文件路径列表,当多个文件时,可以更灵活提取某些文件。
mkdir /root/test-chart/files
mv /root/test-chart/redis.properties /root/test-chart/files
cat >/root/test-chart/files/mysql.properties << EOF
mysql.host=127.0.0.1
mysql.port=3306
EOF
cat >/root/test-chart/templates/configmap << EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-test
data:
{{- $root := . }} #设置作用域为chart根目录
{{- range $path,$bytes := .Files.Glob "files/*.properties" }} #将文件名称赋值给path
{{ base $path }}: | #打印出文件名称
{{ $root.Files.Get $path |indent 4 }} #获取文件内容
{{- end -}} #循环结束符
EOF
helm install web4 /root/test-chart/ -n test --dry-run #渲染模板
#这个步骤我留了一个坑,做到这里就会发现^^
测试渲染结果:
流程控制之if/else
在templates目录下创建ingress.yaml,并在yaml文件增加if判断,为true时执行。
helm install web4 /root/test-chart/ -n test --dry-run --set ingress.enabled=true#默认不部署ingress,执行ingress.enabled=true则部署
如果值为以下几种情况则为false:
一个布尔类型 false
一个数字 0
一个空的字符串
一个 nil(空或 null)
一个空的集合( map、 slice、 tuple、 dict、 array)
条件表达式也支持操作符:
eq 等于
ne 不等于
lt 小于
gt 大于
and 逻辑与
or 逻辑或

#增加if判断后,渲染出来的模板有空行,增加减号删除空行。



流程控制之range
range相当于shell的for循环。
configmap.yaml:
流程控制之with
deployment.yaml
渲染结果:

变量:
# values.yaml
env:
NAME: "wang"
CLASS: "graduate"
#deployment.yaml
env:
{{- range $k,$v := .Values.env }}
- name: {{ $k }}
value: {{ $v }}
{{- end }}
渲染结果:
# cat templates/_helpers.tpl
{{- define "fullname" -}}
{{- .Chart.Name -}}-{{ .Release.Name }}
{{- end -}}
# cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Release.Name |indent 6}}
app: {{ .Release.Name |nindent 6}}
name: {{ include "fullname" . }}
渲染结果:

[root@k8s-master ~]# mkdir example-chart/templates -p
[root@k8s-master ~]# cp mychart/Chart.yaml example-chart/
[root@k8s-master ~]# touch example-chart/values.yaml
[root@k8s-master ~]# touch example-chart/templates/{_helpers.tpl,NOTES.txt}
#Chart.yaml 删除空行与注释文件就保留以下信息,修改name字段为自己的chart名字----------
[root@k8s-master ~]# cat example-chart/Chart.yaml
apiVersion: v2
name: example-chart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
#为chart设置所有yaml都通用的模板资源-------------------------------
root@k8s-master templates]# cat _helpers.tpl
{{/*
注释模板
*/}}
{{/*
这个chart资源的名字
*/}}
{{- define "fullname" -}}
{{ .Chart.Name }}-{{.Release.Name }}
{{- end -}}
{{/*
标签
*/}}
{{- define "labels" -}}
chart_name: {{ .Chart.Name }}
instance_name: {{ .Release.Name }}
{{- end -}}
#为values设置常用参数------------------------------------
[root@k8s-master templates]# cat ../values.yaml
#副本数
replicaCount: 1
#镜像选择
image:
repository: nginx
tag: "latest"
#资源配额
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
#configmap开关,默认关闭
configmap:
enabled: false
#ingress开关,默认关闭
ingress:
enabled: false
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: nginx
host: www.checkqq.com
path: /
#service端口模式
service:
port: 80
targetport: 80
type: ClusterIP
#环境变量
env:
NAME: "wang"
CLASS: "graduate"
#存活检查
livenessProbe:
httpGet:
path: /
port: 80
#就绪检查
readinessProbe:
httpGet:
path: /
port: 80
#为configmap设置配置文件-----------------------------------
[root@k8s-master templates]# cat ../files/redis.properties ../files/mysql.properties
redis.host=127.0.0.1
redis.port=6379
----------------------------------分割线,前面为redis,后面为mysql
redis.passwd=123456
mysql.host=127.0.0.1
mysql.port=3306
#configmap.yaml 最终模板------------------------------------
[root@k8s-master templates]# cat configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "fullname" . }}
data:
{{- $root := . }} #设置作用域为chart根目录
{{- range $path,$bytes := .Files.Glob "files/*.properties" }} #将文件名称赋值给path
{{ base $path }}: | #打印出文件名称
{{ $root.Files.Get $path |indent 4 }} #获取文件内容
{{- end -}}
#deployment.yaml 最终模板------------------------------------
#[root@k8s-master templates]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "fullname" . }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "labels" . | nindent 6 }}
strategy: {}
template:
metadata:
labels:
{{- include "labels" . | nindent 8 }}
spec:
containers:
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: web
resources: {{ toYaml .Values.resources | nindent 10 }}
env:
{{- range $k,$v := .Values.env }}
- name: {{ $k }}
value: {{ $v }}
{{- end }}
{{- if .Values.livenessProbe }}
livenessProbe: {{ toYaml .Values.livenessProbe | nindent 10 }}
{{- end }}
{{- if .Values.readinessProbe }}
readinessProbe: {{ toYaml .Values.readinessProbe | nindent 10 }}
{{- end }}
#service.yaml 最终模板------------------------------------
[root@k8s-master templates]# cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "fullname" . }}
spec:
ports:
- port: {{ .Values.service.port }}
protocol: TCP
targetPort: {{ .Values.service.targetport }}
selector:
{{- include "labels" . | nindent 4}}
type: {{ .Values.service.type }}
#ingress.yaml 最终模板------------------------------------
[root@k8s-master templates]# cat ingress.yaml
{{ if .Values.ingress.enabled }} #如果ingress值为真启用ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "fullname" . }}
annotations:
{{- toYaml .Values.ingress.annotations | nindent 4 }}
spec:
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
- path: {{ .Values.ingress.path }}
pathType: Prefix
backend:
service:
name: {{ include "fullname" . }}
port:
number: {{ .Values.service.port }}
{{- end }}
#####最后的最后为我们的chart写入使用说明########
echo "这家伙很懒,什么也没写" > NOTES.txt
到这里,我们的chart已经书写完毕,接下来是平常该怎么使用的说明。
#对我们的chart进行打包
[root@k8s-master ~]# helm package example-chart/
Successfully packaged chart and saved it to: /root/example-chart-0.1.0.tgz
[root@k8s-master ~]# ls
anaconda-ks.cfg example-chart ingress-controller-1.1.yaml nfs-external-provisioner test-chart
calico.yaml example-chart-0.1.0.tgz linux-amd64 nfs-external-provisioner.zip
deployment.yaml helm-v3.6.0-linux-amd64.tar.gz mychart service.yaml
也就是这个example-chart-0.1.0.tgz,后续使用是直接用这个chart包
例如:[root@k8s-master templates]# helm install web /root/example-chart-0.1.0.tgz --dry-run -n test --dry-run --set ingress.enabled=true --set configmap.enabled=true --set replicaCount=3 --set image.tag=1.19 --set livenessProbe=false --set readinessProbe=false
#--set ingress.enabled=true values默认不启用部署ingress
#--set configmap.enabled=true values默认不启用部署configmap
#--set replicaCount=3 设置pod的副本数为3
#--set image.tag=1.19 设置镜像版本标签为1.19
#--set livenessProbe=false 不启用存活检查
#--set readinessProbe=false 不启用就绪检查
mkdir -p /root/.local/share/helm/plugins/helm-push
cd /root/.local/share/helm/plugins/helm-push
tar zxvf helm-push_0.9.0_linux_amd64.tar.gz
[root@k8s-master ~]# helm repo add --username admin --password Harbor12345 myrepo http://192.168.31.90/chartrepo/library
"myrepo" has been added to your repositories
[root@k8s-master helm-push]# helm repo list
NAME URL
myrepo http://192.168.31.90/chartrepo/library
[root@k8s-master ~]# helm repo list
NAME URL
myrepo http://192.168.31.90/chartrepo/library
[root@k8s-master ~]# helm repo update
[root@k8s-master ~]# helm push example-chart-0.1.0.tgz --username=admin --password=Harbor12345 http://192.168.31.90/chartrepo/library
Pushing example-chart-0.1.0.tgz to http://192.168.31.90/chartrepo/library...
Done.
[root@k8s-master ~]# helm install web2 --version 0.1.0 myrepo/example-chart --set image.repository=nginx --set ingress.enabled=true -n test
NAME: web2
LAST DEPLOYED: Mon Jul 11 01:08:15 2022
NAMESPACE: test
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
这家伙很懒,什么也没写

[root@k8s-master ~]# kubectl get pod,svc,ep -o wide -n test
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/example-chart-web-f7bc75db4-572hn 1/1 Running 0 11m 10.244.36.78 k8s-node1 <none> <none>
pod/example-chart-web2-7455c75b88-754xn 1/1 Running 0 38s 10.244.36.79 k8s-node1 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/example-chart-web ClusterIP 10.102.212.0 <none> 80/TCP 11m chart_name=example-chart,instance_name=web
service/example-chart-web2 ClusterIP 10.102.255.92 <none> 80/TCP 38s chart_name=example-chart,instance_name=web2
NAME ENDPOINTS AGE
endpoints/example-chart-web 10.244.36.78:80 11m
endpoints/example-chart-web2 10.244.36.79:80 38s
[root@k8s-master ~]#
这里我遇到个故障顺便记录下。
Error: Internal error occurred: failed calling webhook"validate.nginx.ingress.kubernetes.io": Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1/ingresses?timeout=10s": dial tcp 10.108.0.150:443: i/o timeout
#部署ingress报错删除ValidatingWebhookConfiguration。
kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission
最后通过部署的ingress测试刚刚部署的chart,域名+ingress的端口

我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po