crt设置平铺窗口
enter description here
准备虚拟机
配置ip地址和hostname
配置ip地址
/etc/netplan/*.yaml
添加配置
ens33:
dhcp4: no
addresses: [192.168.214.188/24]
gateway4: 192.168.214.2
#重启network
netplan apply
从ubuntu17开始抛弃了使用传统的配置ip地址方法。变成了从上面目录下的yaml文件配置
配置hostname
必须把 /etc/cloud/cloud.cfg 文件中的 preserve_hostname 设为 true,否则所有对 hostname 的修改都将是临时的!
然后修改/etc/hostname文件。
然后重启
配置dns(要不然apt更新不了)
vi /etc/systemd/resolved.conf
重启dns
systemctl restart systemd-resolved.service
开启root账户和远程登陆
设置root账户密码。此操作同时将开启root账户
sudo passwd root
配置ssh
vim /etc/ssh/sshd_config
将“#PermitRootLogin prohibit-password”修改为“PermitRootLogin yes”
重启ssh
service ssh restart
取消DNS注释。增加dns然后重启
安装docker,准备环境
安装docker
- 卸载旧版本(如果有的话)
apt-get remove docker docker-engine docker.io - 设置稳定版仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
- 安装依赖包
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
- 添加 Docker 的官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
- 更新apt-get源
- 安装docker-ce
- 安装最新稳定版
apt-get install -y docker-ce - 安装指定版本
#获取版本列表
$ apt-cache madison docker-ce
#指定版本安装(比如版本是17.09.1~ce-0~ubuntu)
$ apt-get install -y docker-ce=17.09.1~ce-0~ubuntu
修改docker的ip数据包转发
- 打开docker配置文件
vim /lib/systemd/system/docker.service - 找到ExecStart=xxx,在这行上面加入一行,内容如下:(k8s的网络需要)
ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT - 重新reload和启动docker
systemctl daemon-reload
service docker restart
关闭防火墙
让所有机器之间都可以通过任意端口建立连接
#开启防火墙
ufw enable
#关闭防火墙
ufw disable
#查看状态
ufw status
设置系统参数 - 允许路由转发
不对bridge的数据进行处理
#写入配置文件
$ cat <<EOF > /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
#生效配置文件
$ sysctl -p /etc/sysctl.d/k8s.conf
配置host文件
#配置host,使每个Node都可以通过名字解析到ip地址
$ vi /etc/hosts
#加入如下片段(ip地址和servername替换成自己的)
192.168.214.188 master
192.168.214.189 node1
192.168.214.190 node2
安装Kubernetes(二进制)
kubernetes的安装有几种方式,不管是kube-admin还是社区贡献的部署方案都离不开这几种方式:
- 使用现成的二进制文件
直接从官方或其他第三方下载,就是kubernetes各个组件的可执行文件。拿来就可以直接运行了。不管是centos,ubuntu还是其他的linux发行版本,只要gcc编译环境没有太大的区别就可以直接运行的。使用较新的系统一般不会有什么跨平台的问题。 - 使用源码编译安装
编译结果也是各个组件的二进制文件,所以如果能直接下载到需要的二进制文件基本没有什么编译的必要性了。 - 使用镜像的方式运行
同样一个功能使用二进制文件提供的服务,也可以选择使用镜像的方式。就像nginx,像mysql,我们可以使用安装版,搞一个可执行文件运行起来,也可以使用它们的镜像运行起来,提供同样的服务。kubernetes也是一样的道理,二进制文件提供的服务镜像也一样可以提供。
准备二进制文件
enter description here
设置全局环境变量
vi /etc/environment
ubuntu的环境变量是用冒号分隔。加入刚才二进制的路径
#使其立刻生效
source /etc/environment
准备配置文件
此方案为临时方案
git clone https://github.com/liuyi01/kubernetes-starter.git
文件说明
- gen-config.sh
shell脚本,用来根据每个同学自己的集群环境(ip,hostname等),根据下面的模板,生成适合大家各自环境的配置文件。生成的文件会放到target文件夹下。 - kubernetes-simple
简易版kubernetes配置模板(剥离了认证授权)。 适合刚接触kubernetes的同学,首先会让大家在和kubernetes初次见面不会印象太差(太复杂啦~~),再有就是让大家更容易抓住kubernetes的核心部分,把注意力集中到核心组件及组件的联系,从整体上把握kubernetes的运行机制。 - kubernetes-with-ca
在simple基础上增加认证授权部分。大家可以自行对比生成的配置文件,看看跟simple版的差异,更容易理解认证授权的(认证授权也是kubernetes学习曲线较高的重要原因) - service-config
这个先不用关注,它是我们曾经开发的那些微服务配置。 等我们熟悉了kubernetes后,实践用的,通过这些配置,把我们的微服务都运行到kubernetes集群中。
生成配置
编辑生成得配置文件
进入刚刚下载得文件夹kubernetes-starter,编辑config.properties配置文件
#kubernetes二进制文件目录,eg: /home/michael/bin
BIN_PATH=/mnt/Downloads/kubernetes-bins
#当前节点ip, eg: 192.168.1.102
NODE_IP=192.168.214.188
#etcd服务集群列表, eg: http://192.168.1.102:2379
#如果已有etcd集群可以填写现有的。没有的话填写:http://${MASTER_IP}:2379 (MASTER_IP自行替换成自己的主节点ip)
##如果用了证书,就要填写https://${MASTER_IP}:2379 (MASTER_IP自行替换成自己的主节点ip)
ETCD_ENDPOINTS=http://192.168.214.188:2379
#kubernetes主节点ip地址, eg: 192.168.1.102
MASTER_IP=192.168.214.188
生成配置文件
./gen-config.sh simple
常见问题
执行gen-config.sh常见问题:
- gen-config.sh: 3: gen-config.sh: Syntax error: "(" unexpected
- bash版本过低,运行:bash -version查看版本,如果小于4需要升级
- 不要使用 sh gen-config.sh的方式运行(sh和bash可能不一样哦)
- config.properties文件填写错误,需要重新生成 再执行一次./gen-config.sh simple即可,不需要手动删除target
部署ETCD(主节点)
简介
kubernetes需要存储很多东西,像它本身的节点信息,组件信息,还有通过kubernetes运行的pod,deployment,service等等。都需要持久化。etcd就是它的数据中心。生产环境中为了保证数据中心的高可用和数据的一致性,一般会部署最少三个节点。我们这里以学习为主就只在主节点部署一个实例。
部署
#把服务配置文件copy到系统服务目录
$ cp /mnt/Downloads/kubernetes-starter/target/master-node/etcd.service /lib/systemd/system/
#enable服务
$ systemctl enable etcd.service
#创建工作目录(保存数据的地方)
$ mkdir -p /var/lib/etcd
# 启动服务
$ service etcd start
# 查看服务日志,看是否有错误信息,确保服务正常
$ journalctl -f -u etcd.service
配置文件
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
ExecStart=/mnt/Downloads/kubernetes-bins/etcd \
--name=192.168.214.188 \
--listen-client-urls=http://192.168.214.188:2379,http://127.0.0.1:2379 \
--advertise-client-urls=http://192.168.214.188:2379 \
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
查看日志如图:
部署APIServer(主节点)
简介
kube-apiserver是Kubernetes最重要的核心组件之一,主要提供以下的功能
- 提供集群管理的REST API接口,包括认证授权(我们现在没有用到)数据校验以及集群状态变更等
- 提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd)
生产环境为了保证apiserver的高可用一般会部署2+个节点,在上层做一个lb做负载均衡,比如haproxy。由于单节点和多节点在apiserver这一层说来没什么区别,所以我们学习部署一个节点就足够啦
部署
和ETCD一摸一样
$ cp /mnt/Downloads/kubernetes-starter/target/master-node/kube-apiserver.service /lib/systemd/system/
$ systemctl enable kube-apiserver.service
$ service kube-apiserver start
$ journalctl -f -u kube-apiserver
可以查看自己提供的swagger
配置文件
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
#可执行文件位置
ExecStart=/mnt/Downloads/kubernetes-bins/kube-apiserver \
#准入控制。和认证授权一起搭配
--admission-control=NamespaceLifecycle,LimitRanger,DefaultStorageClass,ResourceQuota,NodeRestriction \
#不安全的绑定地址
--insecure-bind-address=0.0.0.0 \
#是否开启HTTPS
--kubelet-https=false \
#定义service集群ip的范围。定义前两位即可。使用kube-proxy时候的ip地址
--service-cluster-ip-range=10.68.0.0/16 \
#service的node-port端口。可以提供外界方位
--service-node-port-range=20000-40000 \
#访问etcd。进行交互
--etcd-servers=http://192.168.214.188:2379 \
--enable-swagger-ui=true \
--allow-privileged=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/var/lib/audit.log \
--event-ttl=1h \
#日志级别5是debug。最高
--v=2
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
部署ControllerManager(主节点)
简介
Controller Manager由kube-controller-manager和cloud-controller-manager组成,是Kubernetes的大脑,它通过apiserver监控整个集群的状态,并确保集群处于预期的工作状态。 kube-controller-manager由一系列的控制器组成,像Replication Controller控制副本,Node Controller节点控制,Deployment Controller管理deployment等等 cloud-controller-manager在Kubernetes启用Cloud Provider的时候才需要,用来配合云服务提供商的控制
controller-manager、scheduler和apiserver 三者的功能紧密相关,一般运行在同一个机器上,我们可以把它们当做一个整体来看,所以保证了apiserver的高可用即是保证了三个模块的高可用。也可以同时启动多个controller-manager进程,但只有一个会被选举为leader提供服务。
部署
$ cp /mnt/Downloads/kubernetes-starter/target/master-node/kube-controller-manager.service /lib/systemd/system/
$ systemctl enable kube-controller-manager.service
$ service kube-controller-manager start
$ journalctl -f -u kube-controller-manager
配置
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/mnt/Downloads/kubernetes-bins/kube-controller-manager \
#对外服务的监听地址,这里表示只有本机的程序可以访问它
--address=127.0.0.1 \
#apiserver的url
--master=http://127.0.0.1:8080 \
--allocate-node-cidrs=true \
#服务虚拟ip范围,同apiserver的配置
--service-cluster-ip-range=10.68.0.0/16 \
#pod的ip地址范围
--cluster-cidr=172.20.0.0/16 \
--cluster-name=kubernetes \
--leader-elect=true \
#下面两个表示不使用证书,用空值覆盖默认值
--cluster-signing-cert-file= \
--cluster-signing-key-file= \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
证书如果不使用一定要使用\覆盖。要不然服务启动不了
部署Scheduler(主节点)
简介
kube-scheduler负责分配调度Pod到集群内的节点上,它监听kube-apiserver,查询还未分配Node的Pod,然后根据调度策略为这些Pod分配节点。我们前面讲到的kubernetes的各种调度策略就是它实现的。
部署
$ cp /mnt/Downloads/kubernetes-starter/target/master-node/kube-scheduler.service /lib/systemd/system/
$ systemctl enable kube-scheduler.service
$ service kube-scheduler start
$ journalctl -f -u kube-scheduler
配置文件
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
ExecStart=/mnt/Downloads/kubernetes-bins/kube-scheduler \
--address=127.0.0.1 \
#对外服务的监听地址,这里表示只有本机的程序可以访问它
--master=http://127.0.0.1:8080 \
--leader-elect=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
部署CNI接口(CalicoNode)(所有节点)
简介
Calico实现了CNI接口,是kubernetes网络方案的一种选择,它一个纯三层的数据中心网络方案(不需要Overlay),并且与OpenStack、Kubernetes、AWS、GCE等IaaS和容器平台都有良好的集成。 Calico在每一个计算节点利用Linux Kernel实现了一个高效的vRouter来负责数据转发,而每个vRouter通过BGP协议负责把自己上运行的workload的路由信息像整个Calico网络内传播——小规模部署可以直接互联,大规模下可通过指定的BGP route reflector来完成。 这样保证最终所有的workload之间的数据流量都是通过IP路由的方式完成互联的。
部署
calico是通过系统服务+docker方式完成的
$ cp /mnt/Downloads/kubernetes-starter/target/all-node/kube-calico.service /lib/systemd/system/
$ systemctl enable kube-calico.service
$ service kube-calico start
$ journalctl -f -u kube-calico
验证运行情况
0
查看容器的运行情况
docker ps
1
查看节点运行情况
calicoctl node status
enter description here
2
查看端口BGP 协议是通过TCP 连接来建立邻居的,因此可以用netstat 命令验证 BGP Peer
netstat -natp|grep ESTABLISHED|grep 179
enter description here
3只能再ETCD节点运行
查看集群ippool情况
calicoctl get ipPool -o yaml
配置文件
[Unit]
Description=calico node
After=docker.service
Requires=docker.service
[Service]
User=root
PermissionsStartOnly=true
#以docker方式运行
ExecStart=/usr/bin/docker run --net=host --privileged --name=calico-node \
#指定etcd endpoints(这里主要负责网络元数据一致性,确保Calico网络状态的准确性)
-e ETCD_ENDPOINTS=http://192.168.214.188:2379 \
-e CALICO_LIBNETWORK_ENABLED=true \
-e CALICO_NETWORKING_BACKEND=bird \
-e CALICO_DISABLE_FILE_LOGGING=true \
#网络地址范围(同上面ControllerManager)
-e CALICO_IPV4POOL_CIDR=172.20.0.0/16 \
-e CALICO_IPV4POOL_IPIP=off \
-e FELIX_DEFAULTENDPOINTTOHOSTACTION=ACCEPT \
-e FELIX_IPV6SUPPORT=false \
-e FELIX_LOGSEVERITYSCREEN=info \
-e FELIX_IPINIPMTU=1440 \
-e FELIX_HEALTHENABLED=true \
-e IP=192.168.214.189 \
-v /var/run/calico:/var/run/calico \
-v /lib/modules:/lib/modules \
-v /run/docker/plugins:/run/docker/plugins \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/log/calico:/var/log/calico \
#镜像名,为了加快大家的下载速度,镜像都放到了阿里云上
registry.cn-hangzhou.aliyuncs.com/imooc/calico-node:v2.6.2
ExecStop=/usr/bin/docker rm -f calico-node
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
部署kubectl命令(任意节点)
简介
kubectl是Kubernetes的命令行工具,是Kubernetes用户和管理员必备的管理工具。 kubectl提供了大量的子命令,方便管理Kubernetes集群中的各种功能。
初始化
使用kubectl的第一步是配置Kubernetes集群以及认证方式,包括:
- cluster信息:api-server地址
- 用户信息:用户名、密码或密钥
- Context:cluster、用户信息以及Namespace的组合
我们这没有安全相关的东西,只需要设置好api-server和上下文就好啦:
#指定apiserver地址(ip替换为你自己的api-server地址)
kubectl config set-cluster kubernetes --server=http://192.168.214.188:8080
#指定设置上下文,指定cluster
kubectl config set-context kubernetes --cluster=kubernetes
#选择默认的上下文
kubectl config use-context kubernetes
通过上面的设置最终目的是生成了一个配置文件:~/.kube/config,当然你也可以手写或复制一个文件放在那,就不需要上面的命令了。
部署kubelet(工作节点)
简介
每个工作节点上都运行一个kubelet服务进程,默认监听10250端口,接收并执行master发来的指令,管理Pod及Pod中的容器。每个kubelet进程会在API Server上注册节点自身信息,定期向master节点汇报节点的资源使用情况,并通过cAdvisor监控节点和容器的资源。
部署
通过系统服务方式部署,但步骤会多一些,具体如下:
#确保相关目录存在
mkdir -p /var/lib/kubelet
mkdir -p /etc/kubernetes
mkdir -p /etc/cni/net.d
#复制kubelet服务配置文件
$ cp /mnt/Downloads/kubernetes-starter/target/worker-node/kubelet.service /lib/systemd/system/
#复制kubelet依赖的配置文件
$ cp /mnt/Downloads/kubernetes-starter/target/worker-node/kubelet.kubeconfig /etc/kubernetes/
#复制kubelet用到的cni插件配置文件
$ cp /mnt/Downloads/kubernetes-starter/target/worker-node/10-calico.conf /etc/cni/net.d/
$ systemctl enable kubelet.service
$ service kubelet start
$ journalctl -f -u kubelet
配置文件
kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
#kubelet工作目录,存储当前节点容器,pod等信息
WorkingDirectory=/var/lib/kubelet
ExecStart=/mnt/Downloads/kubernetes-bins/kubelet \
#对外服务的监听地址
--address=192.168.214.190 \
--hostname-override=192.168.214.190 \
#指定基础容器的镜像,负责创建Pod 内部共享的网络、文件系统等,这个基础容器非常重要:K8S每一个运行的 POD里面必然包含这个基础容器,如果它没有运行起来那么你的POD 肯定创建不了
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/imooc/pause-amd64:3.0 \
#访问集群方式的配置,如api-server地址等
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
#声明cni网络插件
--network-plugin=cni \
#cni网络配置目录,kubelet会读取该目录下得网络配置
--cni-conf-dir=/etc/cni/net.d \
--cni-bin-dir=/mnt/Downloads/kubernetes-bins \
#指定 kubedns 的 Service IP(可以先分配,后续创建 kubedns 服务时指定该 IP),--cluster-domain 指定域名后缀,这两个参数同时指定后才会生效
--cluster-dns=10.68.0.2 \
--cluster-domain=cluster.local. \
--allow-privileged=true \
--fail-swap-on=false \
--logtostderr=true \
--v=2
#kubelet cAdvisor 默认在所有接口监听 4194 端口的请求, 以下iptables限制内网访问
ExecStartPost=/sbin/iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -s 172.16.0.0/12 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -s 192.168.0.0/16 -p tcp --dport 4194 -j ACCEPT
ExecStartPost=/sbin/iptables -A INPUT -p tcp --dport 4194 -j DROP
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
kubelet.kubeconfig
kubelet依赖的一个配置,格式看也是我们后面经常遇到的yaml格式,描述了kubelet访问apiserver的方式
apiVersion: v1
clusters:
- cluster:
#跳过tls,即是kubernetes的认证
insecure-skip-tls-verify: true
server: http://192.168.214.188:8080
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: ""
name: system:node:kube-master
current-context: system:node:kube-master
kind: Config
preferences: {}
users: []
10-calico.conf
calico作为kubernets的CNI插件的配置
{
"name": "calico-k8s-network",
"cniVersion": "0.1.0",
"type": "calico",
"etcd_endpoints": "http://192.168.214.188:2379",
"log_level": "info",
"ipam": {
"type": "calico-ipam"
},
"kubernetes": {
"k8s_api_root": "http://192.168.214.188:8080"
}
}
验证
去配置了kubectl命令的机器上执行(本人习惯再master节点部署)
kubectl get nodes
如下图:
部署kube-proxy(工作节点)
简介
每台工作节点上都应该运行一个kube-proxy服务,它监听API server中service和endpoint的变化情况,并通过iptables等来为服务配置负载均衡,是让我们的服务在集群外可以被访问到的重要方式。
部署
#确保工作目录存在
$ mkdir -p /var/lib/kube-proxy
#复制kube-proxy服务配置文件
$ cp /mnt/Downloads/kubernetes-starter/target/worker-node/kube-proxy.service /lib/systemd/system/
#复制kube-proxy依赖的配置文件
$ cp /mnt/Downloads/kubernetes-starter/target/worker-node/kube-proxy.kubeconfig /etc/kubernetes/
$ systemctl enable kube-proxy.service
$ service kube-proxy start
$ journalctl -f -u kube-proxy
配置文件
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
#工作目录
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/mnt/Downloads/kubernetes-bins/kube-proxy \
#监听地址
--bind-address=192.168.214.189 \
--hostname-override=192.168.214.189 \
#依赖的配置文件,描述了kube-proxy如何访问api-server
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \
--logtostderr=true \
--v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
测试使用
#target-port是容器的端口 port是clusterip上提供的端口
kubectl expose deploy test --type="NodePort" --target-port=10005 --port=80
#去工作节点查看
netstat -ntlp|grep 21708
部署kube-dns(主节点)
简介
kube-dns为Kubernetes集群提供命名服务,主要用来解析集群服务名和Pod的hostname。目的是让pod可以通过名字访问到集群内服务。它通过添加A记录的方式实现名字和service的解析。普通的service会解析到service-ip。headless service会解析到pod列表。
部署
kubectl create -f /mnt/Downloads/kubernetes-starter/target/services/kube-dns.yaml
控制和管理Kubernetes
kubectl操作命令
- kubectl version 版本
- kubectl get --help 获取帮助
- kubectl get 获取节点信息 -n kube-system 选中命名空间
- kubectl get pods 获取pods信息 -o wide 查看更多信息 -l app=nginx 查看label相关pod
- kubectl --help
- kubectl run
- kubectl get deployments
- kubectl delete deployments [name] 删除deploy
- kubectl describe [type] [name] 查看描述文件
- kubectl set image deploy test test=[imageAddress] 更新镜像
- kubectl rollout status deploy [deployName]
- kubectl rollout undo deploy [deployName] 回滚操作
- kubectl create -f nginx-pod 使用文件进行创建
- kubectl get services
启动第一个示例
kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --port=8080
kubectl run test --port=10005 --image registry.cn-hangzhou.aliyuncs.com/anqi-java/dlanqi.cmbusiness.test:1.0.0
查看一下下运行再哪个机器上
然后去node节点查看一下日志
journalctl -f
发现提示docker login
添加凭证(没研究明白)
kubectl create secret docker-registry registry-secret --docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=大连安琪科技 --docker-password=1qazXSW@ --docker-email=351520965@qq.com -n default
测试是否可以访问
启动proxy
kubectl proxy --address='0.0.0.0' --accept-hosts='^*$'
http://192.168.214.188:8001/api/v1/proxy/namespaces/default/pods/test-cc95b7c96-ztdxd/swagger-ui.html
扩容缩容
扩容deploy
kubectl scale deploy [deployname] --replicas=4
缩容
kubectl scale deploy [deployname] --replicas=2
使用配置文件管理Kubernetes
- 创建文件夹存放
- 创建pod yaml文件
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
- 创建deploy yaml文件
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
- 创建service yaml文件
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- port: 8080
targetPort: 80
nodePort: 20000
selector:
app: nginx
type: NodePort
为集群增加认证和授权(完整安装k8s)
理解认证和授权
为什么要认证
想理解认证,我们得从认证解决什么问题、防止什么问题的发生入手。
防止什么问题呢?是防止有人入侵你的集群,root你的机器后让我们集群依然安全吗?不是吧,root都到手了,那就为所欲为,防不胜防了。
其实网络安全本身就是为了解决在某些假设成立的条件下如何防范的问题。比如一个非常重要的假设就是两个节点或者ip之间的通讯网络是不可信任的,可能会被第三方窃取,也可能会被第三方篡改。就像我们上学时候给心仪的女孩传纸条,传送的过程可能会被别的同学偷看,甚至内容可能会从我喜欢你修改成我不喜欢你了。当然这种假设不是随便想出来的,而是从网络技术现状和实际发生的问题中发现、总结出来的。kubernetes的认证也是从这个问题出发来实现的。
概念
为了解决上面说的问题,kubernetes并不需要自己想办法,毕竟是网络安全层面的问题,是每个服务都会遇到的问题,业内也有成熟的方案来解决。这里我们一起了解一下业内方案和相关的概念。
- 对称加密/非对称加密 这两个概念属于密码学的东西,对于没接触过的同学不太容易理解。可以参考知乎大神的生动讲解:《如何用通俗易懂的话来解释非对称加密》
- SSL/TLS 了解了对称加密和非对称加密后,我们就可以了解一下SSL/TLS了。同样,已经有大神总结了非常好的入门文章:《SSL/TLS协议运行机制的概述》
什么是授权
授权的概念就简单多了,就是什么人具有什么样的权限,一般通过角色作为纽带把他们组合在一起。也就是一个角色一边拥有多种权限,一边拥有多个人。这样就把人和权限建立了一个关系。
kubernetes的认证授权
Kubernetes集群的所有操作基本上都是通过kube-apiserver这个组件进行的,它提供HTTP RESTful形式的API供集群内外客户端调用。需要注意的是:认证授权过程只存在HTTPS形式的API中。也就是说,如果客户端使用HTTP连接到kube-apiserver,那么是不会进行认证授权的。所以说,可以这么设置,在集群内部组件间通信使用HTTP,集群外部就使用HTTPS,这样既增加了安全性,也不至于太复杂。
对APIServer的访问要经过的三个步骤,前面两个是认证和授权,第三个是 Admission Control,它也能在一定程度上提高安全性,不过更多是资源管理方面的作用。
kubernetes的认证
kubernetes提供了多种认证方式,比如客户端证书、静态token、静态密码文件、ServiceAccountTokens等等。你可以同时使用一种或多种认证方式。只要通过任何一个都被认作是认证通过。下面我们就认识几个常见的认证方式。
- 客户端证书认证 客户端证书认证叫作TLS双向认证,也就是服务器客户端互相验证证书的正确性,在都正确的情况下协调通信加密方案。 为了使用这个方案,api-server需要用--client-ca-file选项来开启。
- 引导Token 当我们有非常多的node节点时,手动为每个node节点配置TLS认证比较麻烦,这时就可以用到引导token的认证方式,前提是需要在api-server开启 experimental-bootstrap-token-auth 特性,客户端的token信息与预先定义的token匹配认证通过后,自动为node颁发证书。当然引导token是一种机制,可以用到各种场景中。
- Service Account Tokens 认证 有些情况下,我们希望在pod内部访问api-server,获取集群的信息,甚至对集群进行改动。针对这种情况,kubernetes提供了一种特殊的认证方式:Service Account。 Service Account 和 pod、service、deployment 一样是 kubernetes 集群中的一种资源,用户也可以创建自己的 Service Account。 ServiceAccount 主要包含了三个内容:namespace、Token 和 CA。namespace 指定了 pod 所在的 namespace,CA 用于验证 apiserver 的证书,token 用作身份验证。它们都通过 mount 的方式保存在 pod 的文件系统中。
kubernetes的授权
在Kubernetes1.6版本中新增角色访问控制机制(Role-Based Access,RBAC)让集群管理员可以针对特定使用者或服务账号的角色,进行更精确的资源访问控制。在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。在一个组织中,角色是为了完成各种工作而创造,用户则依据它的责任和资格来被指派相应的角色,用户可以很容易地从一个角色被指派到另一个角色。 目前 Kubernetes 中有一系列的鉴权机制,因为Kubernetes社区的投入和偏好,相对于其它鉴权机制而言,RBAC是更好的选择。具体RBAC是如何体现在kubernetes系统中的我们会在后面的部署中逐步的深入了解。
kubernetes的AdmissionControl(准入控制)
AdmissionControl - 准入控制本质上为一段准入代码,在对kubernetes api的请求过程中,顺序为:先经过认证 & 授权,然后执行准入操作,最后对目标对象进行操作。这个准入代码在api-server中,而且必须被编译到二进制文件中才能被执行。 在对集群进行请求时,每个准入控制代码都按照一定顺序执行。如果有一个准入控制拒绝了此次请求,那么整个请求的结果将会立即返回,并提示用户相应的error信息。 常用组件(控制代码)如下:
- AlwaysAdmit:允许所有请求
- AlwaysDeny:禁止所有请求,多用于测试环境
- ServiceAccount:它将serviceAccounts实现了自动化,它会辅助serviceAccount做一些事情,比如如果pod没有serviceAccount属性,它会自动添加一个default,并确保pod的serviceAccount始终存在
- LimitRanger:他会观察所有的请求,确保没有违反已经定义好的约束条件,这些条件定义在namespace中LimitRange对象中。如果在kubernetes中使用LimitRange对象,则必须使用这个插件。
- NamespaceExists:它会观察所有的请求,如果请求尝试创建一个不存在的namespace,则这个请求被拒绝。
环境准备
停止原有kubernetes相关服务
开始之前我们要先把基础版本的集群停掉,包括service,deployments,pods以及运行的所有kubernetes组件
#删除services
$ kubectl delete services test
#删除deployments
$ kubectl delete deploy test
#停掉worker节点的服务
service kubelet stop && rm -fr /var/lib/kubelet/*
service kube-proxy stop && rm -fr /var/lib/kube-proxy/*
service kube-calico stop
#停掉master节点的服务
service kube-calico stop
service kube-scheduler stop
service kube-controller-manager stop
service kube-apiserver stop
service etcd stop && rm -fr /var/lib/etcd/*
生成配置(所有节点)
跟基础环境搭建一样,我们需要生成kubernetes-with-ca的所有相关配置文件
cd ~/kubernetes-starter
#按照配置文件的提示编辑好配置,只需要把http改成https
vi config.properties
#生成配置
./gen-config.sh with-ca
安装cfssl(所有节点)
cfssl是非常好用的CA工具,我们用它来生成证书和秘钥文件
安装
#下载
wget -q --show-progress --https-only --timestamping \
https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 \
https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
#修改为可执行权限
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64
#移动到bin目录
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
#验证
cfssl version
生成根证书(主节点)
根证书是证书信任链的根,各个组件通讯的前提是有一份大家都信任的证书(根证书),每个人使用的证书都是由这个根证书签发的。
#所有证书相关的东西都放在这
$ mkdir -p /etc/kubernetes/ca
#准备生成证书的配置文件
cp /mnt/Downloads/kubernetes-starter/target/ca/ca-config.json /etc/kubernetes/ca
cp /mnt/Downloads/kubernetes-starter/target/ca/ca-csr.json /etc/kubernetes/ca
#生成证书和秘钥
$ cd /etc/kubernetes/ca
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
#生成完成后会有以下文件(我们最终想要的就是ca-key.pem和ca.pem,一个秘钥,一个证书)
$ ls
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem
enter description here
改造etcd
准备证书
etcd节点需要提供给其他服务访问,就要验证其他服务的身份,所以需要一个标识自己监听服务的server证书,当有多个etcd节点的时候也需要client证书与etcd集群其他节点交互,当然也可以client和server使用同一个证书因为它们本质上没有区别。
#etcd证书放在这
$ mkdir -p /etc/kubernetes/ca/etcd
#准备etcd证书配置
$ cp /mnt/Downloads/kubernetes-starter/target/ca/etcd/etcd-csr.json /etc/kubernetes/ca/etcd/
$ cd /etc/kubernetes/ca/etcd/
#使用根证书(ca.pem)签发etcd证书
$ cfssl gencert \
-ca=/etc/kubernetes/ca/ca.pem \
-ca-key=/etc/kubernetes/ca/ca-key.pem \
-config=/etc/kubernetes/ca/ca-config.json \
-profile=kubernetes etcd-csr.json | cfssljson -bare etcd
#跟之前类似生成三个文件etcd.csr是个中间证书请求文件,我们最终要的是etcd-key.pem和etcd.pem
$ ls
etcd.csr etcd-csr.json etcd-key.pem etcd.pem
改造ETCD服务
比较
建议先比较一下增加认证的etcd配置与原有配置的区别,做到心中有数。 可以使用命令比较:
cd /mnt/Downloads/kubernetes-starter
vimdiff kubernetes-simple/master-node/etcd.service kubernetes-with-ca/master-node/etcd.service
enter description here
更新etcd服务
$ cp /mnt/Downloads/kubernetes-starter/target/master-node/etcd.service /lib/systemd/system/
$ systemctl daemon-reload
$ service etcd start
#验证etcd服务(endpoints自行替换)
ETCDCTL_API=3 etcdctl \
--endpoints=https://192.168.214.188:2379 \
--cacert=/etc/kubernetes/ca/ca.pem \
--cert=/etc/kubernetes/ca/etcd/etcd.pem \
--key=/etc/kubernetes/ca/etcd/etcd-key.pem \
endpoint health
改造api-server
准备证书
#api-server证书放在这,api-server是核心,文件夹叫kubernetes吧,如果想叫apiserver也可以,不过相关的地方都需要修改哦
$ mkdir -p /etc/kubernetes/ca/kubernetes
#准备apiserver证书配置
$ cp /mnt/Downloads/kubernetes-starter/target/ca/kubernetes/kubernetes-csr.json /etc/kubernetes/ca/kubernetes/
$ cd /etc/kubernetes/ca/kubernetes/
#使用根证书(ca.pem)签发kubernetes证书
$ cfssl gencert \
-ca=/etc/kubernetes/ca/ca.pem \
-ca-key=/etc/kubernetes/ca/ca-key.pem \
-config=/etc/kubernetes/ca/ca-config.json \
-profile=kubernetes kubernetes-csr.json | cfssljson -bare kubernetes
#跟之前类似生成三个文件kubernetes.csr是个中间证书请求文件,我们最终要的是kubernetes-key.pem和kubernetes.pem
$ ls
kubernetes.csr kubernetes-csr.json kubernetes-key.pem kubernetes.pem
enter description here
改造api-server服务
同样先比较文件
cd /mnt/Downloads/kubernetes-starter
vimdiff kubernetes-simple/master-node/kube-apiserver.service kubernetes-with-ca/master-node/kube-apiserver.service
enter description here
生成token认证文件
#生成随机token
$ head -c 16 /dev/urandom | od -An -t x | tr -d ' '
df6497a07bf0314d1f35a4fb78ed12db
#按照固定格式写入token.csv,注意替换token内容
$ echo "df6497a07bf0314d1f35a4fb78ed12db,kubelet-bootstrap,10001,\"system:kubelet-bootstrap\"" > /etc/kubernetes/ca/kubernetes/token.csv
更新api-server服务
$ cp /mnt/Downloads/kubernetes-starter/target/master-node/kube-apiserver.service /lib/systemd/system/
systemctl daemon-reload
service kube-apiserver start
#检查日志
$ journalctl -f -u kube-apiserver
改造controller-manager
controller-manager一般与api-server在同一台机器上,所以可以使用非安全端口与api-server通讯,不需要生成证书和私钥。
改造controller-manager服务
查看diff
cd /mnt/Downloads/kubernetes-starter
vimdiff kubernetes-simple/master-node/kube-controller-manager.service kubernetes-with-ca/master-node/kube-controller-manager.service
enter description here
更新controller-manager服务
cp /mnt/Downloads/kubernetes-starter/target/master-node/kube-controller-manager.service /lib/systemd/system/
systemctl daemon-reload
service kube-controller-manager start
#检查日志
$ journalctl -f -u kube-controller-manager
改造scheduler
这个和之前是一样的。所以直接启动就行
改造kubectl
准备证书
#kubectl证书放在这,由于kubectl相当于系统管理员,我们使用admin命名
$ mkdir -p /etc/kubernetes/ca/admin
#准备admin证书配置 - kubectl只需客户端证书,因此证书请求中 hosts 字段可以为空
$ cp /mnt/Downloads/kubernetes-starter/target/ca/admin/admin-csr.json /etc/kubernetes/ca/admin/
$ cd /etc/kubernetes/ca/admin/
#使用根证书(ca.pem)签发admin证书
$ cfssl gencert \
-ca=/etc/kubernetes/ca/ca.pem \
-ca-key=/etc/kubernetes/ca/ca-key.pem \
-config=/etc/kubernetes/ca/ca-config.json \
-profile=kubernetes admin-csr.json | cfssljson -bare admin
#我们最终要的是admin-key.pem和admin.pem
$ ls
admin.csr admin-csr.json admin-key.pem admin.pem
配置kubectl
#指定apiserver的地址和证书位置(ip自行修改)
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ca/ca.pem \
--embed-certs=true \
--server=https://192.168.214.188:6443
#设置客户端认证参数,指定admin证书和秘钥
$ kubectl config set-credentials admin \
--client-certificate=/etc/kubernetes/ca/admin/admin.pem \
--embed-certs=true \
--client-key=/etc/kubernetes/ca/admin/admin-key.pem
#关联用户和集群
$ kubectl config set-context kubernetes \
--cluster=kubernetes --user=admin
#设置当前上下文
$ kubectl config use-context kubernetes
#设置结果就是一个配置文件,可以看看内容
$ cat ~/.kube/config
验证master节点
kubectl get componentstatus
改造calico-node
准备证书----- 在主节点上
后续可以看到calico证书用在四个地方:
- calico/node 这个docker 容器运行时访问 etcd 使用证书
- cni 配置文件中,cni 插件需要访问 etcd 使用证书
- calicoctl 操作集群网络时访问 etcd 使用证书
- calico/kube-controllers 同步集群网络策略时访问 etcd 使用证书
#calico证书放在这
$ mkdir -p /etc/kubernetes/ca/calico
#准备calico证书配置 - calico只需客户端证书,因此证书请求中 hosts 字段可以为空
$ cp /mnt/Downloads/kubernetes-starter/target/ca/calico/calico-csr.json /etc/kubernetes/ca/calico/
$ cd /etc/kubernetes/ca/calico/
#使用根证书(ca.pem)签发calico证书
$ cfssl gencert \
-ca=/etc/kubernetes/ca/ca.pem \
-ca-key=/etc/kubernetes/ca/ca-key.pem \
-config=/etc/kubernetes/ca/ca-config.json \
-profile=kubernetes calico-csr.json | cfssljson -bare calico
#我们最终要的是calico-key.pem和calico.pem
$ ls
calico.csr calico-csr.json calico-key.pem calico.pem
改造calico服务
查看diff
cd /mnt/Downloads/kubernetes-starter
vimdiff kubernetes-simple/all-node/kube-calico.service kubernetes-with-ca/all-node/kube-calico.service
enter description here
通过diff会发现,calico多了几个认证相关的文件:
/etc/kubernetes/ca/ca.pem
/etc/kubernetes/ca/calico/calico.pem
/etc/kubernetes/ca/calico/calico-key.pem
由于calico服务是所有节点都需要启动的,大家需要把这几个文件拷贝到每台服务器上 在主节点上执行: scp -r /etc/kubernetes/ca root@其他节点ip:/etc/kubernetes/
scp -r /etc/kubernetes/ca/ michael@192.168.214.189:/etc/kubernetes/ca/
enter description here
更新calico服务
cp /mnt/Downloads/kubernetes-starter/target/all-node/kube-calico.service /lib/systemd/system/
systemctl daemon-reload
service kube-calico start
#验证calico(能看到其他节点的列表就对啦)
$ calicoctl node status
问题
我这里除了主节点之外所有工作节点起不来。进一步调查。查看calico日志
发现问题。不知道为啥停calico的时候并没有删除掉镜像。手动删除即可
改造kubelet
我们这里让kubelet使用引导token的方式认证,所以认证方式跟之前的组件不同,它的证书不是手动生成,而是由工作节点TLS BootStrap 向api-server请求,由主节点的controller-manager 自动签发。
创建角色绑定(主节点)
引导token的方式要求客户端向api-server发起请求时告诉他你的用户名和token,并且这个用户是具有一个特定的角色:system:node-bootstrapper,所以需要先将 bootstrap token 文件中的 kubelet-bootstrap 用户赋予这个特定角色,然后 kubelet 才有权限发起创建认证请求。
在主节点执行下面命令
#可以通过下面命令查询clusterrole列表
$ kubectl -n kube-system get clusterrole
#可以查看一下token文件的内容,这个token下面要用到
$ cat /etc/kubernetes/ca/kubernetes/token.csv
df6497a07bf0314d1f35a4fb78ed12db,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
#创建角色绑定(将用户kubelet-bootstrap与角色system:node-bootstrapper绑定)
$ kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
enter description here
创建bootstrap.kubeconfig(工作节点)
这个配置是用来完成bootstrap token认证的,保存了像用户,token等重要的认证信息,这个文件可以借助kubectl命令生成:(也可以自己写配置)
#设置集群参数(注意替换ip)
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ca/ca.pem \
--embed-certs=true \
--server=https://192.168.214.188:6443 \
--kubeconfig=bootstrap.kubeconfig
#设置客户端认证参数(注意替换token)
$ kubectl config set-credentials kubelet-bootstrap \
--token=df6497a07bf0314d1f35a4fb78ed12db \
--kubeconfig=bootstrap.kubeconfig
#设置上下文
$ kubectl config set-context default \
--cluster=kubernetes \
--user=kubelet-bootstrap \
--kubeconfig=bootstrap.kubeconfig
#选择上下文
$ kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
#将刚生成的文件移动到合适的位置
$ mv bootstrap.kubeconfig /etc/kubernetes/
准备cni配置
查看diff
cd /mnt/Downloads/kubernetes-starter
vimdiff kubernetes-simple/worker-node/10-calico.conf kubernetes-with-ca/worker-node/10-calico.conf
enter description here
copy配置
$ cp /mnt/Downloads/kubernetes-starter/target/worker-node/10-calico.conf /etc/cni/net.d/
改造kubelet服务
$ cp /mnt/Downloads/kubernetes-starter/target/worker-node/kubelet.service /lib/systemd/system/
$ systemctl daemon-reload
$ service kubelet start
#启动kubelet之后到master节点允许worker加入(批准worker的tls证书请求)
#--------*在主节点执行*---------
$ kubectl get csr|grep 'Pending' | awk '{print $1}'| xargs kubectl certificate approve
#-----------------------------
#检查日志
$ journalctl -f -u kubelet
改造kube-proxy
准备证书
$ mkdir -p /etc/kubernetes/ca/kube-proxy
#准备proxy证书配置 - proxy只需客户端证书,因此证书请求中 hosts 字段可以为空。
#CN 指定该证书的 User 为 system:kube-proxy,预定义的 ClusterRoleBinding system:node-proxy 将User system:kube-proxy 与 Role system:node-proxier 绑定,授予了调用 kube-api-server proxy的相关 API 的权限
cp /mnt/Downloads/kubernetes-starter/target/ca/kube-proxy/kube-proxy-csr.json /etc/kubernetes/ca/kube-proxy/
cd /etc/kubernetes/ca/kube-proxy/
#使用根证书(ca.pem)签发calico证书
$ cfssl gencert \
-ca=/etc/kubernetes/ca/ca.pem \
-ca-key=/etc/kubernetes/ca/ca-key.pem \
-config=/etc/kubernetes/ca/ca-config.json \
-profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
#我们最终要的是kube-proxy-key.pem和kube-proxy.pem
$ ls
kube-proxy.csr kube-proxy-csr.json kube-proxy-key.pem kube-proxy.pem
生成kube-proxy.kubeconfig配置
#设置集群参数(注意替换ip)
$ kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ca/ca.pem \
--embed-certs=true \
--server=https://192.168.214.188:6443 \
--kubeconfig=kube-proxy.kubeconfig
#置客户端认证参数
$ kubectl config set-credentials kube-proxy \
--client-certificate=/etc/kubernetes/ca/kube-proxy/kube-proxy.pem \
--client-key=/etc/kubernetes/ca/kube-proxy/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
#设置上下文参数
$ kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
#选择上下文
$ kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
#移动到合适位置
$ mv kube-proxy.kubeconfig /etc/kubernetes/kube-proxy.kubeconfig
改造kube-proxy服务
无变化
改造
$ systemctl daemon-reload
#安装依赖软件
$ apt install conntrack
#启动服务
$ service kube-proxy start
#查看日志
$ journalctl -f -u kube-proxy
改造kube-dns
kubectl create -f /mnt/Downloads/kubernetes-starter/target/services/kube-dns.yaml
安装ca之后操作
查看日志 如同docker logs
kubectl logs [pod name] -f^[实时跟踪]
进入容器
kubectl exec -it [pod name] bash
kubectl exec -it [pod name] sh
查看
kubectl get sa -o yaml -o是表示内容显示的格式也可以是json
完全个人研究,有错希望大神纠正。也可留下您的联系方式,共同探讨
——————————————————————————————————
作者:Henny_CHN
转载请标明出处,原文地址:
https://blog.csdn.net/a1234012340a/article/details/110134106
如果感觉本文对您有帮助,请留下您的赞,您的支持是我坚持写作最大的动力,谢谢!