elm与功能性组件

为什么又来一个Helm?

    在向K8S部署应用时,要依次部署Deployment、SVC等,步骤多且麻烦,而且随着越来越多的项目微服务化,复杂的应用在容器中部署以及管理就更为复杂了,这个时候简化就变得很重要了。

什么是Helm?

    Helm是通过打包的方式,支持发布的版本管理和控制,简化K8S应用的部署

    Helm本质就是让K8S的应用管理(Deployment、SVC等)可配置化,能动态生成K8S资源清单文件(deployment.yaml、svc.yaml),然后调用kubectl自动执行K8S资源部署。

    Helm是官方提供的类似于YUM的包管理器,是部署环境的流程封装。

    Helm是由客户端Helm命令行工具和服务端Tiller组成。

 

Helm核心概念:

    chart是创建一个应用的信息集合,包括各种K8S对象的配置模板、参数定义、依赖关系、文档说明等。chart是应用部署的自包含逻辑单元。可以将chart想象成apt、yum中的软件安装包。

    release是chart的运行实例,代表了一个正在运行的应用。当chart被安装到K8S集群,就生成一个release。Chart能够多次安装到同一个集群,每次安装都是一个release。

Helm核心组件:

 

Tiller可以理解为一个服务器,运行在K8S集群中,它会处理Helm客户端的请求,与K8S APIServer交互。

    Helm客户端:负责chart和release的创建和管理以及和Tiller的交互。

 

#Helm客户端安装

mkdir /usr/local/kubernetes/plugin/helm

cd /usr/local/kubernetes/plugin/helm

wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz

 

tar -xf helm-v2.13.1-linux-amd64.tar.gz

 

cd linux-amd64/

 

cp helm /usr/local/bin/

cd .. && chmod a+x /usr/local/bin/*

 

helm version

 

#Helm服务端Tiller安装

#为了安装服务端tiller,还需要在这台机器上配置好kubectl工具和kubeconfig文件,确保kubectl工具可以在这台机器上访问apiserver且正常使用

#而K8S APIServer开启了RBAC访问控制,所以需要创建tiller使用的service account:tiller并分配合适的角色给它。详细内容可以查看helm文档中的Role-based Access Control

 

vi rbac.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

apiVersion: v1

kind: ServiceAccount

metadata:

 name: tiller

 namespace: kube-system

---

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: ClusterRoleBinding

metadata:

 name: tiller

#权限

roleRef:

 apiGroup: rbac.authorization.k8s.io

 kind: ClusterRole

 name: cluster-admin

subjects:

 - kind: ServiceAccount

   name: tiller

   namespace: kube-system

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

kubectl create -f rbac.yaml

 

helm init --service-account tiller --skip-refresh

 

#pod如果失败了,那么则使用kubectl describe查看失败的原因,镜像下载不论,寻找国内的镜像下载,参考K8S集群安装

#默认是部署在kube-system这个名称空间下

kubectl get pod -n kube-system

kubectl get pod -n kube-system -l app=helm

 

#Helm有一个官方仓库:https://hub.helm.sh/

 

#Helm自定义模板:

#创建自描述文件,这个文件必须有name和version定义

mkdir test && cd test

-------------------------------------

cat <<'EOF' > ./Chart.yaml

name: hello-world

version: 1.0.0

EOF

-------------------------------------

 

#创建模板文件,用于生成资源清单(manifests)

#文件夹必须是templates

mkdir ./templates

-------------------------------------

cat <<'EOF' > ./templates/deployment.yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

 name: hello-world

spec:

 replicas: 1

 template:

  metadata:

   labels:

    app: hello-world

  spec:

   containers:

   - name: hello-world

     image: levi.harbor.com/library/nginx:1.9.1

     ports:

      - containerPort: 80

        protocol: TCP

EOF

-------------------------------------

 

-------------------------------------

cat <<'EOF' > ./templates/service.yaml

apiVersion: v1

kind: Service

metadata:

 name: hello-world

spec:

 type: NodePort

 ports:

 - port: 80

   targetPort: 80

   protocol: TCP

 selector:

  app: hello-world

EOF

-------------------------------------

 

#安装,创建出一次Release

helm install .

 

#正在运行

helm list

 

kubectl get pod

 

helm history nobby-eel

 

kubectl get pod -o wide

 

#浏览器访问IP:端口

helm status nobby-eel

 

#升级版本,看文件

 

#常用命令,如delete等,看文件

helm list

 

#发现删除了,再次执行helm install 会报已存在

helm delete RELEASE_NAME

 

#查看已删除的列表

helm list --deleted

 

#在删除时,还是存在,即可恢复,如果要强制删除则可以用--purge

helm list

helm delete --purge cantankerous-seastar

helm delete --purge sanguine-puffin

 

#回滚已在helm list --deleted 列表中的Release

helm rollback RELEASE_NAME

 

helm ls –deleted

 

#实验:通过修改配置文件即可修改镜像的效果

-------------------------------------

cat <<'EOF' > ./values.yaml

image:

 repository: levi.harbor.com/library/nginx

 tag: '1.9.1'

EOF

-------------------------------------

 

#这个文件中定义的值,在模板文件中可以通过 .VAlues对象访问到

-------------------------------------

cat <<'EOF' > ./templates/deployment.yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

 name: hello-world

spec:

 replicas: 1

 template:

  metadata:

   labels:

    app: hello-world

  spec:

   containers:

   - name: hello-world

     image: {{ .Values.image.repository }}:{{ .Values.image.tag }}

     ports:

      - containerPort: 8080

     protocol: TCP

EOF

-------------------------------------

 

#弄多几个镜像版本

docker tag levi.harbor.com/library/nginx:1.9.1 levi.harbor.com/library/nginx:2.0.0

docker tag levi.harbor.com/library/nginx:1.9.1 levi.harbor.com/library/nginx:2.0.1

 

#在 values.yaml 中的值可以被部署 release 时用到的参数 --values YAML_FILE_PATH 或 --set

key1=value1, key2=value2 覆盖掉

helm install --set image.tag='2.0.0' .

 

helm list

 

kubectl get pod

 

#查看版本

kubectl describe pod hello-world-66f6c9d846-cdl6p

 

#tag修改为2.0.1

vi values.yaml

 

#当前名称

helm list

 

#升级版本

helm upgrade -f values.yaml musty-cow .

 

kubectl get pod -w

 

#可以看到版本是2.0.1

kubectl describe pod hello-world-6f764598fc-6sfxq

 

#预览生成结果,即生成前测试,是未执行部署的

helm install --dry-run .

 

Dashboard

    Dashboard就是在B/S结构中去创建和管理的一个工具。

 

cd ..

mkdir dashboard

cd dashboard

 

#先移除原先的仓库

helm repo remove stable

 

#添加新的仓库地址为阿里云的

helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

 

#更新仓库

helm repo updat

 

#更新仓库

helm repo update

 

#拉取stable/kubernetes-dashboard

helm fetch stable/kubernetes-dashboard

 

#解压

tar -xf kubernetes-dashboard-0.6.0.tgz

ll kubernetes-dashboard

 

vi dashboard.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

image:

 repository: k8s.gcr.io/kubernetes-dashboard-amd64

 tag: v1.10.1

ingress:

 enabled: true

 hosts:

 - k8s.frognew.com

 annotations:

  nginx.ingress.kubernetes.io/ssl-redirect: "true"

  nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

 tls:

 - secretName: frognew-com-tls-secret

   hosts:

   - levi.dashboard.com

rbac:

 clusterAdminRole: true

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

 

#安装

helm install kubernetes-dashboard \

-n kubernetes-dashboard \

--namespace kube-system \

-f dashboard.yaml

 

#看看运行的kubernetes-dashboard

kubectl get pod -n kube-system

 

#看kubernetes-dashboard的

kubectl get svc -n kube-system

 

#type改为NodePort类型

kubectl edit svc kubernetes-dashboard -n kube-system

 

#查询到对应的IP+端口访问,是一个https的访问

kubectl get svc -n kube-system

 

#https://192.168.70.110:32750/

#备注:谷歌浏览器如果无法访问则把K8S的ca证书导进去(位于:/etc/kubernetes/pki/ca.crt )或者使用火狐浏览器访问

 

#登录,使用令牌的方式

kubectl -n kube-system get secret | grep kubernetes-dashboard-token

 

#复制出来此token

kubectl describe secret 查询出来的名称 -n kube-system

 

#界面化操作

#创建一个应用 - 创建应用

 

 

 

MetricsServer

    MetericServerK8S集群资源使用情况的聚合器,收集数据给K8S集群内使用,如kubectl、hap、scheduler等

vi metrics-server.yaml

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

args:

- --logtostderr

- --kubelet-insecure-tls

- --kubelet-preferred-address-types=InternalIP

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

#使用helm部署metrics

helm install stable/metrics-server -n metrics-server --namespace kube-system -f metrics-server.yaml

 

#查看集群指标信息

kubectl top node

 

Prometheus

    Prometheus已经继承了MetricServer,因此不需要在部署MetricsServer。

    PrometheusOperator系统检测和举报工具箱,用来存储监控数据。

    NodeExporter用于各Node的关键度量指标状态数据。

    KubeStateMetrics收集K8S集群内资源对象数据,指定报警规则。

    Prometheus采用pull方式收集APIServer、Scheduler、Controller Manager、kubelet组件数据,通过http协议传输。

    Grafana可视化数据统计和监控平台。

#拉取

git clone https://github.com/coreos/kube-prometheus.git

cd kube-prometheus/

ls

 

#使用NodePort方式访问grafana

vi kube-prometheus/manifests/grafana-service.yaml

================================================

apiVersion: v1

kind: Service

metadata:

  labels:

    app: grafana

  name: grafana

  namespace: monitoring

spec:

  type: NodePort   #新增

  ports:

  - name: http

    port: 3000

    targetPort: http

    nodePort: 30100   #新增

  selector:

    app: grafana

================================================

 

#改为NodePort

vi kube-prometheus/manifests/prometheus-service.yaml

================================================

apiVersion: v1

kind: Service

metadata:

  labels:

    prometheus: k8s

  name: prometheus-k8s

  namespace: monitoring

spec:

  type: NodePort   #新增

  ports:

  - name: web

    port: 9090

    targetPort: web

    nodePort: 30300 #新增

  selector:

    app: prometheus

    prometheus: k8s

  sessionAffinity: ClientIP

================================================

 

 

#需要互相连接,运行多几次,直到运行结束没有错误,如果运行了5次了,还是报错,那么则要检查镜像等内容了。

kubectl apply -f manifests/

kubectl apply -f manifests/

kubectl apply -f manifests/

kubectl apply -f manifests/

kubectl apply -f manifests/

 

#建议等待个3分钟左右,让其去收集数据

kubectl get pod -n monitoring

kubectl get pod -n monitoring

 

#收集到的每台机器的信息

kubectl top node

 

kubectl top pod

 

kubectl get svc --all-namespaces

 

#浏览器访问

http://MasterIP:30300

http://MasterIP:30300/targets

 

#访问grafana,默认的用户名和密码都是admin

http://MasterIP:30100

 

#电脑太卡可以把对应的运行内容卸下来

kubectl delete -f kube-prometheus/manifests/

kubectl get pod -n monitoring

 

#具体页面操作可以看文档也可以百度

 

Horizontal Pod Autoscaling

    Horizontal Pod Autoscaling可以根据CPU利用率自动伸缩一个Deployment或RS中的Pod的数量。

 

kubectl run php-apache --image=gcr.io/google_containers/hpa-example --requests=cpu=200m --expose --port=80

 

kubectl get pod

 

kubectl top pod

 

#创建一个HPA控制器

kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10

 

kubectl top pod

 

kubectl get hpa

 

#运行个容器

kubectl run -i --tty load-generator --image=busybox /bin/sh

 

#测试无限访问

while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done

 

#如果一直没有变化则多创建几个镜像和访问

kubectl run -i --tty load-generator --image=busybox /bin/sh

 

#看一个窗口查看

kubectl get hpa -w

 

kubectl get pod -w

 

#退出会发现节点的压力不断下去

exit

 

kubectl get pod -w

 

#回收策略很慢

kubectl get hpa -w

 

Pod资源限制

    K8S对资源的限制实际上是通过cgroup来控制的,cgroup是一组永安里控制内核如何运行进程的相关属性集合,针对内存/CPU和各种设备都有对应的cgroup。

    默认情况下,Pod运行没有CPU和内存的限制。这意味着系统中任何Pod都将能够执行该Pod所在节点一样,消耗足够多的CPU和内存。一般会针对某些应用的Pod资源来进行资源限制,这个资源限制是通过resources和requests和limits来实现。

    具体可以参考《Kubernetes(K8S)入门到运维 ( 三 ) > 资源解析》:https://blog.csdn.net/Su_Levi_Wei/article/details/103410218

   

    requests是要分配的资源,limits为最高请求的资源值,可以理解为初始化值和最大值。

   

spec:

containers:

- image: xxxx

imagePullPolicy: Always

name: auth

ports:

- containerPort: 8080

protocol: TCP

resources:

limits:

cpu: "4"

memory: 2Gi

requests:

cpu: 250m

memory: 250Mi

 

计算资源的限额:

apiVersion: v1

kind: ResourceQuota

metadata:

name: compute-resources

namespace: spark-cluster

spec:

hard:

pods: "20"

requests.cpu: "20"

requests.memory: 100Gi

limits.cpu: "40"

limits.memory: 200Gi

 

配置对象数量配额限制:

apiVersion: v1

kind: ResourceQuota

metadata:

name: object-counts

namespace: spark-cluster

spec:

hard:

configmaps: "10"

persistentvolumeclaims: "4"

replicationcontrollers: "20"

secrets: "10"

services: "10"

services.loadbalancers: "2"

 

配置CPU和内存limitRange

apiVersion: v1

kind: LimitRange

metadata:

name: mem-limit-range

spec:

limits:

  #limit的值

- default:

memory: 50Gi

cpu: 5

    #request的值

defaultRequest:

memory: 1Gi

cpu: 1

type: Container

 

EFK日志收集

#添加 Google incubator 仓库:

helm repo add incubator http://storage.googleapis.com/kubernetes-charts-incubator

helm fetch incubator/elasticsearch

tar -xf elasticsearch-1.10.2.tgz

 

kubectl create namespace efk

 

#部署 Elasticsearch:

#Elasticsearch的节点太多会导致资源过多

ls

cd elasticsearch/

 

#修改MINIMUM_MASTER_NODES节点为1,资源可能会出现不够、master也改为1-enabled也改为false,data也为1

vi values.yaml

--------------------------------------

MINIMUM_MASTER_NODES: "1"  #修改为1

client:

 replicas: 1 #修改为1

master:

 replicas: 1 #修改为1

 persistence:

  enabled: false #修改为false

data:

 replicas: 1

 persistence:

  enabled: false

--------------------------------------

 

#强制删除一直处于Terminating状态的pod

kubectl delete pod els1-elasticsearch-master-0 --force --grace-period=0 -n efk

 

helm install --name els1 --namespace=efk -f values.yaml incubator/elasticsearch

 

kubectl get pod -n efk

 

kubectl get svc -n efk

 

kubectl run cirror-$RANDOM --rm -it --image=cirros -- /bin/sh

curl SVC_IP:9200/_cat/nodes

 

#部署 Fluentd:

#拉取、解压、进入目录

helm fetch stable/fluentd-elasticsearch

# 更改其中 Elasticsearch 访问地址

vim values.yaml

--------------------------------------

elasticsearch:

 host: 'SVC_IP' #修改为SVC的IP

--------------------------------------

 

helm install --name flu1 --namespace=efk -f values.yaml stable/fluentd-elasticsearch

 

#部署kibana

#拉取、解压、进入目录

helm fetch stable/kibana --version 0.14.8

vim values.yaml

--------------------------------------

files:

 kibana.yml:

  elasticsearch.url: http://SVC_IP:9200

--------------------------------------

helm install --name kib1 --namespace=efk -f values.yaml stable/kibana --version 0.14.8

 

#修改kibana的地址让外部可以访问

kubectl get svc -n efk

 

#把ClusterIP改为NodePort

kubectl edit svc kib1-kibana -n efk

 

#使用浏览器访问,192.168.70.110:端口

kubectl get svc

 

K8S证书可用年限修改

#查看证书有效时间

#一年

openss x509 -in apiserver.crt -text -noout

#十年

openss x509 -in ca.crt -text -noout

 

#go 环境部署

wget https://dl.google.com/go/go1.12.7.linux-amd64.tar.gz

tar -zxvf go1.12.7.linux-amd64.tar.gz -C /usr/local/

vi /etc/profile

==========================================

export PATH=$PATH:/usr/local/go/bin

==========================================

source /etc/profile

 

#下载源码

git clone https://github.com/kubernetes/kubernetes.git

cd Kubernetes

git checkout -b remotes/origin/release-1.15.1 v1.15.1

 

#修改 Kubeadm 源码包更新证书策略

kubeadm version

#kubeadm 1.14 版本之前

vim staging/src/k8s.io/client-go/util/cert/cert.go

#kubeadm 1.14 之后

vim cmd/kubeadm/app/util/pkiutil/pki_helpers.go

 

======================================================

#在(*x509.Certificate, error)下一行定义一个常量

const duration365d = time.Hour * 24 * 365 * 10

#在NotAfter中改为如下

NotAfter:     time.Now().Add(duration365d).UTC()

 

make WHAT=cmd/kubeadm GOFLAGS=-v

cp _output/bin/kubeadm /root/kubeadm-new

 

#更新 kubeadm,替换

cp /usr/bin/kubeadm /usr/bin/kubeadm.old

cp /root/kubeadm-new /usr/bin/kubeadm

chmod a+x /usr/bin/kubeadm

 

#更新各节点证书至 Master 节点

cp -r /etc/kubernetes/pki /etc/kubernetes/pki.old

cd /etc/kubernetes/pki

kubeadm alpha certs renew all --config=/root/kubeadm-config.yaml

openssl x509 -in apiserver.crt -text -noout | grep Not

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐