k8s的部署及入门

发布时间 2023-03-24 11:54:24作者: 一条java狗

lucykubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。

这个工具能通过两条指令完成一个kubernetes集群的部署:

1. 安装要求

在开始之前,部署Kubernetes集群机器需要满足以下几个条件:

  • 一台或多台机器,操作系统 CentOS7.x-86_x64
  • 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
  • 可以访问外网,需要拉取镜像,如果服务器不能上网,需要提前下载镜像并导入节点
  • 禁止swap分区

2. 准备环境

角色 IP
master 192.158.195.193
node1 192.158.195.198
node2 192.158.195.199
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 每个节点分别设置对应主机名

hostnamectl set-hostname master
hostnamectl set-hostname node1
hostnamectl set-hostname node2

# 所有节点都修改 hosts
vim /etc/hosts
192.158.195.193 master
192.158.195.198 node1
192.158.195.199 node1

# 所有节点关闭 SELinux
setenforce 0
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

关闭swap分区:
swapoff -a
修改配置文件 - /etc/fstab
删除 /mnt/swap swap swap defaults 0 0 这一行或者注释掉这一行
确认swap已经关闭
free -m
若都显示 0 则表示关闭成功

# 时间同步
yum install ntpdate -y
ntpdate time.windows.com

3. 所有节点安装Docker/kubeadm/kubelet

Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。

3.1 安装Docker

$ wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
$ yum -y install docker-ce-18.06.1.ce-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version
Docker version 18.06.1-ce, build e68fc7a
$ cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

# 重启生效
systemctl daemon-reload
systemctl restart docker

3.2 添加阿里云YUM软件源

cat <<EOF > kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
mv kubernetes.repo /etc/yum.repos.d/

3.3 安装kubeadm,kubelet和kubectl

由于版本更新频繁,这里指定版本号部署:

yum install -y kubelet-1.22.4 kubectl-1.22.4 kubeadm-1.22.4
systemctl enable kubelet
systemctl start kubelet
systemctl enable docker
systemctl start docker

4. 部署Kubernetes Master

在192.168.195.190(Master)执行。

初始化集群控制台 Control plane

失败了可以用 kubeadm reset 重置

kubeadm init --image-repository=registry.aliyuncs.com/google_containers --apiserver-advertise-address=192.168.195.193 --kubernetes-version v1.22.4 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all


或者直接
kubeadm init --image-repository=registry.aliyuncs.com/google_containers也可以,其他值是有默认值
 参数说明
--apiserver-advertise-address=192.168.195.190   这个参数就是master主机的IP地址,例如我的Master主机的IP是:192.168.181.131

--image-repository=registry.aliyuncs.com/google_containers  这个是镜像地址,由于国外地址无法访问,故使用的阿里云仓库地址:registry.aliyuncs.com/google_containers

--kubernetes-version=v1.22.4   这个参数是下载的k8s软件版本号

--service-cidr=10.96.0.0/12       这个参数后的IP地址直接就套用10.96.0.0/12 ,以后安装时也套用即可,不要更改

--pod-network-cidr=10.244.0.0/16       k8s内部的pod节点之间网络可以使用的IP段,不能和service-cidr写一样,如果不知道怎么配,就先用这个10.244.0.0/16

总之,粉色区不做任何更改,只修改红色区的两个地方(master主机IP,k8s软件版本)


kubeadm join 192.168.195.190:6443 --token zwqlu7.4tq40kkcmph1phwt --discovery-token-ca-cert-hash sha256:8410fdd6d9e77856345240d9e9eafc754248f3913be79753610ade39cfd44445

这边如果初始化失败,第一时间应该考虑docker的版本问题,因为k8s和docker是有版本依赖关系的

查看当前支持的版本:yum list docker-ce --showduplicates | sort -r

降低到当前支持的最高版本:yum downgrade --setopt=obsoletes=0 -y docker-ce-18.09.9-3.el7 docker-ce-cli-18.09.9-3.el7 containerd.io

由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址。

使用kubectl工具:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

5. 加入Kubernetes Node

在192.168.1.12/13(Node)执行。

向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:

kubeadm join 192.168.1.11:6443 --token esce21.q6hetwm8si29qxwn \
    --discovery-token-ca-cert-hash sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5

默认token有效期为24小时,当过期之后,该token就不可用了。这时就需要重新创建token,操作如下:

kubeadm token create --print-join-command

6. 部署CNI网络插件

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

默认镜像地址无法访问,sed命令修改为docker hub镜像仓库。

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

kubectl get pods -n kube-system
NAME                          READY   STATUS    RESTARTS   AGE
kube-flannel-ds-amd64-2pc95   1/1     Running   0          72s

7. 测试kubernetes集群

在Kubernetes集群中创建一个pod,验证是否正常运行:

 kubectl create deployment nginx --image=nginx
 kubectl expose deployment nginx --port=80 --type=NodePort
 kubectl get pod,svc

访问地址:http://NodeIP:Port

二、安装Kuboard图形化界面

2.1 安装方式一:

kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml

2.2 安装方式二:

准备kuboard.yaml文件
以下只有一个地方需要更改,就是需要根据实际情况更改,为主机节点名称
vim kuboard-offline.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kuboard
  namespace: kube-system
  annotations:
    k8s.kuboard.cn/displayName: kuboard
    k8s.kuboard.cn/ingress: "true"
    k8s.kuboard.cn/service: NodePort
    k8s.kuboard.cn/workload: kuboard
  labels:
    k8s.kuboard.cn/layer: monitor
    k8s.kuboard.cn/name: kuboard
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s.kuboard.cn/layer: monitor
      k8s.kuboard.cn/name: kuboard
  template:
    metadata:
      labels:
        k8s.kuboard.cn/layer: monitor
        k8s.kuboard.cn/name: kuboard
    spec:
      nodeName: k8s-master  # ----------------------------------需要根据实际情况更改,为主机节点名称
      containers:
      - name: kuboard
        image: eipwork/kuboard:latest
        imagePullPolicy: IfNotPresent
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

---
apiVersion: v1
kind: Service
metadata:
  name: kuboard
  namespace: kube-system
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 32567
  selector:
    k8s.kuboard.cn/layer: monitor
    k8s.kuboard.cn/name: kuboard

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kuboard-user
  namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kuboard-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: kuboard-user
  namespace: kube-system

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kuboard-viewer
  namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kuboard-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
- kind: ServiceAccount
  name: kuboard-viewer
  namespace: kube-system

2.4 执行安装命令
kubectl apply -f kuboard-offline.yaml

三、启动观察

3.1 获取token
echo $(kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)

image

运行结果

3.2 打开浏览器,享受飞一般的感觉
输入token

image

三、yaml生成

一、命令式:会直接生成yaml,进行修改就行

案例:

kubectl create deployment web --image=nginx -o yaml --dry-run >m1.yaml

image

二、使用kubectl get 命令导出yaml文件

image

四、pod

一、介绍

Pod 是 k8s 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最 小资源对象模型,也是在 k8s 上运行容器化应用的资源对象,其他的资源对象都是用来支 撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,k8s 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成 Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为”根容器“的 Pause 容器。Pause 容器对应的镜 像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器

二、pod的特性

image

三、pod的实现机制

image

image

image

四、pod的拉去镜像的策略

image

五、pod的重启策略 restartPolicy

image

六、pod的资源限制

image

image

七、pod的健康检查

image

八、pod的创建

image

1、通过yaml命令创建:kubectl apply -f [pod文件名]

2、创建命令:kubectl run [pod名称]--image=[镜像名]:[镜像版本]

3、删除:

(1)kubectl delete pod [pod名]

(2)kubectl delete pods

(3) kubectl delete -f [pod文件名]

九、pod的调度

1、影响的属性

image

2、节点选择器nodeSelector

给节点打上标签

image

标签的查询和删除

image

选择dev作为创建pod的节点

image

image

3、节点亲和性调度nodsAffinity

比nodeSelector更加强大

image

4、反亲和性调度
1、介绍

image

2、场景

image

3、具体演示

(1)查看污点情况

image

(2)为节点添加污点

image

image

(3)删除污点

image

(4)污点容忍

image

效果:

image

增加、查询、删除效果

image

五、contorller

一、介绍

在集群中管理和运行容器的对象

二、deployment

Deployment 是 Kubenetes v1.2 引入的新概念,引入的目的是为了更好的解决 Pod 的编排 问题,Deployment 内部使用了 Replica Set 来实现。Deployment 的定义与 Replica Set 的 定义很类似,除了 API 声明与 Kind 类型有所区别:

image

(1)场景

image

(2)部署

控制器通过标签来确定需要控制的pod,在下面的截图中可以看到,两个选择的标签为相同的

image

(3)创建服务并运行

image

(4)创建对外发布的文件

image

(5)发布

image

(6)查看发布结果

image

后面通过任何节点的ip都可以访问到此应用了

Welcome to nginx!

(7)修改镜像版本

image

(8)镜像的应用升级

格式:kubectl set image deployment 【应用名称】 【镜像 = 镜像名+版本】

案例:

kubectl set image deployment web nginx=nginx:1.15

image

查看升级状态

image

查看历史版本

kubectl rollout history deployment web

image

还原到上一个版本

kubectl rollout undo deployment web

image

还原到指定版本

kubectl rollout undo deployment web --to-revision=1

image

弹性收缩

kubectl scale deployment web --replicas=10

image

二、Service

1、概念

Service 概述 Service 是 Kubernetes 最核心概念,通过创建 Service,可以为一组具有相同功能的容器应 用提供一个统一的入口地 址,并且将请求负载分发到后端的各个容器应用上。

2、作用

服务发现:防止pod失联(服务发现)

image

负载均衡:定义一组pod访问策略(负载均衡)

image

2、pod与service的关系

通过label和selector标签来建立联系的

image

3、service的常用类型

image

image

(1)ClusterIP:集群内部使用

(2)NodePort:对外访问应用使用

(3)LoadBalancer:对外访问使用,公有云

image

4、创建service

kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --dry-run -o yaml > service.yaml

image

image

5、运行和查询

image

三、StatefulSet

1、无状态和有状态说明

image

2、部署有状态服务

image

image

image

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx

---

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: nginx-statefulset
  namespace: default
spec:
  serviceName: nginx
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

image

image

3、部署守护进程DasemonSet

作用,使得每个加入的节点,都会进入到同一个pod中

image

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ds-test 
  labels:
    app: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      containers:
      - name: logs
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: varlog
          mountPath: /tmp/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

image

image

四、job

1、概念

执行一次任务,执行之后不再执行

2、创建

image

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4
3、查看

直接查看该pod的日志就可以了 kubectl logs [pod名称]

五、cronjob

1、概念

定时的执行任务,

2、创建

image

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
3、查看

直接查看该pod的日志就可以了 kubectl logs [pod名称]

六、Secret

作用:加密数据进行存储在etcd中,让pod容器挂载到Volume方式进行访问(是以base64的加密方式进行加密)

场景:凭证(密码等)

1、创建Secret加密数据
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

创建:kubectl apply -f secret.yaml

查询:kubectl get Secret

image

2、使用

以变量的形式进行挂载到pod容器中

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password

image

进入容器中,查看

kubectl exec -it [pod名] bash

image

3、以数据卷的形式挂载到pod容器中
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret

image

七、ConfigMap

作用:存储不加密数据到etcd,让Pod以变量或者Volume挂载到容器中

场景:配置文件

1、创建和查询
(1)编写配置文件
redis.host=127.0.0.1
redis.port=6379
redis.password=123456
(2)以配置文件创建configmap并且查看

image

(4)查看详细信息

kubectl describe cm redis-config

image

(5)以volume形式挂载到容器中
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: busybox
      image: busybox
      command: [ "/bin/sh","-c","cat /etc/config/redis.properties" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: redis-config
  restartPolicy: Never

image

运行这个容器

image

因为做了输出,所以可以以这个命令查看:

image

(6)、以变量形式挂载

a、创建变量,创建configMap文件

apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfig
  namespace: default
data:
  special.level: info
  special.type: hello

image

b、执行文件并且查看文件

image

c、获取配置

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: busybox
      image: busybox
      command: [ "/bin/sh", "-c", "echo $(LEVEL) $(TYPE)" ]
      env:
        - name: LEVEL
          valueFrom:
            configMapKeyRef:
              name: myconfig
              key: special.level
        - name: TYPE
          valueFrom:
            configMapKeyRef:
              name: myconfig
              key: special.type
  restartPolicy: Never

image

image

八、k8s集群的安全机制

1、概述

(1)访问k8s集群时需要经过三个不走完成具体操作

第一步:认证

第二步:鉴权(授权)

第三步:准入控制

(2)进行访问的时候,过程中都需要经过apiserver,apiserver进行统一协调,比如门卫

访问过程中需要证书、token、或者用户名+密码

如果访问pod,需要serviceAccount

第一步:认证

image

第二步:鉴权(授权)

image

第三步:准入控制

image

2、RBAC

RBAC(Role-Based Access Control,基于角色的访问控制)在 k8s v1.5 中引入,在 v1.6 版 本时升级为 Beta 版本,并成为 kubeadm 安装方式下的默认选项,相对于其他访问控制方式, 新的 RBAC 具有如下优势:

(1)对集群中的资源和非资源权限均有完整的覆盖

(2)整个 RBAC 完全由几个 API 对象完成,同其他 API 对象一样,可以用 kubectl 或 API 进行操作

(3)可以在运行时进行调整,无需重启 API Server 要使用 RBAC 授权模式,需要在 API Server 的启动参数中加上--authorization-mode=RBA

原理:

image

k8s中的角色

image

image

image

3、使用

(1)创建命名空间

kubectl create namespace [命名空间名称]

image

(2)在新建的命名空间下创建pod

image

(3)创建角色

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: pop
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

image

对这个命名空间中,改用户设置了拥有verbs中的权限

image

查询该角色

image

(4)创建角色绑定

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: pop
subjects:
- kind: User
  name: lucy # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io

image

image

查看

image

(5)授权

cat > lucy-csr.json <<EOF
{
  "CN": "lucy",#创建的用户
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
    }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes lucy-csr.json | cfssljson -bare lucy #创建的用户

kubectl config set-cluster kubernetes \
  --certificate-authority=ca.pem \
  --embed-certs=true \
  --server=https://192.168.195.190:6443 \#修改成自己的主机ip
  --kubeconfig=lucy-kubeconfig
  
kubectl config set-credentials lucy \
  --client-key=lucy-key.pem \
  --client-certificate=lucy.pem \
  --embed-certs=true \
  --kubeconfig=lucy-kubeconfig

kubectl config set-context default \
  --cluster=kubernetes \
  --user=lucy \
  --kubeconfig=lucy-kubeconfig

kubectl config use-context default --kubeconfig=lucy-kubeconfig

此文件使用时需要删除掉上面的注释

image

九、Ingress

不是k8s的组件,需要单独的部署

image

3、逻辑

image

4、ingress工作流程

image

5、使用ingress

第一步:部署ingress Controller(这里选择官方提供的nginx控制器)

第二步:创建ingress规则

6、使用ingress对外暴露应用

(1)这边选择创建nginx应用,对外暴露端口使用NodePort

创建容器:kubectl create deployment web --image=nginx

对外暴露端口:kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

(2)部署ingresscontorller

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: tcp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: udp-services
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nginx-ingress-serviceaccount
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nginx-ingress-clusterrole
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - endpoints
      - nodes
      - pods
      - secrets
    verbs:
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - events
    verbs:
      - create
      - patch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - "extensions"
      - "networking.k8s.io"
    resources:
      - ingresses/status
    verbs:
      - update

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: nginx-ingress-role
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
rules:
  - apiGroups:
      - ""
    resources:
      - configmaps
      - pods
      - secrets
      - namespaces
    verbs:
      - get
  - apiGroups:
      - ""
    resources:
      - configmaps
    resourceNames:
      # Defaults to "<election-id>-<ingress-class>"
      # Here: "<ingress-controller-leader>-<nginx>"
      # This has to be adapted if you change either parameter
      # when launching the nginx-ingress-controller.
      - "ingress-controller-leader-nginx"
    verbs:
      - get
      - update
  - apiGroups:
      - ""
    resources:
      - configmaps
    verbs:
      - create
  - apiGroups:
      - ""
    resources:
      - endpoints
    verbs:
      - get

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: nginx-ingress-role-nisa-binding
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: nginx-ingress-role
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: nginx-ingress-clusterrole-nisa-binding
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nginx-ingress-clusterrole
subjects:
  - kind: ServiceAccount
    name: nginx-ingress-serviceaccount
    namespace: ingress-nginx

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: ingress-nginx
      app.kubernetes.io/part-of: ingress-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: ingress-nginx
        app.kubernetes.io/part-of: ingress-nginx
      annotations:
        prometheus.io/port: "10254"
        prometheus.io/scrape: "true"
    spec:
      hostNetwork: true
      # 需要将此改成true,否则不对外暴露
      terminationGracePeriodSeconds: 300
      serviceAccountName: nginx-ingress-serviceaccount
      nodeSelector:
        kubernetes.io/os: linux
      containers:
        - name: nginx-ingress-controller
          image: lizhenliang/nginx-ingress-controller:0.30.0
          args:
            - /nginx-ingress-controller
            - --configmap=$(POD_NAMESPACE)/nginx-configuration
            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
            - --publish-service=$(POD_NAMESPACE)/ingress-nginx
            - --annotations-prefix=nginx.ingress.kubernetes.io
          securityContext:
            allowPrivilegeEscalation: true
            capabilities:
              drop:
                - ALL
              add:
                - NET_BIND_SERVICE
            # www-data -> 101
            runAsUser: 101
          env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
            - name: https
              containerPort: 443
              protocol: TCP
          livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /healthz
              port: 10254
              scheme: HTTP
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 10
          lifecycle:
            preStop:
              exec:
                command:
                  - /wait-shutdown

---

apiVersion: v1
kind: LimitRange
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  limits:
  - min:
      memory: 90Mi
      cpu: 100m
    type: Container

(3)创建ingress控制器

image

(4)查看创建的结果

image

image


image

创建访问规则格式:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.ingredemo.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web
          servicePort: 80

十、helm

1、引入

K8S 上的应用对象,都是由特定的资源描述组成,包括 deployment、service 等。都保存 各自文件中或者集中写到一个配置文件。然后 kubectl apply –f 部署。如果应用只由一 个或几个这样的服务组成,上面部署方式足够了。而对于一个复杂的应用,会有很多类似 上面的资源描述文件,例如微服务架构应用,组成应用的服务可能多达十个,几十个。如 果有更新或回滚应用的需求,可能要修改和维护所涉及的大量资源文件,而这种组织和管 理应用的方式就显得力不从心了。且由于缺少对发布过的应用版本管理和控制,使 Kubernetes 上的应用维护和更新等面临诸多的挑战,主要面临以下问题:

(1)如何将这 些服务作为一个整体管理

(2)这些资源文件如何高效复用

(3)不支持应用级别的版本 管理

image

2、helm介绍

Helm 是一个 Kubernetes 的包管理工具,就像 Linux 下的包管理器,如 yum/apt 等,可以 很方便的将之前打包好的 yaml 文件部署到 kubernetes 上。

Helm 有 3 个重要概念:

(1)helm:一个命令行客户端工具,主要用于 Kubernetes 应用 chart 的创建、打包、发 布和管理。

(2)Chart:应用描述,一系列用于描述 k8s 资源相关文件的集合。

(3)Release:基于 Chart 的部署实体,一个 chart 被 Helm 运行后将会生成对应的一个 release;将在 k8s 中创建出真实运行的资源对象(基于chart部署实体,应用级别的版本管理)

3、解决了哪些问题

image

4、Helm v3 变化

2019 年 11 月 13 日, Helm 团队发布 Helm v3 的第一个稳定版本。

该版本主要变化如下:

架构变化:

1、最明显的变化是 Tiller 的删除

2、Release 名称可以在不同命名空间重用

3、支持将 Chart 推送至 Docker 镜像仓库中

4、使用 JSONSchema 验证 chart values

5、其他

image

5、helm安装

(1)下载heml安装包

(2)解压helm压缩包,将helm移动到/usr/bin目录中

image

image

6、配置helm仓库

(1)添加仓库

helm repo add 仓库名称 仓库地址

例:1 微软的仓库

helm repo add stable http://mirror.azure.cn/kubernetes/charts

例:2 阿里的仓库

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

image

(2)查看:

命令:helm repo list

image

(3)更新:

命令:helm repo update

image

(4)删除:

helm repo remove [仓库名]

image

7、使用

第一步:使用命令搜索应用

helm search repo 名称(weave)

image

第二步: 根据搜索内容,选择进行安装

helm install 【安装之后的名称】 【搜索之后应用的名称】

直接安装时报错,版本问题,需要修改版本

image

使用如下步骤:

helm pull stable/weave-scope
tar -zxvf weave-scope-1.1.12.tgz
cd weave-scope/
grep -r rbac.authorization

之后把对应文件里的rbac.authorization.k8s.io/v1beta1替换成rbac.authorization.k8s.io/v1 即可

再次执行安装 helm install ui weave-scope

image

查看安装之后的状态

helm list

helm status [安装之后的名称]

image

实际上执行的过程是:通过helm下载一个chart的一个yaml的集合,然后对这个集合进行安装
第三步:修改对外提供的端口

因为该应用在安装的时候,没有提供对外的端口,需要我们后期添加

image

执行:kubectl edit svc ui-weave-scope

image

image

之后就可以通过任意节点加端口进行访问

8、自己创建chart

(1)使用命令创建chart

helm create [chart名称]

image

image

charts:只是普通文件夹

Chart.yaml:当前chart的基本信息

templates:将自己写的yaml文件放到这里

values.yaml:定义yaml的全局变量配置

(2)在templates中创建两个文件

deployment.yaml 创建deployment和pod

kubectl create deployment web1 --image=nginx --dry-run -o yaml > deployment.yaml

service.yaml 创建对外暴露的端口

kubectl expose deployment web1 --port= 服务端口 --target-port= 镜像端口 --type=NodePort --dry-run -o yaml > service.yaml

需要先执行deployment.yaml,否则没有这个应用,无法创建service.yaml

image

image

(3)安装mychart

helm install web1 mychart/

image

image

已经显示创建成功,直接可以通过ip和端口号就可以进行访问了

image

(4)升级更新

helm upgrade 【chart名称】 【文件夹】

image

9、实现yaml高效复用

通过传递参数动态渲染模板,yaml内容动态传入参数生成

image

(1)在values.yaml定义变量和值

image

(2)在具体的values.yaml中获取变量值

通过表达式的形式使用全局变量

{{ .Values.变量名称}}

也可以使用这个形式

{{ .Release.Name}}

image

image

运行既可

helm install web1 mychart/

10、卸载安装的应用

1. 列出 Helm 部署

列出当前命名空间中的 Helm 部署:

helm list

要列出特定命名空间中的部署,请使用:

helm list --namespace <namespace_name>

通过运行以下命令列出所有命名空间中的所有 Helm 部署:

helm list --all-namespaces

image

2. 删除 Helm 部署

要删除已安装的 Helm 部署,请运行:

helm uninstall <deployment name> --namespace <namespace_name>

或者,使用别名:

helm delete <deployment name> --namespace <namespace_name>

终端输出移除确认。例如,下面的命令删除命名空间other上名为phoenix-chart的部署:

helm uninstall phoenix-chart --namespace other

image

在 Helm 2 中,使用--purge删除发布和相关 Kubernetes 组件的选项:

helm delete <deployment name> --purge

列出 Helm 部署helm list以确认版本不再存在。

十一、nfs

image

1、nfs,网络存储,pod重启,数据依然存在

yum install -y nfs-utils

vim /etc/exports

image

image

image

systemctl start nfs

image

image

image

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dep1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
        - name: wwwroot
          nfs:
            server: 192.168.44.134
            path: /data/nfs

当进入到nfs服务器中的文件夹创建和删除文件时,会自动在pod容器内部中进行操作(相互的)

2、pv和pvc

image

pv文件

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /k8s/nfs
    server: 192.168.44.134

image

pvc文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dep1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: wwwroot
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:
      - name: wwwroot
        persistentVolumeClaim:
          claimName: my-pvc

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

image

pv和pvc是通过名字进行绑定的

十二、kubernetes监控

1、概述

Kubernetes 作为容器集群系统,通过健康检查+重启策略实现了 Pod 故障自我修复能力, 通过调度算法实现将 Pod 分布式部署,监控其预期副本数,并根据 Node 失效状态自动在正 常 Node 启动 Pod,实现了应用层的高可用性。 针对 Kubernetes 集群,高可用性还应包含以下两个层面的考虑:Etcd 数据库的高可用性 和 Kubernetes Master 组件的高可用性。 而 Etcd 我们已经采用 3 个节点组建集群实现高 可用,本节将对 Master 节点高可用进行说明和实施。 Master 节点扮演着总控中心的角色,通过不断与工作节点上的 Kubelet 和 kube-proxy 进 行通信来维护整个集群的健康工作状态。如果 Master 节点故障,将无法使用 kubectl 工具 或者 API 任何集群管理。 Master 节点主要有三个服务 kube-apiserver、kube-controller-mansger 和 kubescheduler,其中 kube-controller-mansger 和 kube-scheduler 组件自身通过选择机制已 经实现了高可用,所以 Master 高可用主要针对 kube-apiserver 组件,而该组件是以 HTTP API 提供服务,因此对他高可用与 Web 服务器类似,增加负载均衡器对其负载均衡即可, 并且可水平扩容。

架构图:

image

VIP指的是虚拟ip

十三、卸载

yum remove -y kubelet kubeadm kubectl

kubeadm reset -f
modprobe -r ipip
lsmod
rm -rf ~/.kube/
rm -rf /etc/kubernetes/
rm -rf /etc/systemd/system/kubelet.service.d
rm -rf /etc/systemd/system/kubelet.service
rm -rf /usr/bin/kube*
rm -rf /etc/cni
rm -rf /opt/cni
rm -rf /var/lib/etcd
rm -rf /var/etcd