环境
操作系统:ubuntu18.10
docker:docker-ce 18.06
kubernetes:k8s 1.13.1
操作步骤
安装(https://www.runoob.com/docker/ubuntu-docker-install.html)
- 卸载旧版本 apt-get remove docker docker-engine docker.io containerd runc
- uname -a // 检测版本环境
- 安装 apt 依赖包,用于通过HTTPS来获取仓库:
- 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 -
- 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 通过搜索指纹的后8个字符,验证您现在是否拥有带有指纹的密钥。
- apt-key fingerprint 0EBFCD88
- 使用以下指令设置稳定版仓库
- add-apt-repository
“deb [arch=amd64] https://download.docker.com/linux/ubuntu
$(lsb_release -cs)
stable”- 更新 apt 包索引。
- $ sudo apt-get update
- 查看版本
- apt-cache madison docker-ce
- sudo apt-get install docker-ce=<VERSION_STRING>
- 验证是否安装成功
- docker run hello-world
docker基本指令
- docker ps(查看docker镜像)
- docker run -it nginx(下载nginx)
- usermod -aG docker $USER(将当前用户加入docker组)
配置阿里云加速器
- 创建/etc/docker/daemon.json,内容如下
{
"registry-mirrors": ["https://ozcouvlb.mirror.aliyuncs.com"]
}
重启docker服务
- 重载所有修改过的配置文件
systemctl daemon-reload - 重启docker服务
systemctl restart docker - 开机启动docker
systemctl enable docker - 停止所有容器
docker stop $(docker ps -aq) - 删除所有容器
docker rm $(docker ps -aq) - 停止k8s
systemctl stop kubelet - 开启k8s
systemctl start kubelet
安装并配置k8s国内源
-
创建配置文件
$ touch /etc/apt/sources.list.d/kubernetes.list -
添加写权限
$ sudo chmod 666 /etc/apt/sources.list.d/kubernetes.list -
通过vim添加,内容如下:
deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial mainjavascript -
apt update
-
如果上述报错,执行以下代码:
$ apt-get update && apt-get install -y apt-transport-https
$ curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
禁止基础设施
- 禁止防火墙
$ sudo ufw disable
- 关闭swap
$ sudo swapoff -a
- 永久关闭swap分区
$ sudo sed -ri 's/.*swap.*/#&/' /etc/fstab
- 禁止selinux
// 安装操控selinux命令
$ sudo apt install -y selinux-utils
// 禁止selinux
$ setenforce 0
// 重启操作系统
$ shutdown -r now
// 查看selinux是否关闭
$ sudo getenforce
// Disabled表示已经关闭
k8s网络配置
- 配置内核参数,将桥接的IPV4流量传递到iptables的链,添加内容如下:
- 创建/etc/sysctl.d/k8s.conf文件
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness = 0
- 执行以下命令,使其生效:
$ sudo modprobe br_netfilter
$ sudo sysctl -p /etc/sysctl.d/k8s.conf
安装k8s
- 切换到root账号,使用$ su
- 安装k8s,目前版本是v1.13.1
$ apt update && apt-get install -y kubelet=1.13.1-00 kubernetes-cni=0.6.0-00 kubeadm=1.13.1-00 kubectl=1.13.1-00
- 设置开启启动
$ sudo systemctl enable kubelet && systemctl start kubelet
- 开机重启
$ sudo shutdown -r now
验证k8s
- 使用root账号登录master主机
- 执行以下命令:
$ kubectl get nodes
// 如果失败执行以下操作,开始集群部署
集群部署
- 克隆Master环境,再次启动node1,node2两台主机
- 阿里云克隆,参考 https://blog.youkuaiyun.com/jc7067/article/details/82736334
修改hostname(两个子节点)
- 使用root用户登录
- 打开配置文件vim /etc/cloud/cloud.cfg
- 修改配置preserve_hostname: true
- 修改/etc/hostname,只有一行 node1或node2
配置hosts文件
- vim /etc/hosts(三台服务器均需要配置)
172.17.158.84 iZ2ze2yjivclsts0h0lewzZ iZ2ze2yjivclsts0h0lewzZ
172.17.158.85 iZ2zeioqf1qlimfvmhbm1nZ iZ2zeioqf1qlimfvmhbm1nZ
172.17.158.86 iZ2zeioqf1qlimfvmhbm1mZ iZ2zeioqf1qlimfvmhbm1mZ
- 重启机器shutdown -r now
配置master节点
- 创建工作目录
$ mkdir -p /home/itcast/working
$ cd /home/itcast/working/
- 创建kubeadm.conf配置文件
创建k8s的管理工具kubeadm对应的配置文件,候选操作在home/itcast/working/目录下
使用kubeadm配置文件,通过在配置文件中指定docker仓库地址,便于内网快速部署。
生成配置文件
kubeadm config print init-defaults ClusterConfiguration > kubeadm.conf
- vim kubeadm.conf,修改配置
# 修改 imageRepository: k8s.gcr.io
# 改为 imageRepository: registry.cn-beijing.aliyuncs.com/imcto
# 修改kubernetes版本 kubernetesVersion: v1.13.0
# 改为kubernetesVersion: v1.13.1
# 修改kubeadm.conf中的API服务器地址
localAPIEndpoint:
advertiseAddress: 172.17.158.84
bindPort: 6443
# 注意:172.17.158.84是master主机的ip内网地址
# 配置子网网络:
networking:
dnsDomain: cluster.local
podSubnet: "10.244.0.0/16"
serviceSubnet: 10.96.0.0/12
scheduler: {}
# 这里的10.244.0.0/16 和 10.96.0.0/12分别是k8s内部pods和services的子网网络,最好使用这个地址,后续flannel网络需要用到。
拉取K8s必备的模块镜像(在master节点/home/itcast/working/目录下)
- 查看一下都需要哪些镜像文件需要拉取
$ kubeadm config images list --config kubeadm.conf
执行以上命令,获取以下结果
# 外网通过http协议,可以访问集群
registry.cn-beijing.aliyuncs.com/imcto/kube-apiserver:v1.13.1
# 内部进群调度
registry.cn-beijing.aliyuncs.com/imcto/kube-controller-manager:v1.13.1
# 内部任务调度
registry.cn-beijing.aliyuncs.com/imcto/kube-scheduler:v1.13.1
# 反向代理
registry.cn-beijing.aliyuncs.com/imcto/kube-proxy:v1.13.1
# 进程管理
registry.cn-beijing.aliyuncs.com/imcto/pause:3.1
# 保证数据一致性
registry.cn-beijing.aliyuncs.com/imcto/etcd:3.2.24
# 内网域名与dns管理
registry.cn-beijing.aliyuncs.com/imcto/coredns:1.2.6
- 拉取镜像
$ kubeadm config images pull --config ./kubeadm.conf
初始化kubernetes环境
$ sudo kubeadm init --config ./kubeadm.conf
- 如果失败,执行,再去初始化
# 停止k8s
systemctl stop kubelet
# 重置k8s
kubeadm reset
更多kubeadm配置文件参数详见
$ kubeadm config print-defaults
- 成功则执行以下代码(Mstaer与node节点都要执行):
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
systemctl enable kubelet
systemctl start kubelet
如果node节点要加入master,则执行如下代码(这条代码是上面初始化成功以后显示的):
kubeadm join 172.17.158.84:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:b62c729923ffd89dfaf362211975fcb09a2b5d6907d1bf91b4b56be83e9a8d19
配置mater与node通信网络环境(flannel网络)
$ cd $HOME/working
$ wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
- 编辑这个文件,确保flannel网络是对的,找到net-conf.json标记的内容是否正确
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
这个"10.244.0.0/16"和 ./kubeadm.conf中的podSubnet的地址要一致。
- 应用这个文件
kubectl apply -f kube-flannel.yml
- 验证文件(等待一段时间)
kubectl apply -f kube-flannel.yml
配置node
-
确认关闭swap
apt install -y selinux-utils swapoff -a
-
禁止selinux
setenforce 0
-
确认关闭防火墙
ufw disable
配置k8s集群的Node主机环境
-
启动k8s后台服务
# 启动kubelet 设置为开机自启动 $ sudo systemctl enable kubelet # 启动k8s服务程序 $ sudo systemctl start kubelet
-
将master机器的 /etc/kubernetes/admin.conf传到到node1和node2 /home/itcast/ 目录下
-
在root目录下也要传一份
-
登录
node1
终端,创建基础kube配置文件环境
$ mkdir -p $HOME/.kube
$ sudo cp -i $HOME/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 登录
node2
终端,创建基础kube配置文件环境
$ mkdir -p $HOME/.kube
$ sudo cp -i $HOME/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
node1
和node2
分别连接master
加入master集群。这里用的是kubeadm join
指令
$ kubeadm join 172.17.158.84:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:b62c729923ffd89dfaf362211975fcb09a2b5d6907d1bf91b4b56be83e9a8d19
这里要注意,使用的hash应该是master
主机 kubeadm init
成功之后生成的hash码。
-
应用两个node主机分别应用flannel网络,将
master
中的kube-flannel.yml
分别传递给两个node
节点.,目录地址**/home/itcast/** -
分别启动
flannel
网络
itcast@node1:~$ kubectl apply -f kube-flannel.yml
itcast@node2:~$ kubectl apply -f kube-flannel.yml
- 查看node是否已经加入到k8s集群中(需要等一段时间才能ready)
itcast@node2:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 35m v1.13.1
node1 Ready <none> 2m23s v1.13.1
node2 Ready <none> 40s v1.13.1
应用实例
- 在master主机上,cd /home/itcast
- 定义描述文件mysql-svc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql
spec:
replicas: 5
selector:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"
- 定义描述文件mysql-rc.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql1
spec:
type: NodePort
ports:
- port: 3307
nodePort: 32309
targetPort: 3306
selector:
app: mysql
- 创建好mysql-rc.yaml后,在master节点使用kubectl命令将它发布到k8s集群中。
# 如果已存在,执行 kubectl delete -f mysql-rc.yaml
kubectl create -f mysql-rc.yaml
- 创建好mysql-svc.yaml后,在master节点使用kubectl命令将它发布到k8s集群中。
# 如果已存在,执行 kubectl delete -f mysql-svc.yaml
kubectl create -f mysql-svc.yaml
- 查看详细信息
kubectl describe pods mysql
- 查看启动状态
通过查看当前的pods
列表,是否已经启动成功:
# kubectl get pod(master节点)
NAME READY STATUS RESTARTS AGE
mysql-v97f5 1/1 Running 0 16m
# kubectl get svc(node1节点)
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 18m
mysql1 10.254.167.91 <nodes> 3307:32307/TCP 16m
# lsof -i:32307(node1节点)
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
kube-prox 30418 root 9u IPv6 1166802 0t0 TCP *:32307 (LISTEN)
登录mysql
-
在node1节点上,执行“docker ps -a”命令,显示如下:
-
红圈标注的就是mysql的containet id,通过这个,我们来进入容器,执行如下命令:
docker exec -it 2a46168598bb bash
apt-get update
- 然后,就进入到容器了,这里很神奇,因为之前没接触过docker和容器化的东西,直到这里才发现容器的真谛,此时就感觉是进入了一个新的主机一样,可以查看容器的情况,同样,可以进行mysql的登录,像正常在主机上操作一样,如下所示:
- 这就进入mysql了,进入之后,设置mysql可以远程访问,网上一搜有很多的方式,这里贴一个供参考,进入之后执行如下命令:
alter user 'root'@'%' identified with mysql_native_password by'root';
alter user 'root'@'%' identified by '123456';
或者
use mysql;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
flush privileges; #一定要刷新生效
-
然后 exit 退出mysql .ctrl+p ctrl+q 从容器退出返回到node主机。
-
这时就可以对外32309访问mysql
网络异常解决方案(未出现问题可直接跳过)
注意:如果这里出现了ContainerCreating
状态,那么可以尝试如下解决办法:
itcast@master:~/working$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-tscrh 0/1 ContainerCreating 0 17m
- 目前mysql-tscrh 描述文件 已经创建,但是没有启动成功. 状态是
ContainerCreating
没有启动起来. - 通过
kubectl describe pods
来查看pods
的详细状态
itcast@master:~/working$ kubectl describe pods mysql
Name: mysql-tscrh
Namespace: default
Priority: 0
PriorityClassName: <none>
Node: node1/192.168.236.178
Start Time: Mon, 17 Jun 2019 09:10:35 +0000
Labels: app=mysql
Annotations: <none>
Status: Pending
IP:
Controlled By: ReplicationController/mysql
Containers:
mysql:
Container ID:
Image: hub.c.163.com/library/mysql
Image ID:
Port: 3306/TCP
Host Port: 0/TCP
State: Waiting
Reason: ContainerCreating
Ready: False
Restart Count: 0
Environment:
MYSQL_ROOT_PASSWORD: 123456
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-q6ggq (ro)
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
default-token-q6ggq:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-q6ggq
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 22m default-scheduler Successfully assigned default/mysql-tscrh to node1
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "58d143373e767c40610587624c667d8e20dd77fa397952406a085f2ae1dc38e6" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "81d12726dbe075c64af48142638e98863231e8201ccc292f0dda1fccfa7fdaec" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "8bd77ee0176d369435ead7bd3c2675b7bbcbdc2b052cf34c784f04053a7d5288" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "0733fc209e085e96f5823a2280b012a609dace41fda967c5ae951005a8699ce6" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "91f337eb334612b2e7426d820ba4b15a9c9c549050517d459508832b69780b5f" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "48cbba9896068a774d9128a6864394e8726a0d857bae61036421ad73f5d6e3dd" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "d259778aa19418a9a429b3175b66afae3d8ffb7324ec9df492b2947dbc153460" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "3d01c00ac9eaac7b2e983402be38c1cf60c4bbd1d454aa45329ce0ca0c2bf792" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 22m kubelet, node1 Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "98879cbb0405dac3a24753dd1986070a53fe9ee9f1b819996a903c19286a2bb7" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Warning FailedCreatePodSandBox 7m49s (x838 over 22m) kubelet, node1 (combined from similar events): Failed create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "60923335b41c2d0412b279bdb6150f9b9b7eae20c4a02549e35509083c01384b" network for pod "mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
Normal SandboxChanged 2m49s (x1127 over 22m) kubelet, node1 Pod sandbox changed, it will be killed and re-created.
- 会看到一个错误:
"mysql-tscrh": NetworkPlugin cni failed to set up pod "mysql-tscrh_default" network: open /run/flannel/subnet.env: no such file or directory
- 这是缺少/run/flannel/subnet.env文件
解决办法:配置flannel网络
分别在三台服务器上执行如下步骤
-
创建目录
sudo mkdir -p /run/flannel
-
创建环境描述文件
$ sudo tee /run/flannel/subnet.env <<-'EOF' FLANNEL_NETWORK=10.244.0.0/16 FLANNEL_SUBNET=10.244.0.1/24 FLANNEL_MTU=1450 FLANNEL_IPMASQ=true EOF
-
查看mysql实例集群状态
itcast@master:~/working$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-tscrh 0/1 Running 0 17m
如果为Running
状态,则为mysql集群启动成功。