文章目录
helm说明
什么是helm
-
helm是k8s的包管理工具,类似于centos的yum,k8s将管理的资源都抽象成api,并且推荐使用声明方式创建,修改,删除这些对象,每个 API 对象都通过一个 yaml 格式或者 json 格式的文本来声明。这带来的一个问题就是这些 API 对象声明文本的管理成本,每当我需要创建一个应用,都需要去编写一堆这样的声明文件,helm就是管理这些api对象的工具,它把创建一个应用所需的所有 Kubernetes API 对象声明文件组合并打包在一起。并提供了仓库的机制便于分发共享,还支持模版变量替换,同时还有版本的概念,使之能够对一个应用进行版本的管理。
-
Helm chart 是用来封装 Kubernetes 原生应用程序的 YAML 文件,可以在你部署应用的时候自定义应用程序的一些 metadata,便与应用程序的分发。
-
Helm 和 chart 的主要作用是:
- 1.应用程序封装
- 2.版本管理
- 3.依赖检查
- 4.便于应用程序分发
-
Helm 可以安装本地或者远程的 chart,当 chart 安装到 Kubernetes 中后就会创建一个 release,每次更新该 chart 的配置并执行 helm upgrade, release 的版本数就会加 1。同一个 chart 可以部署多次
helm 的架构
- 前面我们在使用wordpress+MySQL 部署博客应用的时候,需要做许多的工作,需要每个pod创建pv 和pvc,然后分别创建每个应用的pod 及svc,整个过程非常的麻烦。
- 如果搭建博客所有步骤作为一个整体,放在一个文件夹里(叫做chart),以后我们直接使用这个chart 就可以把所有的操作一次性做完,这样很容易实现了一个博客应用(chart 的一个实例,叫做release),就非常的方便了。这个就类似于我们用虚拟机模板去克隆出来一台台的虚拟机,这样就省的在一台台的去安装了,这个模板就是chart,克隆出来的虚拟机就是release。
- helm 实现的就是这样的功能,在互联网上存在chart 仓库(也可以自己搭建)包括了各种应用,我们需要什么应用直接拉取部署即可。
- 在helm 2.X 版本的时候,helm 是一种C/S 结构的应用,包括helm 客户端和tiller 服务器端,用户通过helm 客户端向tiller 服务端发送部署请求,tiller 服务端和kubernetes 的apiserver进行交互然后部署。
Helm 常用命令
helm create
:在本地创建新的 chart;helm dependency
:管理 chart 依赖;helm intall
:安装 chart;helm lint
:检查 chart 配置是否有误;helm list
:列出所有 release;helm package
:打包本地 chart;helm repo
:列出、增加、更新、删除 chart 仓库;helm rollback
:回滚 release 到历史版本;helm pull
:拉取远程 chart 到本地;helm search
:使用关键词搜索 chart;helm uninstall
:卸载 release;helm upgrade
:升级 release;
作者:戈羽殇雪
链接:https://www.jianshu.com/p/6edc5ede7177
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
环境准备
- 首先需要有一套集群
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 111d v1.21.0
node1 Ready <none> 110d v1.21.0
node2 Ready <none> 110d v1.21.0
[root@master ~]#
- 然后我们创建一个文件用来放后面的测试文件,创建一个命名空间,后面测试都在这个命名空间做
[root@master ~]# mkdir helm
[root@master ~]# cd helm
[root@master helm]# kubectl create ns helm
namespace/helm created
[root@master helm]# kubens helm
Context "context" modified.
Active namespace is "helm".
[root@master helm]#
helm安装
安装文件和脚本准备
- 如果下面弄不了,可以直接打包我文件里面的,这里面有后面所有需要用到的镜像和代码文件
- 下载安装helm 的脚本
[root@master helm]# curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get
- 这个网站需要配置解析,如果linux解析不了,可以在windows上解析,然后打开这个网址,把内容复制到linux 的文件中即可
修改安装脚本内容
- get文件里面找到下面原文中的3个内容,并做相关修改【下面有说明】
[root@master helm]# cat get | wc -l
306
[root@master helm]#
#1:这是自动拉取最新版本的,我们需要注释掉这部分内容,并且指定当前版本,不然因为无法访问该网址而失败。
checkDesiredVersion() {
if [ "x$DESIRED_VERSION" == "x" ]; then
# Get tag from release URL
local latest_release_url="https://github.com/helm/helm/releases"
if [ "${HAS_CURL}" == "true" ]; then
TAG=$(curl -Ls $latest_release_url | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1)
elif [ "${HAS_WGET}" == "true" ]; then
TAG=$(wget $latest_release_url -O - 2>&1 | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1)
fi
else
TAG=$DESIRED_VERSION
fi
}
#2:这个就是存放上面下载内容的路径定义,因为我们已经下载了这个sha256的文件,所以这也需要修改。
downloadFile() {
HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz"
DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST"
CHECKSUM_URL="$DOWNLOAD_URL.sha256"
HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)"
HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST"
HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256"
echo "Downloading $DOWNLOAD_URL"
if [ "${HAS_CURL}" == "true" ]; then
curl -SsL "$CHECKSUM_URL" -o "$HELM_SUM_FILE"
curl -SsL "$DOWNLOAD_URL" -o "$HELM_TMP_FILE"
elif [ "${HAS_WGET}" == "true" ]; then
wget -q -O "$HELM_SUM_FILE" "$CHECKSUM_URL"
wget -q -O "$HELM_TMP_FILE" "$DOWNLOAD_URL"
fi
}
#3: 检测上面的下载内容,如果检测不通过,就不让安装,所以得吧这判断删了
verifyChecksum() {
printf "Verifying checksum... "
local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}')
local expected_sum=$(cat ${HELM_SUM_FILE})
if [ "$sum" != "$expected_sum" ]; then
echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting."
exit 1
fi
echo "Done."
}
- 修改后成这样【我这使用的是v3.2.1】
改成这样以后呢,就表示,使用这个版本
#1:指定当前版本
checkDesiredVersion() {
TAG=v3.2.1
}
#2:get文件和sha256文件需要在同一路径哈
downloadFile() {
HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz"
DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST"
CHECKSUM_URL="$DOWNLOAD_URL.sha256"
HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)"
HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST"
HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256"
echo "Downloading $DOWNLOAD_URL"
cp helm-v3.2.1* $HELM_TMP_ROOT
}
#3: 不让判断文件是否存在。
verifyChecksum() {
printf "Verifying checksum... "
local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}')
local expected_sum=$(cat ${HELM_SUM_FILE})
echo "Done."
}
- 上面3项修改完毕以后呢,保存退出,并给x权限,然后执行该脚本
[root@master helm]# chmod +x get
[root@master helm]# ./get
Downloading https://get.helm.sh/helm-v3.2.1-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
[root@master helm]#
执行安装并检测与卸载说明
- 上面呢helm就装完了【此时是不能使用tab的】
我们查看下版本,能出现版本内容就算安装成功
[root@master helm]# helm version
version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}
[root@master helm]#
- 上面安装的时候有提示将helm安装到这个路径
所以我们卸载呢就是删除掉该路径内容即可
helm installed into /usr/local/bin/helm
helm子命令使用teb操作
- 方式1
前面我们的kubectl也是使用的 这种方式
[root@master helm]# cat /etc/profile | head -n 4
# /etc/profile
source <(kubectl completion bash)
source <(helm completion bash) # 增加改行内容
[root@master helm]#
[root@master helm]# source /etc/profile
[root@master helm]#
[root@master helm]# hel
helm help
[root@master helm]# helm version
version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}
[root@master helm]#
- 方式2
上面做了就不能再用这个方式了。知道就行
[root@vms10 ~]# helm completion bash > ~/.helmrc
[root@vms10 ~]# echo "source ~/.helmrc" >> ~/.bashrc
[root@vms10 ~]#
[root@vms10 ~]# source .bashrc
[root@vms10 ~]#
helm仓库管理
- 因为这个玩意需要外网才能使用,而我的集群是没有外网的,所以下面只放文档,不做实验,这个其实不难,如果下面理解有难度,可以自行百度查阅困惑内容的相关资料。
配置国内helm源
- 查看现在使用的仓库:
[root@vms10 ~]# helm repo list
Error: no repositories to show
[root@vms10 ~]#
- 国内常用的仓库有:
- 阿里云的源
https://apphub.aliyuncs.com
【建议用这个】 - 微软azure 的源
http://mirror.azure.cn/kubernetes/charts/
- 阿里云的源
- 添加仓库的语法:
helm repo add 名称地址
- 下面把阿里云的源和azure 的源都添加过来:
[root@vms10 ~]# helm repo add azure http://mirror.azure.cn/kubernetes/charts/
"azure" has been added to your repositories
[root@vms10 ~]#
- 这里是吧zaure 的源添加过来,命名为azure
[root@vms10 ~]# helm repo add ali https://apphub.aliyuncs.com
"ali" has been added to your repositories
[root@vms10 ~]#
- 这里是把阿里云的源添加过来,命名为ali
查看现在正在使用的源:
[root@vms10 ~]# helm repo list
NAME URL
azure http://mirror.azure.cn/kubernetes/charts/
ali https://apphub.aliyuncs.com
[root@vms10 ~]#
部署应用【部署chart】
查询应用对应的chart
- 如果我们要部署哪个应用就到仓库里查询这个应用对应的chart,假设我要部署redis
[root@vms10 ~]# mkdir helm
[root@vms10 ~]# cd helm/
[root@vms10 ~]#
[root@vms10 helm]# helm search repo redis
NAME CHART VERSION APP VERSION
DESCRIPTION
ali/prometheus-redis-exporter 3.2.2 1.3.4 Prometheus exporter
for Redis metrics
ali/redis 10.5.3 5.0.7 Open source,
...
azure/redis 10.5.7 5.0.7 DEPRECATED
[root@vms10 helm]#
部署MySQL为例
- 下面开始部署MySQL
切换到ns5 命名空间进行操作
[root@vms10 helm]# kubectl create ns ns5
namespace/ns5 created
[root@vms10 helm]# kubens ns5
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "ns5".
[root@vms10 helm]#
- 下面开始部署MySQL
通过helm pull
单独把chart 下载下来,如下:
[root@vms10 helm]# helm pull azure/mysql
[root@vms10 helm]# ls
mysql-1.6.4.tgz
[root@vms10 helm]#
- 解压并进入到MySQL 目录,会有这么几个文件:
Chart.yaml
是chart 的描述信息README.md
是此chart 的帮助信息templates
目录里是各种模板,比如定义svc,定义pvc 等values.yaml
里记录的是chart 的各种信息,比如镜像是什么,root 密码是什么,是否使用持久性存储等
[root@vms10 helm]# cd mysql/
[root@vms10 mysql]# ls
Chart.yaml README.md templates values.yaml
[root@vms10 mysql]#
-
编辑values.yaml 并按照如下修改
指定自己要使用的镜像,按如下修改【其实就是些创建pod规则,有很多内容,不需要的选项可以注释掉,具体哪些不需要,不同应用有不同的规则。】
-
指定MySQL 的root 密码,注意这里前面不能留有空格:
-
如果要创建普通用户和密码,就修改如下两行,这里我们没有指定
-
是否要使用持久性存储,如果不使用的话就把enabled 的值改成false:
注意:可以用vim 编辑器搜索persistence。 -
关于values.yaml 的其他部分保持默认值即可,保存退出
安装&删除mysql
- 安装应用的命令为
helm install
名字chart 目录
在当前目录里执行安装操作:
[root@vms10 mysql]# helm install db . #最后的点,表示当前目录
NAME: db
LAST DEPLOYED: Tue Jun 9 13:05:58 2020
NAMESPACE: ns5
STATUS: deployed
...大量输出...
# Execute the following command to route the connection:
kubectl port-forward svc/db-mysql 3306
mysql -h ${MYSQL_HOST} -P${MYSQL_PORT} -u root -p${MYSQL_ROOT_PASSWORD}
[root@vms10 mysql]#
- 查看现在已经部署的release 及pod
[root@vms10 mysql]# helm ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
db ns5 1 2020-06-0...T deployed mysql-1.6.4 5.7.30
[root@vms10 mysql]#
[root@vms10 mysql]# kubectl get pods
NAME READY STATUS RESTARTS AGE
db-mysql-84f68ddfdc-m6xgq 1/1 Running 0 92s
[root@vms10 mysql]#
- 安装mariadb 客户端:
[root@vms10 mysql]# yum install mariadb -y
...输出...
作为依赖被升级:
mariadb-libs.x86_64 1:5.5.65-1.el7
完毕!
[root@vms10 mysql]#
- 查看mysql pod 的IP:
[root@vms10 mysql]# kubectl get pods -o wide --no-headers
db-mysql-84f68ddfdc-m6xgq 1/1 Running 0 3m18s 10.244.14.41 ...
[root@vms10 mysql]#
- 用mysql 命令连接到此pod 上:
[root@vms10 mysql]# mysql -uroot -predhat -h10.244.14.41
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 48.
...输出...
MySQL [(none)]> quit
Bye
[root@vms10 mysql]#
- 删除此release
[root@vms10 mysql]# helm delete db
release "db" uninstalled
[root@vms10 mysql]# helm ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
[root@vms10 mysql]#
搭建私有仓库
pod创建【node节点操作】
- 我们用nginx做测试【注意,这是在node节点操作的 】
首先需要确保本地80端口没有被占用,如果被占用,则先吧httpd服务停了【具体方法看下面占用解决方法】 - 在vms12 上用nginx 镜像创建一个容器,名字为c1
[root@vms12 ~]# docker run -dit --name=c1 -p 8080:80 -v /data:/usr/share/nginx/html/charts
docker.io/nginx
ca08a2ce9b8e910ed71f458fa3c7dd53843bf50e5bb92c089fdacf7cd65a1657
[root@vms12 ~]#
80端口被占用解决方法
- 这只是放一个node节点上有一个master上创建的nginx镜像时的处理方法。
# 看到80端口被一个容器占用了,在master上创建的
[root@node2 ~]# netstat -ntlp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 76761/nginx: master
tcp6 0 0 :::80 :::* LISTEN 76761/nginx: master
[root@node2 ~]#
#所以,得一个个的ns去找这个容器在哪。。。晕
[root@master helm]# kubectl get ns
NAME STATUS AGE
ccx Active 116d
ccxhero Active 116d
default Active 121d
deploy Active 61d
ds Active 59d
helm Active 101m
ingress-nginx Active 3d1h
job Active 53d
kube-node-lease Active 121d
kube-public Active 121d
kube-system Active 121d
metallb-system Active 3d19h
net Active 2d
ns1 Active 116d
pod-1 Active 107d
probe Active 57d
sec Active 67d
svc Active 52d
volume Active 75d
[root@master helm]# kubectl get pods -n ds
No resources found in ds namespace.
[root@master helm]# kubectl get pods -n helm
No resources found in helm namespace.
[root@master helm]# kubectl get pods -n ds
No resources found in ds namespace.
[root@master helm]# kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-rr5jq 0/1 Completed 0 3d1h
ingress-nginx-admission-patch-s2zjv 0/1 Completed 1 3d1h
ingress-nginx-controller-744d4fc6b7-56gkg 1/1 Running 2 3d1h
[root@master helm]# kubectl delete pod -n ingress-nginx ingress-nginx-controller-744d4fc6b7-56gkg
pod "ingress-nginx-controller-744d4fc6b7-56gkg" deleted
[root@master helm]#
# 删除以后呢,回到 该node节点,发现80端口没了
[root@node2 ~]# netstat -ntlp | grep 80
[root@node2 ~]#
- 创建一个pod
[root@node2 ~]# docker run -dit --name=web1 --restart=always -p 80:80 -v /mycharts:/usr/share/nginx/html/mycharts nginx
149c4eec2fe83c7d9fcc383ebc36239403b4d7775907ca89094e0e208d2f802a
[root@node2 ~]#
[root@node2 ~]# docker ps | grep web
149c4eec2fe8 nginx "/docker-entrypoint.…" 31 seconds ago Up 28 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web1
[root@node2 ~]#
[root@node2 ~]# !net
netstat -ntlp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 90725/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 90733/docker-proxy
[root@node2 ~]#
- 如果创建docker报错端口映射错误
重启docker即可
[root@node2 ~]# docker run -dit --name=web --restart=always -p 80:80 -v /mycharts:/usr/share/nginx/html/mycharts nginx
1d77aedda2a0f1c29d89b37654bea06b0d9125ab8c450ead78556f358323207c
docker: Error response from daemon: driver failed programming external connectivity on endpoint web (da25351be6b4e272f78849efac2a34f5105f6f4b7da1e04d0aca991441f6506a): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 80 -j DNAT --to-destination 172.17.0.2:80 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1)).
[root@node2 ~]# docker ps | grep nginx
[root@node2 ~]# docker images | grep nginx
liangjw/ingress-nginx-controller v1.0.1 c1f1d7be46ae 5 weeks ago 283MB
nginx latest d1a364dc548d 5 months ago 133MB
[root@node2 ~]# systemctl restart docker
[root@node2 ~]#
定义一个chart【master上操作】
- 在master 上自定义一个chart:
[root@vms10 ~]# mkdir mychar
[root@vms10 ~]#
[root@vms10 ~]# cd mychar/
[root@vms10 mychar]# helm create chart1
Creating chart1
[root@vms10 mychar]# cp -r ../mysql .
[root@vms10 mychar]#
[root@vms10 mychar]# ls
chart1 mysql
[root@vms10 mychar]#
- 对这两个chart 进行打包:
[root@vms10 mychar]# helm package chart1
Successfully packaged chart and saved it to: /root/mychar/chart1-0.1.0.tgz
[root@vms10 mychar]#
[root@vms10 mychar]# helm package mysql/
Successfully packaged chart and saved it to: /root/mychar/mysql-1.6.4.tgz
[root@vms10 mychar]#
[root@vms10 mychar]# ls
chart1 chart1-0.1.0.tgz mysql mysql-1.6.4.tgz
[root@vms10 mychar]#
- 给当前目录下的两个包建立索引文件,并指定私有仓库地址:
[root@vms10 mychar]# helm repo index . --url http://192.168.26.12:8080/charts
[root@vms10 mychar]#
[root@vms10 mychar]# ls
chart1 chart1-0.1.0.tgz index.yaml mysql mysql-1.6.4.tgz
[root@vms10 mychar]#
- 把当前目录下index.yaml 和后缀为tgz 的包全部拷贝192.168.26.12 的/data 目录里(请理解前面c1 容器数据卷的设置):
此时的index.yaml文件内容如下:
[root@vms10 mychar]# scp index.yaml *.tgz 192.168.26.12:/data
root@192.168.26.12's password:
index.yaml 100% 1192 1.1MB/s 00:00
chart1-0.1.0.tgz 100% 3572 2.5MB/s 00:00
mysql-1.6.4.tgz 100% 11KB 5.2MB/s 00:00
[root@vms10 mychar]#
- 切换到vms12 上【上面ip地址所属node】:
[root@vms12 ~]# ls /data/
index.yaml mychartxx-0.1.0.tgz mysql-1.6.2.tgz
[root@vms12 ~]# docker exec -it c1 \
> ls /usr/share/nginx/html/charts
index.yaml mychartxx-0.1.0.tgz mysql-1.6.2.tgz
[root@vms12 ~]#
- 切换到master 上,添加
http://192.168.26.12:8080/charts
作为仓库:
[root@vms10 mychar]# helm repo add myrepo http://192.168.26.12:8080/charts
"myrepo" has been added to your repositories
[root@vms10 mychar]#
[root@vms10 mychar]# helm repo list
NAME URL
azure http://mirror.azure.cn/kubernetes/charts/
ali https://apphub.aliyuncs.com
myrepo http://192.168.26.12:8080/charts
[root@vms10 mychar]#
- 搜索mysql 的chart:
可以看到除了在阿里云里可以找到mysql 的仓库之外,在我们自定义的仓库里也能找到mysql。
[root@vms10 mychar]# helm search repo mysql
NAME CHART VERSION APP VERSION DESCRIPTION
ali/mysql 6.8.0 8.0.19 Chart to create a
...输出...
azure/mysql 1.6.4 5.7.30 Fast, reliable, scalable,
myrepo/mysql 1.6.4 5.7.30 Fast, reliable, scalable,
[root@vms10 mychar]#
- 创建chart1:
出现下列内容以后呢,此时执行:kubectl get pods
是可以看到一个runing的pod的。
[root@vms10 mychar]# helm search repo chart1
NAME CHART VERSION APP VERSION DESCRIPTION
myrepo/chart1 0.1.0 1.16.0 A Helm chart for Kubernetes
[root@vms10 mychar]#
私有仓库配置完毕。
- 删除本地私有仓库地址:
[root@vms10 mychar]# helm repo remove myrepo
"myrepo" has been removed from your repositories
[root@vms10 mychar]#
今天的文章helm怎么打包一个chart_helm怎么打包一个chart分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/84152.html