k8s解决证书过期问题

在k8s中的时间会提示证书过期问题,如

# kubectl get nodes
Unable to connect to the server: x509: certificate has expired or is not yet valid

这里我们介绍一下续期方法。

注意:当前集群通过 kubeadm 命令创建。

kubeadm 安装得证书默认为 1 年,注意原证书文件必须保留在服务器上才能做延期操作,否则就会重新生成,集群可能无法恢复

准备

这里先查看一下测试集群的证书过期时间

# kubeadm certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Aug 30, 2022 03:18 UTC   324d                                    no      
apiserver                  Aug 30, 2022 03:18 UTC   324d            ca                      no      
apiserver-etcd-client      Aug 30, 2022 03:18 UTC   324d            etcd-ca                 no      
apiserver-kubelet-client   Aug 30, 2022 03:18 UTC   324d            ca                      no      
controller-manager.conf    Aug 30, 2022 03:18 UTC   324d                                    no      
etcd-healthcheck-client    Aug 30, 2022 03:18 UTC   324d            etcd-ca                 no      
etcd-peer                  Aug 30, 2022 03:18 UTC   324d            etcd-ca                 no      
etcd-server                Aug 30, 2022 03:18 UTC   324d            etcd-ca                 no      
front-proxy-client         Aug 30, 2022 03:18 UTC   324d            front-proxy-ca          no      
scheduler.conf             Aug 30, 2022 03:18 UTC   324d                                    no      

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Aug 28, 2031 03:18 UTC   9y              no      
etcd-ca                 Aug 28, 2031 03:18 UTC   9y              no      
front-proxy-ca          Aug 28, 2031 03:18 UTC   9y              no  

可以看到过期时间为 2022-08-30。

Continue reading

k8s安装负载均衡器:Metallb

在使用kubenetes的过程中,如何将服务开放到集群外部访问是一个重要的问题。当使用云平台(阿里云、腾讯云、AWS等)的容器服务时,我们可以通过配置 service 为 LoadBalancer 模式来绑定云平台的负载均衡器,从而实现外网的访问。但是,如果对于自建的 kubernetes裸机集群,这个问题则要麻烦的多。

祼机集群不支持负载均衡的方式,可用的不外乎NodePort、HostNetwork、ExternalIPs等方式来实现外部访问。但这些方式并不完美,他们或多或少都存在的一些缺点,这使得裸机集群成为Kubernetes生态系统中的二等公民。

MetalLB 旨在通过提供与标准网络设备集成的Network LB实施来解决这个痛点,从而使裸机群集上的外部服务也尽可能“正常运行”,减少运维上的管理成本。它是一种纯软件的解决方案,参考 https://kubernetes.github.io/ingress-nginx/deploy/baremetal/

从 v0.13.0 版本开始,官方对解决方案进行了部分调整,操作步骤简洁一些,建议使用最新版本,参考官方教程 https://metallb.universe.tf/installation/

Continue reading

在linux下安装Kubernetes

环境 ubuntu18.04 64位

为了解决国内访问一些国外网站慢的问题,本文使用了国内阿里云的镜像。

更换apt包源

这里使用aliyun镜像 https://developer.aliyun.com/mirror/, 为了安全起见,建议备份原来系统默认的 /etc/apt/sources.list 文件

编辑文件 /etc/apt/sources.list,将默认网址 http://archive.ubuntu.com 或 http://cn.archive.ubuntu.com 替换为 http://mirrors.aliyun.com

更新缓存

$ sudo apt-get clean all
$ sudo apt-get update

安装Docker

参考官方文档 https://docs.docker.com/engine/install/ubuntu/ 或 aliyun 文档 https://developer.aliyun.com/mirror/docker-ce

Continue reading

初识kubernetes

对于一个刚刚接触kubernetes(k8s)的新手来说,想好更好的学习它,首先就要对它有一个大概的认知,所以本文我们先以全局观来介绍一个kubernetes。

kubernetes架构

8ee9f2fa987eccb490cfaa91c6484f67
kubernetes 架构图

kubernets整体可以分为两大部分,分别为 MasterNode ,我们一般称其为节点,这两种角色分别对应着控制节点和计算节点,根据我们的经验可以清楚的知道 Master 是控制节点。

Master 节点

控制节点 Master 节点由三部分组成,分别为 Controller ManagerAPI ServerScheduler ,它们相互紧密协作,每个部分负责不同的工作职责。

  • controller-manager 全称为 kube-controler-manager 组件,主要用来负责容器编排。如一个容器(实际上是pod,pod是最基本的调度单元。一般一个pod里会部署一个容器服务)服务可以指定副本数量,如果实际运行的副本数据与期望的不一致,则会自动再启动几个容器副本,最终实现期望的数量。这个组件,就是一系列控制器的集合。我们可以查看一下 Kubernetes 项目的 pkg/controller 目录, 伪代码如下:
for {
  实际状态 := 获取集群中对象X的实际状态(Actual State)
  期望状态 := 获取集群中对象X的期望状态(Desired State)
  if 实际状态 == 期望状态{
    什么都不做
  } else {
    执行编排动作,将实际状态调整为期望状态
  }
}
  • api server 对外提供api服务,用来接收命令进行集群管理。对内负责与etcd注册中心进行通讯,进行一些配置信息的存储与读取
  • scheduler 负责调度。如一个容器存放到k8s集群中的哪个node节点最为合适

实际上这三个节点的功能远远多于我们描述的。

Continue reading

k8s中的Service与Ingress

集群中的服务要想向外提供服务,就不得不提到Service和Ingress。 下面我们就介绍一下两者的区别和关系。

Service

必须了解的一点是 Service 的访问信息在 Kubernetes 集群内是有效的,集群之外是无效的

Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。对于Service 的工作原理请参考https://time.geekbang.org/column/article/68636

当需要从集群外部访问k8s里的服务的时候,方式有四种:ClusterIP(默认)、NodePortLoadBalancerExternalName

下面我们介绍一下这几种方式的区别

一、ClusterIP

该方式是指通过集群的内部 IP 暴露服务,但此服务只能够在集群内部可以访问,这种方式也是默认的 ServiceType。

我们先看一下最简单的Service定义

apiVersion: v1
kind: Service
metadata:
  name: hostnames
spec:
  selector:
    app: hostnames
  ports:
  - name: default
    protocol: TCP
    port: 80
    targetPort: 9376

这里我使用了 selector 字段来声明这个 Service 只携带了 app=hostnames 标签的 Pod。并且这个 Service 的 80 端口,代理的是 Pod 的 9376 端口。

我们定义一个 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hostnames
spec:
  selector:
    matchLabels:
      app: hostnames
  replicas: 3
  template:
    metadata:
      labels:
        app: hostnames
    spec:
      containers:
      - name: hostnames
        image: k8s.gcr.io/serve_hostname
        ports:
        - containerPort: 9376
          protocol: TCP

这里我们使用的 webservice 镜像为 k8s.gcr.io/serve_hostname,其主要提供输出当前服务器的 hostname 的功能,这里声明的Pod份数是 3 份,此时如果我们依次访问 curl 10.0.1.175:80 的话,会发现每次响应内容不一样,说明后端请求了不同的 pod 。这是因为 Service 提供的负载均衡方式是 Round Robin

这里的 10.0.1.175 是当前集群的IP,俗称为 VIP,是 Kubernetes 自动为 Service 分配的。对于这种方式称为 ClusterIP 模式的 Service

Continue reading

mac下利用minikube安装Kubernetes环境

本机为mac环境,安装有brew工具,所以为了方便这里直接使用brew来安装minikube工具。同时本机已经安装过VirtualBox虚拟机软件。

minikube是一款专门用来创建k8s 集群的工具。

一、安装minikube

参考 https://kubernetes.io/docs/tasks/tools/install-minikube/, 在安装minkube之前建议先了解一下minikube需要的环境https://kubernetes.io/docs/setup/learning-environment/minikube/

1. 先安装一个虚拟化管理系统,如果还未安装,则在 HyperKit、VirtualBox 或 VMware Fusion 三个中任选一个即可,这里我选择了VirtualBox。

如果你想使用hyperkit的话,可以直接执行 brew install hyperkit 即可。

对于支持的driver_name有效值参考https://kubernetes.io/docs/setup/learning-environment/minikube/#specifying-the-vm-driver, 目前docker尚处于实现阶段。

$ brew install minikube

查看版本号

$ minikube version

minikube version: v1.8.2
commit: eb13446e786c9ef70cb0a9f85a633194e62396a1

安装kubectl命令行工具

$ brew install kubectl

二、启动minikube 创建集群

$ minikube start --driver=virtualbox

如果国内的用户安装时提示失败”VM is unable to access k8s.gcr.io, you may need to configure a proxy or set –image-repository”,
则指定参数–image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

 $ minikube start --driver=virtualbox --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

😄 minikube v1.8.2 on Darwin 10.15.3
✨ Using the virtualbox driver based on existing profile
✅ Using image repository registry.cn-hangzhou.aliyuncs.com/google_containers
💾 Downloading preloaded images tarball for k8s v1.17.3 …
⌛ Reconfiguring existing host …
🏃 Using the running virtualbox “minikube” VM …
🐳 Preparing Kubernetes v1.17.3 on Docker 19.03.6 …
> kubelet.sha256: 65 B / 65 B [————————–] 100.00% ? p/s 0s
> kubeadm.sha256: 65 B / 65 B [————————–] 100.00% ? p/s 0s
> kubectl.sha256: 65 B / 65 B [————————–] 100.00% ? p/s 0s
> kubeadm: 37.52 MiB / 37.52 MiB [—————] 100.00% 1.01 MiB p/s 37s
> kubelet: 106.42 MiB / 106.42 MiB [————-] 100.00% 2.65 MiB p/s 40s
> kubectl: 41.48 MiB / 41.48 MiB [—————] 100.00% 1.06 MiB p/s 40s
🚀 Launching Kubernetes …
🌟 Enabling addons: default-storageclass, storage-provisioner
🏄 Done! kubectl is now configured to use “minikube”

另外在minikube start 有一个选项是–image-mirror-country=’cn’  这个选项是专门为中国准备的,还有参数–iso-url,官方文档中已经提供了阿里云的地址……… 这个选项会让你使用阿里云的镜像仓库,我这里直接指定了镜像地址。

对于大部分国内无法访问到的镜像k8s.gcr.io域名下的镜像都可以在http://registry.cn-hangzhou.aliyuncs.com/google_containers 找到。

Continue reading

kubernetes dashboard向外网提供服务

目前新版本的 kubernetes dashboard (https://github.com/kubernetes/dashboard)安装了后,为了安全起见,默认情况下已经不向外提供服务,只能通过 http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ 本机访问。在我们学习过程中,总有些不方便,这时我们可以利用 kubectl proxy 命令来实现。

首先我们看一下此命令的一些想着参数

➜  ~ kubectl proxy -h
To proxy all of the kubernetes api and nothing else, use:

  $ kubectl proxy --api-prefix=/

To proxy only part of the kubernetes api and also some static files:

  $ kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/

The above lets you 'curl localhost:8001/api/v1/pods'.

To proxy the entire kubernetes api at a different root, use:

  $ kubectl proxy --api-prefix=/custom/

The above lets you 'curl localhost:8001/custom/api/v1/pods'

Examples:
  # Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/
  kubectl proxy --port=8011 --www=./local/www/

  # Run a proxy to kubernetes apiserver on an arbitrary local port.
  # The chosen port for the server will be output to stdout.
  kubectl proxy --port=0

  # Run a proxy to kubernetes apiserver, changing the api prefix to k8s-api
  # This makes e.g. the pods api available at localhost:8011/k8s-api/v1/pods/
  kubectl proxy --api-prefix=/k8s-api

Options:
      --accept-hosts='^localhost$,^127\.0\.0\.1$,^\[::1\]$': Regular expression for hosts that the proxy should accept.
      --accept-paths='^/.*': Regular expression for paths that the proxy should accept.
      --address='127.0.0.1': The IP address on which to serve on.
      --api-prefix='/': Prefix to serve the proxied API under.
      --disable-filter=false: If true, disable request filtering in the proxy. This is dangerous, and can leave you
vulnerable to XSRF attacks, when used with an accessible port.
  -p, --port=8001: The port on which to run the proxy. Set to 0 to pick a random port.
      --reject-methods='POST,PUT,PATCH': Regular expression for HTTP methods that the proxy should reject.
      --reject-paths='^/api/.*/pods/.*/exec,^/api/.*/pods/.*/attach': Regular expression for paths that the proxy should
reject.
  -u, --unix-socket='': Unix socket on which to run the proxy.
  -w, --www='': Also serve static files from the given directory under the specified prefix.
  -P, --www-prefix='/static/': Prefix to serve static files under, if static file directory is specified.

Usage:
  kubectl proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix] [options]

Use "kubectl options" for a list of global command-line options (applies to all commands).

这里我们只要关注其中的三个参数就可以了

--accept-hosts='^localhost$,^127\.0\.0\.1$,^\[::1\]$': Regular expression for hosts that the proxy should accept.
--address='127.0.0.1': The IP address on which to serve on.
--port=8001: The port on which to run the proxy. Set to 0 to pick a random port.

–accept-hosts 表示哪些客户端访问,默认只允许 localhost 和 127.0.0.1
–address 表示本机绑定的ip地址,如果值为0.0.0.0 则表示不限,通过任何ip都可以访问.
a
–port 表示代理的接口,如果值为0的话,则随机一个端口

这里为了外网访问,可设置如下

nohup kubectl proxy --address='0.0.0.0' --port=8888 --accept-hosts='^*$'

这时就实现了通过外网访问

http://192.168.0.107:8888/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

其实说白了,只要你把基本的命令参数搞清楚了,实现起来就方便了,就看你基础牢不牢。

Kubernetes学习资源

k8s guide

准备

对于一个新手来说,第一步是必须了解什么是 kubernetees设计架构和相关概念。只有在了解了这些的情况下,才能更好的知道k8s中每个组件的作用以及它解决的问题。

安装工具

以上是安装k8s环境的两种推荐方法,这里更推荐使用kind。主要原因是 minikube 只支持单个节点,而 kind 可以支持多个节点,这样就可以实现在一台电脑上部署的环境与生产环境一样,方便大家学习。

要实现管理控制 Kubernetes 集群资源如pod、node、service等的管理,还必须安装一个命令工具 kubectl,请参考:https://kubernetes.io/zh/docs/tasks/tools/

学习文档