参考链接
https://blog.csdn.net/real_myth/article/details/78719244
服务器IP角色分布
Test-01 172.16.119.214 kubernetes node
Test-02 172.16.119.223 kubernetes node
Test-03 172.16.119.224 kubernetes node
Test-04 172.16.119.225 kubernetes master
Master节点必需组件
组件名称 | 作用 | 版本号 |
etcd | 非关系型数据库 | v1.9.1 |
kube-apiserver | 核心组件,所有组件均与其通信,提供Http Restful接口 | v1.9.1 |
kube-controller-manager | 集群内部管理中心,负责各类资源管理,如RC,Pod,命名空间等 | v1.9.1 |
kube-scheduler | 调度组件,负责node的调度 |
Node节点必需组件
组件名称 | 作用 | 版本号 |
kubelet | Node节点中核心组件,负责执行Master下发的任务 | v1.9.1 |
kube-proxy | 代理,负责kubelet与apiserver网络。相当于负载均衡,将请求转到后端pod中 |
准备工作
先设置本机hosts,编译/etc/hosts添加如下内容:
172.16.119.225 test-04
修改内核参数
cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward=1 EOF sysctl --system
关闭swap k8s1.8版本以后,要求关闭swap,否则默认配置下kubelet将无法启动。
swapoff -a #防止开机自动挂载 swap 分区 sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
开启ipvs
不是必须,只是建议,pod的负载均衡是用kube-proxy来实现的,实现方式有两种,一种是默认的iptables,一种是ipvs,ipvs比iptable的性能更好而已。
ipvs是啥?为啥要用ipvs?:https://blog.csdn.net/fanren224/article/details/86548398
后面master的高可用和集群服务的负载均衡要用到ipvs,所以加载内核的以下模块
需要开启的模块是
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4
检查有没有开启
cut -f1 -d " " /proc/modules | grep -e ip_vs -e nf_conntrack_ipv4
没有的话,使用以下命令加载
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
ipvs还需要ipset,检查下有没有。如果没有,安装
yum install ipset -y
关闭防火墙,禁用selinux
vi /etc/selinux/config disabled systemctl disable firewalld systemctl stop firewalld
软件安装
1、Mster节点:
yum install etcd kubernetes flannel
kubeadm:用于k8s节点管理(比如初始化主节点、集群中加入子节占为、移除节点等)。
kubectl:用于管理k8s的各种资源(比如查看logs、rs、deploy、ds等)。
kubelet:k8s的服务。
配置/etc/etcd/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd/master.etcd" ETCD_LISTEN_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.119.225:2379 " ETCD_NAME="master" ETCD_ADVERTISE_CLIENT_URLS="http://127.0.0.1:2379,http://172.16.119.225:2379"
启动etcd
systemctl restart etcd && systemctl enable etcd
检查etcd的健康指标
etcdctl -C http://172.16.119.225:2379 cluster-health
配置etcd中关于flannel的key 也就是分配给docker的网段
etcdctl mk /atomic.io/network/config '{ "Network": "10.254.0.0/16" }'
配置 /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://172.16.119.225:2379" FLANNEL_ETCD_PREFIX="/atomic.io/network"
启动flannel
systemctl start flanneld && systemctl enable flanneld
配置/etc/kubernetes/apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0" #此参数为绑定不安全地址,绑定安全地址参数是 --bind-address=172.16.119.225KUBE_ETCD_SERVERS="--etcd-servers=http://172.16.119.225:2379" KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota" KUBE_API_ARGS=""
重启服务并设置开机自启动
systemctl restart kube-apiserver && systemctl enable kube-apiserver systemctl restart kube-controller-manager && systemctl enable kube-controller-manager systemctl restart kube-scheduler && systemctl enable kube-scheduler
2、node节点:
1、安装配置flannel
yum install flannel
配置flannel:/etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://172.16.119.225:2379" # 172.16.119.225为master地址
FLANNEL_ETCD_PREFIX="/atomic.io/network"
启动flannel
systemctl start flanneld && systemctl enable flanneld
2、安装kubernetes
yum install kubernetes
不同于master节点,slave节点上需要运行kubernetes的如下组件:
kubelet
kubernets-proxy
配置/etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true" # journal message level, 0 is debug KUBE_LOG_LEVEL="--v=0" # Should this cluster be allowed to run privileged docker containers KUBE_ALLOW_PRIV="--allow-privileged=false" # How the controller-manager, scheduler, and proxy find the apiserver KUBE_MASTER="--master=http://172.16.119.225:8080" #172.16.119.225为master地址
配置 /etc/kubernetes/kubelet
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces) KUBELET_ADDRESS="--address=172.16.119.225" # The port for the info server to serve on KUBELET_PORT="--port=10250" # You may leave this blank to use the actual hostname KUBELET_HOSTNAME="--hostname-override= 172.16.119.214" #node的名字,随意取 # 172.16.119.214为node地址 # location of the api-server KUBELET_API_SERVER="--api-servers=http://172.16.119.225:6442" #172.16.119.225为master地址 # pod infrastructure container KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest" # Add your own! KUBELET_ARGS=""
启动kube服务
systemctl restart kubelet && systemctl enable kubelet
systemctl restart kube-proxy && systemctl enable kube-proxy
至此,k8s集群的搭建过程就完成一半了
验证集群状态
- 1、查看端点信息:kubectl get endpoints
- 2、查看集群信息:kubectl cluster-info
- 3、获取集群中的节点状态: kubectl get nodes
认证授权设置
参考链接:https://www.cnblogs.com/lemon-le/p/9970783.html
集群搭建好后务必设置认证授权,否则等后面配置Kubernetes Api Server时会因为没有安全配置导致服务器被渗透,参考https://www.jianshu.com/p/e443b3171253
步骤如下:
1、停止原有kubernetes相关服务,包括service,deployments,pods以及运行的所有kubernetes组件
master节点上:
systemctl stop kube-apiserver
systemctl stop kube-controller-manager
systemctl stop kube-scheduler
rm -fr /var/lib/kubelet/*
rm -fr /var/lib/kube-proxy/*
node节点上:
systemctl stop kubelet
systemctl stop kube-proxy
rm -fr /var/lib/kubelet/*
rm -fr /var/lib/kube-proxy/*
2、设置kube-apiserver的ca证书的相关文件和启动参数
openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -subj "/CN=test-04" -days 5000 -out ca.crt openssl genrsa -out server.key 2048
注意:生成ca.crt时 /CN 值为master主机名
然后准备master_ssl.conf文件,该文件用于x509 v3版本证书,文件中主要设置master主机 hostname 、ip、 k8s 虚拟赋权名称和该虚拟服务的ClusterIP地址
内容如下:
[req] req_extensions = v3_req distinguished_name = req_distinguished_name [req_distinguished_name] [ v3_req ] basicConstraints = CA:FALSE keyUsage = nonRepudiation,digitalSignature,keyEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = kubernetes DNS.2 = kubernetes.default DNS.3 = kubernetes.default.svc DNS.4 = kubernetes.default.svc.cluster.local DNS.5 = test-04 #服务器的hostname IP.1 = 172.16.119.225 #master ip IP.2 = 10.254.0.1 #svc的cluster ip 如果cluster网段是 10.254.0.0/16 此处就写10.254.0.1
然后基于master_ssl.conf文件创建server.csr和server.crt文件,在生成server.csr时,-subject参数中 /CN 值为master主机名
openssl req -new -key server.key -subj "/CN=test-04" -config master_ssl.conf -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 5000 -extensions v3_req -extfile master_ssl.conf -out server.crt
全部执行完毕会生成6个文件:ca.crt ca.key ca.srl server.crt server.csr server.key 将这些文件复制到一个目录下,如 /var/run/kubernetes/
/var/run/kubernetes/ 默认只有apiserver.crt 、 apiserver.key 、kubelet.crt和kubelet.key四个文件
然后在kube-apiserver文件 KUBE_API_ARGS中添加三个启动参数 --client-ca-file --tls-cert-file 和 --tls-private-key-file,分别代表CA根证书文件、服务器端证书文件和服务端私钥文件
同时可以更改KUBE_API_ADDRESS KUBE_API_PORT KUBE_API_ARGS参数关掉非安全端口8080,设置安全端口为6442,默认为6443
KUBE_API_ADDRESS="--bind-address=172.16.119.225" KUBE_API_PORT="--secure-port=0" # Comma separated list of nodes in the etcd cluster KUBE_ETCD_SERVERS="--etcd-servers=http://172.16.119.225:2379" # Address range to use for services KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" # default admission control policies KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota" # Add your own! KUBE_API_ARGS="--client-ca-file=/var/run/kubernetes/ca.crt --tls-cert-file=/var/run/kubernetes/server.crt --tls-private-key-file=/var/run/kubernetes/server.key --secure-port=6442"
最后重启kube-apiserver服务
systemctl restart kube-apiserver
3、设置kube-controller-manager的客户端证书、私钥和启动参数
openssl genrsa -out cs_client.key 2048 openssl req -new -key cs_client.key -subj "/CN=test-04" -out cs_client.csr openssl x509 -req -in cs_client.csr -CA /var/run/kubernetes/ca.crt -CAkey /var/run/kubernetes/ca.key -CAcreateserial -out cs_client.crt -days 5000
此步会生成3个文件:cs_client.key cs_client.crt cs_client.csr 把生成的证书复制到/var/run/kubernetes/ 然后创建/etc/kubernetes/kubeconfig文件,(kube-controller-manager与kube-scheduler共用),配置客户端证书等参数,内容如下:
apiVersion: v1
kind: Config
users:
- name: controllermanager
user:
client-certificate: /var/run/kubernetes/cs_client.crt
client-key: /var/run/kubernetes/cs_client.key
clusters:
- name: local
cluster:
certificate-authority: /var/run/kubernetes/ca.crt
contexts:
- context:
cluster: local
user: controllermanager
name: my-context
current-context: my-context
然后,设置kube-controller-manager服务启动参数,注意 --master的地址为https安全服务地址
更改/etc/kubernetes/controller-manager 启动参数
KUBE_CONTROLLER_MANAGER_ARGS="--master=https://172.16.119.225:6442 --service_account_private_key_file=/var/run/kubernetes/server.key --root-ca-file=/var/run/kubernetes/ca.crt --kubeconfig=/etc/kubernetes/kubeconfig"
更改/etc/kubernetes/config 里 KUBE_MASTER="--master=http://127.0.0.1:8080" 改成上面设置的安全地址 KUBE_MASTER="--master=https://172.16.119.225:6442"
重启kube-controller-manager服务
systemctl restart kube-controller-manager
4、设置kube-scheduler参数
kube-scheduler复用上一步kube-controller-manager创建的客户端证书,只需要修改/etc/kubernetes/scheduler启动参数即可
KUBE_SCHEDULER_ARGS="--master=https://172.16.119.225:6442 --kubeconfig=/etc/kubernetes/kubeconfig"
重启kube-scheduler服务
systemctl restart kube-scheduler
5、设置每台node上kubelet的客户端证书、私钥和启动参数
首先复制kube-apiserver的ca.crt和ca.key文件到node上,然后生成kubelet_client.crt证书,生成证书时-CA参数和-CAkey参数使用的是apiserver的ca.crt和ca.key文件;生成kubelet_client.csr是 -subj参数中 /CN 为本机node ip地址
openssl genrsa -out kubelet_client.key 2048 openssl req -new -key kubelet_client.key -subj "/CN=172.16.119.225" -out kubelet_client.csr openssl x509 -req -in kubelet_client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet_client.crt -days 5000
此步会生成3个文件:kubelet_client.key kubelet_client.csr kubelet_client.crt 然后把生成的证书复制到/var/run/kubernetes/目录下
接下来创建/etc/kubernetes/kube_client_config文件(kubelet和kube-proxy共用),配置客户端证书等相关参数,内容如下:
apiVersion: v1
kind: Config
users:
- name: kubelet
user:
client-certificate: /var/run/kubernetes/kubelet_client.crt
client-key: /var/run/kubernetes/kubelet_client.key
clusters:
- name: local
cluster:
certificate-authority: /var/run/kubernetes/ca.crt
contexts:
- context:
cluster: local
user: kubelet
name: my-context
current-context: my-context
然后设置kubelet启动参数
# location of the api-server KUBELET_API_SERVER="--api-servers=https://172.16.119.225:6442" # pod infrastructure container KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest" # Add your own! KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kube_client_config"
重启kubelet服务
systemctl restart kubelet
6、设置kube-proxy启动参数
kube-proxy复用上一步创建的客户端证书,只需配置启动参数即可
vim /etc/kubernetes/proxy
KUBE_PROXY_ARGS="--master=https://172.16.119.225:6442 --kubeconfig=/etc/kubernetes/kube_client_config"
重启kube-proxy服务
systemctl restart kube-proxy
7、设置kubectl客户端使用安全方式访问apiserver
在使用kubectl对kubenetes集群进行操作时,默认使用非安全端口8080对apiserver进行访问,也可以设置设置为安全访问apiserver的模式,此模式需要设置3个证书相关的参数 --certificat-authority --client-certificate 和 --client-key
分别表示用于CA授权证书、客户端证书和客户端秘钥,其中
--certificat-authority 使用为kube-apiserver生成的ca.crt文件
--client-certificate 使用为kube-controller-manager生成的cs_client.crt文件
--client-key 使用为kube-controller-manager生成的cs_client.key文件
同时指定apiserver的URL地址为HTTPS安全地址,最后输入需要执行的子命令,即可对apiserver进行安全访问了:
kubectl --server=https://172.16.119.225:6442 --certificate-authority=/var/run/kubernetes/ca.crt --client-certificate=/var/run/kubernetes/cs_client.crt --client-key=/var/run/kubernetes/cs_client.key get nodes
但每次这样忒麻烦了,所以写个alias,不知道还有没有其他方法
编辑 ~/.bashrc
vim ~/.bashrc 增加下面一局然后source ~/.bashrc 即可
alias kubectl='kubectl --server=https://172.16.119.225:6442 --certificate-authority=/var/run/kubernetes/ca.crt --client-certificate=/var/run/kubernetes/cs_client.crt --client-key=/var/run/kubernetes/cs_client.key'
DNS服务搭建
https://blog.51cto.com/ylw6006/2067923
Kubernetes集群机制通过DNS进行服务名和ip的映射,如果没有配置dns,可以通过kubectl get svc 命令查询集群ip,
但Cluster-ip是变化的,如果通过一个create命令一次批量建立一堆具有相互依赖关系的Pod或者RC,就需要配置DNS
DNS 有两种配置方式,在 1.3 之前使用 etcd + kube2sky + skydns 的方式,在 1.3 之后可以使用 kubedns + dnsmasq 的方式。
推荐使用kubedns + dnsmasq 的方式,本次也是使用此方式。
先创建目录,skydns文件都放在/etc/kubernetes/skydns 下
mkdir /etc/kubernetes/skydns
1、配置etcd中关于skyDNS的key
etcdctl mk /skydns/config '{"dns-addr":"10.254.254.254:53","ttl":3600,"domain":"cluster.local."}'
2、skynds服务由一个RC和一个Service定义组成,分别由配置文件skydns-rc.yaml和 skydns-svc.yaml定义:
skydns-rc.yaml包含2个容器的定义,需要修改如下几个参数:
--kube_master_url 为master所在的物理主机IP和端口
--domain=cluster.local 设置kubernetes集群中Service所属的域名,本例为cluster.local
apiVersion: v1 kind: ReplicationController metadata: name: kube-dns namespace: kube-system labels: k8s-app: kube-dns version: v12 kubernetes.io/cluster-service: "true" spec: replicas: 1 selector: k8s-app: kube-dns version: v12 template: metadata: labels: k8s-app: kube-dns version: v12 kubernetes.io/cluster-service: "true" spec: containers: - name: kube2sky image: docker.io/port/kubernetes-kube2sky resources: limits: cpu: 100m memory: 50Mi requests: cpu: 100m memory: 50Mi args: - --kube_master_url=https://172.16.119.225:6442 - -domain=cluster.local - -etcd-server=http://172.16.119.225:2379 - name: skydns image: docker.io/skynetservices/skydns resources: limits: cpu: 100m memory: 50Mi requests: cpu: 100m memory: 50Mi args: - -machines=http://172.16.119.225:2379 - -addr=0.0.0.0:53 - -ns-rotate=false - -domain=cluster.local. # 点 不能少 ports: - containerPort: 53 name: dns protocol: UDP - containerPort: 53 name: dns-tcp protocol: TCP dnsPolicy: Default
skydns-svc.yaml
apiVersion: v1 kind: Service metadata: name: kube-dns namespace: kube-system labels: k8s-app: kube-dns kubernetes.io/cluster-service: "true" kubernetes.io/name: "KubeDNS" spec: selector: k8s-app: kube-dns clusterIP: 10.254.254.254 ports: - name: dns port: 53 protocol: UDP - name: dns-tcp port: 53 protocol: TCP
注意,skydns需要指定一个固定的IP,之后每个node节点启动都将使用这个IP,且这个IP一定要是kube-apiserver启动参数--service-cluster-ip-range范围内的IP。
创建skydns之前需要修改每个node上kubelet的启动参数。
3、修改node启动参数
编译kubelet文件,添加俩个启动参数
--cluster-dns 上面配置的10.254.254.254
--cluster-domain 上面配置的cluster.local
KUBELET_ARGS="--kubeconfig=/etc/kubernetes/kube_client_config --cluster-dns=10.254.254.254 --cluster-domain=cluster.local"
然后重启kubelet服务
systemctl restart kubelet
4、创建skydns的RC和SVC
kubectl create -f skydns/skydns-rc.yaml
kubectl create -f skydns/skydns-svc.yaml
查看RC pod svc,确保容器启动成功,如果没有启动成功,查看原因是不是镜像地址更改了,如果镜像地址改了,可以登录http://docker.gaoxiaobang.com查看新的镜像地址
如果pod无法启动,可参考文尾解决办法
至此,在Kubernetes集群内的虚拟DNS服务已搭建完毕。
5、测试效果
部署一个test-dns的Pod进行验证
apiVersion: v1 kind: Pod metadata: name: test-dns namespace: default spec: containers: - name: test-dns image: busybox command: - sleep - "3600"
启动test-dns
容器启动成功后,通过下面命令进行测试
kubectl exec -it test-dns sh
也可以新建一个pod,然后用 kubectl exec <container_id> nslookup 验证
如果某个Service属于不同的命名空间,则进行Service查找时,需要带上namespace的名字,如:
kubectl exec test-dns -- nslookup default.kubernetes
安装Dashboard
1、下载代码
git clone https://github.com/Qihoo360/wayne/
其中 hack/kubernetes
目录下面就是我们需要部署的 Wayne 的资源清单文件
2、我们这里将所有服务都部署到 kube-system
命名空间下面,所以将这里的资源清单中的 namespace
都统一改成 kube-system
grep -rl default wayne/hack/kubernetes/wayne/ | xargs sed -i 's/default/kube-system/'
3、由于我们这里是使用上面集群中部署的 MySQL 服务,所以这里需要对 configmap.yaml 文件进行简单的配置,而 360 文档上面的 ConfigMap 是不完整的,需要使用源码里面的 app.conf
文件来进行创建,所以我们这里可以使用 --from-file
关键字来创建 ConfigMap 对象,首先配置下 wayne/src/backend/conf/app.conf 文件,根据个人需要修改,也可以不改,使用默认的配置,然后创建ConfigMap
kubectl create configmap infra-wayne --namespace kube-system --from-file=wayne/src/backend/conf/app.conf
4、然后部署另外俩个应用
kubectl create -f wayne/hack/kubernetes/wayne/deployment.yaml
kubectl create -f wayne/hack/kubernetes/wayne/service.yaml
5、创建完成后,可以查看下 Pod 的状态,如果没有错误信息,就证明部署成功了
kubectl get pods -n kube-system
如果失败可用
kubectl logs -n kube-system -f infra-wayne-312744915-xdb8b 查看错误信息
或者
kubectl describe -n kube-system pods infra-wayne-312744915-xdb8b
6、查看端口
kubectl get svc -n kube-system -l app=infra-wayne
然后使用本机IP:30771来访问 Wayne
---------------------------------------------
异常解决
1、kubectl create -f mysql.yaml 后pod无法启动,用kubectl get pod 发现该pod处于ContainerCreating状态
使用kubectl describe pod mysql-wayne-3939478235-x83pm 查看具体信息时发现报错如下:
解决办法:
各个node节点上都需要安装
yum install *rhsm*
docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest
如果还报错则进行如下步骤
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | tee /etc/rhsm/ca/redhat-uep.pem docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest
然后删除pod 重新创建
kubectl delete -f mysql.yaml
kubectl create -f mysql.yaml
2、pod无法删除排查
https://www.58jb.com/html/155.html
3、etcd简单操作
ls 查看
get 获取key的值
rm 删除key
更多的参考 etcdctl help