一、安装k8s集群

前置准备:准备两台2核cpu、2G内存的服务器
本例的master和node1节点的ip分别为[192.168.106.137]、[192.168.106.138]

在这里插入图片描述在这里插入图片描述

1.前置配置

# 每个节点分别设置对应主机名
hostnamectl set-hostname master #master节点设置
hostnamectl set-hostname node1  #node1节点设置
# 所有节点都修改 hosts
vi /etc/hosts
192.168.106.138 node1
192.168.106.137 master

在这里插入图片描述

# 所有节点关闭 SELinux
setenforce 0
sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
# 所有节点确保防火墙关闭
systemctl stop firewalld
systemctl disable firewalld
# 所有节点关闭swap分区
sudo swapoff -a  #临时关闭
vi /etc/fstab  #永久关闭 如果选择永久关闭的话要重启或者再执行一次临时关闭
#注释掉以下内容
/dev/mapper/cl-swap  swap  swap defaults 0 0

在这里插入图片描述

# 所有节点开启ipvs
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 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

【无视下方内容,直接到添加安装源】

# 无视这个内容,直接到添加安装源
1.设置允许路由转发、不对bridge的数据进行处理(所有节点) --> 这步与后面的错误情况之一比较类似
vi /etc/sysctl.d/k8s.conf
#内容如下
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
#执行文件
sysctl -p /etc/sysctl.d/k8s.conf

2.添加安装源(所有节点)

# 添加 k8s 安装源
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/
# 安装yum工具
yum -y install yum-utils
# 添加 Docker 安装源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装所需组件(所有节点)

yum install -y kubelet-1.18.6 kubectl-1.18.6 kubeadm-1.18.6 docker-ce-18.03.1.ce

注意,kubelet 1.24 以上的版本会报错

启动 kubelet、docker,并设置开机启动(所有节点)

systemctl enable kubelet
systemctl start kubelet
systemctl enable docker
systemctl start docker

修改 docker 配置(所有节点)

# kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了
cat <<EOF > daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": ["https://ud6340vz.mirror.aliyuncs.com"]
}
EOF
mv daemon.json /etc/docker/

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

3.用 kubeadm 初始化集群(仅在主节点跑)

# --pod-network-cidr 10.244.0.0/16 可以不指定,默认似乎就是这个
kubeadm init --image-repository=registry.aliyuncs.com/google_containers --pod-network-cidr 10.244.0.0/16
# 复制授权文件,以便 kubectl 可以有权限访问集群。 如果你其他节点需要访问集群,需要从主节点复制这个文件过去其他节点
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# 保存密钥,如图。如果忘记了执行如下命令重新获取
kubeadm token create --print-join-command

在这里插入图片描述


# 初始化失败了可以用 kubeadm reset 重置
# 重置方法 链接
https://www.cnblogs.com/shunzi115/p/14776507.html

# 如果出现/proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
# 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 使系统修改生效
sysctl --system

4.把工作节点加入集群(所有node工作节点)

# 刚刚保存的那串密钥
kubeadm join 192.168.106.137:6443 --token xxx --discovery-token-ca-cert-hash xxx

在这里插入图片描述

5.安装网络插件,否则 node 是 NotReady 状态(主节点跑)

kube-flannel.yml网盘文件

执行如下命令的话,它会在每个节点下载安装两个docker镜像,【flannel】、【flannel-cni-plugin】
如果有本地文件的话,可以提前 docker load -i 一下

#安装网络插件 ps:很有可能国内网络访问不到这个资源,你可以网上找找国内的源安装 flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#本地有yml文件的话
kubectl apply -f kube-flannel.yml
# flannel如果出现卡在CrashLoopBackOff状态
kubectl logs -n kube-flannel kube-flannel-ds-7qc82
# 查看对应日志 一般都是这个Error registering network: failed to acquire lease: node “master“ pod cidr not assigne
# 解决办法
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
#找到spec->containers->command
#增加参数:
--allocate-node-cidrs=true
--cluster-cidr=10.244.0.0/16  #这个一般在kubeadm init的时候可以指定 不指定就是这个默认值

# 如果上面的插件安装失败,可以选用 Weave,下面的命令二选一就可以了。
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
kubectl apply -f http://static.corecore.cn/weave.v2.8.1.yaml

# 更多其他网路插件查看下面介绍,自行网上找 yaml 安装
https://blog.csdn.net/ChaITSimpleLove/article/details/117809007

6.查看节点,要在主节点查看(其他节点有安装 kubectl 也可以查看)

kubectl get nodes

在这里插入图片描述


二.部署应用到集群中

1.部署服务

直接命令运行

kubectl run testapp --image=helloworldcontainers/java-spring-boot-hello-world:latest

helloworldcontainers/java-spring-boot-hello-world:latest : 一个helloworld的服务

在这里插入图片描述

执行命令将pod端口映射到本地:kubectl port-forward testapp 8090:8080 --address 0.0.0.0
访问地址:http://ip:8090

在这里插入图片描述

pod运行

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  # 定义容器,可以多个
  containers:
    - name: test-k8s # 容器名字
      image: docker镜像地址 # 镜像

Deployment运行

apiVersion: apps/v1
kind: Deployment
metadata:
  # 部署名字
  name: test-k8s
spec:
  replicas: 2  #部署几个pod
  # 用来查找关联的 Pod,所有标签都匹配才行
  selector:
    matchLabels:
      app: test-k8s
  # 定义 Pod 相关数据
  template:
    metadata:
      labels:
        app: test-k8s
    spec:
      # 定义容器,可以多个
      containers:
      - name: test-k8s # 容器名字
        image: docker镜像地址 # 镜像

2.结合harbor使用的Deployment(simpleapp.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  # 部署名字
  name: simpleapp-k8s
spec:
  replicas: 2
  # 用来查找关联的 Pod,所有标签都匹配才行
  selector:
    matchLabels:
      app: simpleapp-k8s
  # 定义 Pod 相关数据
  template:
    metadata:
      labels:
        app: simpleapp-k8s
    spec:
      # 定义容器,可以多个
      containers:
      - name: simpleapp-k8s # 容器名字
        image: 192.168.106.130:85/demo/simple:v1  #harbor镜像地址
      imagePullSecrets:
      - name: harborlogin #下方secret的name

上方harbor需要登入的密钥(secret.yaml)

apiVersion: v1
kind: Secret
metadata:
  name: harborlogin
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEwNi4xMzA6ODUiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
 #注意 需要在每个节点都要添加harbor免密,否则在创建deployment的时候会拉取镜像失败
 #该json文件在执行docker login 后会生成
 #上方的密钥为下方json文件的base64编码
 cat ~/.docker/config.json 
 cat ~/.docker/config.json |base64 -w 0
#将secret.yaml装载到k8s
kubectl create -f secret.yaml
#查看密钥
kubectl get secret

3.一些命令

# 部署应用
kubectl apply -f app.yaml
# 查看 deployment
kubectl get deployment
# 查看所有pod
kubectl get pod --all-namespaces  #等效于 kubectl get pod -A
# 查看指定命名空间pod(比如kube-system)
kubectl get pod -n kube-system
# 查看 pod
kubectl get pod -o wide
# 查看 pod 详情
kubectl describe pod pod-name
# 查看 log
kubectl logs pod-name
# 进入 Pod 容器终端, -c container-name 可以指定进入哪个容器。
kubectl exec -it pod-name -- bash
# 伸缩扩展副本
kubectl scale deployment test-k8s --replicas=5
# 把集群内端口映射到节点  增加--address虚拟机就可以在节点访问容器了 否则只能在pod里访问
kubectl port-forward pod-name 8090:8080 --address 0.0.0.0
# 查看历史
kubectl rollout history deployment test-k8s
# 回到上个版本
kubectl rollout undo deployment test-k8s
# 回到指定版本
kubectl rollout undo deployment test-k8s --to-revision=2
# 删除部署
kubectl delete deployment test-k8s
# -------------------------更多命令-------------------------------
# 查看全部
kubectl get all
# 重新部署
kubectl rollout restart deployment test-k8s
# 命令修改镜像,--record 表示把这个命令记录到操作历史中
kubectl set image deployment test-k8s test-k8s=ccr.ccs.tencentyun.com/k8s-tutorial/test-k8s:v2-with-error --record
# 暂停运行,暂停后,对 deployment 的修改不会立刻生效,恢复后才应用设置
kubectl rollout pause deployment test-k8s
# 恢复
kubectl rollout resume deployment test-k8s
# 输出到文件
kubectl get deployment test-k8s -o yaml >> app2.yaml
# 删除全部资源
kubectl delete all --all

如果你运行 kubectl describe pod/pod-name 发现 Events 中有下面这个错误

networkPlugin cni failed to set up pod "test-k8s-68bb74d654-mc6b9_default" network: open /run/flannel/subnet.env: no such file or directory

在每个节点创建文件/run/flannel/subnet.env写入以下内容,配置后等待一会就好了(可以重启docker?)

FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

更多官网关于 Deployment 的介绍

将 Pod 指定到某个节点运行:nodeselector
限定 CPU、内存总量:文档

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

工作负载分类

  • Deployment
    适合无状态应用,所有pod等价,可替代
  • StatefulSet
    有状态的应用,适合数据库这种类型。
  • DaemonSet
    在每个节点上跑一个 Pod,可以用来做节点监控、节点日志收集等
  • Job & CronJob
    Job 用来表达的是一次性的任务,而 CronJob 会根据其时间规划反复运行。

文档

现存问题

  • 每次只能访问一个 pod,没有负载均衡自动转发到不同 pod
  • 访问还需要端口转发
  • Pod 重创后 IP 变了,名字也变了

下节我们讲解如何解决。


三、创建 Service

创建 一个 Service,通过标签test-k8s跟对应的 Pod 关联上
service.yaml

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s  #注意这个标签绝对要正确 不然无法访问
  type: ClusterIP
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口

应用配置 kubectl apply -f service.yaml
查看服务 kubectl get svc
在这里插入图片描述

查看服务详情 kubectl describe svc test-k8s,可以发现 Endpoints 是各个 Pod 的 IP,也就是他会把流量转发到这些节点。

服务的默认类型是ClusterIP,只能在集群内部访问,我们可以进入到 Pod 里面访问:
kubectl exec -it pod-name -- bash
curl http://test-k8s:8080

如果要在集群外部访问,可以通过端口转发实现(只适合临时测试用):
kubectl port-forward service/test-k8s 8888:8080

对外暴露服务

上面我们是通过端口转发的方式可以在外面访问到集群里的服务,如果想要直接把集群服务暴露出来,我们可以使用NodePortLoadbalancer 类型的 Service

apiVersion: v1
kind: Service
metadata:
  name: test-k8s
spec:
  selector:
    app: test-k8s   #注意这个标签绝对要正确 不然无法访问
  # 默认 ClusterIP 集群内可访问,NodePort 节点可访问,LoadBalancer 负载均衡模式(需要负载均衡器才可用)
  type: NodePort
  ports:
    - port: 8080        # 本 Service 的端口
      targetPort: 8080  # 容器端口
      nodePort: 31000   # 节点端口,范围固定 30000 ~ 32767

应用配置 kubectl apply -f service.yaml
在这里插入图片描述
此刻可以选择节点ip访问 http://192.168.106.137:31000/ (注意,暴露service的服务得是deployment模式运行的!因为deployment模式有标签选择,跟service的标签选择对应上)
在这里插入图片描述

在节点内部,我们也可以 curl http://localhost:31000/ 访问到应用

并且是有负载均衡的。
pod报错解决

如果出现主节点无法访问service、其他节点可以访问 ->
解决方案


四、rancher部署结合k8s

前置准备:
准备一台新的服务器
执行一遍k8s的前置配置(hosts那些)
linux务必要有4G内存 3G应该也可以

  1. 安装并运行docker
  2. 拉取rancher
//注意 一定要是这个版本 其他版本可能会不行 原因如下方链接
//https://blog.k4nz.com/db239dfdf4d4d2319fcaaad89ae25311/
docker pull rancher/rancher:v2.5.12
//如果有本地的tar文件,可以直接docker load一下
  1. 运行rancher
docker run --privileged --name=rancher -d --restart=unless-stopped -p 80:80 -p 443:443 -v /rancherdata:/var/lib/rancher rancher/rancher:v2.5.12

在这里插入图片描述

  1. 打开rancher网页(设置密码,其他默认配置)
https://ip地址
  1. 添加集群,选择导入集群 选择无证书的那个 然后复制到k8s主节点运行(第一次会失败,再来一次) 完事

运行实际上是在node节点安装rancher-agent镜像,所以如果有本地tar文件,也可以先load一下

在这里插入图片描述

  1. 网页中会显示xx不健康,可以百度解决,是一个配置的问题来着,不过没必要。。。
    在这里插入图片描述

五、helm安装loki日志收集+grafana展示

1.安装helm

#以下在master节点执行
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
#安装失败的话 手动安装
tar -zxvf  helm-v3.11.3-linux-amd64.tar.gz
cp -a linux-amd64/helm /usr/local/bin/
chmod a+x /usr/local/bin/helm

2.添加repo并更新(这步要等一会)

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

在这里插入图片描述

3.创建loki命名空间

kubectl create namespace loki

4.安装loki

# 注意这里后面是 -stack 的是默认打包好在一起的,没stack的是默认只有 loki 的,自定义安装请参考官网给出的命令
helm upgrade --install loki --namespace=loki grafana/loki-stack

在这里插入图片描述

5.安装grafana

# 安装grafana
kubectl apply -f grafana.yaml
# 打开grafana网页,选择loki数据源,导入dashbord面板
# 文件在网盘中(Loki_Kubernetes_Logs-1681870713163)

6.打开grafana首页,选择loki数据源,默认账号密码admin
192.168.106.137:32554 ps:这个端口是随机的,执行命令kubectl get svc查看
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

7.自行diy面板或导入模板
模板地址https://grafana.com/grafana/dashboards/
我的模板json文件
在这里插入图片描述

选择上传json文件导入。(参数那些要重新设置一下loki源),不然如下图没数据
在这里插入图片描述
点击上图中的设置按钮(在选择时间范围的左边那个)
在这里插入图片描述
在这里插入图片描述
结果
在这里插入图片描述

如下为grafana.yaml文件

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: grafana
  name: grafana
  namespace: default
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 10555
        fsGroup: 10555
      containers:
        - name: grafana
          image: grafana/grafana:9.2.4
          imagePullPolicy: IfNotPresent
          env:
            - name: GF_AUTH_BASIC_ENABLED
              value: "true"
            - name: GF_AUTH_ANONYMOUS_ENABLED
              value: "false"
          readinessProbe:
            httpGet:
              path: /login
              port: 3000
          volumeMounts:
            - mountPath: /var/lib/grafana
              name: grafana-data-volume
          ports:
            - containerPort: 3000
              protocol: TCP
      volumes:
        - name: grafana-data-volume
          emptyDir: {}
---
kind: Service
apiVersion: v1
metadata:
  labels:
    app: grafana
  name: grafana-service
  namespace: default
spec:
  ports:
    - port: 3000
      targetPort: 3000
  selector:
    app: grafana
  type: NodePort

Logo

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

更多推荐