文档地址:https://helm.sh/zh/docs/topics/charts/
通过下面命令创建一个chart,指定chart名:mychart
[root@Kubernetes charts]# helm create mychart
Creating mychart
[root@Kubernetes charts]# tree mychart
mychart
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
3 directories, 10 files
目录 | 介绍 |
---|---|
charts | 存放子chart的目录,目录里存放这个chart依赖的所有子chart |
Chart.yaml | 保存chart的基本信息,包括名字、描述信息及版本等,这个变量文件都可以被template目录下文件所引用 |
templates | 模板文件目录,目录里面存放所有yaml模板文件,包含了所有部署应用的yaml文件 |
templates/deployment.yaml | 创建deployment对象的模板文件 |
templates/_helpers.tpl_ | 放置模板助手的文件,可以在整个chart中重复使用,是放一些templates目录下这些yaml都有可能会用的一些模板 |
templates/hpa.yaml | |
templates/ingress.yaml | |
templates/NOTES.txt | 存放提示信息的文件,介绍chart帮助信息,helm install部署后展示给用户,如何使用chart等,是部署chart后给用户的提示信息 |
templates/serviceaccount.yaml | |
templates/service.yaml | |
templates/tests | 用于测试的文件,测试完部署完chart后,如web,做一个连接,看看是否部署成功 |
templates/tests/test-connection.yaml | 用于渲染模板的文件(变量文件,定义变量的值)定义templates目录下的yaml文件可能引用到的变量 |
values.yaml | values.yaml用于存储templates目录中模板文件中用到变量的值,这些变量定义都是为了让templates目录下yaml引用 |
编写一个chart,不引用内置对象的变量值(用HELM3发布创建一个ConfigMap,创建到K8s集群中,发布其他应用也一样,我们由浅入深进行学习)
编写Chart:
[root@Kubernetes charts]# helm create myConfigMapChart
Creating myConfigMapChart
[root@Kubernetes charts]# cd myConfigMapChart/templates/
[root@Kubernetes templates]# rm -rf ./*
[root@Kubernetes templates]# vim configmap.yaml
# 文件内容如下
apiVersion: v1
kind: ConfigMap
metadata:
name: my-cm-chart
data:
myValue: "Hello,World"
创建release实例:
[root@Kubernetes charts]# ls
mychart myConfigMapChart
[root@Kubernetes charts]# helm install mycm ./myConfigMapChart/
NAME: mycm
LAST DEPLOYED: Thu May 11 00:26:16 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
查看release实例:
[root@Kubernetes charts]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
mycm default 1 2023-05-11 00:26:16.392817959 +0800 CST deployed myConfigMapChart-0.1.0 1.16.0
查看release的详细信息:
[root@Kubernetes charts]# helm get manifest mycm
---
# Source: myConfigMapChart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-cm-chart
data:
myValue: "Hello,World"
删除release实例:
[root@Kubernetes charts]# helm uninstall mycm
release "mycm" uninstalled
[root@Kubernetes charts]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
案例1只是简单的创建一个configmap实际和直接apply没啥区别,案例2将引入变量进行创建chart,把configmap的名称改为变量的方式进行创建。
修改Chart:
[root@Kubernetes charts]# vim myConfigMapChart/templates/configmap.yaml
[root@Kubernetes charts]# cat myConfigMapChart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
# name: my-cm-chart
name: {{ .Release.Name }}-configmap
data:
# myValue: "Hello,World"
myValue: {{ .Values.MY_VALUE }}
[root@Kubernetes charts]# > myConfigMapChart/values.yaml
[root@Kubernetes charts]# vim myConfigMapChart/values.yaml
[root@Kubernetes charts]# cat !$
cat myConfigMapChart/values.yaml
MY_VALUE: "Hello,World"
创建实例:
[root@Kubernetes charts]# helm install mycm2 ./myConfigMapChart/
NAME: mycm2
LAST DEPLOYED: Thu May 11 00:49:06 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
查看实例:
[root@Kubernetes charts]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
mycm2 default 1 2023-05-11 00:49:06.855993522 +0800 CST deployed myConfigMapChart-0.1.0 1.16.0
[root@Kubernetes charts]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 77d
mycm2-configmap 1 87s
YAML解释:
apiVersion: v1
kind: ConfigMap
metadata:
# name: my-cm-chart
name: {{ .Release.Name }}-configmap
data:
# myValue: "Hello,World"
myValue: {{ .Values.MY_VALUE }}
引用内置对象或其他变量的好处:
如果metadata.name中色湖之的值就是一个固定值,这样的模板是无法在k8s中多次部署的,所以我们可以试着在每次安装chart时,都自动metadata.name的设置为release的名称,因为每次部署release的时候实例名称是不一样的,这样部署的时候里面的资源名也就可以作为一个分区,而可以进行重复部署。
HELM提供了一个用来渲染模板的命令,该命令可以将模板内容渲染出来,但是不会进行任何安装的操作。可以用该命令来测试模板渲染的内容是否正确。语法如下:
helm install [release实例名] chart目录 --debug --dry-run
例:
[root@Kubernetes charts]# helm install mycm3 ./myConfigMapChart/ --debug --dry-run
install.go:200: [debug] Original chart version: ""
install.go:217: [debug] CHART PATH: /root/charts/myConfigMapChart
NAME: mycm3
LAST DEPLOYED: Thu May 11 01:03:15 2023
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
MY_VALUE: Hello,World
HOOKS:
MANIFEST:
---
# Source: myConfigMapChart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
# name: my-cm-chart
name: mycm3-configmap
data:
# myValue: "Hello,World"
myValue: Hello,World
[root@Kubernetes charts]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
]]>传统服务部署到K8s集群的流程:
拉取代码-----》打包编译-----》构建镜像-----》准备相关的yaml文件-----》kubectl apply进行部署
传统方式部署引发的问题:
Helm是K8s的包管理工具,可以方便地发现、共享和构建K8s应用
Helm是k8s的包管理器,相当于centos系统中的yum工具,可以将一个服务相关的所有资源信息整合到一个chart中,并且可以使用一套资源发布到多个环境中,可以将应用程序的所有资源和部署信息组合到单个部署包中。
就像Linux下的rpm包管理器,如yum/apt等,可以很方便的将之前打包好的yaml文件部署到k8s上。
helm3中必须指定release名称,如果需要生成一个随机名称,需要加选项--generate-name,helm2中如果不指定release名称,可以自动生成一个随机名称
helm install ./mychart --generate-name
相关连接:
Github:https://github.com/helm/helm/releases
官网:https://helm.sh/zh/docs/intro/install/
下载好对应的版本上传到服务器进行解压缩
[root@Kubernetes helm]# ls
helm-v3.11.3-linux-amd64.tar.gz
[root@Kubernetes helm]# tar xvf helm-v3.11.3-linux-amd64.tar.gz
linux-amd64/
linux-amd64/LICENSE
linux-amd64/README.md
linux-amd64/helm
之后配置一下系统环境,让命令可以在系统中随机调用
[root@Kubernetes helm]# ls
helm-v3.11.3-linux-amd64.tar.gz linux-amd64
[root@Kubernetes helm]# cd linux-amd64/
[root@Kubernetes linux-amd64]# pwd
/opt/helm/linux-amd64
[root@Kubernetes linux-amd64]# vim /etc/profile
#追加下面内容
export PATH=$PATH:/opt/helm/linux-amd64
[root@Kubernetes linux-amd64]# source /etc/profile
检查一下是否安装成功
[root@Kubernetes ~]# helm version
version.BuildInfo{Version:"v3.11.3", GitCommit:"323249351482b3bbfc9f5004f65d400aa70f9ae7", GitTreeState:"clean", GoVersion:"go1.20.3"}
]]>主机名 | 系统 | 硬件 | 环境 |
---|---|---|---|
master.host.com | rocky8.5 | 2核CPU,2G内存 | 关闭selinux和防火墙,可使用主机名通信 |
work1.host.com | rocky8.5 | 2核CPU,2G内存 | 关闭selinux和防火墙,可使用主机名通信 |
work2.host.com | rocky8.5 | 2核CPU,2G内存 | 关闭selinux和防火墙,可使用主机名通信 |
一下操作所有主机都做
curl -o /etc/yum.repos.d/docker.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y install containerd.io
containerd config default | sudo tee /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
systemctl enable --now containerd
sudo swapoff -a
sudo sed -ri 's/.*swap.*/#&/' /etc/fstab
modprobe br_netfilter
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
service有基于iptables和基于ipvs两种代理模型。基于ipvs的性能要高一些。需要手动载入才能使用ipvs模块
yum install -y ipset ipvsadm
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
chmod +x /etc/sysconfig/modules/ipvs.modules
/bin/bash /etc/sysconfig/modules/ipvs.modules
如果出现以下报错则执行下面内容modprobe: FATAL: Module nf_conntrack_ipv4 not found in directory /lib/modules/4.18.0-348.el8.0.2.x86_64
sed -i 's/nf_conntrack_ipv4/nf_conntrack/g' /etc/sysconfig/modules/ipvs.modules
/bin/bash /etc/sysconfig/modules/ipvs.modules
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum install -y kubelet-1.24.0 kubeadm-1.24.0 kubectl-1.24.0
systemctl enable --now kubelet
生成kubeadm配置文件:sudo kubeadm config print init-defaults > kubeadm.yaml
编辑kubeadm.yaml并修改下面内容
advertiseAddress: 改成自己的ip
nodeRegistration下的name字段:改成自己的主机名
imageRepository: registry.aliyuncs.com/google_containers
在networking段添加pod的网段:podSubnet: 10.244.0.0/16
修改后内容如下:
$ cat kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.0.109
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: master.host.com
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: 1.24.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
podSubnet: 10.244.0.0/16
scheduler: {}
下载Kubernetes所需镜像:
$ kubeadm config --config kubeadm.yaml images pull
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.24.0
[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.7
[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.5.3-0
[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:v1.8.6
在意一下pause镜像的的版本名称我这里是registry.aliyuncs.com/google_containers/pause:3.7
修改containerd的配置文件/etc/containerd/config.toml,把里面的sandbox_image的值改为pause镜像的全称加版本
$ cat /etc/containerd/config.toml |grep sandbox
sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
重启Containerd:systemctl restart containerd
初始化master节点:kubeadm init --config kubeadm.yaml
注意:修改containerd的sandbox_image配置是全部的主机都要修改
初始化成功之后会打印下面的内容
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.4:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:91b1d4502e8950ece37fbc591160007f5e2a3311ff0ebe05112d24851ca082a9
其中下面内容需要自己去执行
o start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
之后这段内容是加入集群的命令,work节点可以通过下面命令来加入集群
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.4:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:91b1d4502e8950ece37fbc591160007f5e2a3311ff0ebe05112d24851ca082a9
WORK节点执行master节点返回的加入集群命令加入集群,出现下面内容即加入成功
kubeadm join 192.168.0.4:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:91b1d4502e8950ece37fbc591160007f5e2a3311ff0ebe05112d24851ca082a9
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
选择网络插件可参考官方文档进行选择本文选用Calico网络插件
在master节点下载calico的yaml文件
curl https://projectcalico.docs.tigera.io/archive/v3.22/manifests/calico.yaml -O
找到下面两行内容进行取消注释并修改value值
# - name: CALICO_IPV4POOL_CIDR
# value: "192.168.0.0/16"
value值应为开始创建master节点时的pod网络10.244.0.0/16
,修改后为
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
之后进行创建,创建方法如下
$ sudu kubectl apply -f calico.yaml
configmap/calico-config unchanged
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org configured
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org configured
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers unchanged
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers unchanged
clusterrole.rbac.authorization.k8s.io/calico-node unchanged
clusterrolebinding.rbac.authorization.k8s.io/calico-node unchanged
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
Warning: policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
poddisruptionbudget.policy/calico-kube-controllers created
执行完成没有报错之后可以运行kubectl get node
来查看节点的联通状态,当STATUS
全都变成Ready即部署成功
$ kubectl get node
NAME STATUS ROLES AGE VERSION
master.host.com Ready control-plane 43m v1.24.3
work1.host.com Ready <none> 39m v1.24.3
work2.host.com Ready <none> 39m v1.24.3
出现报错以及问题欢迎在评论区讨论]]>
Kubernetes又称K8s,是用8代替名字中间的8个字符"ubernete"而成的缩写。Kubernetes是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。
Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。
Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
k8s的中心,各个组件信息交互都要通过它,也是k8s管理集群的入口。
集群的状态管理器,保证Pod或其他资源达到期望值,也是需要和APIServer进行通信,在需要的时候创建、更新或删除它所管理的资源。
k8s 集群的调度器,选择工作pod节点,预选 > 优选。
负责监听节点和pod状态的,(监听状态发送 Kebu-APIserver 信息推送给 Etcd)
负责Pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器上。
键值数据库,用于保存k8s集群信息,网络信息,网络信息。
由于k8s内部,使用‘资源’来定义每一种逻辑感念(功能)故每种’资源’,都应该有自己的‘名称’。资源有api版本,元数据,定义清单,状态等配置信息。名称通常定义在‘资源’的‘元数据’信息里面。
Pod是K8s里能够被运行的最小逻辑单元。1个Pod里面可以运行多个容器,他们共享UTS+NET+IPC命名空间。可以把Pod理解成豌豆荚,而同一个Pod内的每一个容器就是一颗颗豌豆。一个Pod里面运行多个容器,又叫边车(SideCar)模式.
Pod控制器是pod启动的一种模板,用来保证k8s里面启动的Pod应始终按照人们的预期运行(副本数,生命周期,健康状态检查…)
随着项目增多,人员增加,集群规模的扩大,需要一种能够以隔离k8s内各种“资源”的方法,这个就是名称空间(Namespace)。不同的名称空间(Namespace)可以理解为K8s内部的虚拟集群组。不同名称空间(Namespace)的“资源”名称可以相同,相同名称空间(Namespace)内的同种“资源”,”名称”不能相同。合理的使用K8s的名称空间,使得集群管理员能够更好的对交付到K8s里的服务进行分类管理和浏览
标签是k8s的管理方式,便于分类管理资源对象。一个标签可以对应多个资源,一个资源也可以有多个标签,他们是多对多的关系。一个资源拥有多个标签,可以实现不同维度的管理。
给资源打上标签后,可以使用标签选择器过滤指定的标签。
在K8S的世界里,虽然每个pod都会被分配一个单独的ip地址,但是这个IP地址会随着Pod的销毁而消失。Service就是用来珏姐这个问题的核心概念。一个Service可以看作一组提供相同服务的Pod的对外访问接口。Service作用于那些通过标签选择器来定义的
Ingress是K8S集群里工作在OSI网络参考模型下,第七层的应用,对外暴露的接口。Service只进行L4流量调度,表现形式是IP+port。Ingress则可以调度不同业务域。不同URL访问路径的业务流量
]]>