Ansible AWX 部署于k8s集群
github地址:https://github.com/ansible/awx
介绍
新版awx需要awx operator去搭建,官方建议使用minikube去部署awx operater,本人在公司测试环境机器中搭建,因为测试环境的网络代理问题,在搭建完minikube后,虚拟出的主机通过docker连接,若ssh后配置docker代理重启后会遇到集群损坏的问题,且minikube ssh后的主机配置很低,在外部也不好访问到内部的服务,诸多不易,最终选择用Kubeadm搭建一个单节点k8s集群,之后的节点扩容也比较方便。
此篇编写时最新的awx版本是21.4.0, 网上博客教程大多还是以17.1.0甚至更老的版本为主,并且都是使用ansible playbook的形式直接部署,所以决定分享自己的踩坑记录供大家学习,因为搭建过程中的有些问题已经修复不能复现,我会引用一些其他博客的教程并解释,若有任何问题欢迎留言,回复不及时还请海涵!
部署虚拟机
[root@k8s-master qateadmin]# hostnamectl
Static hostname: k8s-master
Icon name: computer-vm
Chassis: vm
Machine ID: 0a10d5ce5ae4446eaaca9f5babc65162
Boot ID: b0903daf3ac14d6084ef575b0b655541
Virtualization: kvm
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-957.21.2.el7.x86_64
Architecture: x86-64
虚拟机型号如上,配置要求内存不低于4G,CPU核数2个以上,公司申请的机器配置较高就没有这个顾虑。
环境配置
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
setenforce 0 # 临时
# 关闭swap
swapoff -a # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久
# 根据规划设置主机名
hostnamectl set-hostname <hostname>
# 在master添加hosts
cat >> /etc/hosts << EOF
192.168.178.171 k8s-master
192.168.178.172 k8s-node1
192.168.178.173 k8s-node2
EOF
# 将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 生效
# 时间同步
yum install ntpdate -y
ntpdate time.windows.com
安装 Docker、kubeadm、kubelet:
docker安装可以用daocloud源直接一键安装或者使用脚本安装最新docker:
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
或
curl -sSL https://get.daocloud.io/docker | sh
这里给出菜鸟教程的手册:https://www.runoob.com/docker/centos-docker-install.html
[root@k8s-master qateadmin]# docker version
Client: Docker Engine - Community
Version: 20.10.17
API version: 1.41
Go version: go1.17.11
Git commit: 100c701
Built: Mon Jun 6 23:05:12 2022
OS/Arch: linux/amd64
Context: default
Experimental: true
配置下载加速器:公司的配置要求,自己主机配置时cgroupdriver=systemd
一定要配置
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries": [
"k8s.gcr.io",
"gcr.io",
"quay.io"
],
"registry-mirrors": [
"http://k8s.gcr.io",
"http://gcr.io",
"http://quay.io"
]
}
systemctl restart docker
docker info #查看docker信息,进行确认
在公司测试环境中不仅要配置网络代理,也需要配置docker的网络代理,这个给出配置记得替换url:
vim /etc/systemd/system/docker.service.d/http-proxy.conf #没有的文件夹记得创建
[Service]
Environment="HTTP_PROXY=http:// " "HTTPS_PROXY=http://" "NO_PROXY=localhost,127.0.0.1,10.96.0.0/16, 10.244.0.0/16"
安装kubernetes:
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
安装kubeadm、kubelet、kubectl:
yum install -y kubelet-1.23.0 kubeadm-1.23.0 kubectl-1.23.0
systemctl enable kubelet
在kubernetes官网中指出,在1.24.0版本已经移除对Dockershim的支持,dockershim将不会再被包含在Kubernetes的包中
https://kubernetes.io/blog/2022/05/03/dockershim-historical-context/
所以如果安装kubernetes1.24版本的需要注意这一点。
部署k8s-master:
kubeadm init \
--apiserver-advertise-address=192.168.178.171 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all
- –apiserver-advertise-address 集群通告地址
- –image-repository 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
- –kubernetes-version K8s版本,与上面安装的一致
- –service-cidr 集群内部虚拟网络,Pod统一访问入口
- –pod-network-cidr Pod网络,与下面部署的CNI网络组件yaml中保持一致
初始化之后,会输出一个join命令,先复制出来,node节点加入master会使用。
拷贝k8s认证文件;
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
如果遇到类似拉取镜像失败,k8s创建失败的问题,检查自己的网络,在报错日志中找到拉不下来的镜像,直接docker pull,在公司可以直接将k8s镜像同步到公司的镜像库,docker pull下来后记得更改docker tag。
类似于这样:
下图还需关闭swap虚拟内存
k8s.gcr.io/kube-apiserver v1.23.0 e6bf5ddd4098 8 months ago 135MB
k8s.gcr.io/kube-proxy v1.23.0 e03484a90585 8 months ago 112MB
k8s.gcr.io/kube-controller-manager v1.23.0 37c6aeb3663b 8 months ago 125MB
k8s.gcr.io/kube-scheduler v1.23.0 56c5af1d00b5 8 months ago 53.5MB
k8s.gcr.io/etcd 3.5.1-0 25f8c7f3da61 9 months ago 293MB
k8s.gcr.io/coredns v1.8.6 a4ca41631cc7 10 months ago 46.8MB
k8s.gcr.io/coredns/coredns v1.8.6 a4ca41631cc7 10 months ago 46.8MB
centos 8 5d0da3dc9764 10 months ago 231MB
k8s.gcr.io/pause 3.6 6270bb605e12 11 months ago 683kB
init之后查看节点:
[root@k8s-master qateadmin]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 8d v1.23.0
部署容器网络
Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的网络方案。
wget https://docs.projectcalico.org/manifests/calico.yaml #若拉取不下来,可以直接google源码
下载完后还需要修改里面定义Pod网络(CALICO_IPV4POOL_CIDR),与前面kubeadm init的 --pod-network-cidr指定的一样。
修改完后文件后,进行部署:
kubectl apply -f calico.yaml
kubectl get pods -n kube-system #执行结束要等上一会才全部running
[root@k8s-master qateadmin]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5c64b68895-4fphf 1/1 Running 1 (6d22h ago) 8d
calico-node-lbs7q 1/1 Running 0 8d
coredns-64897985d-bm4lb 1/1 Running 0 8d
coredns-64897985d-k7qfm 1/1 Running 0 8d
etcd-k8s-master 1/1 Running 2 8d
kube-apiserver-k8s-master 1/1 Running 7 (6d22h ago) 8d
kube-controller-manager-k8s-master 1/1 Running 13 (6d22h ago) 8d
kube-proxy-czvgx 1/1 Running 0 8d
kube-scheduler-k8s-master 1/1 Running 13 (6d22h ago) 8d
调试挂起的 Pod
k8s部署时查看未就绪的节点情况:
kubectl describe pod coredns-f9fd979d6-7xshl -n kube-system
在单节点的k8s集群配置中,master会被打上污点,作为不可调度的node资源,我们这里可以直接去除master上的污点,让node直接部署在master成为一个单节点的集群。
使用kubectl taint nodes --all node-role.kubernetes.io/master-
命令去除。
存储
为了让 AWX 保留其数据库,我们需要定义一些持久性存储。在 Kubernetes 中,这称为持久卷(PV),它们通常由持久卷声明 (PVC) 构建,这是对满足特定规范的 PV 的请求。这些规范由存储类(SC) 定义。
传统 Kubernetes 多节点集群中的持久性数据需要保存在某种共享存储上,以便 pod 可以在任何节点上运行。但是对于我们的单节点 Kubernetes 堆栈,我们可以使用本地分区来保存我们的数据。Rancher Labs有一个本地存储配置器 YAML,我们可以使用它。所以让我们得到它,并修改 YAML 以指向我们上面定义的分区:
[root@k8s-master qateadmin]# wget https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.19/deploy/local-path-storage.yaml -O /root/local-path-storage.yaml
[root@k8s-master qateadmin]# sed -i "s#/opt/local-path-provisioner#/mnt/local-storage#g" /root/local-path-storage.yaml
[root@k8s-master qateadmin]# kubectl apply -f /root/local-path-storage.yaml
现在,如果我们运行,kubectl get sc
我们应该看到我们的新存储类,AWX 应用程序应该能够将其用作它将定义的持久卷声明的一部分。
[root@k8s-master qateadmin]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 8d
AWX Operator
github地址:https://github.com/ansible/awx-operator
安装Kustomize:
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
创建kustomization.yaml
文件
Vim kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
# Find the latest tag here: https://github.com/ansible/awx-operator/releases
- github.com/ansible/awx-operator/config/default?ref=0.25.0
- awx-demo.yaml
# Set the image tags to match the git version from above
images:
- name: quay.io/ansible/awx-operator
newTag: 0.25.0
# Specify a custom namespace in which to install AWX
namespace: awx
然后执行
$ kustomize build . | kubectl apply -f -
namespace/awx created
customresourcedefinition.apiextensions.k8s.io/awxbackups.awx.ansible.com created
customresourcedefinition.apiextensions.k8s.io/awxrestores.awx.ansible.com created
customresourcedefinition.apiextensions.k8s.io/awxs.awx.ansible.com created
serviceaccount/awx-operator-controller-manager created
role.rbac.authorization.k8s.io/awx-operator-awx-manager-role created
role.rbac.authorization.k8s.io/awx-operator-leader-election-role created
clusterrole.rbac.authorization.k8s.io/awx-operator-metrics-reader created
clusterrole.rbac.authorization.k8s.io/awx-operator-proxy-role created
rolebinding.rbac.authorization.k8s.io/awx-operator-awx-manager-rolebinding created
rolebinding.rbac.authorization.k8s.io/awx-operator-leader-election-rolebinding created
clusterrolebinding.rbac.authorization.k8s.io/awx-operator-proxy-rolebinding created
configmap/awx-operator-awx-manager-config created
service/awx-operator-controller-manager-metrics-service created
deployment.apps/awx-operator-controller-manager created
如果网络不好也可以拉取awx operator
的github
文件,如下:
git clone https://github.com/ansible/awx-operator.git
cd awx-operator
git checkout 0.25.0 # 查看github中的release版本选择
export NAMESPACE=awx
make deploy
查看:
$ kubectl get pods -n awx
NAME READY STATUS RESTARTS AGE
awx-operator-controller-manager-66ccd8f997-rhd4z 2/2 Running 0 11s
设置当前的命名空间kubectl
默认为awx
:
$ kubectl config set-context --current --namespace=awx
创建awx-demo.yaml
文件,在同一目录
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: awx-demo
spec:
service_type: nodeport
# default nodeport_port is 30080
nodeport_port: 30080
~
添加新文件到文件kustomization.yaml
列表:
...
resources:
- github.com/ansible/awx-operator/config/default?ref=<tag>
# Add this extra line:
- awx-demo.yaml
...
最后,kustomize
再次运行以在集群中创建 AWX 实例:
kustomize build . | kubectl apply -f -
[root@k8s-master awx]# kubectl get pods -l "app.kubernetes.io/managed-by=awx-operator" -n awx
NAME READY STATUS RESTARTS AGE
awx-demo-854b55644b-kqtll 4/4 Running 2 (7d23h ago) 8d
awx-demo-postgres-0 1/1 Running 0 8d
[root@k8s-master awx]# kubectl get svc -l "app.kubernetes.io/managed-by=awx-operator" -n awx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
awx-demo-postgres ClusterIP None <none> 5432/TCP 8d
awx-demo-service NodePort 10.97.217.172 <none> 80:30080/TCP 8d
获取密码:
kubectl get secret awx-demo-admin-password -o jsonpath="{.data.password}" | base64 --decode
yDL2Cx5Za94g9MvBP6B73nzVLlmfgPjR
上述是官网使用minikube
的案例,我们使用单节点就没有这样友好,在awx pod
创建中,会有pod卡住的问题,如下图:
查看pod情况:
kubectl describe pods awx-postgres-0
这次 pod 没有被调度的原因是因为它有未绑定的即时 PersistentVolumeClaims
kubectl describe pvc
如果应用程序没有定义特定的存储类,那么 Kubernetes 集群必须有一个“默认”存储类
设置默认存储类
[root@k8s-master awx]# kubectl patch sc local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
[root@k8s-master awx]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 8d
导出当前 PVC 的配置,删除 PVC,然后重新制作它(注意pod名字的对应)
kubectl get pvc postgres-awx-postgres-0 -o=yaml > awx-pvc.yml
kubectl delete pvc postgres-awx-postgres-0
kubectl apply -f awx-pvc.yml
再次查看pvc:
[root@k8s-master awx]# kubectl get pvc -n awx
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
postgres-awx-demo-postgres-0 Bound pvc-e4f13e9b-f8b4-405d-8ddb-a8b95da28e65 8Gi RWO local-path 8d
最后可以看到pod会重新running成功。
登录并查看