Skip to content

kubernetes 环境搭建之 minikube for CentOS

minikube start

官方文档:https://minikube.sigs.k8s.io/docs/start/

由于国内网络原因,使用 aliyun 版本的 minikube: https://github.com/AliyunContainerService/minikube

Wiki: https://github.com/AliyunContainerService/minikube/wiki

文档:https://developer.aliyun.com/article/221687

Installation

前提条件

  • 配置了 163 repo 源
  • 已经安装了 Docker
  • 关闭 CentOS 中的防火墙

安装 conntrack

在 Vmware 中的 CentOS 下启动 minikube, 需要安装 conntrack, 解决方法:下载 yum 源,安装依赖包

bash
cd /etc/yum.repos.d/
wget http://mirrors.aliyun.com/repo/epel-7.repo
wget http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all && yum makecache
yum -y install epel-release && yum -y install conntrack-tools

k8s 运行要求 docker 的--cgroup-driver=systemd

  • 配置 Docker 镜像加速器
  • 您可以通过修改 daemon 配置文件/etc/docker/daemon.json 来使用加速器
  • 并且配置 k8s 运行要求 docker 的--cgroup-driver=systemd
bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://bfflggen.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

关闭 selinux

bash
# 查看selinux是否关闭
[root@centos7 yum.repos.d]# getenforce
Enforcing # Enforcing 为未关闭

# 先设置当前环境临时关闭,就不用重启操作系统了
[root@centos7 yum.repos.d]# setenforce 0
[root@centos7 yum.repos.d]# getenforce
Permissive # Permissive 已关闭

# 然后设置永久关闭
[root@centos7 yum.repos.d]# vi /etc/sysconfig/selinux
设置:SELINUX=disabled

[root@centos7 yum.repos.d]# cat /etc/sysconfig/selinux

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
# 这一行显示为 disabled.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

关闭 swap

bash
# k8s要求系统关闭,否则安装过程会报错
# 查看系统是否关闭了swap
[root@centos7 yum.repos.d]# top
top - 12:43:28 up  1:55,  2 users,  load average: 0.15, 0.21, 0.29
Tasks: 113 total,   1 running, 112 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.9 us,  0.5 sy,  0.0 ni, 98.3 id,  0.2 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem :  1863032 total,   623164 free,   411380 used,   828488 buff/cache
# 下面这一行表示 swap 没有关闭
KiB Swap:  2097148 total,  2095348 free,     1800 used.  1277688 avail Mem

# 先设置当前环境临时关闭,就不用重启操作系统了
[root@centos7 yum.repos.d]# swapoff -a
[root@centos7 yum.repos.d]# top
top - 12:49:05 up  2:00,  2 users,  load average: 0.06, 0.12, 0.22
Tasks: 118 total,   1 running, 117 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.1 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1863032 total,   622488 free,   409664 used,   830880 buff/cache
# 下面这一行表示 swap 已经关闭。都是 0
KiB Swap:        0 total,        0 free,        0 used.  1279404 avail Mem

# 然后设置永久关闭。注释掉swap那一行
[root@centos7 yum.repos.d]# vi /etc/fstab
[root@centos7 yum.repos.d]# cat /etc/fstab
# /etc/fstab
# Created by anaconda on Tue Mar 23 18:33:21 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=ae5b7810-0161-4858-98e4-799b61266440 /boot                   xfs     defaults        0 0
# 下面这一行前面添加了 # 号,注释掉了
#/dev/mapper/centos-swap swap                    swap    defaults        0 0

安装 kubectl 并配置 kubernetes.repo 源

配置 kubernetes.repo

bash
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=0
EOF
bash
cd /etc/yum.repos.d

# 查看文件:kubernetes.repo
ll

yum clean all && yum makecache

# 检查是否安装成功
yum repolist

安装 kubectl

bash
yum install -y kubectl

[root@centos7 yum.repos.d]# kubectl version
Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.5", GitCommit:"6b1d87acf3c8253c123756b9e61dac642678305f", GitTreeState:"clean", BuildDate:"2021-03-18T01:10:43Z", GoVersion:"go1.15.8", Compiler:"gc", Platform:"linux/amd64"}
The connection to the server localhost:8080 was refused - did you specify the right host or port?

启动 minikube

bash

# Minikube 还支持使用一个 --vm-driver=none 选项,让 Kubernetes 组件运行在主机中,而不是在 VM 中。 使用这种驱动方式需要 Docker 和 Linux 环境,但不需要 hypervisor,但 none 不支持 Ingress, 一般使用 --vm-driver=docker。
# 但此处使用 --vm-driver=docker 会有这个问题:The "docker" driver should not be used with root privileges
# 于是创建用户(或者有非root用户,可以不用创建新用户):
useradd mengweijin
# 设置密码,回车后,输入两边密码
passwd mengweijin

# 下载 minikube aliyun 版本。最新版本的 minikube 参考本文最前面章节的链接。
curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.18.1/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

# 这里一定使用 mengweijin 用户登录,然后 切换到 root 用户执行以下命令:
# 将您的用户添加到该docker组。激活对组的更改:newgrp docker
# 如果后面依然报这个错,再次切换到root执行该命令,然后再切换回mengweijin用户继续执行
usermod -aG docker $USER && newgrp docker

# 再切换为刚创建的用户,然后启动minikube
su mengweijin

# 正式启动(记得每次切换为 mengweijin用户启动)
minikube start --vm-driver=docker --cpus=4 --memory=4096mb

# start 日志如下
[mengweijin@centos7 bin]$ minikube start --vm-driver=docker
* Centos 7.9.2009 上的 minikube v1.17.1
* 根据用户配置使用 docker 驱动程序

X Requested memory allocation (1819MB) is less than the recommended minimum 1900MB. Deployments may fail.


X The requested memory allocation of 1819MiB does not leave room for system overhead (total system memory: 1819MiB). You may face stability issues.
* 建议:Start minikube with less memory allocated: 'minikube start --memory=1819mb'

* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Creating docker container (CPUs=2, Memory=1819MB) ...
    > kubectl: 38.37 MiB / 38.37 MiB [-------------] 100.00% 902.39 KiB p/s 43s
    > kubelet: 108.73 MiB / 108.73 MiB [------------] 100.00% 1.82 MiB p/s 1m0s
  - Generating certificates and keys ...
  - Booting up control plane ...
  - Configuring RBAC rules ...
* Verifying Kubernetes components...
* Enabled addons: default-storageclass, storage-provisioner
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default



# 安装完毕后,在命令行输入以下命令来验证是否安装成功。
minikube status

# Linux 下如果没有安装 kubectl, 可以这样使用 kubectl 命令(建议安装):
minikube kubectl -- get po -A

# 如果安装了,这样查询
kubectl get po -A

# 打开Kubernetes控制台(mengweijin用户)
minikube dashboard

[root@centos7 yum.repos.d]# minikube dashboard
* 正在开启 dashboard ...
* 正在验证 dashboard 运行情况 ...
* Launching proxy ...
* 正在验证 proxy 运行状况 ...
http://127.0.0.1:36524/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

# 此时,不能关闭当前进程和窗口,由于是在Vmware中的CentOS启动的dashboard, 要在Windows下的浏览器中访问:
# 用SSH工具新开一个连接窗口,开启代理(mengweijin用户)
# kube-proxy 端口转发
kubectl proxy --address=0.0.0.0 --disable-filter=true

[root@centos7 ~]# kubectl proxy --address='0.0.0.0' --disable-filter=true
W0323 13:23:25.795951   38729 proxy.go:167] Request filter disabled, your proxy is vulnerable to XSRF attacks, please be cautious
Starting to serve on [::]:8001

# 依然不能关闭当前进程和窗口,Windows 浏览器访问 dashboard:
http://<CentOS虚拟机的IP>:<端口为上面proxy中显示的端口,默认8001>/api/v1/namespaces/<服务的namespace>/services/http:<服务名称>:<服务端口>/proxy/

# Windows 浏览器访问示例:
http://192.168.171.131:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

kubectl proxy

让外部网络访问 K8S service 的 ClusterIP

bash
# 使用kubectl proxy命令就可以使API server监听在本地的8001端口上:
kubectl proxy
Starting to serve on 127.0.0.1:8001

# 如果想通过其它主机访问就需要指定监听的地址:
kubectl proxy --address=0.0.0.0

# 此时通过curl访问会出现未认证的提示:
curl -X GET -L http://k8s-master:8009/
<h3>Unauthorized</h3>

# 设置API server接收所有主机的请求:
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'
Starting to serve on [::]:8001

# 访问正常:
curl -X GET -L http://k8s-master:8009/
{
  "paths": [
    "/api",
    "/api/v1",
    ...
  ]
}

# 指定一个端口:
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$' --port=8009
Starting to serve on [::]:8009

# 关于未认证的问题,干脆禁用:
kubectl proxy --address='0.0.0.0' --disable-filter=true

minikube aliyun 说明

为了访问海外的资源,阿里云提供了一系列基础设施,请按照如下参数进行配置。其中常见参数

  • --driver=*** 从 1.5.0 版本开始,Minikube 缺省使用本地最好的驱动来创建 Kubernetes 本地环境,测试过的版本 docker, kvm
  • --image-mirror-country cn 将缺省利用 registry.cn-hangzhou.aliyuncs.com/google_containers 作为安装 Kubernetes 的容* 器镜像仓库 (阿里云版本可选)
  • --iso-url=*** 利用阿里云的镜像地址下载相应的 .iso 文件 (阿里云版本可选)
  • --registry-mirror=***为了拉取 Docker Hub 镜像,需要为 Docker daemon 配置镜像加速,参考阿里云镜像服务
  • --cpus=2: 为 minikube 虚拟机分配 CPU 核数
  • --memory=2048mb: 为 minikube 虚拟机分配内存数
  • --kubernetes-version=***: minikube 虚拟机将使用的 kubernetes 版本

启用 Ingress

官方文档:https://kubernetes.io/zh/docs/tasks/access-application-cluster/ingress-minikube/

bash
# 用时较长,耐心等待,如果第一遍开启失败,多尝试几遍
minikube addons enable ingress

# 查看
minikube addons list

# 检查验证 NGINX Ingress 控制器处于运行状态
kubectl get pods -n kube-system

部署 nginx.yaml

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.16.1
          # IfNotPresent, Always, Never
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  # #如果使用Ingress, 这里可以不通过NodePort暴露端口,即可以注释掉。这里为了测试Service, 所以暴露出来
  type: NodePort
  selector:
    app: nginx
  ports:
    # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 80
      targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  annotations:
    # 指定了我们使用后端ingress controller的类别,如果后端有多个ingress controller的时候很重要
    kubernetes.io/ingress.class: "nginx"
    # nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: mengweijin.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80

说明

查看当前可用的 API 版本

kubectl api-versions

关于限制 cpu 和内存,建议学习环境不要限制,限制了容易启动卡死,必须分配足够的资源才行。

minikube ssh : 进入 Docker 容器

执行部署命令:

bash
# --record 标志将所执行的命令写入资源注解 kubernetes.io/change-cause 中。 这对于以后的检查是有用的。例如,要查看针对每个 Deployment 修订版本所执行过的命令。
kubectl apply -f nginx.yaml --record

使用 Service 访问应用

bash
# 方式一 VMware 虚拟机中访问
# 显示访问 service 的 url: 然后把这个 url 放到浏览器里
minikube service nginx --url
# port 通过 kubectl get service nginx 查看
curl url:port

# 方式二 Windows 下访问
# 或者通过 kubectl port-forward 端口转发的方式访问 K8S 中的应用
kubectl port-forward service/nginx 7000:80
# Windows 下访问(或用浏览器访问 mengweijin.com)
curl http://localhost:7000

# 方式三 Windows 下访问
# kube-proxy 端口转发(在新的 ssh 窗口下运行),转发端口:8001
kubectl proxy --address=0.0.0.0 --disable-filter=true
# Windows 下访问:
http://192.168.171.131:8001/api/v1/namespaces/default/services/http:nginx:80/proxy/

使用 Ingress 访问应用

bash
kubectl get ingress

# 命令行输出
PS C:\Users\mengweijin\Documents\MobaXterm\home> kubectl get ingress
NAME    CLASS    HOSTS            ADDRESS        PORTS   AGE
nginx   <none>   mengweijin.com   192.168.49.2   80      14m

Ingress 中没有配置 host 路由

bash
# 如果 Ingress 中没有配置host路由: host: mengweijin.com,直接可以使用如下IP访问到。
curl 192.168.49.2

Ingress 中配置了 host 路由

bash
# (root用户)
vi /etc/hosts
# 在 hosts 文件的末尾添加以下内容
192.168.49.2 mengweijin.com

# 使hosts立刻生效
/etc/init.d/network restart

# 说明: 如果你在本地运行 Minikube 环境,需要使用下面命令获得外部 IP 地址。 Ingress 列表中显示的 IP 地址会是内部 IP 地址。
minikube ip

# 查看 ingress 映射详情
kubectl describe ingress nginx

# 在CentOS虚拟机中访问(或用CentOS中的浏览器访问 mengweijin.com)能看到 nginx 首页
curl mengweijin.com

Windows 浏览器访问 ingress 服务

类似于访问 dashboard, 开启 proxy 后:

bash
http://192.168.171.131:8001/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

# 照猫画虎
http://192.168.171.131:8001/api/v1/namespaces/default/services/http:nginx:/proxy/

Manage your cluster

bash
# Pause Kubernetes without impacting deployed applications:
minikube pause

# Halt the cluster:
minikube stop

# Increase the default memory limit (requires a restart):
minikube config set memory 16384

# Browse the catalog of easily installed Kubernetes services:
minikube addons list

# Create a second cluster running an older Kubernetes release:
minikube start -p aged --kubernetes-version=v1.16.1

# Delete all of the minikube clusters:
minikube delete --all

kubectl

bash
kubectl version
kubectl get namespace
kubectl get nodes
kubectl describe node nodeName
kubectl apply -f nginx.yaml --record
kubectl get deployment
kubectl get deployments
kubectl get pods
kubectl get pods -o wide
kubectl get pods --all-namespaces
kubectl get service
kubectl get all
kubectl get all --all-namespaces
kubectl describe pod nginx
kubectl delete -f nginx.yaml
kubectl delete deployment nginx
kubectl delete service nginx
kubectl logs -f podName
kubectl exec -it podName -- /bin/bash
kubectl port-forward service/nginx 7000:8888
kubectl describe quota                        # 查看当前 namespace 下的cpu, memory, storage 的限制和使用情况
kubectl get pods/podname -o yaml
kubectl get deployment ingress-nginx-controller -n kube-system -o yaml
kubectl get deployment ingress-nginx-controller -n kube-system -o yaml > ingress-nginx-controller-deploy.yaml
--enable-ssl-passthrough

kubectl patch deployment ingress-nginx-controller --patch "$(cat ingress-nginx-patch.yaml)" -n kube-system
# 监控 ingress-nginx-controller 日志
kubectl get pods -n kube-system
kubectl -n kube-system logs -f ingress-nginx-controller-84db5fd745-xqdc4

# 在 ingress-nginx-controller pod 中可以测试请求外面的服务
kubectl exec -n kube-system <ingress pod> -- curl -v <service name>:8080

kubectl exec -it -n kube-system ingress-nginx-controller-6c8559fd4d-2r8xf -- cat /etc/nginx/nginx.conf

kubectl label namespace default istio-injection-

# 从本地复制 aaa.txt 文件到 容器 application-demo-deployment-823726322c-9ssfd9 中的 /tmp 目录下
kubectl cp -n default aaa.txt application-demo-deployment-823726322c-9ssfd9:/tmp

# 从Pod容器中copy文件至本地
kubectl cp <some-namespace>/<some-pod>:<root_dir>/<parent_dir>/temp/lalalaB ./lalalaC
kubectl cp default/cloud-786d84c554-p7jz7:app/logs/app/cloud.log cloud.log

k8s 对外暴露服务的方法

向 k8s 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress。每种方式都有各自的优缺点。

  • nodePort 方式在服务变多的情况下会导致节点要开的端口越来越多,不好管理。
  • LoadBalancer 更适合结合云提供商的 LB 来使用,但是在 LB 越来越多的情况下对成本的花费也是不可小觑。
  • Ingress 是 k8s 官方提供的用于对外暴露服务的方式,也是在生产环境用的比较多的方式,一般在云环境下是 LB + Ingress Controller 方式对外提供服务,这样就可以在一个 LB 的情况下根据域名路由到对应后端的 Service,有点类似于 Nginx 反向代理,只不过在 k8s 集群中,这个反向代理是集群外部流量的统一入口。

K8S 中同一集群服务之间的访问

k8s 的服务名 DNS 解析

Kubernetes 目前使用的 kube-dns 来实现集群内部的 service dns 记录解析。默认情况下/etc/resolv.conf 里,它的内容是统一的格式。

bash
/ # more /etc/resolv.conf
nameserver 172.19.0.10
search saas.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

search doamin 列表默认情况下,它只包含本地域名。这可以通过在 search 关键字后面列出所需的域搜索路径来添加。kubernetes 为每个容器配置默认是${namespace}.svc.cluster.local svc.cluster.local cluster.local。在一次 dns 域名查询时,将会尝试使用每个 search doamin 依次搜索少于 ndots 点(默认值为 1)的解析器查询,直到找到匹配项。对于具有多个子域的环境,建议调整选项 ndots:n,以避免 man-in-the-middle 攻击和 root-dns-servers 的不必要通信。

这个我们可以把它理解成服务名 dns 解析的层次,例如{服务名}是一级,而{服务名}.{命名空间}为二层,{服务名}.{命名空间}.svc.cluster.local 是第三层,上面的配置一共有 5 层,同时也开启了 5 层,这样做可以保证最大限度的找到你的服务,但对于解析的性能是有影响的。

同一 namespace 下的 pod 之间的访问

假如 A 服务(serviceName=aaaa) 调用 B 服务(serviceName=bbbb)中的接口:http://localhost:8080/test

那么在 A 工程中可以通过 B 服务的 serviceName 来调用 B 服务。例如在 A 服务中配置 B 服务中的接口格式为:http://bbbb:8080/test

跨 namespace 下的 pod 之间的访问

假如 A 服务(namespace=ns1, serviceName=aaaa) 调用 B 服务(namespace=ns2, serviceName=bbbb)中的接口:http://localhost:8080/test

A 服务调用 B 服务的调用方式为:http://bbbb.ns2:8080/test