# OpenShift ZTP - The Hard Way 1. Install RHACM lol 2. Create Namespaces ```bash= oc create namespace hive --dry-run=client -o yaml > 00_ns-hive.yaml oc create namespace assisted-installer --dry-run=client -o yaml > 00_ns-assisted-installer.yaml oc create namespace multicluster-engine --dry-run=client -o yaml > 00_ns-multicluster-engine.yaml oc create namespace ztp-mirror --dry-run=client -o yaml > 00_ns-multicluster-engine.yaml ``` ```yaml= apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: assisted-installer spec: {} --- apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: hive spec: {} --- apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: multicluster-engine spec: {} --- ``` 3. Create Root CA Bundle ConfigMap (optional) ```yaml= kind: ConfigMap apiVersion: v1 metadata: name: trusted-ca namespace: assisted-installer labels: config.openshift.io/inject-trusted-cabundle: 'true' data: {} --- kind: ConfigMap apiVersion: v1 metadata: name: trusted-ca namespace: hive labels: config.openshift.io/inject-trusted-cabundle: 'true' data: {} --- kind: ConfigMap apiVersion: v1 metadata: name: trusted-ca namespace: multicluster-engine labels: config.openshift.io/inject-trusted-cabundle: 'true' data: {} --- kind: ConfigMap apiVersion: v1 metadata: name: trusted-ca namespace: open-cluster-management labels: config.openshift.io/inject-trusted-cabundle: 'true' data: {} --- ``` 4. Get just the custom certs ```bash= # Get the proxy config for the custom certs CA_CERT_NAME=$(oc get proxy/cluster -o jsonpath='{.spec.trustedCA.name}') oc get cm -n openshift-config $CA_CERT_NAME -o jsonpath='{.data.ca-bundle\.crt}' > custom-ca-certs.pem ``` 5. Create a CA Cert Secret for Hive/RHACM ```bash= oc create secret generic custom-ca-certs -n hive --from-file=ca.crt=custom-ca-certs.pem oc create secret generic custom-ca-certs -n multicluster-engine --from-file=ca.crt=custom-ca-certs.pem oc create secret generic custom-ca-certs -n open-cluster-management --from-file=ca.crt=custom-ca-certs.pem ``` 6. Point hive to use the custom ca ```bash= oc edit hiveconfigs.hive.openshift.io -n hive ``` ```yaml= apiVersion: hive.openshift.io/v1 kind: HiveConfig metadata: labels: installer.name: multiclusterhub installer.namespace: open-cluster-management name: hive spec: additionalCertificateAuthoritiesSecretRef: - name: custom-ca-certs ``` 7. Create a Pull Secret for AI/CIM/MCE/whateveritscalledthesedays ```bash= PULL_SECRET=$(oc get secret/pull-secret -n openshift-config -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d) echo $PULL_SECRET > tmp-ps.json oc create secret docker-registry cluster-pull-secret -n hive --from-file=.dockerconfigjson=./tmp-ps.json oc create secret docker-registry cluster-pull-secret -n multicluster-engine --from-file=.dockerconfigjson=./tmp-ps.json oc create secret docker-registry cluster-pull-secret -n open-cluster-management --from-file=.dockerconfigjson=./tmp-ps.json rm ./tmp-ps.json unset PULL_SECRET ```` 8. Configure RHACM RBAC: ```yaml= kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: hive-ca subjects: - kind: ServiceAccount name: hiveadmission namespace: hive - kind: ServiceAccount name: hive-controllers namespace: hive - kind: ServiceAccount name: hive-frontend namespace: hive roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin --- ``` 9. Configure the Assisted Installer Configuration Overrides if needed ```bash= OC_HTTP_PROXY=$(oc get proxy/cluster -o jsonpath='{.status.httpProxy}') OC_HTTPS_PROXY=$(oc get proxy/cluster -o jsonpath='{.status.httpsProxy}') OC_NO_PROXY="YOUR_IP_NETWORK/24,$(oc get proxy/cluster -o jsonpath='{.status.noProxy}')" cat > 05_cm-assisted-installer-config.yaml <<EOF apiVersion: v1 kind: ConfigMap metadata: creationTimestamp: null name: assisted-service-config namespace: multicluster-engine labels: app: assisted-service data: LOG_LEVEL: "debug" AUTH_TYPE: "none" SKIP_CERT_VERIFICATION: "True" HTTP_PROXY: "${OC_HTTP_PROXY}" HTTPS_PROXY: "${OC_HTTPS_PROXY}" NO_PROXY: "${OC_NO_PROXY}" #SERVICE_IMAGE: registry.access.redhat.com/rhacm2/agent-service-rhel8@sha256:b6deaffb775887853123bac203ae1e0441014392f43ccb38e456389d20af34e4 #SELF_VERSION: registry.access.redhat.com/rhacm2/agent-service-rhel8@sha256:b6deaffb775887853123bac203ae1e0441014392f43ccb38e456389d20af34e4 EOF oc apply -f 05_cm-assisted-installer-config.yaml ``` 10. enable console MCE https://github.com/Red-Hat-SE-RTO/openshift-ztp/blob/main/ansible/roles/configure_rhacm_oas/templates/06_multiclusterengine.yml.j2 ```bash oc edit multiclusterengines.multicluster.openshift.io ``` ```yaml= spec: availabilityConfig: High imagePullSecret: YOUR_IMAGE_PULL_SECRET_GOES_HERE overrides: components: - enabled: true name: console-mce ``` --- # Spoke Cluster YAMLs ```bash= export SPOKE_CLUSTER_NAME="YOUR_HOSTNAME" export SPOKE_CLUSTER_DOMAIN="YOUR_BASE_DOMAIN" export SPOKE_CLUSTER_TYPE="full" export SPOKE_CLUSTER_API_VIP="YOUR_IP_GOES_HERE" export SPOKE_CLUSTER_APP_VIP="YOUR_IP_GOES_HERE" export SPOKE_CLUSTER_VM_SUBNET="YOUR_SUBNET_HERE/CIDR" export SPOKE_CLUSTER_LOCATION="YOUR_LOCATION_HERE" export NTP_SERVER1="NTP_IP_1" export NTP_SERVER2="NTP_IP_2" export DNS_SERVER1="NTP_IP_3" export DNS_SERVER2="NTP_IP_4" export GATEWAY_IP="YOUR_GATEWAY_IP_HERE" mkdir $SPOKE_CLUSTER_NAME cd $SPOKE_CLUSTER_NAME ## Create SSH Key pair for the cluster ssh-keygen -t rsa -b 4096 ## Tell it to save it to ./ssh-key # Spoke Cluster Namespace cat > 00_namespace.yaml <<EOF apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: $SPOKE_CLUSTER_NAME spec: {} EOF # Spoke Cluster SSH Key cat > 01_secret-ssh-key.yaml <<EOF apiVersion: v1 kind: Secret metadata: creationTimestamp: null name: ssh-key namespace: ${SPOKE_CLUSTER_NAME} labels: name: ssh-key cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE stringData: ssh_private_key: | $(cat ./ssh-key | awk '{printf " %s\n", $0}') ssh_public_key: $(cat ./ssh-key.pub) EOF # Spoke Cluster Pull Secret cat > 01_secret-pull-secret.yaml <<EOF apiVersion: v1 kind: Secret metadata: creationTimestamp: null name: pull-secret namespace: ${SPOKE_CLUSTER_NAME} labels: name: pull-secret cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE data: .dockerconfigjson: $(oc get secret/pull-secret -n openshift-config -o jsonpath='{.data.\.dockerconfigjson}') EOF # Custom Root CAs for the Spoke Cluster cat > 01_cm_custom-root-ca.yaml <<EOF kind: ConfigMap apiVersion: v1 metadata: name: custom-root-ca namespace: ${SPOKE_CLUSTER_NAME} labels: name: custom-root-ca cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE config.openshift.io/inject-trusted-cabundle: 'true' data: {} EOF # Spoke Cluster AgentClusterInstall CR cat > 02_agentclusterinstall.yaml <<EOF apiVersion: extensions.hive.openshift.io/v1beta1 kind: AgentClusterInstall metadata: name: ${SPOKE_CLUSTER_NAME} namespace: ${SPOKE_CLUSTER_NAME} labels: name: agentclusterinstall cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE spec: clusterDeploymentRef: name: ${SPOKE_CLUSTER_NAME} imageSetRef: name: img4.11.34-x86-64-appsub # if using UserManagedNetworking VIPs are not needed #apiVIP: "${SPOKE_CLUSTER_API_VIP}" #ingressVIP: "${SPOKE_CLUSTER_APP_VIP}" holdInstallation: true networking: networkType: openShiftSDN # userManagedNetwork == true if using an external LB userManagedNetworking: true clusterNetwork: - cidr: "100.80.0.0/14" hostPrefix: 23 serviceNetwork: - "100.126.0.0/16" # machineNetwork defines the subnet(s) that the VMs are in # If using UserManagedNetworking machineNetworks cannot be defined #machineNetwork: # - cidr: "${SPOKE_CLUSTER_VM_SUBNET}" provisionRequirements: controlPlaneAgents: 3 workerAgents: 7 sshPublicKey: "$(cat ./ssh-key.pub)" proxy: httpProxy: "$(oc get proxy/cluster -o jsonpath='{.status.httpProxy}')" httpsProxy: "$(oc get proxy/cluster -o jsonpath='{.status.httpsProxy}')" noProxy: "IP.ADDRESS.HERE/24,$(oc get proxy/cluster -o jsonpath='{.status.noProxy}')" EOF # Spoke Cluster ClusterDeployment CR cat > 03_clusterdeployment.yaml <<EOF --- apiVersion: hive.openshift.io/v1 kind: ClusterDeployment metadata: annotations: agentBareMetal-agentSelector/autoSelect: "true" name: ${SPOKE_CLUSTER_NAME} namespace: ${SPOKE_CLUSTER_NAME} labels: name: clusterdeployment cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE cluster.open-cluster-management.io/clusterset: default spec: installAttemptsLimit: 0 baseDomain: ${SPOKE_CLUSTER_DOMAIN} clusterName: ${SPOKE_CLUSTER_NAME} installed: false clusterInstallRef: group: extensions.hive.openshift.io kind: AgentClusterInstall name: ${SPOKE_CLUSTER_NAME} version: v1beta1 platform: agentBareMetal: agentSelector: matchLabels: cluster-name: ${SPOKE_CLUSTER_NAME} agentBareMetal-generated-infraenv-ai-flow: ${SPOKE_CLUSTER_NAME} pullSecretRef: name: pull-secret certificateBundles: - name: custom-root-ca certificateSecretRef: name: custom-root-ca EOF # Spoke Cluster KlusterletAddonConfig CR cat > 04_klusterletaddonconfig.yaml <<EOF --- apiVersion: agent.open-cluster-management.io/v1 kind: KlusterletAddonConfig metadata: name: $SPOKE_CLUSTER_NAME namespace: $SPOKE_CLUSTER_NAME labels: name: klusterletaddonconfig cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE spec: clusterName: $SPOKE_CLUSTER_NAME clusterNamespace: $SPOKE_CLUSTER_NAME clusterLabels: cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE applicationManager: enabled: true policyController: enabled: true searchCollector: enabled: true certPolicyController: enabled: true iamPolicyController: enabled: true EOF # Spoke Cluster ManagedCluster CR cat > 05_managedcluster.yaml <<EOF --- apiVersion: cluster.open-cluster-management.io/v1 kind: ManagedCluster metadata: name: $SPOKE_CLUSTER_NAME namespace: $SPOKE_CLUSTER_NAME labels: name: managedcluster cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE spec: hubAcceptsClient: true EOF # Spoke Cluster InfraEnv CR cat > 07_infraenv.yaml <<EOF --- apiVersion: agent-install.openshift.io/v1beta1 kind: InfraEnv metadata: name: $SPOKE_CLUSTER_NAME namespace: $SPOKE_CLUSTER_NAME labels: name: infraenv cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE agentclusterinstalls.extensions.hive.openshift.io/location: $SPOKE_CLUSTER_LOCATION networkType: static spec: agentLabels: agentclusterinstalls.extensions.hive.openshift.io/location: $SPOKE_CLUSTER_LOCATION clusterRef: name: $SPOKE_CLUSTER_NAME namespace: $SPOKE_CLUSTER_NAME sshAuthorizedKey: "$(cat ./ssh-key.pub)" pullSecretRef: name: pull-secret nmStateConfigLabelSelector: matchLabels: cluster-name: $SPOKE_CLUSTER_NAME additionalNTPSources: - $NTP_SERVER1 - $NTP_SERVER2 proxy: httpProxy: "$(oc get proxy/cluster -o jsonpath='{.status.httpProxy}')" httpsProxy: "$(oc get proxy/cluster -o jsonpath='{.status.httpsProxy}')" noProxy: "153.2.255.0/24,$(oc get proxy/cluster -o jsonpath='{.status.noProxy}')" EOF # Spoke Cluster NMStateConfig CR - Node 1 function generateNMStateConfigFile () { NODE_NAME=$1 NODE192_ADDRESS=$2 NODE224_ADDRESS=$3 NODE192_MAC_ADDRESS=$4 NODE224_MAC_ADDRESS=$5 cat > 11_nmstate_$NODE_NAME.yaml <<EOF --- apiVersion: agent-install.openshift.io/v1beta1 kind: NMStateConfig metadata: name: $NODE_NAME namespace: $SPOKE_CLUSTER_NAME labels: name: nmstateconfig cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE spec: config: dns-resolver: config: server: - $DNS_SERVER1 - $DNS_SERVER2 search: - YOURZONE.COM - MYZONE.COM - OURZONE.COM interfaces: - ipv4: address: - ip: ${NODE192_ADDRESS} prefix-length: 20 dhcp: false enabled: true ipv6: enabled: false mtu: 1500 name: ens192 state: up type: ethernet - ipv4: address: - ip: ${NODE224_ADDRESS} prefix-length: 20 dhcp: false enabled: true ipv6: enabled: false mtu: 1500 name: ens224 state: up type: ethernet routes: config: - destination: 0.0.0.0/0 next-hop-address: $GATEWAY_IP next-hop-interface: ens224 table-id: 254 interfaces: - name: ens192 macAddress: $NODE192_MAC_ADDRESS - name: ens224 macAddress: $NODE224_MAC_ADDRESS EOF } # generateNMStateConfigFile HOSTNAME ENS192_IP ENS224_IP ENS192_MAC ENS224_MAC # generateNMStateConfigFile HOSTNAME VSAN_IP PUBLIC_IP VSAN_MAC PUBLIC_MAC # Masters generateNMStateConfigFile your_master_node_name "interface1_IP" "interface2_IP" "interface1_MAC" "interface2_MAC" # Infra generateNMStateConfigFile your_infra_node_name "interface1_IP" "interface2_IP" "interface1_MAC" "interface2_MAC" # Worker/Storage generateNMStateConfigFile your_storage_worker_node_name "interface1_IP" "interface2_IP" "interface1_MAC" "interface2_MAC" # Worker generateNMStateConfigFile your_worker_node_name "interface1_IP" "interface2_IP" "interface1_MAC" "interface2_MAC" ``` --- ## Bonded Networks ```bash= export SPOKE_CLUSTER_NAME="YOUR_CLUSTER_NAME" export SPOKE_CLUSTER_DOMAIN="YOUR_DOMAIN" export SPOKE_CLUSTER_TYPE="full" export DNS_SERVER1="DNS_SERVER_1" export DNS_SERVER2="DNS_SERVER_2" export GATEWAY_IP="Gateway_IP" # createBondedNMStateConfig NODE_NAME BOND0_ADDRESS BOND1_ADDRESS ENO1_MAC_ADDRESS ENO2_MAC_ADDRESS ENO3_MAC_ADDRESS ENO4_MAC_ADDRESS function createBondedNMStateConfig () { NODE_NAME=$1 BOND0_ADDRESS=$2 BOND1_ADDRESS=$3 ENO1_MAC_ADDRESS=$4 ENO2_MAC_ADDRESS=$5 ENO3_MAC_ADDRESS=$6 ENO4_MAC_ADDRESS=$7 cat > 11_nmstate_$NODE_NAME.yaml <<EOF --- apiVersion: agent-install.openshift.io/v1beta1 kind: NMStateConfig metadata: name: $NODE_NAME namespace: $SPOKE_CLUSTER_NAME labels: name: nmstateconfig cloud: baremetal vendor: OpenShift cluster-name: $SPOKE_CLUSTER_NAME cluster-domain: $SPOKE_CLUSTER_DOMAIN cluster-role: ztp-spoke cluster-type: $SPOKE_CLUSTER_TYPE spec: config: dns-resolver: config: server: - $DNS_SERVER1 - $DNS_SERVER2 search: - domain1.com - domain2.com interfaces: - name: eno1 type: ethernet state: up - name: eno2 type: ethernet state: up - name: eno3 type: ethernet state: up - name: eno4 type: ethernet state: up - name: bond0 type: bond state: down ipv4: address: - ip: ${BOND0_ADDRESS} prefix-length: 20 dhcp: false enabled: true ipv6: enabled: false mtu: 1500 link-aggregation: mode: active-backup options: primary: eno1 port: - eno1 - eno3 - name: bond1 type: bond state: up ipv4: address: - ip: ${BOND1_ADDRESS} prefix-length: 20 dhcp: false enabled: true ipv6: enabled: false mtu: 1500 link-aggregation: mode: active-backup options: primary: eno2 port: - eno2 - eno4 routes: config: - destination: 0.0.0.0/0 next-hop-address: $GATEWAY_IP next-hop-interface: bond1 table-id: 254 interfaces: - name: eno1 macAddress: $ENO1_MAC_ADDRESS - name: eno2 macAddress: $ENO2_MAC_ADDRESS - name: eno3 macAddress: $ENO3_MAC_ADDRESS - name: eno4 macAddress: $ENO4_MAC_ADDRESS EOF } createBondedNMStateConfig your_node_name_here \ "ip.address.1.here" \ "ip.address.2.here" \ "MA:CA:DD:RE:SS:01" \ "MA:CA:DD:RE:SS:02" \ "MA:CA:DD:RE:SS:03" \ "MA:CA:DD:RE:SS:04" ``` --- ## Optional: Deploy ZTP Mirror > Make sure to replace the placeholder Jinja2 variables for the Proxy with proper values ```yaml= apiVersion: v1 kind: Namespace metadata: creationTimestamp: null name: ztp-mirror spec: {} --- apiVersion: v1 kind: ConfigMap metadata: name: mirror-config namespace: ztp-mirror data: config.yml: |- app: assets: - source: https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos/4.11/latest/rhcos-live.x86_64.iso destination: "/tmp/server/pub/openshift-v4/x86_64/dependencies/rhcos/4.11/latest/rhcos-live.x86_64.iso" - source: https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos/4.11/latest/rhcos-live-rootfs.x86_64.img destination: "/tmp/server/pub/openshift-v4/x86_64/dependencies/rhcos/4.11/latest/rhcos-live-rootfs.x86_64.img" - source: https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos/4.12/latest/rhcos-live.x86_64.iso destination: "/tmp/server/pub/openshift-v4/x86_64/dependencies/rhcos/4.12/latest/rhcos-live.x86_64.iso" - source: https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos/4.12/latest/rhcos-live-rootfs.x86_64.img destination: "/tmp/server/pub/openshift-v4/x86_64/dependencies/rhcos/4.12/latest/rhcos-live-rootfs.x86_64.img" #overwrite: true server: host: 0.0.0.0 base_path: "/pub/" fs_path: "/tmp/server/pub" skip_tls_verify: true port: 8080 timeouts: server: 0 read: 0 write: 0 idle: 0 --- kind: ConfigMap apiVersion: v1 metadata: name: trusted-ca namespace: ztp-mirror labels: config.openshift.io/inject-trusted-cabundle: 'true' data: {} --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: ztp-mirror namespace: ztp-mirror spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 20Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: mirror-server namespace: ztp-mirror spec: selector: matchLabels: app: mirror-server replicas: 1 strategy: type: Recreate template: metadata: labels: app: mirror-server spec: volumes: - name: ztp-mirror persistentVolumeClaim: claimName: ztp-mirror - name: mirror-config configMap: name: mirror-config - name: trusted-ca configMap: name: trusted-ca items: - key: ca-bundle.crt path: tls-ca-bundle.pem containers: - name: mirror-server image: quay.io/kenmoini/go-http-mirror:latest imagePullPolicy: Always env: - name: HTTP_PROXY value: "{{ cluster_wide_http_proxy }}" - name: http_proxy value: "{{ cluster_wide_http_proxy }}" - name: HTTPS_PROXY value: "{{ cluster_wide_https_proxy }}" - name: https_proxy value: "{{ cluster_wide_https_proxy }}" - name: NO_PROXY value: "{{ cluster_wide_no_proxy }}" - name: no_proxy value: "{{ cluster_wide_no_proxy }}" ports: - containerPort: 8080 resources: requests: cpu: "100m" memory: "100Mi" limits: cpu: "500m" memory: "500Mi" volumeMounts: - name: mirror-config mountPath: /etc/ztp-mirror - name: ztp-mirror mountPath: /tmp/server/pub - mountPath: /etc/pki/ca-trust/extracted/pem name: trusted-ca readOnly: true --- apiVersion: v1 kind: Service metadata: name: ztp-mirror namespace: ztp-mirror spec: selector: app: mirror-server ports: - protocol: TCP port: 8080 targetPort: 8080 --- apiVersion: route.openshift.io/v1 kind: Route metadata: name: ztp-mirror namespace: ztp-mirror annotations: haproxy.router.openshift.io/timeout: "600s" spec: # No need to specify the host unless you want it on a specific FQDN #host: ztp-mirror-ztp-mirror.apps.core-ocp.lab.kemo.network path: / to: kind: Service name: ztp-mirror port: targetPort: 8080 tls: termination: edge insecureEdgeTerminationPolicy: Allow wildcardPolicy: None ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up