目录

CentOS7下安装docker

在Linux上安装守护程序和客户端二进制文件:

安装静态二进制文件:

配置Docker:

1)建立 docker 用户组

2)将当前用户加入 docker 组

3) 退出当前终端并重新登录即可

二进制方式安装docker不能使用systemd(systemctl)工具管理docker服务的问题:

操作命令

安装Kubernetes(k8s)

资料:

配置iptables设置

创建 CA 根证书

安装etcd

安装kube-apiserver

创建客户端CA证书

创建kubeconfig

安装kube-controller-manager服务

安装kube-scheduler服务

安装kubelet 服务

安装CNI

安装kube-apiserver

安装kube-apiserver

安装kube-apiserver

安装kubectl

问题:

为什么 kubernetes 环境要求开启 bridge-nf-call-iptables ?

配置linux net.ipv4.ip_forward 数据包转发:

CentOS7下安装docker

由于配置文件粘贴会让文档显示很乱,所以文档中缺少部分红色字体标记的service配置文件,具体内部可参数官方文档.如果需要整个文档内容可点击下载:https://download.csdn.net/download/lyclngs/89634260

在Linux上安装守护程序和客户端二进制文件:

先决条件

在尝试从二进制文件安装Docker之前,请确保您的主机满足以下先决条件:

64位安装/Linux内核的3.10或更高版本。建议使用适用于您的平台的最新版本的内核。

iptables 1.4版或更高版本/git 1.7或更高版本/ps可执行,通常由提供procps或类似的包。

XZ Utils 4.9或更高

安装静态二进制文件:

下载静态二进制存档:

转到 https://download.docker.com/linux/static/stable/ (或更改stable为nightly或test),选择您的硬件平台,然后下载.tgz与要安装的Docker Engine版本有关的文件。

使用该tar实用程序提取存档。在dockerd和docker 二进制文件被提取。

$>wget https://download.docker.com/linux/static/stable/x86_64/docker-23.0.0.tgz

$>tar xzvf docker-23.0.0.tgz

$>cd docker

可选:将二进制文件移到可执行路径上的目录,例如/usr/bin/。如果跳过此步骤,则在调用docker或dockerd命令时必须提供可执行文件的路径。

$>  sudo cp docker/doc* /usr/bin/

配置docker.server,docker.socket,containerd.service 此目录/etc/systemd/system/ 或者如下目录

$>vim /usr/lib/systemd/system/docker.service

$>vim /usr/lib/systemd/system/docker.socket

$>vim /usr/lib/systemd/system/containerd.service

启动Docker守护程序:启动doker时会启动docker.service,docker.socket,containerd.service

$>systemctl daemon-reload && systemctl start docker && systemctl enable docker

$>systemctl status docker && systemctl status docker.socket && systemctl status containerd

如果需要使用其他选项启动守护程序,请相应地修改以上命令,或者创建并编辑文件/etc/docker/daemon.json 以添加定制配置选项。

通过运行hello-world 映像来验证是否正确安装了Docker 。

$>  sudo docker run hello-world

此命令下载测试图像并在容器中运行它。容器运行时,它会打印参考消息并退出

$>  docker --version 查看安装版本

配置Docker:

1)建立 docker 用户组

默认情况下,docker 命令会使用 Unix socket 与 Docker 引擎通讯。而只有 root 用户和 docker 组的用户才可以访问 Docker 引擎的 Unix socket。出于安全考虑,一般 Linux 系统上不会直接使用 root 用户。因此,更好地做法是将需要使用 docker 的用户加入 docker 用户组。

命令如下:

$ sudo groupadd docker

2)将当前用户加入 docker 组

$ sudo usermod -G docker $USER

  1. 退出当前终端并重新登录即可

二进制方式安装docker不能使用systemd(systemctl)工具管理docker服务的问题:

配置 docker 的开启自启动:

$> sudo systemctl enable docker

Failed to execute operation: No such file or directory

看官网配置 systemd 的文章:Control and configure Docker with systemd

下载docker.servcie和docker.socket放到我们的/etc/systemd/system目录下

$> systemctl start docker

A dependency job for docker.service faled. See ‘journalctl -xe’ for details.

参数文档:https://github.com/moby/moby/issues/25559

修改docker.socker文档:

修改docker.service文档:

再次运行:$> service start docker

操作命令

启动docker:$> systemctl start docker / service docker start

重启docker:$> systemctl restart docker / service docker restart

关闭docker :$>systemctl stop docker /  service docker stop

重启守护进程:$>systemctl daemon-reload

安装Kubernetes(k8s)

资料:

官网:https://kubernetes.io/

Github:https://github.com/kubernetes/kubernetes

版本:kubernetes-1.28.0

server地址:https://github.com/kelseyhightower/kubestack/blob/master/packer/units/kube-scheduler.service

配置iptables设置

# 设置所需的 sysctl 参数,参数在重新启动后保持不变

$>cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf

net.bridge.bridge-nf-call-iptables  = 1

net.bridge.bridge-nf-call-ip6tables = 1

net.ipv4.ip_forward                 = 1

EOF

# 应用 sysctl 参数而不重新启动

$>sudo sysctl --system

创建 CA 根证书

生成ca.crt  ca.key证书文件放到/etc/kubernetes/pki目录下

$> mkdir -p /etc/kubernetes/pki && cd /etc/kubernetes/pki

$> openssl genrsa -out ca.key 2048

$> openssl req -x509 -new -nodes -key ca.key -subj "/CN=l92.168.106.101" -days 36500 -out ca.crt

安装etcd

下载:https://github.com/etcd-io/etcd/releases

wget https://github.com/etcd-io/etcd/archive/refs/tags/v3.4.22.tar.gz

$>tar -zxvf etcd-v3.4.22-linux-amd64.tar.gz

$>cd etcd-v3.4.22-linux-amd64/

$>cp etcd* /usr/bin/

$>mkdir /usr/local/etcd && cd /usr/local/etcd

创建配置文件:etcd.conf

$>vim /usr/locl/etcd/etcd.conf

创建etcd.service:https://github.com/search?q=repo%3Aetcd-io%2Fetcd%20etcd.service&type=code

$>vim /usr/lib/systemd/system/etcd.service

创建etcd的CA证书

$>vim /usr/local/etcd/etcd_ssl.conf

创建etcd的服务端面CA证书/etc/etcd/pki/ 

$>mkdir -p /etc/etcd/pki/ && cd /etc/etcd/pki/

$>openssl genrsa -out etcd_server.key 2048

$>openssl req -new -key etcd_server.key -config /usr/local/etcd/etcd_ssl.conf -subj "/CN=etcd-server" -out etcd_server.csr

$>openssl x509 -req -in etcd_server.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile /usr/local/etcd/etcd_ssl.conf -out etcd_server.crt

创建客户端使用的CA证书:/etc/etcd/pki/

$>openssl genrsa -out etcd_client.key 2048

$>openssl req -new -key etcd_client.key -config /usr/local/etcd/etcd_ssl.conf -subj "/CN=etcd-client" -out etcd_client.csr

$>openssl x509 -req -in etcd_client.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile /usr/local/etcd/etcd_ssl.conf -out etcd_client.crt

$>systemctl daemon-reload

$>systemctl enable etcd

$>systemctl start etcd

验证etcd集群状态:

$>etcdctl --cacert=/etc/kubernetes/pki/ca.crt --cert=/etc/etcd/pki/etcd_client.crt --key=/etc/etcd/pki/etcd_client.key --endpoints=https://192.168.106.101:2379,https://192.168.106.102:2379,https://192.168.106.103:2379 endpoint health

$>etcdctl --cacert=/etc/kubernetes/pki/ca.crt --cert=/etc/etcd/pki/etcd_client.crt --key=/etc/etcd/pki/etcd_client.key --endpoints=https://192.168.106.101:2379,https://192.168.106.102:2379,https://192.168.106.103:2379 member list -w table

证书在其中一台服务器生成.复制到其它服务器.文档目录保持一致

报错信息:

安装kube-apiserver

Master 节点上需要部署的服务包括 etcd kube-apiserver kube-controller-manager kube-scheduler

在工作节点 (Worker Node)上需要部署的服务包括 docker kubelet kube-proxy

下载:https://github.com/kubernetes/kubernetes/tree/master/CHANGELOG

$>wget https://dl.k8s.io/v1.28.0/kubernetes-server-linux-amd64.tar.gz

$>tar -zxvf kubernetes-server-linux-amd64.tar.gz

$>cd kubernetes

将Kubernetes二进制可执行文件复制到/usr/bin目录下,然后在usr/lib/systemd/system目录下为各服务创建systemd服务配置文件

$>cp apiextensions-apiserver kubeadm kube-aggregator kube-apiserver kube-controller-manager kubectl kubectl-convert kubelet kube-log-runner kube-proxy kube-scheduler mounter /usr/bin/

创建master_ssl.cnf

$>vim /usr/local/kubernetes/master_ssl.cnf

$>cd /etc/kubernetes/pki/

$>openssl genrsa -out apiserver.key 2048

$>openssl req -new -key apiserver.key -config /usr/local/kubernetes/master_ssl.cnf -subj "/CN=l92.168.106.101" -out apiserver.csr

$>openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 36500 -extensions v3_req -extfile /usr/local/kubernetes/master_ssl.cnf -out apiserver.crt

创建kube-apiserver.service

$>vim /usr/lib/systemd/system/kube-apiserver.service

配置apiserver

$>vim /etc/kubernetes/apiserver

$>systemctl daemon-reload && systemctl start kube-apiserver && systemctl enable kube-apiserver

报错:W0831 19:34:13.143157   17709 lease.go:263] Resetting endpoints for master service

修改配置文件--endpoint-reconciler-type=master-count改为lease

创建客户端CA证书

kube-controller-manager kube-scheduler kubelet kube-proxy作为客户端连接kube-apiserver需要为他们创建客户端证书

$>cd /etc/kubernetes/pki

$>openssl genrsa -out client.key 2048

$>openssl req -new -key client.key -subj "/CN=admin" -out client.csr

$>openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 36500 -out client.crt

subj 参数中/CN的名称可以被设置为admin用标识连接kube-apiserver的客户端用户的名称

创建kubeconfig

客户端连接kube-apiserver服务所需要的kubeconfig配置文件

为kube-controller-manager,kube-scheduler,kubelet,kube-proxy服务统一创建一个kubeconfig文件作为连接kube-apiserver服务的配置文件,后续也作为kubectl命令行工具连接kube-apiserver服务的配置文件在kubeconfig文件中主要设置访问kube-apiserver的URL地址及所需CA证书的相关参数,示例如下:

$>cd /etc/kubernetes/

$>vim kubeconfig

安装kube-controller-manager服务

$>vim /usr/lib/systemd/system/kube-controller-manager.service

配置controller-manager

$>vim /etc/kubernetes/controller-manager

$>systemctl daemon-reload && systemctl start kube-controller-manager && systemctl enable kube-controller-manager

安装kube-scheduler服务

$>vim /usr/lib/systemd/system/kube-scheduler.service

报错信息

配置kube-scheduler

$>vim /etc/kubernetes/kube-scheduler

$>systemctl daemon-reload && systemctl start kube-scheduler && systemctl enable kube-scheduler

安装kubelet 服务

配置kubelet.service 和kubelet,kubelet.config

$>vim /usr/lib/systemd/system/kubelet.service

$>vim /etc/kubernetes/kubelet

$>vim /usr/local/kubernetes/kubelet.config

$>systemctl daemon-reload && systemctl start kubelet && systemctl enable kubelet

Kubelet.config参数文档:

https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/

https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/

$>systemctl daemon-reload && systemctl start kubelet && systemctl enable kubelet

$>systemctl status kubelet

$>systemctl status containerd

$>kubectl version --client

安装CNI

Kubernetes CNI 提供了一个标准的接口,用于容器运行时(如 Docker、rkt 等)与网络插件之间的通信。这种插件化的设计使得 Kubernetes 可以与各种不同的网络解决方案集成,例如 Calico、Flannel、Weave 等。

Kubernetes CNI 主要负责以下几个方面的工作:

分配和管理 Pod 的 IP 地址

配置容器的网络接口

安装和配置网络插件(CNI 插件)

$>cd /usr/local/lib

$>wget https://github.com/containernetworking/plugins/releases/download/v1.1.0/cni-plugins-linux-amd64-v1.1.0.tgz

$>mkdir /opt/cni/bin -p

$>tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin

$>cd /usr/local/cni/

执行如下命令,初始化admin.conf 报错可根据提示忽略(--ignore-preflight-errors=all),执行kubeadm init会生成配置文件包含admin.conf

$>kubeadm init

$>echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile

$>source ~/.bash_profile

#获取yaml文件

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

$>kubectl create -f kube-flannel.yml

执行成功输出:

安装到后面发现问题不断.

使用以下命令检查 Kubernetes CNI 的状态:

kubectl describe pod <pod-name> -n kube-system

kubectl get pod -n kube-system

遇到问题:

关闭swap分区

swapoff -a  #临时

sed -ri 's/.*swap.*/#&/' /etc/fstab  #永久

sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab #永久

查询是否开启:free -m 最后一行显示0 0 0表示没有开启

问题:dial tcp 127.0.0.1:8080: socket: too many open files

$>vim /etc/security/limits.conf

添加:

* soft nofile 65535

* hard nofile 65535

$>ulimit -n 65535 --临时生效

此问题没有找到解决方案:直接删除了kube-fannel

$>kubectl delete -f kube-flannel.yml

下面命令只为查看配置使用:

kubectl get pod -n kube-flannel

kubectl describe pod kube-flannel-ds-2wz5z -n kube-flannel

安装配置kubectl自动补全

设置全局有效

vim /etc/bashrc

source <(kubectl completion bash)

若设置当前shell环境有效

source <(kubectl completion bash)

安装kube-proxy服务

配置kube-proxy.service 和 kube-proxy

$>vim /usr/lib/systemd/system/kube-proxy.service

$>vim /etc/kubernetes/kube-proxy

$>systemctl daemon-reload && systemctl start kube-proxy && systemctl enable kube-proxy

Master上通过 kubectl 验证 Node 信息

在各个 Node 的 kubelet 和 kube-proxy 服务正常启动之后,会将本 Node 自动注册到Master上,然后就可以到 Master 主机上通过 kubectl 查询自动注册到 Kubernetes 集群的Node 的信息了由于 Master 开启了 HTTPS 认证 ,所以 kubectl 需要使用客户端 CA 证书连接 Master,可以直接使用 kube-controller-manager 的 kubeconfig 文件,命令如下:

$> kubectl --kubeconfig=/etc/kubernetes/kubeconfig get nodes

如果输出

Node 的状态为 NotReady 这是因为还没有部署 CNI 网络插件无法设置容器网络。

类似于通 kubeadm 创建 Kubernetes 集群,例如选择 Calico CNI 插件运行下面的命令一键完成 CNI 网络插件的部署:

$> kubectl apply -f "https://docs.projectcalico.org/manifests/calico.yaml"

在CNI 网络插件成功运行之后,Node 的状态会更新为 Ready,再运行命令:

$> kubectl --kubeconfig=/etc/kubernetes/kubeconfig get nodes

为了使 kubernetes 集群正常工作我们还需要部署 DNS务,建议使用 CoreDNS进行部署.

至此,一个有三个 Master 节点的高可用 Kubernetes 集群就部署完成了.接下来就可以创建 Pod、Deployment、Service 等资源对象来部署、管理容器应用和微服务了

安装coredns服务

添加coredns.yaml配置,获取配置信息地址 https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed

$>cd /usr/local/dns

$>vim coredns.yaml

通过 kubectl create 命令完成 CoreDNS 服务的创建:

$>kubectl create -f coredns.yaml

查看 deployment Pod Service, 确保容器成功启动:

$>kubectl get deployment --namespace=kube-system

NAME READY UP-TO-DATE AVAILABLE AGE

coredns 1/1 1 1 33h

$>kubectl get pods --namespace=kube-system

NAME READY STATUS RESTARTS AGE

coredns-85b4878f78-vcdnh 1/1 Running 2 33h

$>kubectl get services --namespace=kube-system

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

kube-dns ClusterIP 169.169.0.100 <none> 53/UDP, 53/TCP, 9153/TCP 33h

查看信息:crictl ps -a

  $>crictl logs -f 4d820678d2cde[CONTAINER]

  $>crictl logs -f 4d820678d2cde[CONTAINER]

错误:

解决方案:

cat > /etc/crictl.yaml <<EOF

runtime-endpoint: unix:///var/run/containerd/containerd.sock

image-endpoint: unix:///var/run/containerd/containerd.sock

timeout: 0

debug: false

pull-image-on-create: false

EOF

安装mysql服务

官网地址:

Run a Single-Instance Stateful Application | Kubernetes

版本地址:https://hub.docker.com/_/mysql

创建服务: Service:mysql-service.yaml

$>vim /usr/local/mysql/mysqlk8s/mysql-service.yaml

创建持久卷: PV:mysql-pv.yaml

$>vim /usr/local/mysql/mysqlk8s/mysql-pv.yaml

创建持久卷声明: PVC:mysql-pvc.yaml

$>vim /usr/local/mysql/mysqlk8s/mysql-pvc.yaml

部署 MySQL:mysql-deployment.yaml

$>vim /usr/local/mysql/mysqlk8s/mysql-deployment.yaml

创建服务:kubectl create/apply -f ***

$>kubectl create -f mysql-service.yaml

$>kubectl create -f mysql-pv.yaml

$>kubectl create -f mysql-pvc.yaml

$>kubectl create -f mysql-deployment.yaml

删除服务:kubectl create -f ***

查看已创建服务:

$>kubectl get pods

如果指定了命令空间则需要加上 -n 空间名称

$>kubectl get pods -n mysql

$>kubectl describe pod mysql -n k8s-mysql

$>kubectl get deployment

$>kubectl get svc

$>kubectl get pv

$>kubectl get pvc

$>kubectl get ns

$>kubectl get rs

可以写一个文件中以“---”分隔每一个kind.创建所有的服务:

$>vim /usr/local/mysql/mysqlk8s/mysql-deployment-all.yaml

$>kubectl create -f mysql-deployment-all.yaml

连接mysql,IP+30366端口

问题:

为什么 kubernetes 环境要求开启 bridge-nf-call-iptables ?

Kubernetes环境中,很多时候都要求节点内核参数开启 bridge-nf-call-iptables:

sysctl -w net.bridge.bridge-nf-call-iptables=1

参考官方文档 Network Plugin Requirements

如果不开启或中途因某些操作导致参数被关闭了,就可能造成一些奇奇怪怪的网络问题,排查起来非常麻烦。

为什么要开启呢?本文就来跟你详细掰扯下。

基于网桥的容器网络

Kubernetes 集群网络有很多种实现,有很大一部分都用到了 Linux 网桥:

每个 Pod 的网卡都是 veth 设备,veth pair 的另一端连上宿主机上的网桥。

由于网桥是虚拟的二层设备,同节点的 Pod 之间通信直接走二层转发,跨节点通信才会经过宿主机 eth0。

Service 同节点通信问题

不管是 iptables 还是 ipvs 转发模式,Kubernetes 中访问 Service 都会进行 DNAT,将原本访问 ClusterIP:Port 的数据包 DNAT 成 Service 的某个 Endpoint (PodIP:Port),然后内核将连接信息插入 conntrack 表以记录连接,目的端回包的时候内核从 conntrack 表匹配连接并反向 NAT,这样原路返回形成一个完整的连接链路:

但是 Linux 网桥是一个虚拟的二层转发设备,而 iptables conntrack 是在三层上,所以如果直接访问同一网桥内的地址,就会直接走二层转发,不经过 conntrack:

Pod 访问 Service,目的 IP 是 Cluster IP,不是网桥内的地址,走三层转发,会被 DNAT 成 PodIP:Port。

如果 DNAT 后是转发到了同节点上的 Pod,目的 Pod 回包时发现目的 IP 在同一网桥上,就直接走二层转发了,没有调用 conntrack,导致回包时没有原路返回 (见下图)。

由于没有原路返回,客户端与服务端的通信就不在一个 “频道” 上,不认为处在同一个连接,也就无法正常通信。

常见的问题现象就是偶现 DNS 解析失败,当 coredns 所在节点上的 pod 解析 dns 时,dns 请求落到当前节点的 coredns pod 上时,就可能发生这个问题。

开启 bridge-nf-call-iptables

如果 Kubernetes 环境的网络链路中走了 bridge 就可能遇到上述 Service 同节点通信问题,而 Kubernetes 很多网络实现都用到了 bridge。

启用 bridge-nf-call-iptables 这个内核参数 (置为 1),表示 bridge 设备在二层转发时也去调用 iptables 配置的三层规则 (包含 conntrack),所以开启这个参数就能够解决上述 Service 同节点通信问题,这也是为什么在 Kubernetes 环境中,大多都要求开启 bridge-nf-call-iptables 的原因。

配置linux net.ipv4.ip_forward 数据包转发:

出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将数据包发往本机另一块网卡,该网卡根据路由表继续发送数据包。这通常是路由器所要实现的功能。

要让Linux系统具有路由转发功能,需要配置一个Linux的内核参数net.ipv4.ip_forward。这个参数指定了Linux系统当前对路由转发功能的支持情况;其值为0时表示禁止进行IP转发;如果是1,则说明IP转发功能已经打开

文档

Logo

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

更多推荐