资讯专栏INFORMATION COLUMN

循序渐进的手动安装k8s笔记-1

CoderDock / 3080人阅读

摘要:日志级别通过启动并设置为开机自启动之后可以通过来检查服务器运行状态安装服务编辑服务文件环境变量文件中定义了启动参数。

不知道有没有人和我一样,在手动安装时因为很多原因没有成功(主要还是知识储备不够),被各种高可用配置和各种证书权限弄得迷迷糊糊。这个笔记是我在尝试了很多种手动安装Kubernetes集群教程中的方法失败后产生的想法,希望能够将复杂的配置化繁为简,呈现出一个基本功能的Kubernetes程序,记录下如何以最简的方式配置各个组件,使其能够实现基本的功能。然后再逐步添加多节点、安全认证、高可用等复杂配置,通过这个过程来理解Kubernetes各种基础组件之间的关系已经配置方法。

计划的第一步就是完成一个非安全的单 master 单 node 集群,api-server 和 kubelet 等组件都通过systemd来管理,master 上不安装kubelet 只做管理端使用。首先我尝试用比较新的 1.10.X 版k8s 安装,但是安装过程中没有办法用非证书认证方式指定 api-server 的地址,似乎官方在有意逐步取消对非安全方式的支持。最后还是选择了比较旧的k8s 1.6.0 来完成安装。

参考资料:

《Kubernetes权威指南》

运行环境&软件版本:

Ubuntu 16.04.4 LTS

kubernetes v1.6.0

etcd v3.0.14

docker-ce 18.06.1-ce

角色规划:
主机名 IP地址 角色 CPU/内存
u16-1 192.168.112.148 master(only as master) 2核/2G
u16-2 192.168.112.149 node 2核/2G
环境准备

从 github 的 Kubernetes 项目页面 上找到我们需要的 V1.6.0版本,然后点击 CHANGELOG,在 Older releases 下面点击 CHANGELOG-1.6.md ,找到 v1.6.0 版本的 Server Binaries 中对应的架构的包(kubernetes-server-linux-amd64.tar.gz)下载并上传到服务器(国内上网环境可能无法正常下载)

k8s 1.6.0 对应的 etcd 版本为 v3.0.14,同样可以从 github 上 etcd 项目对应版本的页面找到并下载到服务器

wget https://github.com/etcd-io/etcd/releases/download/v3.0.14/etcd-v3.0.14-linux-amd64.tar.gz

关闭 swap并在 /etc/fstab 文件中取消掉自动挂载

sudo swapoff -a

如果系统上安装了SELinux,需要将其关闭。另外还需要在防火墙上放开下面步骤中所有需要使用的端口,或者关闭防火墙管理软件,我这里选择将ubuntu16.04默认的ufw关闭

sudo ufw disable
MASTER 节点安装 安装 etcd 服务
tar xf etcd-v3.0.14-linux-amd64.tar.gz
#把解压后的 etcd 和 etcdctl 复制到 /usr/bin 目录下
sudo cp etcd-v3.0.14-linux-amd64/etcd{,ctl} /usr/bin/

然后设置 systemd 服务文件 /lib/systemd/system/etcd.service

[Unit]
Description=Etcd Server
After=network.target

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd

[Install]
WantedBy=multi-user.target

这里 WorkingDirectory 指定的目录需要提前创建好,这个目录将作为etcd数据保存的目录。

EnvironmentFile 可以指定 etcd 的配置文件。在我这里因为只是测试安装,所以 etcd 使用默认配置就可以了。

通过 systemd 启动 etcd 并设置为开机自启动

sudo systemctl daemon-reload
sudo systemctl start etcd
sudo systemctl enable etcd
# 完成后可以检查一下服务是否正常运行
systemctl status etcd
# 也可以使用 etcdctl 来检查 etcd 健康状况
etcdctl cluster-health
# 正常的输出为:
# member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379
# cluster is healthy
安装 kube-apiserver 服务
tar xf kubernetes-server-linux-amd64.tar.gz
# 将 kube-apiserver、kube-controller-manager 和 kube-scheduler 的二进制文件复制到 /usr/bin 目录下
sudo cp kubernetes/server/bin/kube-{apiserver,controller-manager,scheduler} /usr/bin/

编辑 systemd 服务文件 /lib/systemd/system/kube-apiserver.service

[Unit]
Description=Kubernetes API Server
After=etcd.service
Wants=etcd.service

[Service]
EnvironmentFile=/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

环境变量文件 /etc/kubernetes/apiserver 中定义了 kube-apiserver 启动参数 KUBE_API_ARGS。我们创建这个文件并填入如下内容

KUBE_API_ARGS="--storage-backend=etcd3 --etcd-servers=http://127.0.0.1:2379 
--insecure-bind-address=0.0.0.0 --insecure-port=8080 
--service-cluster-ip-range=169.169.0.0/16 --service-node-port-range=1-65535 
--admission_control=NamespaceLifecycle,LimitRanger,ServiceAccount, 
DefaultStorageClass,ResourceQuota 
--logtostderr=false --log-dir=/var/log/kubernetes --v=2"
参数说明:  
--storage-backend :指定 etcd 版本。
--etcd-servers :指定 etcd 服务器地址和端口。
--insecure-bind-address :指定 api-server 非安全方式绑定的地址。0.0.0.0 表示所有地址。
--insecure-port :指定 api-server 非安全方式启用的端口号。
--service-cluster-ip-range :指定集群 Cluster IP 网段,如果后续需要使用网络插件这里需要按照网络插件要求的网段配置。
--service-node-port-range :指定集群中 Service 可以映射物理机端口号范围
--admission_control :Kubernetes 集群的准入控制设置,各控制模块以插件形式依次生效。
--logtostderr :指定为 false 时将错误日志写入日志文件而非 标准输出。
--log-dir :日志保存路径。
--v :日志级别

通过 systemd 启动 kube-apiserver 并设置为开机自启动

sudo systemctl daemon-reload
sudo systemctl start kube-apiserver
sudo systemctl enable kube-apiserver
# 之后可以通过 status 来检查服务器运行状态
systemctl status kube-apiserver
安装 kube-controller-manager 服务

编辑 systemd 服务文件 /lib/systemd/system/kube-controller-manager.service

[Unit]
Description=Kubernetes Controller Manager
After=kube-apiserver.service
Requires=kube-apiserver.service

[Service]
EnvironmentFile=/etc/kubernetes/controller-manager
ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

环境变量文件 /etc/kubernetes/controller-manager 中定义了 kube-controller-manager 启动参数 KUBE_CONTROLLER_MANAGER_ARGS。我们创建这个文件并填入如下内容

KUBE_CONTROLLER_MANAGER_ARGS="--master=http://192.168.112.148:8080 
--logtostderr=false 
--log-dir=/var/log/kubernetes 
--v=2"
参数说明:

--master :指定 API-server 的URL地址

安装 kube-scheduler 服务

编辑 systemd 服务文件 /lib/systemd/system/kube-scheduler.service

[Unit]
Description=Kubernetes Scheduler Server
After=kube-apiserver.service
Requires=kube-apiserver.service

[Service]
EnvironmentFile=/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

环境变量文件 /etc/kubernetes/scheduler 中定义了 kube-scheduler 启动参数 KUBE_SCHEDULER_ARGS。我们创建这个文件并填入如下内容

KUBE_SCHEDULER_ARGS="--master=http://192.168.112.148:8080 
--logtostderr=false 
--log-dir=/var/log/kubernetes 
--v=2"

安装完 kube-controller-manager 和 kube-scheduler 之后将其启动并设置为开机自启动

sudo systemctl daemon-reload
sudo systemctl start kube-controller-manager kube-scheduler
sudo systemctl enable kube-controller-manager kube-scheduler
# 同样,启动之后可以通过 systemctl status XXXX 来检查服务的状态
systemctl status kube-controller-manager
systemctl status kube-scheduler.service

master 上的安装已经完成,下一步就要开始安装 node 节点上需要的服务了。

NODE 节点安装

node 节点上需要安装的服务有 docker 、kubelet 和 kube-proxy。

安装 docker-ce

安装 docker 的方式很多,在这里我使用添加阿里云的源并使用 apt-get 安装:

# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

按装好后 docker 就是启动状态并且设置了开机自启。

安装 kubelet
tar xf kubernetes-server-linux-amd64.tar.gz
# 将 kubelet 和 kube-proxy 的二进制文件复制到 /usr/bin 目录下
sudo cp kubernetes/server/bin/kube{let,-proxy} /usr/bin/

编辑 systemd 服务文件 /lib/systemd/system/kubelet.service

[Unit]
Description=Kubernetes Kubelet Server
After=docker.service
Requires=docker.service

[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet $KUBELET_ARGS
Restart=on-failure

[Install]
WantedBy=mulit-user.target

WorkingDirectory 指定的路径是 kubelet 的数据目录,需要在服务运行前创建提前创建。

环境变量文件 /etc/kubernetes/kubelet 中定义了 kubelet 启动参数 KUBELET_ARGS。我们创建这个文件并填入如下内容

KUBELET_ARGS="--api-servers=http://192.168.112.148:8080 
--hostname-override=u16-2 
--logtostderr=false 
--log-dir=/var/log/kubernetes 
--v=2"
参数说明:

--api-servers :指定 apiserver 的URL地址。

--hostname-override :指定注册到 apiserver 时本节点的名称。

通过 systemd 启动 kubelet 并设置为开机自启动

sudo systemctl daemon-reload
sudo systemctl start kubelet
sudo systemctl enable kubelet
# 之后可以通过 status 来检查服务器运行状态
systemctl status kubelet
安装 kube-proxy 服务

编辑 systemd 服务文件 /lib/systemd/system/kube-proxy.service

[Unit]
Description=Kubernetes Kube-Proxy Server
After=networking.service
Requires=networking.service

[Service]
EnvironmentFile=/etc/kubernetes/proxy
ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

环境变量文件 /etc/kubernetes/proxy 中定义了 kube-proxy 启动参数 KUBE_PROXY_ARGS。我们创建这个文件并填入如下内容

KUBE_PROXY_ARGS="--master=http://192.168.112.148:8080 
--logtostderr=false 
--log-dir=/var/log/kubernetes 
--v=2"

通过 systemd 启动 kubu-proxy 并设置为开机自启动

sudo systemctl daemon-reload
sudo systemctl start kube-proxy
sudo systemctl enable kube-proxy
# 之后可以通过 status 来检查服务器运行状态
systemctl status kube-proxy

node 节点设置完成后, 如果 master 节点上有 kubernetes 的命令行管理软件 kubectl ,就可以使用kubectl 查看到新增加的节点。kubectl 的二进制文件可以从 kubernetes-server-linux-amd64.tar.gz 中找到。

sudo cp kubernetes/server/bin/kubectl /usr/bin/
sudo chmod +x /usr/bin/kubectl
kubectl get node
# 输出为
# NAME      STATUS     AGE       VERSION
# u16-2     NotReady   17m       v1.6.0

这时可以看到新增加的节点 u16-2 的状态为 NotReady,通过命令来查看 node 状态

kubectl describe node u16-2

这时可以在 Events: 中看到一条报错,Massage是

Failed to start ContainerManager failed to initialise top level QOS containers: root container /kubepods doesn"t exist

解决办法参考这里,在kubelet 的启动参数中加上下面参数并重启

    --cgroups-per-qos=false
    --enforce-node-allocatable=""

重启后 node 变为 Ready 状态。

在 Kubernetes 集群上运行服务 创建示例服务
# 在集群上运行 kubernetes-bootcamp 镜像
kubectl run kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1 --port=8080
# 因为上面命令中的镜像位置在国内可能也无法正常访问 所以可以将其替换为 dockerhub 上相同的镜像 jocatalin/kubernetes-bootcamp:v1
kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --port=8080
# 检查 deployment 运行状态
kubectl get deployment
# ---显示如下---
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         0         0            0           4m
# 当前的 Pod 数一直为0,检查一下 deployment 状态
kubectl describe deployment kubernetes-bootcamp
# Events 中最后的信息为 Scaled up replica set kubernetes-bootcamp-4025819334 to 1 ,再看一下 replicaSet 的状态
kubectl describe replicaset kubernetes-bootcamp-4025819334

发现 Events 中的报错:

Error creating: No API token found for service account "default", retry after the token is automatically created and added to the service account

解决方法参考这里,因为这里搭建的整个集群都是无安全认证的,所以将 api-server 中的 --admission_control 参数里的 ServiceAccount 删除,并重启 kube-apiserver 。

之后再次查看 deployment 状态

kubectl get deployment
# ---显示如下---
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         1         1            0           18m

这次 pod 成功创建了,但仍然不是 AVAILABLE 状态。

# 查看现有的 pod 
kubectl get pod
# ---显示如下---
NAME                                   READY     STATUS              RESTARTS   AGE
kubernetes-bootcamp-4025819334-q61xj   0/1       ContainerCreating   0          5m
# 查看这个 Pod 的详细信息
kubectl describe pod kubernetes-bootcamp-4025819334-q61xj
# 在Events 里看到了错误信息:
# Error syncing pod, skipping: failed to "CreatePodSandbox" for "kubernetes-bootcamp-4025819334-q61xj_default(1d20e7af-af48-11e8-bf2f-000c29a01556)" with CreatePodSandboxError: "CreatePodSandbox for pod "kubernetes-bootcamp-4025819334-q61xj_default(1d20e7af-af48-11e8-bf2f-000c29a01556)" failed: rpc error: code = 2 desc = unable to pull sandbox image "gcr.io/google_containers/pause-amd64:3.0": Error response from daemon: {"message":"Get https://gcr.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)"}"

根据信息可知错误是因为下载这个镜像失败:gcr.io/google_containers/pause-amd64:3.0 。还是网络环境的问题,这时可以在 dockerhub 上找到相同的镜像下载并修改 tag 来得到这个镜像。

在 node 节点上执行

sudo docker image pull mirrorgooglecontainers/pause-amd64:3.0
sudo docker tag mirrorgooglecontainers/pause-amd64:3.0 gcr.io/google_containers/pause-amd64:3.0

镜像下载好之后再次查看 deployment 状态:

kubectl get deployment
# ---显示如下---
NAME                  DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kubernetes-bootcamp   1         1         1            1           35m
在节点上暴露端口

此时服务已经部署正确,为了集群外部也能够访问到服务,现在需要使用 NodePort 方式将端口暴露出来。

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
kubectl get service
# ---输出如下---
NAME                  CLUSTER-IP        EXTERNAL-IP   PORT(S)          AGE
kubernetes            169.169.0.1               443/TCP          2d
kubernetes-bootcamp   169.169.210.120          8080:10412/TCP   12m

此时 node 上的 10412 端口已经打开(这里的 10412 端口是在 kube-apiserver 启动参数 --service-node-port-range 范围内随机分配的),并且在 node 本机上是可以访问的。但是集群外部访问就会超时,包括没有安装 kube-proxy 的 master 访问也会超时。解决办法参考这里。

为了安全起见, docker 在 1.13 版本之后,将系统iptables 中 FORWARD 链的默认策略设置为 DROP,并为连接到 docker0 网桥的容器添加了放行规则。

知道了原因是 docker 启动时修改了iptables 规则后,可以修改 docker 的服务文件 /lib/systemd/system/docker.service 添加下面内容

ExecStartPost=/sbin/iptables -P FORWARD ACCEPT

含义为在启动 docker 之后,修改 FORWARD 链的默认规则为 ACCEPT。配置完成之后重启 docker 。此时外部就可以访问了。

至此,一个单 master 单 node 的非安全 kubernets 集群已经配置完成,并且基础功能可以正常使用。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/32713.html

相关文章

  • 循序渐进手动安装k8s笔记-2

    摘要:启动并设置为开机自启动安装服务这部分配置与上一篇笔记完全相同。我们创建这个文件并填入如下内容安装完和之后将其启动并设置为开机自启动以上,角色的功能已经安装完成。 上一篇笔记中,我尝试了使用 k8s 1.6 版本安装一个最简单的集群。这一次,我希望能够增加 node 的数量并且安装网络插件,然后配置内部的域名解析功能。 在起初的设想中,我仍然希望不配置各个组件间的认证,只关心功能的正常运...

    pingink 评论0 收藏0
  • 快收藏!52篇25万字,微服务、云原生、容器、K8S、Serverless精华文章集锦

    摘要:正在走远,新年之初,小数精选过去一年阅读量居高的技术干货,从容器到微服务云原生,汇集成篇精华集锦,充分反映了这一年的技术热点走向。此文值得收藏,方便随时搜索和查看。,小数将继续陪伴大家,为朋友们奉献更有逼格的技术内容。 2017正在走远,新年之初,小数精选过去一年阅读量居高的技术干货,从容器、K8S 到微服务、云原生、Service Mesh,汇集成52篇精华集锦,充分反映了这一年的技...

    AaronYuan 评论0 收藏0
  • k8s安装总结

    摘要:主要在文件附加下面的源我使用的是阿里的镜像,如果你使用的其他国内镜像,请找对应的镜像源然后执行下列命令,安装软件。参考资料只要用小朋友都能部署基本安装基于阿里云镜像站安装用在上快速构建测试集群 本次安装环境是Ubuntu16.04,其他环境下,shell命令会有一些不同,但步骤应该大致相同,默认docker已经安装完成 下载 下载安装下列软件 kubelet Node上运行的节点代理...

    Nosee 评论0 收藏0
  • microk8s安装过程中遇到几个问题

    摘要:问题安装过程中部分镜像需要从的镜像仓库拉取但是国内无法访问其镜像仓库故需要手动获取镜像再自行安装从官方提供的仓库获取不是使用的宿主机器的进程故不能简单的把自己获取的镜像重新来完成安装需要导出之后然后使用提供的镜像管理功能进行导入解决原理获取 问题 microk8s安装过程中,部分镜像需要从google的镜像仓库拉取,但是国内无法访问其镜像仓库, 故需要手动获取镜像再自行安装(从官方提...

    DC_er 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<